USB: improve uses of usb_mark_last_busy

This patch (as1434) cleans up the uses of usb_mark_last_busy() in
usbcore.  The function will be called when a device is resumed and
whenever a usage count is decremented.  A call that was missing from
the hub driver is added: A hub is used whenever one of its ports gets
suspended (this prevents hubs from suspending immediately after their
last child).

In addition, the call to disable autosuspend support for new devices
by default is moved from usb_detect_quirks() (where it doesn't really
belong) into usb_new_device() along with all the other runtime-PM
initializations.  Finally, an extra pm_runtime_get_noresume() is added
to prevent new devices from autosuspending while they are being
registered.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 43c25c2..b9278a1 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1261,6 +1261,7 @@
 					udev->reset_resume);
 		}
 	}
+	usb_mark_last_busy(udev);
 
  done:
 	dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status);
@@ -1328,7 +1329,6 @@
 			pm_runtime_disable(dev);
 			pm_runtime_set_active(dev);
 			pm_runtime_enable(dev);
-			usb_mark_last_busy(udev);
 			do_unbind_rebind(udev, DO_REBIND);
 		}
 	}
@@ -1660,11 +1660,6 @@
 		return -EAGAIN;
 
 	status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
-
-	/* Prevent the parent from suspending immediately after */
-	if (status == 0 && udev->parent)
-		usb_mark_last_busy(udev->parent);
-
 	return status;
 }
 
@@ -1677,7 +1672,6 @@
 	 * and all its interfaces.
 	 */
 	status = usb_resume_both(udev, PMSG_AUTO_RESUME);
-	usb_mark_last_busy(udev);
 	return status;
 }
 
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index fdb62ca..b98efae 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1803,9 +1803,15 @@
 
 	/* Tell the runtime-PM framework the device is active */
 	pm_runtime_set_active(&udev->dev);
+	pm_runtime_get_noresume(&udev->dev);
 	pm_runtime_use_autosuspend(&udev->dev);
 	pm_runtime_enable(&udev->dev);
 
+	/* By default, forbid autosuspend for all devices.  It will be
+	 * allowed for hubs during binding.
+	 */
+	usb_disable_autosuspend(udev);
+
 	err = usb_enumerate_device(udev);	/* Read descriptors */
 	if (err < 0)
 		goto fail;
@@ -1831,6 +1837,8 @@
 	}
 
 	(void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev);
+	usb_mark_last_busy(udev);
+	pm_runtime_put_sync_autosuspend(&udev->dev);
 	return err;
 
 fail:
@@ -2221,6 +2229,7 @@
 		usb_set_device_state(udev, USB_STATE_SUSPENDED);
 		msleep(10);
 	}
+	usb_mark_last_busy(hub->hdev);
 	return status;
 }
 
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index e3531da..44c5954 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -117,15 +117,6 @@
 		dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
 				udev->quirks);
 
-#ifdef	CONFIG_USB_SUSPEND
-
-	/* By default, disable autosuspend for all devices.  The hub driver
-	 * will enable it for hubs.
-	 */
-	usb_disable_autosuspend(udev);
-
-#endif
-
 	/* For the present, all devices default to USB-PERSIST enabled */
 #if 0		/* was: #ifdef CONFIG_PM */
 	/* Hubs are automatically enabled for USB-PERSIST */