diff options
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.patch | 99 |
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; + }; |