[PATCH] USB: code cleanup in suspend/resume path

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From 186ed6425f31636d1bb52de0f48a76dddf8e6224 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oliver@xxxxxxxxxx>
Date: Tue, 3 Jan 2012 12:34:31 +0100
Subject: [PATCH] USB: code cleanup in suspend/resume path

Do the cleanup to avoid behaviorial parameters Linus
requested.

Signed-off-by: Oliver Neukum <oneukum@xxxxxxx>
---
 drivers/usb/core/driver.c |   54 ++++++++++++++++++++++++++++----------------
 1 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 07f8718..9d708c3 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -974,12 +974,11 @@ void usb_rebind_intf(struct usb_interface *intf)
 #define DO_UNBIND	0
 #define DO_REBIND	1
 
-/* Unbind drivers for @udev's interfaces that don't support suspend/resume,
- * or rebind interfaces that have been unbound, according to @action.
+/* Unbind drivers for @udev's interfaces that don't support suspend/resume
  *
  * The caller must hold @udev's device lock.
  */
-static void do_unbind_rebind(struct usb_device *udev, int action)
+static void kick_unsupportive_drivers_from_interfaces(struct usb_device *udev)
 {
 	struct usb_host_config	*config;
 	int			i;
@@ -990,23 +989,32 @@ static void do_unbind_rebind(struct usb_device *udev, int action)
 	if (config) {
 		for (i = 0; i < config->desc.bNumInterfaces; ++i) {
 			intf = config->interface[i];
-			switch (action) {
-			case DO_UNBIND:
-				if (intf->dev.driver) {
-					drv = to_usb_driver(intf->dev.driver);
-					if (!drv->suspend || !drv->resume)
-						usb_forced_unbind_intf(intf);
-				}
-				break;
-			case DO_REBIND:
-				if (intf->needs_binding)
-					usb_rebind_intf(intf);
-				break;
+
+			if (intf->dev.driver) {
+				drv = to_usb_driver(intf->dev.driver);
+				if (!drv->suspend || !drv->resume)
+					usb_forced_unbind_intf(intf);
 			}
 		}
 	}
 }
 
+static void do_rebind(struct usb_device *udev)
+{
+	struct usb_host_config	*config;
+	int			i;
+	struct usb_interface	*intf;
+
+	config = udev->actconfig;
+	if (config) {
+		for (i = 0; i < config->desc.bNumInterfaces; ++i) {
+			intf = config->interface[i];
+			if (intf->needs_binding)
+				usb_rebind_intf(intf);
+		}
+	}
+}
+
 static int usb_suspend_device(struct usb_device *udev, pm_message_t msg)
 {
 	struct usb_device_driver	*udriver;
@@ -1296,7 +1304,11 @@ int usb_suspend(struct device *dev, pm_message_t msg)
 {
 	struct usb_device	*udev = to_usb_device(dev);
 
-	do_unbind_rebind(udev, DO_UNBIND);
+	kick_unsupportive_drivers_from_interfaces(udev);
+	/* From now on we are sure all drivers support suspend/resume
+	 * but not necessarily reset_resume()
+	 * so we may still need to rebind upon resumption
+	 */
 	choose_wakeup(udev, msg);
 	return usb_suspend_both(udev, msg);
 }
@@ -1307,15 +1319,17 @@ int usb_resume(struct device *dev, pm_message_t msg)
 	struct usb_device	*udev = to_usb_device(dev);
 	int			status;
 
-	/* For PM complete calls, all we do is rebind interfaces */
+	/* For PM complete calls, all we do is rebind interfaces
+	 * if the need has arisen earlier
+	 */
 	if (msg.event == PM_EVENT_ON) {
 		if (udev->state != USB_STATE_NOTATTACHED)
-			do_unbind_rebind(udev, DO_REBIND);
+			do_rebind(udev);
 		status = 0;
 
 	/* For all other calls, take the device back to full power and
 	 * tell the PM core in case it was autosuspended previously.
-	 * Unbind the interfaces that will need rebinding later.
+	 * Rebind the interfaces that need it.
 	 */
 	} else {
 		status = usb_resume_both(udev, msg);
@@ -1323,7 +1337,7 @@ int usb_resume(struct device *dev, pm_message_t msg)
 			pm_runtime_disable(dev);
 			pm_runtime_set_active(dev);
 			pm_runtime_enable(dev);
-			do_unbind_rebind(udev, DO_REBIND);
+			do_rebind(udev);
 		}
 	}
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux