diff options
author | David Brownell <david-b@pacbell.net> | 2006-08-15 02:11:06 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-09-26 00:08:37 -0400 |
commit | 185849991d592497e43bcd264c6152af1261ffe2 (patch) | |
tree | 856077e37e40bbda2af95fe64aaa92db626f30de | |
parent | c78a7c2dd913e68ce853d43edaba14eac91b2fd1 (diff) |
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: David Brownell <dbrownell@users.sourceforge.net>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/core/hcd-pci.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ehci-pci.c | 6 | ||||
-rw-r--r-- | drivers/usb/host/ohci-pci.c | 5 | ||||
-rw-r--r-- | drivers/usb/host/sl811-hcd.c | 9 | ||||
-rw-r--r-- | drivers/usb/host/uhci-hcd.c | 4 |
5 files changed, 23 insertions, 3 deletions
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 5078fb3375e3..fa36391fedd3 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
@@ -281,7 +281,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) | |||
281 | (void) usb_hcd_pci_resume (dev); | 281 | (void) usb_hcd_pci_resume (dev); |
282 | } | 282 | } |
283 | 283 | ||
284 | } else { | 284 | } else if (hcd->state != HC_STATE_HALT) { |
285 | dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n", | 285 | dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n", |
286 | hcd->state); | 286 | hcd->state); |
287 | WARN_ON(1); | 287 | WARN_ON(1); |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index cadffacd945b..6967ab71e282 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -238,6 +238,12 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message) | |||
238 | writel (0, &ehci->regs->intr_enable); | 238 | writel (0, &ehci->regs->intr_enable); |
239 | (void)readl(&ehci->regs->intr_enable); | 239 | (void)readl(&ehci->regs->intr_enable); |
240 | 240 | ||
241 | /* make sure snapshot being resumed re-enumerates everything */ | ||
242 | if (message.event == PM_EVENT_PRETHAW) { | ||
243 | ehci_halt(ehci); | ||
244 | ehci_reset(ehci); | ||
245 | } | ||
246 | |||
241 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 247 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
242 | bail: | 248 | bail: |
243 | spin_unlock_irqrestore (&ehci->lock, flags); | 249 | spin_unlock_irqrestore (&ehci->lock, flags); |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index b268537e389e..37e122812b67 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -135,6 +135,11 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) | |||
135 | } | 135 | } |
136 | ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | 136 | ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); |
137 | (void)ohci_readl(ohci, &ohci->regs->intrdisable); | 137 | (void)ohci_readl(ohci, &ohci->regs->intrdisable); |
138 | |||
139 | /* make sure snapshot being resumed re-enumerates everything */ | ||
140 | if (message.event == PM_EVENT_PRETHAW) | ||
141 | ohci_usb_reset(ohci); | ||
142 | |||
138 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 143 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
139 | bail: | 144 | bail: |
140 | spin_unlock_irqrestore (&ohci->lock, flags); | 145 | spin_unlock_irqrestore (&ohci->lock, flags); |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index fa34092bbcde..9de115d9db27 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -1783,10 +1783,15 @@ sl811h_suspend(struct platform_device *dev, pm_message_t state) | |||
1783 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 1783 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
1784 | int retval = 0; | 1784 | int retval = 0; |
1785 | 1785 | ||
1786 | if (state.event == PM_EVENT_FREEZE) | 1786 | switch (state.event) { |
1787 | case PM_EVENT_FREEZE: | ||
1787 | retval = sl811h_bus_suspend(hcd); | 1788 | retval = sl811h_bus_suspend(hcd); |
1788 | else if (state.event == PM_EVENT_SUSPEND) | 1789 | break; |
1790 | case PM_EVENT_SUSPEND: | ||
1791 | case PM_EVENT_PRETHAW: /* explicitly discard hw state */ | ||
1789 | port_power(sl811, 0); | 1792 | port_power(sl811, 0); |
1793 | break; | ||
1794 | } | ||
1790 | if (retval == 0) | 1795 | if (retval == 0) |
1791 | dev->dev.power.power_state = state; | 1796 | dev->dev.power.power_state = state; |
1792 | return retval; | 1797 | return retval; |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 4151f618602d..b7402ceb3e93 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -734,6 +734,10 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) | |||
734 | 734 | ||
735 | /* FIXME: Enable non-PME# remote wakeup? */ | 735 | /* FIXME: Enable non-PME# remote wakeup? */ |
736 | 736 | ||
737 | /* make sure snapshot being resumed re-enumerates everything */ | ||
738 | if (message.event == PM_EVENT_PRETHAW) | ||
739 | uhci_hc_died(uhci); | ||
740 | |||
737 | done_okay: | 741 | done_okay: |
738 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 742 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
739 | done: | 743 | done: |