arm: mvebu: i2c come back in defconfig
[firefly-linux-kernel-4.4.55.git] / drivers / usb / host / ehci-mxc.c
1 /*
2  * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
3  * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 #include <linux/platform_device.h>
21 #include <linux/clk.h>
22 #include <linux/delay.h>
23 #include <linux/usb/otg.h>
24 #include <linux/usb/ulpi.h>
25 #include <linux/slab.h>
26
27 #include <linux/platform_data/usb-ehci-mxc.h>
28
29 #include <asm/mach-types.h>
30
31 #define ULPI_VIEWPORT_OFFSET    0x170
32
33 struct ehci_mxc_priv {
34         struct clk *usbclk, *ahbclk, *phyclk;
35         struct usb_hcd *hcd;
36 };
37
38 /* called during probe() after chip reset completes */
39 static int ehci_mxc_setup(struct usb_hcd *hcd)
40 {
41         hcd->has_tt = 1;
42
43         return ehci_setup(hcd);
44 }
45
46 static const struct hc_driver ehci_mxc_hc_driver = {
47         .description = hcd_name,
48         .product_desc = "Freescale On-Chip EHCI Host Controller",
49         .hcd_priv_size = sizeof(struct ehci_hcd),
50
51         /*
52          * generic hardware linkage
53          */
54         .irq = ehci_irq,
55         .flags = HCD_USB2 | HCD_MEMORY,
56
57         /*
58          * basic lifecycle operations
59          */
60         .reset = ehci_mxc_setup,
61         .start = ehci_run,
62         .stop = ehci_stop,
63         .shutdown = ehci_shutdown,
64
65         /*
66          * managing i/o requests and associated device resources
67          */
68         .urb_enqueue = ehci_urb_enqueue,
69         .urb_dequeue = ehci_urb_dequeue,
70         .endpoint_disable = ehci_endpoint_disable,
71         .endpoint_reset = ehci_endpoint_reset,
72
73         /*
74          * scheduling support
75          */
76         .get_frame_number = ehci_get_frame,
77
78         /*
79          * root hub support
80          */
81         .hub_status_data = ehci_hub_status_data,
82         .hub_control = ehci_hub_control,
83         .bus_suspend = ehci_bus_suspend,
84         .bus_resume = ehci_bus_resume,
85         .relinquish_port = ehci_relinquish_port,
86         .port_handed_over = ehci_port_handed_over,
87
88         .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
89 };
90
91 static int ehci_mxc_drv_probe(struct platform_device *pdev)
92 {
93         struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
94         struct usb_hcd *hcd;
95         struct resource *res;
96         int irq, ret;
97         unsigned int flags;
98         struct ehci_mxc_priv *priv;
99         struct device *dev = &pdev->dev;
100         struct ehci_hcd *ehci;
101
102         dev_info(&pdev->dev, "initializing i.MX USB Controller\n");
103
104         if (!pdata) {
105                 dev_err(dev, "No platform data given, bailing out.\n");
106                 return -EINVAL;
107         }
108
109         irq = platform_get_irq(pdev, 0);
110
111         hcd = usb_create_hcd(&ehci_mxc_hc_driver, dev, dev_name(dev));
112         if (!hcd)
113                 return -ENOMEM;
114
115         priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
116         if (!priv) {
117                 ret = -ENOMEM;
118                 goto err_alloc;
119         }
120
121         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
122         if (!res) {
123                 dev_err(dev, "Found HC with no register addr. Check setup!\n");
124                 ret = -ENODEV;
125                 goto err_alloc;
126         }
127
128         hcd->rsrc_start = res->start;
129         hcd->rsrc_len = resource_size(res);
130
131         hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
132         if (!hcd->regs) {
133                 dev_err(dev, "error mapping memory\n");
134                 ret = -EFAULT;
135                 goto err_alloc;
136         }
137
138         /* enable clocks */
139         priv->usbclk = devm_clk_get(&pdev->dev, "ipg");
140         if (IS_ERR(priv->usbclk)) {
141                 ret = PTR_ERR(priv->usbclk);
142                 goto err_alloc;
143         }
144         clk_prepare_enable(priv->usbclk);
145
146         priv->ahbclk = devm_clk_get(&pdev->dev, "ahb");
147         if (IS_ERR(priv->ahbclk)) {
148                 ret = PTR_ERR(priv->ahbclk);
149                 goto err_clk_ahb;
150         }
151         clk_prepare_enable(priv->ahbclk);
152
153         /* "dr" device has its own clock on i.MX51 */
154         priv->phyclk = devm_clk_get(&pdev->dev, "phy");
155         if (IS_ERR(priv->phyclk))
156                 priv->phyclk = NULL;
157         if (priv->phyclk)
158                 clk_prepare_enable(priv->phyclk);
159
160
161         /* call platform specific init function */
162         if (pdata->init) {
163                 ret = pdata->init(pdev);
164                 if (ret) {
165                         dev_err(dev, "platform init failed\n");
166                         goto err_init;
167                 }
168                 /* platforms need some time to settle changed IO settings */
169                 mdelay(10);
170         }
171
172         ehci = hcd_to_ehci(hcd);
173
174         /* EHCI registers start at offset 0x100 */
175         ehci->caps = hcd->regs + 0x100;
176         ehci->regs = hcd->regs + 0x100 +
177                 HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
178
179         /* set up the PORTSCx register */
180         ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]);
181
182         /* is this really needed? */
183         msleep(10);
184
185         /* Initialize the transceiver */
186         if (pdata->otg) {
187                 pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET;
188                 ret = usb_phy_init(pdata->otg);
189                 if (ret) {
190                         dev_err(dev, "unable to init transceiver, probably missing\n");
191                         ret = -ENODEV;
192                         goto err_add;
193                 }
194                 ret = otg_set_vbus(pdata->otg->otg, 1);
195                 if (ret) {
196                         dev_err(dev, "unable to enable vbus on transceiver\n");
197                         goto err_add;
198                 }
199         }
200
201         priv->hcd = hcd;
202         platform_set_drvdata(pdev, priv);
203
204         ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
205         if (ret)
206                 goto err_add;
207
208         if (pdata->otg) {
209                 /*
210                  * efikamx and efikasb have some hardware bug which is
211                  * preventing usb to work unless CHRGVBUS is set.
212                  * It's in violation of USB specs
213                  */
214                 if (machine_is_mx51_efikamx() || machine_is_mx51_efikasb()) {
215                         flags = usb_phy_io_read(pdata->otg,
216                                                         ULPI_OTG_CTRL);
217                         flags |= ULPI_OTG_CTRL_CHRGVBUS;
218                         ret = usb_phy_io_write(pdata->otg, flags,
219                                                         ULPI_OTG_CTRL);
220                         if (ret) {
221                                 dev_err(dev, "unable to set CHRVBUS\n");
222                                 goto err_add;
223                         }
224                 }
225         }
226
227         return 0;
228
229 err_add:
230         if (pdata && pdata->exit)
231                 pdata->exit(pdev);
232 err_init:
233         if (priv->phyclk)
234                 clk_disable_unprepare(priv->phyclk);
235
236         clk_disable_unprepare(priv->ahbclk);
237 err_clk_ahb:
238         clk_disable_unprepare(priv->usbclk);
239 err_alloc:
240         usb_put_hcd(hcd);
241         return ret;
242 }
243
244 static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
245 {
246         struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
247         struct ehci_mxc_priv *priv = platform_get_drvdata(pdev);
248         struct usb_hcd *hcd = priv->hcd;
249
250         if (pdata && pdata->exit)
251                 pdata->exit(pdev);
252
253         if (pdata->otg)
254                 usb_phy_shutdown(pdata->otg);
255
256         usb_remove_hcd(hcd);
257         usb_put_hcd(hcd);
258         platform_set_drvdata(pdev, NULL);
259
260         clk_disable_unprepare(priv->usbclk);
261         clk_disable_unprepare(priv->ahbclk);
262
263         if (priv->phyclk)
264                 clk_disable_unprepare(priv->phyclk);
265
266         return 0;
267 }
268
269 static void ehci_mxc_drv_shutdown(struct platform_device *pdev)
270 {
271         struct ehci_mxc_priv *priv = platform_get_drvdata(pdev);
272         struct usb_hcd *hcd = priv->hcd;
273
274         if (hcd->driver->shutdown)
275                 hcd->driver->shutdown(hcd);
276 }
277
278 MODULE_ALIAS("platform:mxc-ehci");
279
280 static struct platform_driver ehci_mxc_driver = {
281         .probe = ehci_mxc_drv_probe,
282         .remove = __exit_p(ehci_mxc_drv_remove),
283         .shutdown = ehci_mxc_drv_shutdown,
284         .driver = {
285                    .name = "mxc-ehci",
286         },
287 };