kernel: bump 4.14 to 4.14.144
[oweals/openwrt.git] / target / linux / gemini / patches-4.14 / 0029-usb-host-fotg2-add-silicon-clock-handling.patch
1 From acd19633751f14607ccd76f9dfde5bde7935766c Mon Sep 17 00:00:00 2001
2 From: Linus Walleij <linus.walleij@linaro.org>
3 Date: Fri, 21 Apr 2017 20:46:12 +0200
4 Subject: [PATCH 29/31] usb: host: fotg2: add silicon clock handling
5
6 When used in a system with software-controller silicon clocks,
7 the FOTG210 needs to grab, prepare and enable the clock.
8 This is needed on for example the Cortina Gemini, where the
9 platform will by default gate off the clock unless the
10 peripheral (in this case the USB driver) grabs and enables
11 the clock.
12
13 Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
14 ---
15  drivers/usb/host/fotg210-hcd.c | 26 ++++++++++++++++++++++----
16  drivers/usb/host/fotg210.h     |  3 +++
17  2 files changed, 25 insertions(+), 4 deletions(-)
18
19 --- a/drivers/usb/host/fotg210-hcd.c
20 +++ b/drivers/usb/host/fotg210-hcd.c
21 @@ -45,6 +45,7 @@
22  #include <linux/uaccess.h>
23  #include <linux/platform_device.h>
24  #include <linux/io.h>
25 +#include <linux/clk.h>
26  
27  #include <asm/byteorder.h>
28  #include <asm/irq.h>
29 @@ -5639,7 +5640,7 @@ static int fotg210_hcd_probe(struct plat
30         hcd->regs = devm_ioremap_resource(&pdev->dev, res);
31         if (IS_ERR(hcd->regs)) {
32                 retval = PTR_ERR(hcd->regs);
33 -               goto failed;
34 +               goto failed_put_hcd;
35         }
36  
37         hcd->rsrc_start = res->start;
38 @@ -5649,22 +5650,35 @@ static int fotg210_hcd_probe(struct plat
39  
40         fotg210->caps = hcd->regs;
41  
42 +       /* It's OK not to supply this clock */
43 +       fotg210->pclk = clk_get(dev, "PCLK");
44 +       if (!IS_ERR(fotg210->pclk)) {
45 +               retval = clk_prepare_enable(fotg210->pclk);
46 +               if (retval) {
47 +                       dev_err(dev, "failed to enable PCLK\n");
48 +                       goto failed_dis_clk;
49 +               }
50 +       }
51 +
52         retval = fotg210_setup(hcd);
53         if (retval)
54 -               goto failed;
55 +               goto failed_dis_clk;
56  
57         fotg210_init(fotg210);
58  
59         retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
60         if (retval) {
61                 dev_err(dev, "failed to add hcd with err %d\n", retval);
62 -               goto failed;
63 +               goto failed_dis_clk;
64         }
65         device_wakeup_enable(hcd->self.controller);
66  
67         return retval;
68  
69 -failed:
70 +failed_dis_clk:
71 +       if (!IS_ERR(fotg210->pclk))
72 +               clk_disable_unprepare(fotg210->pclk);
73 +failed_put_hcd:
74         usb_put_hcd(hcd);
75  fail_create_hcd:
76         dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval);
77 @@ -5680,6 +5694,10 @@ static int fotg210_hcd_remove(struct pla
78  {
79         struct device *dev = &pdev->dev;
80         struct usb_hcd *hcd = dev_get_drvdata(dev);
81 +       struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
82 +
83 +       if (!IS_ERR(fotg210->pclk))
84 +               clk_disable_unprepare(fotg210->pclk);
85  
86         if (!hcd)
87                 return 0;
88 --- a/drivers/usb/host/fotg210.h
89 +++ b/drivers/usb/host/fotg210.h
90 @@ -182,6 +182,9 @@ struct fotg210_hcd {                        /* one per contro
91  #      define COUNT(x)
92  #endif
93  
94 +       /* silicon clock */
95 +       struct clk              *pclk;
96 +
97         /* debug files */
98         struct dentry           *debug_dir;
99  };