aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-pci.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2008-04-03 18:03:17 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-04-25 00:16:48 -0400
commit43bbb7e015c4380064796c5868b536437b165615 (patch)
tree6f4b8e184904917677ce00f600ebf3c8839f47f0 /drivers/usb/host/ohci-pci.c
parent7be7d7418776a41badce7ca00246e270d408e4b9 (diff)
USB: OHCI: host-controller resumes leave root hub suspended
Drivers in the ohci-hcd family should perform certain tasks whenever their controller device is resumed. These include checking for loss of power during suspend, turning on port power, and enabling interrupt requests. Until now these jobs have been carried out when the root hub is resumed, not when the controller is. Many drivers work around the resulting awkwardness by automatically resuming their root hub whenever the controller is resumed. But this is wasteful and unnecessary. To simplify the situation, this patch (as1066) adds a new core routine, ohci_finish_controller_resume(), which can be used by all the OHCI-variant drivers. They can call the new routine instead of resuming their root hubs. And ohci-pci.c can call it instead of using its own special-purpose handler. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ohci-pci.c')
-rw-r--r--drivers/usb/host/ohci-pci.c43
1 files changed, 1 insertions, 42 deletions
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 40b62a35fd3c..4696cc912e16 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -238,42 +238,6 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd)
238 return ret; 238 return ret;
239} 239}
240 240
241#if defined(CONFIG_USB_PERSIST) && (defined(CONFIG_USB_EHCI_HCD) || \
242 defined(CONFIG_USB_EHCI_HCD_MODULE))
243
244/* Following a power loss, we must prepare to regain control of the ports
245 * we used to own. This means turning on the port power before ehci-hcd
246 * tries to switch ownership.
247 *
248 * This isn't a 100% perfect solution. On most systems the OHCI controllers
249 * lie at lower PCI addresses than the EHCI controller, so they will be
250 * discovered (and hence resumed) first. But there is no guarantee things
251 * will always work this way. If the EHCI controller is resumed first and
252 * the OHCI ports are unpowered, then the handover will fail.
253 */
254static void prepare_for_handover(struct usb_hcd *hcd)
255{
256 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
257 int port;
258
259 /* Here we "know" root ports should always stay powered */
260 ohci_dbg(ohci, "powerup ports\n");
261 for (port = 0; port < ohci->num_ports; port++)
262 ohci_writel(ohci, RH_PS_PPS,
263 &ohci->regs->roothub.portstatus[port]);
264
265 /* Flush those writes */
266 ohci_readl(ohci, &ohci->regs->control);
267 msleep(20);
268}
269
270#else
271
272static inline void prepare_for_handover(struct usb_hcd *hcd)
273{ }
274
275#endif /* CONFIG_USB_PERSIST etc. */
276
277#ifdef CONFIG_PM 241#ifdef CONFIG_PM
278 242
279static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) 243static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
@@ -312,13 +276,8 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
312 276
313static int ohci_pci_resume (struct usb_hcd *hcd) 277static int ohci_pci_resume (struct usb_hcd *hcd)
314{ 278{
315 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
316
317 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 279 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
318 280 ohci_finish_controller_resume(hcd);
319 /* FIXME: we should try to detect loss of VBUS power here */
320 prepare_for_handover(hcd);
321 ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
322 return 0; 281 return 0;
323} 282}
324 283