USB: separate root and non-root suspend/resume

This patch (as916) completes the separation of code paths for suspend
and resume of root hubs as opposed to non-root devices.  Root hubs
will be power-managed through their bus_suspend and bus_resume
methods, whereas normal devices will use usb_port_suspend() and
usb_port_resume().

Changes to the hcd_bus_{suspend,resume} routines mostly represent
motion of code that was already present elsewhere.  They include:

	Adding debugging log messages,

	Setting the device state appropriately, and

	Adding a resume recovery time delay.

Changes to the port-suspend and port-resume routines in hub.c include:

	Removal of checks for root devices (since they will never
	be triggered), and

	Removal of checks for NULL or invalid device pointers (these
	were left over from earlier kernel versions and aren't needed
	at all).

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index d363b0e..4cbe7b3 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -196,20 +196,15 @@
 {
 	int rc;
 
-	rc = usb_port_suspend(udev);
-
-	/* Root hubs don't have upstream ports to suspend,
-	 * so the line above won't do much for them.  We have to
-	 * shut down their downstream HC-to-USB interfaces manually,
-	 * by doing a bus (or "global") suspend.
+	/* Normal USB devices suspend through their upstream port.
+	 * Root hubs don't have upstream ports to suspend,
+	 * so we have to shut down their downstream HC-to-USB
+	 * interfaces manually by doing a bus (or "global") suspend.
 	 */
-	if (rc == 0 && !udev->parent) {
-		rc = hcd_bus_suspend(udev->bus);
-		if (rc) {
-			dev_dbg(&udev->dev, "'global' suspend %d\n", rc);
-			usb_port_resume(udev);
-		}
-	}
+	if (!udev->parent)
+		rc = hcd_bus_suspend(udev);
+	else
+		rc = usb_port_suspend(udev);
 	return rc;
 }
 
@@ -217,25 +212,17 @@
 {
 	int rc;
 
-	if (udev->reset_resume)
+	/* Normal USB devices resume/reset through their upstream port.
+	 * Root hubs don't have upstream ports to resume or reset,
+	 * so we have to start up their downstream HC-to-USB
+	 * interfaces manually by doing a bus (or "global") resume.
+	 */
+	if (!udev->parent)
+		rc = hcd_bus_resume(udev);
+	else if (udev->reset_resume)
 		rc = usb_reset_suspended_device(udev);
 	else
 		rc = usb_port_resume(udev);
-
-	/* Root hubs don't have upstream ports to resume or reset,
-	 * so the line above won't do much for them.  We have to
-	 * start up their downstream HC-to-USB interfaces manually,
-	 * by doing a bus (or "global") resume.
-	 */
-	if (rc == 0 && !udev->parent) {
-		rc = hcd_bus_resume(udev->bus);
-		if (rc)
-			dev_dbg(&udev->dev, "'global' resume %d\n", rc);
-		else {
-			/* TRSMRCY = 10 msec */
-			msleep(10);
-		}
-	}
 	return rc;
 }