diff options
author | Nicolas Ferre <nicolas.ferre@atmel.com> | 2007-12-13 18:52:58 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-12-17 13:47:15 -0500 |
commit | 08cbc706acd2dd601b0663e28fa97ffb0564e105 (patch) | |
tree | fc9cc0a4aab57dee2b30a8b145dfbb5ee3688388 /drivers/usb/gadget | |
parent | 442258e2ff69276ff767f3703b30ce6a31fdd181 (diff) |
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')
-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 a6adf7e0f6f8..cd62b029d176 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) | |||
887 | 887 | ||
888 | if (is_on) { | 888 | if (is_on) { |
889 | clk_on(udc); | 889 | clk_on(udc); |
890 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM); | ||
890 | at91_udp_write(udc, AT91_UDP_TXVC, 0); | 891 | at91_udp_write(udc, AT91_UDP_TXVC, 0); |
891 | if (cpu_is_at91rm9200()) | 892 | if (cpu_is_at91rm9200()) |
892 | at91_set_gpio_value(udc->board.pullup_pin, 1); | 893 | at91_set_gpio_value(udc->board.pullup_pin, 1); |
@@ -904,6 +905,7 @@ static void pullup(struct at91_udc *udc, int is_on) | |||
904 | } | 905 | } |
905 | } else { | 906 | } else { |
906 | stop_activity(udc); | 907 | stop_activity(udc); |
908 | at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM); | ||
907 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); | 909 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); |
908 | if (cpu_is_at91rm9200()) | 910 | if (cpu_is_at91rm9200()) |
909 | at91_set_gpio_value(udc->board.pullup_pin, 0); | 911 | at91_set_gpio_value(udc->board.pullup_pin, 0); |