blob: 6181549883afef022f3769e11adf3935d2c5980c [file] [log] [blame]
Andrew Victor39a269c2006-01-22 10:32:13 -08001/*
2 * OHCI HCD (Host Controller Driver) for USB.
3 *
4 * Copyright (C) 2004 SAN People (Pty) Ltd.
5 * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
6 *
David Brownell0365ee02006-06-19 14:27:20 -07007 * AT91 Bus Glue
Andrew Victor39a269c2006-01-22 10:32:13 -08008 *
9 * Based on fragments of 2.4 driver by Rick Bronson.
10 * Based on ohci-omap.c
11 *
12 * This file is licenced under the GPL.
13 */
14
15#include <linux/clk.h>
Manjunath Goudare3825b42013-09-21 16:38:42 +053016#include <linux/dma-mapping.h>
Jean-Christophe PLAGNIOL-VILLARD24197302011-11-21 06:55:18 +080017#include <linux/of_platform.h>
18#include <linux/of_gpio.h>
Manjunath Goudare3825b42013-09-21 16:38:42 +053019#include <linux/platform_device.h>
Jean-Christophe PLAGNIOL-VILLARDbcd23602012-10-30 05:12:23 +080020#include <linux/platform_data/atmel.h>
Manjunath Goudare3825b42013-09-21 16:38:42 +053021#include <linux/io.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/usb.h>
25#include <linux/usb/hcd.h>
Andrew Victor39a269c2006-01-22 10:32:13 -080026
David Brownell4bde4a42007-12-27 11:19:49 -080027#include <asm/gpio.h>
28
Manjunath Goudare3825b42013-09-21 16:38:42 +053029#include "ohci.h"
Andrew Victor39a269c2006-01-22 10:32:13 -080030
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +010031#define valid_port(index) ((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
32#define at91_for_each_port(index) \
33 for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++)
34
Boris BREZILLON6b0a1cf2013-08-01 19:09:13 +020035/* interface, function and usb clocks; sometimes also an AHB clock */
36static struct clk *iclk, *fclk, *uclk, *hclk;
Manjunath Goudare3825b42013-09-21 16:38:42 +053037/* interface and function clocks; sometimes also an AHB clock */
38
39#define DRIVER_DESC "OHCI Atmel driver"
40
41static const char hcd_name[] = "ohci-atmel";
42
43static struct hc_driver __read_mostly ohci_at91_hc_driver;
David Brownell0365ee02006-06-19 14:27:20 -070044static int clocked;
Andrew Victor39a269c2006-01-22 10:32:13 -080045
46extern int usb_disabled(void);
47
48/*-------------------------------------------------------------------------*/
49
Andrew Victored077bb2007-02-16 10:18:58 -080050static void at91_start_clock(void)
51{
Boris BREZILLON6b0a1cf2013-08-01 19:09:13 +020052 if (IS_ENABLED(CONFIG_COMMON_CLK)) {
53 clk_set_rate(uclk, 48000000);
54 clk_prepare_enable(uclk);
55 }
Boris BREZILLON8e82d8d2013-06-19 13:21:08 +020056 clk_prepare_enable(hclk);
57 clk_prepare_enable(iclk);
58 clk_prepare_enable(fclk);
Andrew Victored077bb2007-02-16 10:18:58 -080059 clocked = 1;
60}
61
62static void at91_stop_clock(void)
63{
Boris BREZILLON8e82d8d2013-06-19 13:21:08 +020064 clk_disable_unprepare(fclk);
65 clk_disable_unprepare(iclk);
66 clk_disable_unprepare(hclk);
Boris BREZILLON6b0a1cf2013-08-01 19:09:13 +020067 if (IS_ENABLED(CONFIG_COMMON_CLK))
68 clk_disable_unprepare(uclk);
Andrew Victored077bb2007-02-16 10:18:58 -080069 clocked = 0;
70}
71
Andrew Victor39a269c2006-01-22 10:32:13 -080072static void at91_start_hc(struct platform_device *pdev)
73{
74 struct usb_hcd *hcd = platform_get_drvdata(pdev);
75 struct ohci_regs __iomem *regs = hcd->regs;
76
David Brownell0365ee02006-06-19 14:27:20 -070077 dev_dbg(&pdev->dev, "start\n");
Andrew Victor39a269c2006-01-22 10:32:13 -080078
79 /*
80 * Start the USB clocks.
81 */
Andrew Victored077bb2007-02-16 10:18:58 -080082 at91_start_clock();
Andrew Victor39a269c2006-01-22 10:32:13 -080083
84 /*
85 * The USB host controller must remain in reset.
86 */
87 writel(0, &regs->control);
88}
89
90static void at91_stop_hc(struct platform_device *pdev)
91{
92 struct usb_hcd *hcd = platform_get_drvdata(pdev);
93 struct ohci_regs __iomem *regs = hcd->regs;
94
David Brownell0365ee02006-06-19 14:27:20 -070095 dev_dbg(&pdev->dev, "stop\n");
Andrew Victor39a269c2006-01-22 10:32:13 -080096
97 /*
98 * Put the USB host controller into reset.
99 */
100 writel(0, &regs->control);
101
102 /*
103 * Stop the USB clocks.
104 */
Andrew Victored077bb2007-02-16 10:18:58 -0800105 at91_stop_clock();
Andrew Victor39a269c2006-01-22 10:32:13 -0800106}
107
108
109/*-------------------------------------------------------------------------*/
110
Bill Pembertonfb4e98a2012-11-19 13:26:20 -0500111static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
Andrew Victor39a269c2006-01-22 10:32:13 -0800112
113/* configure so an HC device and id are always provided */
114/* always called with process context; sleeping is OK */
115
116
117/**
David Brownell0365ee02006-06-19 14:27:20 -0700118 * usb_hcd_at91_probe - initialize AT91-based HCDs
Andrew Victor39a269c2006-01-22 10:32:13 -0800119 * Context: !in_interrupt()
120 *
121 * Allocates basic resources for this USB host controller, and
122 * then invokes the start() method for the HCD associated with it
123 * through the hotplug entry's driver_data.
Andrew Victor39a269c2006-01-22 10:32:13 -0800124 */
Bill Pemberton41ac7b32012-11-19 13:21:48 -0500125static int usb_hcd_at91_probe(const struct hc_driver *driver,
David Brownell0365ee02006-06-19 14:27:20 -0700126 struct platform_device *pdev)
Andrew Victor39a269c2006-01-22 10:32:13 -0800127{
Manjunath Goudare3825b42013-09-21 16:38:42 +0530128 struct at91_usbh_data *board;
129 struct ohci_hcd *ohci;
Andrew Victor39a269c2006-01-22 10:32:13 -0800130 int retval;
131 struct usb_hcd *hcd = NULL;
Boris BREZILLONfb5f1832013-12-08 15:59:59 +0100132 struct device *dev = &pdev->dev;
133 struct resource *res;
134 int irq;
Andrew Victor39a269c2006-01-22 10:32:13 -0800135
Boris BREZILLONfb5f1832013-12-08 15:59:59 +0100136 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
137 if (!res) {
138 dev_dbg(dev, "hcd probe: missing memory resource\n");
139 return -ENXIO;
Andrew Victor39a269c2006-01-22 10:32:13 -0800140 }
141
Boris BREZILLONfb5f1832013-12-08 15:59:59 +0100142 irq = platform_get_irq(pdev, 0);
143 if (irq < 0) {
144 dev_dbg(dev, "hcd probe: missing irq resource\n");
145 return irq;
Andrew Victor39a269c2006-01-22 10:32:13 -0800146 }
147
Boris BREZILLON5b218a02013-12-09 09:51:54 +0100148 hcd = usb_create_hcd(driver, dev, "at91");
Andrew Victor39a269c2006-01-22 10:32:13 -0800149 if (!hcd)
150 return -ENOMEM;
Boris BREZILLONfb5f1832013-12-08 15:59:59 +0100151 hcd->rsrc_start = res->start;
152 hcd->rsrc_len = resource_size(res);
Andrew Victor39a269c2006-01-22 10:32:13 -0800153
Boris BREZILLONcca2bbb2013-12-09 09:51:53 +0100154 hcd->regs = devm_ioremap_resource(dev, res);
155 if (IS_ERR(hcd->regs)) {
156 retval = PTR_ERR(hcd->regs);
157 goto err;
Andrew Victor39a269c2006-01-22 10:32:13 -0800158 }
159
Boris BREZILLONfc7a3252013-12-09 09:51:55 +0100160 iclk = devm_clk_get(dev, "ohci_clk");
Jean-Christophe PLAGNIOL-VILLARD68134632011-12-08 16:32:00 +0100161 if (IS_ERR(iclk)) {
Boris BREZILLON5b218a02013-12-09 09:51:54 +0100162 dev_err(dev, "failed to get ohci_clk\n");
Jean-Christophe PLAGNIOL-VILLARD68134632011-12-08 16:32:00 +0100163 retval = PTR_ERR(iclk);
Boris BREZILLONcca2bbb2013-12-09 09:51:53 +0100164 goto err;
Jean-Christophe PLAGNIOL-VILLARD68134632011-12-08 16:32:00 +0100165 }
Boris BREZILLONfc7a3252013-12-09 09:51:55 +0100166 fclk = devm_clk_get(dev, "uhpck");
Jean-Christophe PLAGNIOL-VILLARD68134632011-12-08 16:32:00 +0100167 if (IS_ERR(fclk)) {
Boris BREZILLON5b218a02013-12-09 09:51:54 +0100168 dev_err(dev, "failed to get uhpck\n");
Jean-Christophe PLAGNIOL-VILLARD68134632011-12-08 16:32:00 +0100169 retval = PTR_ERR(fclk);
Boris BREZILLONfc7a3252013-12-09 09:51:55 +0100170 goto err;
Jean-Christophe PLAGNIOL-VILLARD68134632011-12-08 16:32:00 +0100171 }
Boris BREZILLONfc7a3252013-12-09 09:51:55 +0100172 hclk = devm_clk_get(dev, "hclk");
Jean-Christophe PLAGNIOL-VILLARD68134632011-12-08 16:32:00 +0100173 if (IS_ERR(hclk)) {
Boris BREZILLON5b218a02013-12-09 09:51:54 +0100174 dev_err(dev, "failed to get hclk\n");
Jean-Christophe PLAGNIOL-VILLARD68134632011-12-08 16:32:00 +0100175 retval = PTR_ERR(hclk);
Boris BREZILLONfc7a3252013-12-09 09:51:55 +0100176 goto err;
Jean-Christophe PLAGNIOL-VILLARD68134632011-12-08 16:32:00 +0100177 }
Boris BREZILLON6b0a1cf2013-08-01 19:09:13 +0200178 if (IS_ENABLED(CONFIG_COMMON_CLK)) {
Boris BREZILLONfc7a3252013-12-09 09:51:55 +0100179 uclk = devm_clk_get(dev, "usb_clk");
Boris BREZILLON6b0a1cf2013-08-01 19:09:13 +0200180 if (IS_ERR(uclk)) {
Boris BREZILLON5b218a02013-12-09 09:51:54 +0100181 dev_err(dev, "failed to get uclk\n");
Boris BREZILLON6b0a1cf2013-08-01 19:09:13 +0200182 retval = PTR_ERR(uclk);
Boris BREZILLONfc7a3252013-12-09 09:51:55 +0100183 goto err;
Boris BREZILLON6b0a1cf2013-08-01 19:09:13 +0200184 }
185 }
Andrew Victor39a269c2006-01-22 10:32:13 -0800186
Manjunath Goudare3825b42013-09-21 16:38:42 +0530187 board = hcd->self.controller->platform_data;
188 ohci = hcd_to_ohci(hcd);
189 ohci->num_ports = board->ports;
Andrew Victor39a269c2006-01-22 10:32:13 -0800190 at91_start_hc(pdev);
Andrew Victor39a269c2006-01-22 10:32:13 -0800191
Boris BREZILLONfb5f1832013-12-08 15:59:59 +0100192 retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
Arnd Bergmann1f53b482014-01-07 12:54:58 +0100193 if (retval == 0) {
Peter Chen3c9740a2013-11-05 10:46:02 +0800194 device_wakeup_enable(hcd->self.controller);
Andrew Victor39a269c2006-01-22 10:32:13 -0800195 return retval;
Peter Chen3c9740a2013-11-05 10:46:02 +0800196 }
Andrew Victor39a269c2006-01-22 10:32:13 -0800197
198 /* Error handling */
199 at91_stop_hc(pdev);
200
Boris BREZILLONcca2bbb2013-12-09 09:51:53 +0100201 err:
Andrew Victor39a269c2006-01-22 10:32:13 -0800202 usb_put_hcd(hcd);
203 return retval;
204}
205
206
Andrew Victor39a269c2006-01-22 10:32:13 -0800207/* may be called with controller, bus, and devices active */
208
209/**
David Brownell0365ee02006-06-19 14:27:20 -0700210 * usb_hcd_at91_remove - shutdown processing for AT91-based HCDs
Andrew Victor39a269c2006-01-22 10:32:13 -0800211 * @dev: USB Host Controller being removed
212 * Context: !in_interrupt()
213 *
214 * Reverses the effect of usb_hcd_at91_probe(), first invoking
215 * the HCD's stop() method. It is always called from a thread
David Brownell0365ee02006-06-19 14:27:20 -0700216 * context, "rmmod" or something similar.
Andrew Victor39a269c2006-01-22 10:32:13 -0800217 *
218 */
Bill Pembertonfb4e98a2012-11-19 13:26:20 -0500219static void usb_hcd_at91_remove(struct usb_hcd *hcd,
David Brownell0365ee02006-06-19 14:27:20 -0700220 struct platform_device *pdev)
Andrew Victor39a269c2006-01-22 10:32:13 -0800221{
222 usb_remove_hcd(hcd);
223 at91_stop_hc(pdev);
Pete Zaitcev421b4bf2008-06-01 14:38:43 -0700224 usb_put_hcd(hcd);
Andrew Victor39a269c2006-01-22 10:32:13 -0800225}
226
227/*-------------------------------------------------------------------------*/
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200228static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
229{
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100230 if (!valid_port(port))
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200231 return;
232
Jean-Christophe PLAGNIOL-VILLARD8a7a49d2011-09-19 15:32:23 +0800233 if (!gpio_is_valid(pdata->vbus_pin[port]))
Jean-Christophe PLAGNIOL-VILLARD770f0ba2011-11-12 16:46:13 +0100234 return;
235
Jean-Christophe PLAGNIOL-VILLARD8134ff52011-12-08 16:32:01 +0100236 gpio_set_value(pdata->vbus_pin[port],
Nicolas Ferre1e7caf82012-03-21 14:38:55 +0100237 pdata->vbus_pin_active_low[port] ^ enable);
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200238}
239
240static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
241{
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100242 if (!valid_port(port))
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200243 return -EINVAL;
244
Jean-Christophe PLAGNIOL-VILLARD8a7a49d2011-09-19 15:32:23 +0800245 if (!gpio_is_valid(pdata->vbus_pin[port]))
Jean-Christophe PLAGNIOL-VILLARD770f0ba2011-11-12 16:46:13 +0100246 return -EINVAL;
247
Jean-Christophe PLAGNIOL-VILLARD8134ff52011-12-08 16:32:01 +0100248 return gpio_get_value(pdata->vbus_pin[port]) ^
Nicolas Ferre1e7caf82012-03-21 14:38:55 +0100249 pdata->vbus_pin_active_low[port];
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200250}
251
252/*
253 * Update the status data from the hub with the over-current indicator change.
254 */
255static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
256{
Manjunath Goudare3825b42013-09-21 16:38:42 +0530257 struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
Laurent Pinchart42b59eb2014-04-16 18:00:09 +0200258 int length = ohci_hub_status_data(hcd, buf);
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200259 int port;
260
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100261 at91_for_each_port(port) {
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200262 if (pdata->overcurrent_changed[port]) {
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100263 if (!length)
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200264 length = 1;
265 buf[0] |= 1 << (port + 1);
266 }
267 }
268
269 return length;
270}
271
272/*
273 * Look at the control requests to the root hub and see if we need to override.
274 */
275static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
276 u16 wIndex, char *buf, u16 wLength)
277{
Jingoo Hand4f09e22013-07-30 19:59:40 +0900278 struct at91_usbh_data *pdata = dev_get_platdata(hcd->self.controller);
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200279 struct usb_hub_descriptor *desc;
280 int ret = -EINVAL;
281 u32 *data = (u32 *)buf;
282
283 dev_dbg(hcd->self.controller,
284 "ohci_at91_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n",
285 hcd, typeReq, wValue, wIndex, buf, wLength);
286
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100287 wIndex--;
288
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200289 switch (typeReq) {
290 case SetPortFeature:
291 if (wValue == USB_PORT_FEAT_POWER) {
292 dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n");
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100293 if (valid_port(wIndex)) {
294 ohci_at91_usb_set_power(pdata, wIndex, 1);
295 ret = 0;
296 }
297
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200298 goto out;
299 }
300 break;
301
302 case ClearPortFeature:
303 switch (wValue) {
304 case USB_PORT_FEAT_C_OVER_CURRENT:
305 dev_dbg(hcd->self.controller,
306 "ClearPortFeature: C_OVER_CURRENT\n");
307
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100308 if (valid_port(wIndex)) {
309 pdata->overcurrent_changed[wIndex] = 0;
310 pdata->overcurrent_status[wIndex] = 0;
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200311 }
312
313 goto out;
314
315 case USB_PORT_FEAT_OVER_CURRENT:
316 dev_dbg(hcd->self.controller,
317 "ClearPortFeature: OVER_CURRENT\n");
318
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100319 if (valid_port(wIndex))
320 pdata->overcurrent_status[wIndex] = 0;
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200321
322 goto out;
323
324 case USB_PORT_FEAT_POWER:
325 dev_dbg(hcd->self.controller,
326 "ClearPortFeature: POWER\n");
327
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100328 if (valid_port(wIndex)) {
329 ohci_at91_usb_set_power(pdata, wIndex, 0);
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200330 return 0;
331 }
332 }
333 break;
334 }
335
Laurent Pinchart42b59eb2014-04-16 18:00:09 +0200336 ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200337 if (ret)
338 goto out;
339
340 switch (typeReq) {
341 case GetHubDescriptor:
342
343 /* update the hub's descriptor */
344
345 desc = (struct usb_hub_descriptor *)buf;
346
347 dev_dbg(hcd->self.controller, "wHubCharacteristics 0x%04x\n",
348 desc->wHubCharacteristics);
349
350 /* remove the old configurations for power-switching, and
351 * over-current protection, and insert our new configuration
352 */
353
354 desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM);
355 desc->wHubCharacteristics |= cpu_to_le16(0x0001);
356
357 if (pdata->overcurrent_supported) {
358 desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM);
359 desc->wHubCharacteristics |= cpu_to_le16(0x0008|0x0001);
360 }
361
362 dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n",
363 desc->wHubCharacteristics);
364
365 return ret;
366
367 case GetPortStatus:
368 /* check port status */
369
370 dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex);
371
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100372 if (valid_port(wIndex)) {
373 if (!ohci_at91_usb_get_power(pdata, wIndex))
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200374 *data &= ~cpu_to_le32(RH_PS_PPS);
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200375
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100376 if (pdata->overcurrent_changed[wIndex])
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200377 *data |= cpu_to_le32(RH_PS_OCIC);
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200378
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100379 if (pdata->overcurrent_status[wIndex])
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200380 *data |= cpu_to_le32(RH_PS_POCI);
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200381 }
382 }
383
384 out:
385 return ret;
386}
387
Andrew Victor39a269c2006-01-22 10:32:13 -0800388/*-------------------------------------------------------------------------*/
389
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200390static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
391{
392 struct platform_device *pdev = data;
Jingoo Hand4f09e22013-07-30 19:59:40 +0900393 struct at91_usbh_data *pdata = dev_get_platdata(&pdev->dev);
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200394 int val, gpio, port;
395
396 /* From the GPIO notifying the over-current situation, find
397 * out the corresponding port */
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100398 at91_for_each_port(port) {
Joachim Eastwood01bb6502012-09-23 22:56:00 +0200399 if (gpio_is_valid(pdata->overcurrent_pin[port]) &&
400 gpio_to_irq(pdata->overcurrent_pin[port]) == irq) {
Nicolas Ferree4499072012-02-11 14:23:06 +0100401 gpio = pdata->overcurrent_pin[port];
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200402 break;
Nicolas Ferree4499072012-02-11 14:23:06 +0100403 }
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200404 }
405
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100406 if (port == AT91_MAX_USBH_PORTS) {
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200407 dev_err(& pdev->dev, "overcurrent interrupt from unknown GPIO\n");
408 return IRQ_HANDLED;
409 }
410
411 val = gpio_get_value(gpio);
412
413 /* When notified of an over-current situation, disable power
414 on the corresponding port, and mark this port in
415 over-current. */
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100416 if (!val) {
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200417 ohci_at91_usb_set_power(pdata, port, 0);
418 pdata->overcurrent_status[port] = 1;
419 pdata->overcurrent_changed[port] = 1;
420 }
421
422 dev_dbg(& pdev->dev, "overcurrent situation %s\n",
423 val ? "exited" : "notified");
424
425 return IRQ_HANDLED;
426}
427
Jean-Christophe PLAGNIOL-VILLARD24197302011-11-21 06:55:18 +0800428#ifdef CONFIG_OF
429static const struct of_device_id at91_ohci_dt_ids[] = {
430 { .compatible = "atmel,at91rm9200-ohci" },
431 { /* sentinel */ }
432};
433
434MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids);
435
Bill Pemberton41ac7b32012-11-19 13:21:48 -0500436static int ohci_at91_of_init(struct platform_device *pdev)
Jean-Christophe PLAGNIOL-VILLARD24197302011-11-21 06:55:18 +0800437{
438 struct device_node *np = pdev->dev.of_node;
Russell King22d9d8e2013-06-10 16:28:49 +0100439 int i, gpio, ret;
Jean-Christophe PLAGNIOL-VILLARD24197302011-11-21 06:55:18 +0800440 enum of_gpio_flags flags;
441 struct at91_usbh_data *pdata;
442 u32 ports;
443
444 if (!np)
445 return 0;
446
447 /* Right now device-tree probed devices don't get dma_mask set.
448 * Since shared usb code relies on it, set it here for now.
449 * Once we have dma capability bindings this can go away.
450 */
Russell Kinge1fd7342013-06-27 12:36:37 +0100451 ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
Russell King22d9d8e2013-06-10 16:28:49 +0100452 if (ret)
453 return ret;
Jean-Christophe PLAGNIOL-VILLARD24197302011-11-21 06:55:18 +0800454
455 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
456 if (!pdata)
457 return -ENOMEM;
458
459 if (!of_property_read_u32(np, "num-ports", &ports))
460 pdata->ports = ports;
461
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100462 at91_for_each_port(i) {
Jean-Christophe PLAGNIOL-VILLARD24197302011-11-21 06:55:18 +0800463 gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i, &flags);
464 pdata->vbus_pin[i] = gpio;
465 if (!gpio_is_valid(gpio))
466 continue;
467 pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW;
Jean-Christophe PLAGNIOL-VILLARD24197302011-11-21 06:55:18 +0800468 }
469
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100470 at91_for_each_port(i)
Nicolas Ferreaaf9f5f2012-03-21 16:58:11 +0100471 pdata->overcurrent_pin[i] =
472 of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
Jean-Christophe PLAGNIOL-VILLARD24197302011-11-21 06:55:18 +0800473
474 pdev->dev.platform_data = pdata;
475
476 return 0;
477}
478#else
Bill Pemberton41ac7b32012-11-19 13:21:48 -0500479static int ohci_at91_of_init(struct platform_device *pdev)
Jean-Christophe PLAGNIOL-VILLARD24197302011-11-21 06:55:18 +0800480{
481 return 0;
482}
483#endif
484
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200485/*-------------------------------------------------------------------------*/
486
Bill Pemberton41ac7b32012-11-19 13:21:48 -0500487static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
Andrew Victor39a269c2006-01-22 10:32:13 -0800488{
Jean-Christophe PLAGNIOL-VILLARD24197302011-11-21 06:55:18 +0800489 struct at91_usbh_data *pdata;
David Brownell4bde4a42007-12-27 11:19:49 -0800490 int i;
Nicolas Ferreaaf9f5f2012-03-21 16:58:11 +0100491 int gpio;
492 int ret;
David Brownell4bde4a42007-12-27 11:19:49 -0800493
Nicolas Ferre1887ab2b2012-03-28 11:49:01 +0200494 ret = ohci_at91_of_init(pdev);
495 if (ret)
496 return ret;
Jean-Christophe PLAGNIOL-VILLARD24197302011-11-21 06:55:18 +0800497
Jingoo Hand4f09e22013-07-30 19:59:40 +0900498 pdata = dev_get_platdata(&pdev->dev);
Jean-Christophe PLAGNIOL-VILLARD24197302011-11-21 06:55:18 +0800499
David Brownell4bde4a42007-12-27 11:19:49 -0800500 if (pdata) {
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100501 at91_for_each_port(i) {
Nicolas Ferre6fffb772012-08-29 11:49:18 +0200502 /*
503 * do not configure PIO if not in relation with
504 * real USB port on board
505 */
506 if (i >= pdata->ports) {
507 pdata->vbus_pin[i] = -EINVAL;
508 pdata->overcurrent_pin[i] = -EINVAL;
509 break;
510 }
511
Jean-Christophe PLAGNIOL-VILLARD8a7a49d2011-09-19 15:32:23 +0800512 if (!gpio_is_valid(pdata->vbus_pin[i]))
David Brownell4bde4a42007-12-27 11:19:49 -0800513 continue;
Nicolas Ferreaaf9f5f2012-03-21 16:58:11 +0100514 gpio = pdata->vbus_pin[i];
515
516 ret = gpio_request(gpio, "ohci_vbus");
517 if (ret) {
518 dev_err(&pdev->dev,
519 "can't request vbus gpio %d\n", gpio);
520 continue;
521 }
522 ret = gpio_direction_output(gpio,
523 !pdata->vbus_pin_active_low[i]);
524 if (ret) {
525 dev_err(&pdev->dev,
526 "can't put vbus gpio %d as output %d\n",
527 gpio, !pdata->vbus_pin_active_low[i]);
528 gpio_free(gpio);
529 continue;
530 }
531
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200532 ohci_at91_usb_set_power(pdata, i, 1);
533 }
534
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100535 at91_for_each_port(i) {
Jean-Christophe PLAGNIOL-VILLARD8a7a49d2011-09-19 15:32:23 +0800536 if (!gpio_is_valid(pdata->overcurrent_pin[i]))
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200537 continue;
Nicolas Ferreaaf9f5f2012-03-21 16:58:11 +0100538 gpio = pdata->overcurrent_pin[i];
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200539
Nicolas Ferreaaf9f5f2012-03-21 16:58:11 +0100540 ret = gpio_request(gpio, "ohci_overcurrent");
541 if (ret) {
542 dev_err(&pdev->dev,
543 "can't request overcurrent gpio %d\n",
544 gpio);
545 continue;
546 }
547
548 ret = gpio_direction_input(gpio);
549 if (ret) {
550 dev_err(&pdev->dev,
551 "can't configure overcurrent gpio %d as input\n",
552 gpio);
553 gpio_free(gpio);
554 continue;
555 }
556
557 ret = request_irq(gpio_to_irq(gpio),
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200558 ohci_hcd_at91_overcurrent_irq,
559 IRQF_SHARED, "ohci_overcurrent", pdev);
560 if (ret) {
Nicolas Ferreaaf9f5f2012-03-21 16:58:11 +0100561 gpio_free(gpio);
562 dev_err(&pdev->dev,
563 "can't get gpio IRQ for overcurrent\n");
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200564 }
David Brownell4bde4a42007-12-27 11:19:49 -0800565 }
566 }
567
David Brownell0365ee02006-06-19 14:27:20 -0700568 device_init_wakeup(&pdev->dev, 1);
569 return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
Andrew Victor39a269c2006-01-22 10:32:13 -0800570}
571
Bill Pembertonfb4e98a2012-11-19 13:26:20 -0500572static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
Andrew Victor39a269c2006-01-22 10:32:13 -0800573{
Jingoo Hand4f09e22013-07-30 19:59:40 +0900574 struct at91_usbh_data *pdata = dev_get_platdata(&pdev->dev);
David Brownell4bde4a42007-12-27 11:19:49 -0800575 int i;
576
577 if (pdata) {
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100578 at91_for_each_port(i) {
Jean-Christophe PLAGNIOL-VILLARD8a7a49d2011-09-19 15:32:23 +0800579 if (!gpio_is_valid(pdata->vbus_pin[i]))
David Brownell4bde4a42007-12-27 11:19:49 -0800580 continue;
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200581 ohci_at91_usb_set_power(pdata, i, 0);
David Brownell4bde4a42007-12-27 11:19:49 -0800582 gpio_free(pdata->vbus_pin[i]);
583 }
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200584
Nicolas Ferre0ee6d1e2012-03-21 16:53:09 +0100585 at91_for_each_port(i) {
Jean-Christophe PLAGNIOL-VILLARD8a7a49d2011-09-19 15:32:23 +0800586 if (!gpio_is_valid(pdata->overcurrent_pin[i]))
Thomas Petazzoniaa6e52a2011-07-13 11:29:17 +0200587 continue;
588 free_irq(gpio_to_irq(pdata->overcurrent_pin[i]), pdev);
589 gpio_free(pdata->overcurrent_pin[i]);
590 }
David Brownell4bde4a42007-12-27 11:19:49 -0800591 }
592
David Brownell0365ee02006-06-19 14:27:20 -0700593 device_init_wakeup(&pdev->dev, 0);
Pete Zaitcev421b4bf2008-06-01 14:38:43 -0700594 usb_hcd_at91_remove(platform_get_drvdata(pdev), pdev);
595 return 0;
Andrew Victor39a269c2006-01-22 10:32:13 -0800596}
597
598#ifdef CONFIG_PM
Andrew Victor39a269c2006-01-22 10:32:13 -0800599
David Brownell68ba61b2006-04-02 20:26:21 -0800600static int
David Brownell0365ee02006-06-19 14:27:20 -0700601ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
David Brownell68ba61b2006-04-02 20:26:21 -0800602{
David Brownell0365ee02006-06-19 14:27:20 -0700603 struct usb_hcd *hcd = platform_get_drvdata(pdev);
604 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
Majunath Goudara9d38402013-11-13 17:40:17 +0530605 bool do_wakeup = device_may_wakeup(&pdev->dev);
606 int ret;
David Brownell0365ee02006-06-19 14:27:20 -0700607
Majunath Goudara9d38402013-11-13 17:40:17 +0530608 if (do_wakeup)
David Brownell0365ee02006-06-19 14:27:20 -0700609 enable_irq_wake(hcd->irq);
David Brownell0365ee02006-06-19 14:27:20 -0700610
Majunath Goudara9d38402013-11-13 17:40:17 +0530611 ret = ohci_suspend(hcd, do_wakeup);
612 if (ret) {
613 disable_irq_wake(hcd->irq);
614 return ret;
615 }
David Brownell0365ee02006-06-19 14:27:20 -0700616 /*
617 * The integrated transceivers seem unable to notice disconnect,
618 * reconnect, or wakeup without the 48 MHz clock active. so for
619 * correctness, always discard connection state (using reset).
620 *
621 * REVISIT: some boards will be able to turn VBUS off...
622 */
623 if (at91_suspend_entering_slow_clock()) {
Manjunath Goudare3825b42013-09-21 16:38:42 +0530624 ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
625 ohci->hc_control &= OHCI_CTRL_RWC;
626 ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
627 ohci->rh_state = OHCI_RH_HALTED;
628
Patrice Vilchez869aa982010-04-28 13:45:40 +0200629 /* flush the writes */
630 (void) ohci_readl (ohci, &ohci->regs->control);
Andrew Victored077bb2007-02-16 10:18:58 -0800631 at91_stop_clock();
David Brownell0365ee02006-06-19 14:27:20 -0700632 }
Andrew Victor39a269c2006-01-22 10:32:13 -0800633
Majunath Goudara9d38402013-11-13 17:40:17 +0530634 return ret;
Andrew Victor39a269c2006-01-22 10:32:13 -0800635}
636
David Brownell0365ee02006-06-19 14:27:20 -0700637static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
Andrew Victor39a269c2006-01-22 10:32:13 -0800638{
Marc Pignat6dde8962007-01-09 14:00:11 -0800639 struct usb_hcd *hcd = platform_get_drvdata(pdev);
640
641 if (device_may_wakeup(&pdev->dev))
642 disable_irq_wake(hcd->irq);
643
Andrew Victored077bb2007-02-16 10:18:58 -0800644 if (!clocked)
645 at91_start_clock();
Andrew Victor39a269c2006-01-22 10:32:13 -0800646
Florian Fainellicfa49b42012-10-08 15:11:29 +0200647 ohci_resume(hcd, false);
Andrew Victor39a269c2006-01-22 10:32:13 -0800648 return 0;
649}
650#else
651#define ohci_hcd_at91_drv_suspend NULL
652#define ohci_hcd_at91_drv_resume NULL
653#endif
654
Andrew Victor39a269c2006-01-22 10:32:13 -0800655static struct platform_driver ohci_hcd_at91_driver = {
656 .probe = ohci_hcd_at91_drv_probe,
Bill Pemberton76904172012-11-19 13:21:08 -0500657 .remove = ohci_hcd_at91_drv_remove,
Aleksey Gorelov64a21d02006-08-08 17:24:08 -0700658 .shutdown = usb_hcd_platform_shutdown,
Andrew Victor39a269c2006-01-22 10:32:13 -0800659 .suspend = ohci_hcd_at91_drv_suspend,
660 .resume = ohci_hcd_at91_drv_resume,
661 .driver = {
David Brownell0365ee02006-06-19 14:27:20 -0700662 .name = "at91_ohci",
Andrew Victor39a269c2006-01-22 10:32:13 -0800663 .owner = THIS_MODULE,
Jean-Christophe PLAGNIOL-VILLARD24197302011-11-21 06:55:18 +0800664 .of_match_table = of_match_ptr(at91_ohci_dt_ids),
Andrew Victor39a269c2006-01-22 10:32:13 -0800665 },
666};
Manjunath Goudare3825b42013-09-21 16:38:42 +0530667
668static int __init ohci_at91_init(void)
669{
670 if (usb_disabled())
671 return -ENODEV;
672
673 pr_info("%s: " DRIVER_DESC "\n", hcd_name);
674 ohci_init_driver(&ohci_at91_hc_driver, NULL);
675
676 /*
677 * The Atmel HW has some unusual quirks, which require Atmel-specific
678 * workarounds. We override certain hc_driver functions here to
679 * achieve that. We explicitly do not enhance ohci_driver_overrides to
680 * allow this more easily, since this is an unusual case, and we don't
681 * want to encourage others to override these functions by making it
682 * too easy.
683 */
684
Manjunath Goudare3825b42013-09-21 16:38:42 +0530685 ohci_at91_hc_driver.hub_status_data = ohci_at91_hub_status_data;
686 ohci_at91_hc_driver.hub_control = ohci_at91_hub_control;
687
688 return platform_driver_register(&ohci_hcd_at91_driver);
689}
690module_init(ohci_at91_init);
691
692static void __exit ohci_at91_cleanup(void)
693{
694 platform_driver_unregister(&ohci_hcd_at91_driver);
695}
696module_exit(ohci_at91_cleanup);
697
698MODULE_DESCRIPTION(DRIVER_DESC);
699MODULE_LICENSE("GPL");
700MODULE_ALIAS("platform:at91_ohci");