USB: at91_udc wakeup event updates
authorDavid Brownell <david-b@pacbell.net>
Tue, 16 Jan 2007 20:46:39 +0000 (12:46 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 7 Feb 2007 23:44:37 +0000 (15:44 -0800)
This updates the AT91 UDC driver's handling of wakeup events:

 - Fix a bug in the original scheme, which was never updated after
   the {enable,disable}_irq_wake() semantics were updated to address
   refcounting issues (i.e. behave for shared irqs).

 - Couple handling of both type of wakeup events, to be more direct.  The
   controller can be source of wakeup events for cases like bus reset
   and USB resume.  On some boards, VBUS sensing is also IRQ driven.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/at91_udc.h

index 5a72743606fdc4233bd97d22a44758b840f12598..f39050145f1f9be9f5b47cfa6760eb25fc202c13 100644 (file)
@@ -1807,16 +1807,13 @@ static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
                        || !wake
                        || at91_suspend_entering_slow_clock()) {
                pullup(udc, 0);
-               disable_irq_wake(udc->udp_irq);
+               wake = 0;
        } else
                enable_irq_wake(udc->udp_irq);
 
-       if (udc->board.vbus_pin > 0) {
-               if (wake)
-                       enable_irq_wake(udc->board.vbus_pin);
-               else
-                       disable_irq_wake(udc->board.vbus_pin);
-       }
+       udc->active_suspend = wake;
+       if (udc->board.vbus_pin > 0 && wake)
+               enable_irq_wake(udc->board.vbus_pin);
        return 0;
 }
 
@@ -1824,8 +1821,14 @@ static int at91udc_resume(struct platform_device *pdev)
 {
        struct at91_udc *udc = platform_get_drvdata(pdev);
 
+       if (udc->board.vbus_pin > 0 && udc->active_suspend)
+               disable_irq_wake(udc->board.vbus_pin);
+
        /* maybe reconnect to host; if so, clocks on */
-       pullup(udc, 1);
+       if (udc->active_suspend)
+               disable_irq_wake(udc->udp_irq);
+       else
+               pullup(udc, 1);
        return 0;
 }
 #else
index 677089baa59dd8bcacfc71fa801a18e91e42fda1..7e34e2f864f9d70efcfd41ed1c2e6719e91dcb30 100644 (file)
@@ -136,6 +136,7 @@ struct at91_udc {
        unsigned                        wait_for_addr_ack:1;
        unsigned                        wait_for_config_ack:1;
        unsigned                        selfpowered:1;
+       unsigned                        active_suspend:1;
        u8                              addr;
        struct at91_udc_data            board;
        struct clk                      *iclk, *fclk;