fotg210-udc: Handle PCLK
authorLinus Walleij <linus.walleij@linaro.org>
Mon, 14 Nov 2022 11:52:00 +0000 (12:52 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 22 Nov 2022 16:25:23 +0000 (17:25 +0100)
This adds optional handling of the peripheral clock PCLK.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20221114115201.302887-3-linus.walleij@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/fotg210/fotg210-udc.c
drivers/usb/fotg210/fotg210-udc.h

index 4026103..de0f72c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <linux/clk.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/phy.h>
 
@@ -1132,6 +1133,10 @@ int fotg210_udc_remove(struct platform_device *pdev)
        fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req);
        for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
                kfree(fotg210->ep[i]);
+
+       if (!IS_ERR(fotg210->pclk))
+               clk_disable_unprepare(fotg210->pclk);
+
        kfree(fotg210);
 
        return 0;
@@ -1167,17 +1172,34 @@ int fotg210_udc_probe(struct platform_device *pdev)
 
        fotg210->dev = dev;
 
+       /* It's OK not to supply this clock */
+       fotg210->pclk = devm_clk_get(dev, "PCLK");
+       if (!IS_ERR(fotg210->pclk)) {
+               ret = clk_prepare_enable(fotg210->pclk);
+               if (ret) {
+                       dev_err(dev, "failed to enable PCLK\n");
+                       return ret;
+               }
+       } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) {
+               /*
+                * Percolate deferrals, for anything else,
+                * just live without the clocking.
+                */
+               ret = -EPROBE_DEFER;
+               goto err;
+       }
+
        fotg210->phy = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0);
        if (IS_ERR(fotg210->phy)) {
                ret = PTR_ERR(fotg210->phy);
                if (ret == -EPROBE_DEFER)
-                       goto err;
+                       goto err_pclk;
                dev_info(dev, "no PHY found\n");
                fotg210->phy = NULL;
        } else {
                ret = usb_phy_init(fotg210->phy);
                if (ret)
-                       goto err;
+                       goto err_pclk;
                dev_info(dev, "found and initialized PHY\n");
        }
 
@@ -1277,6 +1299,10 @@ err_map:
 err_alloc:
        for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
                kfree(fotg210->ep[i]);
+err_pclk:
+       if (!IS_ERR(fotg210->pclk))
+               clk_disable_unprepare(fotg210->pclk);
+
        kfree(fotg210);
 
 err:
index e3067d2..fadb57c 100644 (file)
@@ -231,6 +231,7 @@ struct fotg210_ep {
 struct fotg210_udc {
        spinlock_t              lock; /* protect the struct */
        void __iomem            *reg;
+       struct clk              *pclk;
 
        unsigned long           irq_trigger;