aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-au1xxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-au1xxx.c')
-rw-r--r--drivers/usb/host/ehci-au1xxx.c27
1 files changed, 14 insertions, 13 deletions
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c
index e3a74e75e822..faa61748db70 100644
--- a/drivers/usb/host/ehci-au1xxx.c
+++ b/drivers/usb/host/ehci-au1xxx.c
@@ -69,6 +69,15 @@ static void au1xxx_stop_ehc(void)
69 au_sync(); 69 au_sync();
70} 70}
71 71
72static int au1xxx_ehci_setup(struct usb_hcd *hcd)
73{
74 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
75 int ret = ehci_init(hcd);
76
77 ehci->need_io_watchdog = 0;
78 return ret;
79}
80
72static const struct hc_driver ehci_au1xxx_hc_driver = { 81static const struct hc_driver ehci_au1xxx_hc_driver = {
73 .description = hcd_name, 82 .description = hcd_name,
74 .product_desc = "Au1xxx EHCI", 83 .product_desc = "Au1xxx EHCI",
@@ -86,7 +95,7 @@ static const struct hc_driver ehci_au1xxx_hc_driver = {
86 * FIXME -- ehci_init() doesn't do enough here. 95 * FIXME -- ehci_init() doesn't do enough here.
87 * See ehci-ppc-soc for a complete implementation. 96 * See ehci-ppc-soc for a complete implementation.
88 */ 97 */
89 .reset = ehci_init, 98 .reset = au1xxx_ehci_setup,
90 .start = ehci_run, 99 .start = ehci_run,
91 .stop = ehci_stop, 100 .stop = ehci_stop,
92 .shutdown = ehci_shutdown, 101 .shutdown = ehci_shutdown,
@@ -215,26 +224,17 @@ static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
215 msleep(10); 224 msleep(10);
216 225
217 /* Root hub was already suspended. Disable irq emission and 226 /* Root hub was already suspended. Disable irq emission and
218 * mark HW unaccessible, bail out if RH has been resumed. Use 227 * mark HW unaccessible. The PM and USB cores make sure that
219 * the spinlock to properly synchronize with possible pending 228 * the root hub is either suspended or stopped.
220 * RH suspend or resume activity.
221 *
222 * This is still racy as hcd->state is manipulated outside of
223 * any locks =P But that will be a different fix.
224 */ 229 */
225 spin_lock_irqsave(&ehci->lock, flags); 230 spin_lock_irqsave(&ehci->lock, flags);
226 if (hcd->state != HC_STATE_SUSPENDED) { 231 ehci_prepare_ports_for_controller_suspend(ehci);
227 rc = -EINVAL;
228 goto bail;
229 }
230 ehci_writel(ehci, 0, &ehci->regs->intr_enable); 232 ehci_writel(ehci, 0, &ehci->regs->intr_enable);
231 (void)ehci_readl(ehci, &ehci->regs->intr_enable); 233 (void)ehci_readl(ehci, &ehci->regs->intr_enable);
232 234
233 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 235 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
234 236
235 au1xxx_stop_ehc(); 237 au1xxx_stop_ehc();
236
237bail:
238 spin_unlock_irqrestore(&ehci->lock, flags); 238 spin_unlock_irqrestore(&ehci->lock, flags);
239 239
240 // could save FLADJ in case of Vaux power loss 240 // could save FLADJ in case of Vaux power loss
@@ -264,6 +264,7 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
264 if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { 264 if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
265 int mask = INTR_MASK; 265 int mask = INTR_MASK;
266 266
267 ehci_prepare_ports_for_controller_resume(ehci);
267 if (!hcd->self.root_hub->do_remote_wakeup) 268 if (!hcd->self.root_hub->do_remote_wakeup)
268 mask &= ~STS_PCD; 269 mask &= ~STS_PCD;
269 ehci_writel(ehci, mask, &ehci->regs->intr_enable); 270 ehci_writel(ehci, mask, &ehci->regs->intr_enable);