[PATCH 024/144] USB: use the no_callbacks flag for interfaces

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

 



From: Ming Lei <tom.leiming@xxxxxxxxx>

Call pm_runtime_no_callbacks to set no_callbacks flag for USB
interfaces.  Since interfaces cannot be power-managed separately from
their parent devices, there's no reason for the runtime-PM core to
invoke any callbacks for them.

Signed-off-by: Ming Lei <tom.leiming@xxxxxxxxx>
Reviewed-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
---
 drivers/usb/core/driver.c  |   82 +++++++++++++++----------------------------
 drivers/usb/core/message.c |    2 +
 2 files changed, 31 insertions(+), 53 deletions(-)

diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index c0e60fb..eda2d2c 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1612,18 +1612,9 @@ EXPORT_SYMBOL_GPL(usb_autopm_get_interface);
  */
 int usb_autopm_get_interface_async(struct usb_interface *intf)
 {
-	int		status = 0;
-	enum rpm_status	s;
-
-	/* Don't request a resume unless the interface is already suspending
-	 * or suspended.  Doing so would force a running suspend timer to be
-	 * cancelled.
-	 */
-	pm_runtime_get_noresume(&intf->dev);
-	s = ACCESS_ONCE(intf->dev.power.runtime_status);
-	if (s == RPM_SUSPENDING || s == RPM_SUSPENDED)
-		status = pm_request_resume(&intf->dev);
+	int	status;
 
+	status = pm_runtime_get(&intf->dev);
 	if (status < 0 && status != -EINPROGRESS)
 		pm_runtime_put_noidle(&intf->dev);
 	else
@@ -1717,71 +1708,56 @@ static int autosuspend_check(struct usb_device *udev)
 
 static int usb_runtime_suspend(struct device *dev)
 {
-	int	status = 0;
+	struct usb_device	*udev = to_usb_device(dev);
+	int			status;
 
 	/* A USB device can be suspended if it passes the various autosuspend
 	 * checks.  Runtime suspend for a USB device means suspending all the
 	 * interfaces and then the device itself.
 	 */
-	if (is_usb_device(dev)) {
-		struct usb_device	*udev = to_usb_device(dev);
-
-		if (autosuspend_check(udev) != 0)
-			return -EAGAIN;
-
-		status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
+	if (autosuspend_check(udev) != 0)
+		return -EAGAIN;
 
-		/* If an interface fails the suspend, adjust the last_busy
-		 * time so that we don't get another suspend attempt right
-		 * away.
-		 */
-		if (status) {
-			udev->last_busy = jiffies +
-					(udev->autosuspend_delay == 0 ?
-						HZ/2 : 0);
-		}
+	status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
 
-		/* Prevent the parent from suspending immediately after */
-		else if (udev->parent)
-			udev->parent->last_busy = jiffies;
+	/* If an interface fails the suspend, adjust the last_busy
+	 * time so that we don't get another suspend attempt right
+	 * away.
+	 */
+	if (status) {
+		udev->last_busy = jiffies +
+				(udev->autosuspend_delay == 0 ? HZ/2 : 0);
 	}
 
-	/* Runtime suspend for a USB interface doesn't mean anything. */
+	/* Prevent the parent from suspending immediately after */
+	else if (udev->parent)
+		udev->parent->last_busy = jiffies;
+
 	return status;
 }
 
 static int usb_runtime_resume(struct device *dev)
 {
+	struct usb_device	*udev = to_usb_device(dev);
+	int			status;
+
 	/* Runtime resume for a USB device means resuming both the device
 	 * and all its interfaces.
 	 */
-	if (is_usb_device(dev)) {
-		struct usb_device	*udev = to_usb_device(dev);
-		int			status;
-
-		status = usb_resume_both(udev, PMSG_AUTO_RESUME);
-		udev->last_busy = jiffies;
-		return status;
-	}
-
-	/* Runtime resume for a USB interface doesn't mean anything. */
-	return 0;
+	status = usb_resume_both(udev, PMSG_AUTO_RESUME);
+	udev->last_busy = jiffies;
+	return status;
 }
 
 static int usb_runtime_idle(struct device *dev)
 {
+	struct usb_device	*udev = to_usb_device(dev);
+
 	/* An idle USB device can be suspended if it passes the various
-	 * autosuspend checks.  An idle interface can be suspended at
-	 * any time.
+	 * autosuspend checks.
 	 */
-	if (is_usb_device(dev)) {
-		struct usb_device	*udev = to_usb_device(dev);
-
-		if (autosuspend_check(udev) != 0)
-			return 0;
-	}
-
-	pm_runtime_suspend(dev);
+	if (autosuspend_check(udev) == 0)
+		pm_runtime_suspend(dev);
 	return 0;
 }
 
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index d6e3e41..f377e49 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -12,6 +12,7 @@
 #include <linux/ctype.h>
 #include <linux/nls.h>
 #include <linux/device.h>
+#include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
 #include <linux/usb/quirks.h>
 #include <linux/usb/hcd.h>	/* for usbcore internals */
@@ -1804,6 +1805,7 @@ free_interfaces:
 		INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
 		intf->minor = -1;
 		device_initialize(&intf->dev);
+		pm_runtime_no_callbacks(&intf->dev);
 		dev_set_name(&intf->dev, "%d-%s:%d.%d",
 			dev->bus->busnum, dev->devpath,
 			configuration, alt->desc.bInterfaceNumber);
-- 
1.7.3.2

--
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