summaryrefslogtreecommitdiffstats
path: root/drivers/usb/fotg210
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2022-11-14 12:52:00 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-11-22 17:25:23 +0100
commit718a38d092ec920dd84a5e25510cc6721f527c3e (patch)
tree2d7a99abc75fe70bc82bbdf908565d1916f5c616 /drivers/usb/fotg210
parent5f217ccd520f155c2e3b3dd95627140dd5ec947e (diff)
downloadlinux-stable-718a38d092ec920dd84a5e25510cc6721f527c3e.tar.gz
linux-stable-718a38d092ec920dd84a5e25510cc6721f527c3e.tar.bz2
linux-stable-718a38d092ec920dd84a5e25510cc6721f527c3e.zip
fotg210-udc: Handle PCLK
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>
Diffstat (limited to 'drivers/usb/fotg210')
-rw-r--r--drivers/usb/fotg210/fotg210-udc.c30
-rw-r--r--drivers/usb/fotg210/fotg210-udc.h1
2 files changed, 29 insertions, 2 deletions
diff --git a/drivers/usb/fotg210/fotg210-udc.c b/drivers/usb/fotg210/fotg210-udc.c
index 4026103330e1..de0f72ca103c 100644
--- a/drivers/usb/fotg210/fotg210-udc.c
+++ b/drivers/usb/fotg210/fotg210-udc.c
@@ -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:
diff --git a/drivers/usb/fotg210/fotg210-udc.h b/drivers/usb/fotg210/fotg210-udc.h
index e3067d22a895..fadb57ca8d78 100644
--- a/drivers/usb/fotg210/fotg210-udc.h
+++ b/drivers/usb/fotg210/fotg210-udc.h
@@ -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;