diff options
author | Nicolas Ferre <nicolas.ferre@atmel.com> | 2007-12-13 15:52:58 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-12-17 10:47:15 -0800 |
commit | 08cbc706acd2dd601b0663e28fa97ffb0564e105 (patch) | |
tree | fc9cc0a4aab57dee2b30a8b145dfbb5ee3688388 /drivers/usb/gadget/at91_udc.c | |
parent | 442258e2ff69276ff767f3703b30ce6a31fdd181 (diff) | |
download | op-kernel-dev-08cbc706acd2dd601b0663e28fa97ffb0564e105.zip op-kernel-dev-08cbc706acd2dd601b0663e28fa97ffb0564e105.tar.gz |
USB: at91_udc: correct hanging while disconnecting usb cable
Correct hanging while disconnecting the USB device cable. Prevent a race
between vbus and UDP interrupts. This bug was tracked on at91sam9260ek
boards.
A usb resume interrupt was firing after the vbus interrupt : the IP was
then already stoped and not able to deal with it (no more clock). A simple
interrupt disabling is ok as the "end of bus reset" irq is non maskable and
ok to resume the USB device IP.
Signed-off-by: Nicolas Ferre <nicolas.ferre@rfo.atmel.com>
Acked-by: David Brownell <david-b@pacbell.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/at91_udc.c')
-rw-r--r-- | drivers/usb/gadget/at91_udc.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index a6adf7e..cd62b02 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -887,6 +887,7 @@ static void pullup(struct at91_udc *udc, int is_on) if (is_on) { clk_on(udc); + at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM); at91_udp_write(udc, AT91_UDP_TXVC, 0); if (cpu_is_at91rm9200()) at91_set_gpio_value(udc->board.pullup_pin, 1); @@ -904,6 +905,7 @@ static void pullup(struct at91_udc *udc, int is_on) } } else { stop_activity(udc); + at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM); at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); if (cpu_is_at91rm9200()) at91_set_gpio_value(udc->board.pullup_pin, 0); |