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>

diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 40b62a3..4696cc9 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -238,42 +238,6 @@
 	return ret;
 }
 
-#if	defined(CONFIG_USB_PERSIST) && (defined(CONFIG_USB_EHCI_HCD) || \
-		defined(CONFIG_USB_EHCI_HCD_MODULE))
-
-/* Following a power loss, we must prepare to regain control of the ports
- * we used to own.  This means turning on the port power before ehci-hcd
- * tries to switch ownership.
- *
- * This isn't a 100% perfect solution.  On most systems the OHCI controllers
- * lie at lower PCI addresses than the EHCI controller, so they will be
- * discovered (and hence resumed) first.  But there is no guarantee things
- * will always work this way.  If the EHCI controller is resumed first and
- * the OHCI ports are unpowered, then the handover will fail.
- */
-static void prepare_for_handover(struct usb_hcd *hcd)
-{
-	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	int		port;
-
-	/* Here we "know" root ports should always stay powered */
-	ohci_dbg(ohci, "powerup ports\n");
-	for (port = 0; port < ohci->num_ports; port++)
-		ohci_writel(ohci, RH_PS_PPS,
-				&ohci->regs->roothub.portstatus[port]);
-
-	/* Flush those writes */
-	ohci_readl(ohci, &ohci->regs->control);
-	msleep(20);
-}
-
-#else
-
-static inline void prepare_for_handover(struct usb_hcd *hcd)
-{ }
-
-#endif	/* CONFIG_USB_PERSIST etc. */
-
 #ifdef	CONFIG_PM
 
 static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
@@ -312,13 +276,8 @@
 
 static int ohci_pci_resume (struct usb_hcd *hcd)
 {
-	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-
 	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
-	/* FIXME: we should try to detect loss of VBUS power here */
-	prepare_for_handover(hcd);
-	ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
+	ohci_finish_controller_resume(hcd);
 	return 0;
 }