aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2007-01-16 15:46:39 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 18:44:37 -0500
commit66e56ce75e39210415fb12ceacd5f3580ad72d50 (patch)
treeaefd162287e90def0a034c4a6c7aaa24617c779f
parent57e06c11372eccf5acebdd4664eb025fee76c561 (diff)
USB: at91_udc wakeup event updates
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>
-rw-r--r--drivers/usb/gadget/at91_udc.c19
-rw-r--r--drivers/usb/gadget/at91_udc.h1
2 files changed, 12 insertions, 8 deletions
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 5a72743606fd..f39050145f1f 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1807,16 +1807,13 @@ static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
1807 || !wake 1807 || !wake
1808 || at91_suspend_entering_slow_clock()) { 1808 || at91_suspend_entering_slow_clock()) {
1809 pullup(udc, 0); 1809 pullup(udc, 0);
1810 disable_irq_wake(udc->udp_irq); 1810 wake = 0;
1811 } else 1811 } else
1812 enable_irq_wake(udc->udp_irq); 1812 enable_irq_wake(udc->udp_irq);
1813 1813
1814 if (udc->board.vbus_pin > 0) { 1814 udc->active_suspend = wake;
1815 if (wake) 1815 if (udc->board.vbus_pin > 0 && wake)
1816 enable_irq_wake(udc->board.vbus_pin); 1816 enable_irq_wake(udc->board.vbus_pin);
1817 else
1818 disable_irq_wake(udc->board.vbus_pin);
1819 }
1820 return 0; 1817 return 0;
1821} 1818}
1822 1819
@@ -1824,8 +1821,14 @@ static int at91udc_resume(struct platform_device *pdev)
1824{ 1821{
1825 struct at91_udc *udc = platform_get_drvdata(pdev); 1822 struct at91_udc *udc = platform_get_drvdata(pdev);
1826 1823
1824 if (udc->board.vbus_pin > 0 && udc->active_suspend)
1825 disable_irq_wake(udc->board.vbus_pin);
1826
1827 /* maybe reconnect to host; if so, clocks on */ 1827 /* maybe reconnect to host; if so, clocks on */
1828 pullup(udc, 1); 1828 if (udc->active_suspend)
1829 disable_irq_wake(udc->udp_irq);
1830 else
1831 pullup(udc, 1);
1829 return 0; 1832 return 0;
1830} 1833}
1831#else 1834#else
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h
index 677089baa59d..7e34e2f864f9 100644
--- a/drivers/usb/gadget/at91_udc.h
+++ b/drivers/usb/gadget/at91_udc.h
@@ -136,6 +136,7 @@ struct at91_udc {
136 unsigned wait_for_addr_ack:1; 136 unsigned wait_for_addr_ack:1;
137 unsigned wait_for_config_ack:1; 137 unsigned wait_for_config_ack:1;
138 unsigned selfpowered:1; 138 unsigned selfpowered:1;
139 unsigned active_suspend:1;
139 u8 addr; 140 u8 addr;
140 struct at91_udc_data board; 141 struct at91_udc_data board;
141 struct clk *iclk, *fclk; 142 struct clk *iclk, *fclk;