aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/gemini/patches-4.14/0029-usb-host-fotg2-add-silicon-clock-handling.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/gemini/patches-4.14/0029-usb-host-fotg2-add-silicon-clock-handling.patch')
-rw-r--r--target/linux/gemini/patches-4.14/0029-usb-host-fotg2-add-silicon-clock-handling.patch99
1 files changed, 99 insertions, 0 deletions
diff --git a/target/linux/gemini/patches-4.14/0029-usb-host-fotg2-add-silicon-clock-handling.patch b/target/linux/gemini/patches-4.14/0029-usb-host-fotg2-add-silicon-clock-handling.patch
new file mode 100644
index 0000000000..4a1faf938e
--- /dev/null
+++ b/target/linux/gemini/patches-4.14/0029-usb-host-fotg2-add-silicon-clock-handling.patch
@@ -0,0 +1,99 @@
+From acd19633751f14607ccd76f9dfde5bde7935766c Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Fri, 21 Apr 2017 20:46:12 +0200
+Subject: [PATCH 29/31] usb: host: fotg2: add silicon clock handling
+
+When used in a system with software-controller silicon clocks,
+the FOTG210 needs to grab, prepare and enable the clock.
+This is needed on for example the Cortina Gemini, where the
+platform will by default gate off the clock unless the
+peripheral (in this case the USB driver) grabs and enables
+the clock.
+
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/usb/host/fotg210-hcd.c | 26 ++++++++++++++++++++++----
+ drivers/usb/host/fotg210.h | 3 +++
+ 2 files changed, 25 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/fotg210-hcd.c
++++ b/drivers/usb/host/fotg210-hcd.c
+@@ -45,6 +45,7 @@
+ #include <linux/uaccess.h>
+ #include <linux/platform_device.h>
+ #include <linux/io.h>
++#include <linux/clk.h>
+
+ #include <asm/byteorder.h>
+ #include <asm/irq.h>
+@@ -5635,7 +5636,7 @@ static int fotg210_hcd_probe(struct plat
+ hcd->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(hcd->regs)) {
+ retval = PTR_ERR(hcd->regs);
+- goto failed;
++ goto failed_put_hcd;
+ }
+
+ hcd->rsrc_start = res->start;
+@@ -5645,22 +5646,35 @@ static int fotg210_hcd_probe(struct plat
+
+ fotg210->caps = hcd->regs;
+
++ /* It's OK not to supply this clock */
++ fotg210->pclk = clk_get(dev, "PCLK");
++ if (!IS_ERR(fotg210->pclk)) {
++ retval = clk_prepare_enable(fotg210->pclk);
++ if (retval) {
++ dev_err(dev, "failed to enable PCLK\n");
++ goto failed_dis_clk;
++ }
++ }
++
+ retval = fotg210_setup(hcd);
+ if (retval)
+- goto failed;
++ goto failed_dis_clk;
+
+ fotg210_init(fotg210);
+
+ retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ if (retval) {
+ dev_err(dev, "failed to add hcd with err %d\n", retval);
+- goto failed;
++ goto failed_dis_clk;
+ }
+ device_wakeup_enable(hcd->self.controller);
+
+ return retval;
+
+-failed:
++failed_dis_clk:
++ if (!IS_ERR(fotg210->pclk))
++ clk_disable_unprepare(fotg210->pclk);
++failed_put_hcd:
+ usb_put_hcd(hcd);
+ fail_create_hcd:
+ dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval);
+@@ -5676,6 +5690,10 @@ static int fotg210_hcd_remove(struct pla
+ {
+ struct device *dev = &pdev->dev;
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
++ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
++
++ if (!IS_ERR(fotg210->pclk))
++ clk_disable_unprepare(fotg210->pclk);
+
+ if (!hcd)
+ return 0;
+--- a/drivers/usb/host/fotg210.h
++++ b/drivers/usb/host/fotg210.h
+@@ -182,6 +182,9 @@ struct fotg210_hcd { /* one per contro
+ # define COUNT(x)
+ #endif
+
++ /* silicon clock */
++ struct clk *pclk;
++
+ /* debug files */
+ struct dentry *debug_dir;
+ };