misc: aspeed-lpc: Request and enable LPC clock
authorJoel Stanley <joel@jms.id.au>
Mon, 19 Feb 2018 07:24:21 +0000 (17:54 +1030)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Mar 2018 17:20:51 +0000 (18:20 +0100)
The LPC device needs to ensure it's clock is enabled before it can do
anything.

In the past the clock was enabled and left running by u-boot, however
Linux now has an upstream clock driver that disables unused clocks.

Tested-by: Lei YU <mine260309@gmail.com>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Cyril Bur <cyrilbur@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/aspeed-lpc-ctrl.c

index b543964..1827b7a 100644 (file)
@@ -7,6 +7,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/clk.h>
 #include <linux/mfd/syscon.h>
 #include <linux/miscdevice.h>
 #include <linux/mm.h>
@@ -26,6 +27,7 @@
 struct aspeed_lpc_ctrl {
        struct miscdevice       miscdev;
        struct regmap           *regmap;
+       struct clk              *clk;
        phys_addr_t             mem_base;
        resource_size_t         mem_size;
        u32             pnor_size;
@@ -221,16 +223,33 @@ static int aspeed_lpc_ctrl_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
+       lpc_ctrl->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(lpc_ctrl->clk)) {
+               dev_err(dev, "couldn't get clock\n");
+               return PTR_ERR(lpc_ctrl->clk);
+       }
+       rc = clk_prepare_enable(lpc_ctrl->clk);
+       if (rc) {
+               dev_err(dev, "couldn't enable clock\n");
+               return rc;
+       }
+
        lpc_ctrl->miscdev.minor = MISC_DYNAMIC_MINOR;
        lpc_ctrl->miscdev.name = DEVICE_NAME;
        lpc_ctrl->miscdev.fops = &aspeed_lpc_ctrl_fops;
        lpc_ctrl->miscdev.parent = dev;
        rc = misc_register(&lpc_ctrl->miscdev);
-       if (rc)
+       if (rc) {
                dev_err(dev, "Unable to register device\n");
-       else
-               dev_info(dev, "Loaded at %pr\n", &resm);
+               goto err;
+       }
+
+       dev_info(dev, "Loaded at %pr\n", &resm);
+
+       return 0;
 
+err:
+       clk_disable_unprepare(lpc_ctrl->clk);
        return rc;
 }
 
@@ -239,6 +258,7 @@ static int aspeed_lpc_ctrl_remove(struct platform_device *pdev)
        struct aspeed_lpc_ctrl *lpc_ctrl = dev_get_drvdata(&pdev->dev);
 
        misc_deregister(&lpc_ctrl->miscdev);
+       clk_disable_unprepare(lpc_ctrl->clk);
 
        return 0;
 }