Commit 18584999 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

PM: USB HCDs use PM_EVENT_PRETHAW

This teaches several USB host controller drivers to treat PRETHAW as a chip
reset since the controller, and all devices connected to it, are no longer in
states compatible with how the snapshotted suspend() left them.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent c78a7c2d
...@@ -281,7 +281,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) ...@@ -281,7 +281,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
(void) usb_hcd_pci_resume (dev); (void) usb_hcd_pci_resume (dev);
} }
} else { } else if (hcd->state != HC_STATE_HALT) {
dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n", dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n",
hcd->state); hcd->state);
WARN_ON(1); WARN_ON(1);
......
...@@ -238,6 +238,12 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message) ...@@ -238,6 +238,12 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message)
writel (0, &ehci->regs->intr_enable); writel (0, &ehci->regs->intr_enable);
(void)readl(&ehci->regs->intr_enable); (void)readl(&ehci->regs->intr_enable);
/* make sure snapshot being resumed re-enumerates everything */
if (message.event == PM_EVENT_PRETHAW) {
ehci_halt(ehci);
ehci_reset(ehci);
}
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
bail: bail:
spin_unlock_irqrestore (&ehci->lock, flags); spin_unlock_irqrestore (&ehci->lock, flags);
......
...@@ -135,6 +135,11 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) ...@@ -135,6 +135,11 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
} }
ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
(void)ohci_readl(ohci, &ohci->regs->intrdisable); (void)ohci_readl(ohci, &ohci->regs->intrdisable);
/* make sure snapshot being resumed re-enumerates everything */
if (message.event == PM_EVENT_PRETHAW)
ohci_usb_reset(ohci);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
bail: bail:
spin_unlock_irqrestore (&ohci->lock, flags); spin_unlock_irqrestore (&ohci->lock, flags);
......
...@@ -1783,10 +1783,15 @@ sl811h_suspend(struct platform_device *dev, pm_message_t state) ...@@ -1783,10 +1783,15 @@ sl811h_suspend(struct platform_device *dev, pm_message_t state)
struct sl811 *sl811 = hcd_to_sl811(hcd); struct sl811 *sl811 = hcd_to_sl811(hcd);
int retval = 0; int retval = 0;
if (state.event == PM_EVENT_FREEZE) switch (state.event) {
case PM_EVENT_FREEZE:
retval = sl811h_bus_suspend(hcd); retval = sl811h_bus_suspend(hcd);
else if (state.event == PM_EVENT_SUSPEND) break;
case PM_EVENT_SUSPEND:
case PM_EVENT_PRETHAW: /* explicitly discard hw state */
port_power(sl811, 0); port_power(sl811, 0);
break;
}
if (retval == 0) if (retval == 0)
dev->dev.power.power_state = state; dev->dev.power.power_state = state;
return retval; return retval;
......
...@@ -734,6 +734,10 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) ...@@ -734,6 +734,10 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
/* FIXME: Enable non-PME# remote wakeup? */ /* FIXME: Enable non-PME# remote wakeup? */
/* make sure snapshot being resumed re-enumerates everything */
if (message.event == PM_EVENT_PRETHAW)
uhci_hc_died(uhci);
done_okay: done_okay:
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
done: done:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment