diff options
author | Greg KH <greg@press.(none)> | 2005-06-28 01:07:56 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-06-28 01:07:56 -0400 |
commit | 8644d2a42bdba2d513f71c07eaf1b6f9b718b8eb (patch) | |
tree | c43b6c2fdf1b68b66906a2de69446dcec0f9af6b /drivers/usb/gadget/pxa2xx_udc.c | |
parent | 1cde8a16815bd85c8137d1ea556398983c597c11 (diff) | |
parent | 99f95e5286df2f69edab8a04c7080d986ee4233b (diff) |
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/usb/gadget/pxa2xx_udc.c')
-rw-r--r-- | drivers/usb/gadget/pxa2xx_udc.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index b8b4524ed746..6a0b957af335 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/usb/gadget/pxa2xx_udc.c | 2 | * linux/drivers/usb/gadget/pxa2xx_udc.c |
3 | * Intel PXA2xx and IXP4xx on-chip full speed USB device controllers | 3 | * Intel PXA25x and IXP4xx on-chip full speed USB device controllers |
4 | * | 4 | * |
5 | * Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker) | 5 | * Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker) |
6 | * Copyright (C) 2003 Robert Schwebel, Pengutronix | 6 | * Copyright (C) 2003 Robert Schwebel, Pengutronix |
@@ -63,7 +63,7 @@ | |||
63 | 63 | ||
64 | 64 | ||
65 | /* | 65 | /* |
66 | * This driver handles the USB Device Controller (UDC) in Intel's PXA 2xx | 66 | * This driver handles the USB Device Controller (UDC) in Intel's PXA 25x |
67 | * series processors. The UDC for the IXP 4xx series is very similar. | 67 | * series processors. The UDC for the IXP 4xx series is very similar. |
68 | * There are fifteen endpoints, in addition to ep0. | 68 | * There are fifteen endpoints, in addition to ep0. |
69 | * | 69 | * |
@@ -79,8 +79,8 @@ | |||
79 | * pxa250 a0/a1 b0/b1/b2 sure act like they're still there. | 79 | * pxa250 a0/a1 b0/b1/b2 sure act like they're still there. |
80 | */ | 80 | */ |
81 | 81 | ||
82 | #define DRIVER_VERSION "14-Dec-2003" | 82 | #define DRIVER_VERSION "4-May-2005" |
83 | #define DRIVER_DESC "PXA 2xx USB Device Controller driver" | 83 | #define DRIVER_DESC "PXA 25x USB Device Controller driver" |
84 | 84 | ||
85 | 85 | ||
86 | static const char driver_name [] = "pxa2xx_udc"; | 86 | static const char driver_name [] = "pxa2xx_udc"; |
@@ -290,6 +290,7 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep, | |||
290 | static int pxa2xx_ep_disable (struct usb_ep *_ep) | 290 | static int pxa2xx_ep_disable (struct usb_ep *_ep) |
291 | { | 291 | { |
292 | struct pxa2xx_ep *ep; | 292 | struct pxa2xx_ep *ep; |
293 | unsigned long flags; | ||
293 | 294 | ||
294 | ep = container_of (_ep, struct pxa2xx_ep, ep); | 295 | ep = container_of (_ep, struct pxa2xx_ep, ep); |
295 | if (!_ep || !ep->desc) { | 296 | if (!_ep || !ep->desc) { |
@@ -297,6 +298,8 @@ static int pxa2xx_ep_disable (struct usb_ep *_ep) | |||
297 | _ep ? ep->ep.name : NULL); | 298 | _ep ? ep->ep.name : NULL); |
298 | return -EINVAL; | 299 | return -EINVAL; |
299 | } | 300 | } |
301 | local_irq_save(flags); | ||
302 | |||
300 | nuke (ep, -ESHUTDOWN); | 303 | nuke (ep, -ESHUTDOWN); |
301 | 304 | ||
302 | #ifdef USE_DMA | 305 | #ifdef USE_DMA |
@@ -313,6 +316,7 @@ static int pxa2xx_ep_disable (struct usb_ep *_ep) | |||
313 | ep->desc = NULL; | 316 | ep->desc = NULL; |
314 | ep->stopped = 1; | 317 | ep->stopped = 1; |
315 | 318 | ||
319 | local_irq_restore(flags); | ||
316 | DBG(DBG_VERBOSE, "%s disabled\n", _ep->name); | 320 | DBG(DBG_VERBOSE, "%s disabled\n", _ep->name); |
317 | return 0; | 321 | return 0; |
318 | } | 322 | } |
@@ -971,10 +975,10 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) | |||
971 | kick_dma(ep, req); | 975 | kick_dma(ep, req); |
972 | #endif | 976 | #endif |
973 | /* can the FIFO can satisfy the request immediately? */ | 977 | /* can the FIFO can satisfy the request immediately? */ |
974 | } else if ((ep->bEndpointAddress & USB_DIR_IN) != 0 | 978 | } else if ((ep->bEndpointAddress & USB_DIR_IN) != 0) { |
975 | && (*ep->reg_udccs & UDCCS_BI_TFS) != 0 | 979 | if ((*ep->reg_udccs & UDCCS_BI_TFS) != 0 |
976 | && write_fifo(ep, req)) { | 980 | && write_fifo(ep, req)) |
977 | req = NULL; | 981 | req = NULL; |
978 | } else if ((*ep->reg_udccs & UDCCS_BO_RFS) != 0 | 982 | } else if ((*ep->reg_udccs & UDCCS_BO_RFS) != 0 |
979 | && read_fifo(ep, req)) { | 983 | && read_fifo(ep, req)) { |
980 | req = NULL; | 984 | req = NULL; |
@@ -1290,7 +1294,7 @@ udc_proc_read(char *page, char **start, off_t off, int count, | |||
1290 | "%s version: %s\nGadget driver: %s\nHost %s\n\n", | 1294 | "%s version: %s\nGadget driver: %s\nHost %s\n\n", |
1291 | driver_name, DRIVER_VERSION SIZE_STR DMASTR, | 1295 | driver_name, DRIVER_VERSION SIZE_STR DMASTR, |
1292 | dev->driver ? dev->driver->driver.name : "(none)", | 1296 | dev->driver ? dev->driver->driver.name : "(none)", |
1293 | is_usb_connected() ? "full speed" : "disconnected"); | 1297 | is_vbus_present() ? "full speed" : "disconnected"); |
1294 | size -= t; | 1298 | size -= t; |
1295 | next += t; | 1299 | next += t; |
1296 | 1300 | ||
@@ -1339,7 +1343,7 @@ udc_proc_read(char *page, char **start, off_t off, int count, | |||
1339 | next += t; | 1343 | next += t; |
1340 | } | 1344 | } |
1341 | 1345 | ||
1342 | if (!is_usb_connected() || !dev->driver) | 1346 | if (!is_vbus_present() || !dev->driver) |
1343 | goto done; | 1347 | goto done; |
1344 | 1348 | ||
1345 | t = scnprintf(next, size, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", | 1349 | t = scnprintf(next, size, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", |
@@ -1454,7 +1458,7 @@ static void udc_disable(struct pxa2xx_udc *dev) | |||
1454 | UFNRH = UFNRH_SIM; | 1458 | UFNRH = UFNRH_SIM; |
1455 | 1459 | ||
1456 | /* if hardware supports it, disconnect from usb */ | 1460 | /* if hardware supports it, disconnect from usb */ |
1457 | make_usb_disappear(); | 1461 | pullup_off(); |
1458 | 1462 | ||
1459 | udc_clear_mask_UDCCR(UDCCR_UDE); | 1463 | udc_clear_mask_UDCCR(UDCCR_UDE); |
1460 | 1464 | ||
@@ -1567,7 +1571,7 @@ static void udc_enable (struct pxa2xx_udc *dev) | |||
1567 | UICR0 &= ~UICR0_IM0; | 1571 | UICR0 &= ~UICR0_IM0; |
1568 | 1572 | ||
1569 | /* if hardware supports it, pullup D+ and wait for reset */ | 1573 | /* if hardware supports it, pullup D+ and wait for reset */ |
1570 | let_usb_appear(); | 1574 | pullup_on(); |
1571 | } | 1575 | } |
1572 | 1576 | ||
1573 | 1577 | ||
@@ -2052,10 +2056,10 @@ pxa2xx_udc_irq(int irq, void *_dev, struct pt_regs *r) | |||
2052 | if (unlikely(udccr & UDCCR_SUSIR)) { | 2056 | if (unlikely(udccr & UDCCR_SUSIR)) { |
2053 | udc_ack_int_UDCCR(UDCCR_SUSIR); | 2057 | udc_ack_int_UDCCR(UDCCR_SUSIR); |
2054 | handled = 1; | 2058 | handled = 1; |
2055 | DBG(DBG_VERBOSE, "USB suspend%s\n", is_usb_connected() | 2059 | DBG(DBG_VERBOSE, "USB suspend%s\n", is_vbus_present() |
2056 | ? "" : "+disconnect"); | 2060 | ? "" : "+disconnect"); |
2057 | 2061 | ||
2058 | if (!is_usb_connected()) | 2062 | if (!is_vbus_present()) |
2059 | stop_activity(dev, dev->driver); | 2063 | stop_activity(dev, dev->driver); |
2060 | else if (dev->gadget.speed != USB_SPEED_UNKNOWN | 2064 | else if (dev->gadget.speed != USB_SPEED_UNKNOWN |
2061 | && dev->driver | 2065 | && dev->driver |
@@ -2073,7 +2077,7 @@ pxa2xx_udc_irq(int irq, void *_dev, struct pt_regs *r) | |||
2073 | if (dev->gadget.speed != USB_SPEED_UNKNOWN | 2077 | if (dev->gadget.speed != USB_SPEED_UNKNOWN |
2074 | && dev->driver | 2078 | && dev->driver |
2075 | && dev->driver->resume | 2079 | && dev->driver->resume |
2076 | && is_usb_connected()) | 2080 | && is_vbus_present()) |
2077 | dev->driver->resume(&dev->gadget); | 2081 | dev->driver->resume(&dev->gadget); |
2078 | } | 2082 | } |
2079 | 2083 | ||
@@ -2509,7 +2513,7 @@ static int __init pxa2xx_udc_probe(struct device *_dev) | |||
2509 | udc_disable(dev); | 2513 | udc_disable(dev); |
2510 | udc_reinit(dev); | 2514 | udc_reinit(dev); |
2511 | 2515 | ||
2512 | dev->vbus = is_usb_connected(); | 2516 | dev->vbus = is_vbus_present(); |
2513 | 2517 | ||
2514 | /* irq setup after old hardware state is cleaned up */ | 2518 | /* irq setup after old hardware state is cleaned up */ |
2515 | retval = request_irq(IRQ_USB, pxa2xx_udc_irq, | 2519 | retval = request_irq(IRQ_USB, pxa2xx_udc_irq, |
@@ -2555,6 +2559,12 @@ lubbock_fail0: | |||
2555 | 2559 | ||
2556 | return 0; | 2560 | return 0; |
2557 | } | 2561 | } |
2562 | |||
2563 | static void pxa2xx_udc_shutdown(struct device *_dev) | ||
2564 | { | ||
2565 | pullup_off(); | ||
2566 | } | ||
2567 | |||
2558 | static int __exit pxa2xx_udc_remove(struct device *_dev) | 2568 | static int __exit pxa2xx_udc_remove(struct device *_dev) |
2559 | { | 2569 | { |
2560 | struct pxa2xx_udc *dev = dev_get_drvdata(_dev); | 2570 | struct pxa2xx_udc *dev = dev_get_drvdata(_dev); |
@@ -2624,6 +2634,7 @@ static struct device_driver udc_driver = { | |||
2624 | .name = "pxa2xx-udc", | 2634 | .name = "pxa2xx-udc", |
2625 | .bus = &platform_bus_type, | 2635 | .bus = &platform_bus_type, |
2626 | .probe = pxa2xx_udc_probe, | 2636 | .probe = pxa2xx_udc_probe, |
2637 | .shutdown = pxa2xx_udc_shutdown, | ||
2627 | .remove = __exit_p(pxa2xx_udc_remove), | 2638 | .remove = __exit_p(pxa2xx_udc_remove), |
2628 | .suspend = pxa2xx_udc_suspend, | 2639 | .suspend = pxa2xx_udc_suspend, |
2629 | .resume = pxa2xx_udc_resume, | 2640 | .resume = pxa2xx_udc_resume, |