Commit 89842ae6 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

USB: fix interface runtime-PM settings

This patch (as1379) reworks the logic for handling USB interface
runtime-PM settings -- hopefully it's right this time!  The problem is
that when a driver is unbound or binding fails, runtime PM for the
interface always gets disabled.  But pm_runtime_disable() nests, so it
shouldn't be called unless the interface was previously enabled for
runtime PM.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Reported-by: default avatarRob Duncan <Robert.Duncan@exar.com>
Tested-by: default avatarRob Duncan <Robert.Duncan@exar.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 54b5acf3
...@@ -334,7 +334,8 @@ static int usb_probe_interface(struct device *dev) ...@@ -334,7 +334,8 @@ static int usb_probe_interface(struct device *dev)
usb_cancel_queued_reset(intf); usb_cancel_queued_reset(intf);
/* Unbound interfaces are always runtime-PM-disabled and -suspended */ /* Unbound interfaces are always runtime-PM-disabled and -suspended */
pm_runtime_disable(dev); if (driver->supports_autosuspend)
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev); pm_runtime_set_suspended(dev);
usb_autosuspend_device(udev); usb_autosuspend_device(udev);
...@@ -389,7 +390,8 @@ static int usb_unbind_interface(struct device *dev) ...@@ -389,7 +390,8 @@ static int usb_unbind_interface(struct device *dev)
intf->needs_remote_wakeup = 0; intf->needs_remote_wakeup = 0;
/* Unbound interfaces are always runtime-PM-disabled and -suspended */ /* Unbound interfaces are always runtime-PM-disabled and -suspended */
pm_runtime_disable(dev); if (driver->supports_autosuspend)
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev); pm_runtime_set_suspended(dev);
/* Undo any residual pm_autopm_get_interface_* calls */ /* Undo any residual pm_autopm_get_interface_* calls */
...@@ -438,14 +440,17 @@ int usb_driver_claim_interface(struct usb_driver *driver, ...@@ -438,14 +440,17 @@ int usb_driver_claim_interface(struct usb_driver *driver,
iface->condition = USB_INTERFACE_BOUND; iface->condition = USB_INTERFACE_BOUND;
/* Claimed interfaces are initially inactive (suspended). They are /* Claimed interfaces are initially inactive (suspended) and
* runtime-PM-enabled only if the driver has autosuspend support. * runtime-PM-enabled, but only if the driver has autosuspend
* They are sensitive to their children's power states. * support. Otherwise they are marked active, to prevent the
* device from being autosuspended, but left disabled. In either
* case they are sensitive to their children's power states.
*/ */
pm_runtime_set_suspended(dev);
pm_suspend_ignore_children(dev, false); pm_suspend_ignore_children(dev, false);
if (driver->supports_autosuspend) if (driver->supports_autosuspend)
pm_runtime_enable(dev); pm_runtime_enable(dev);
else
pm_runtime_set_active(dev);
/* if interface was already added, bind now; else let /* if interface was already added, bind now; else let
* the future device_add() bind it, bypassing probe() * the future device_add() bind it, bypassing probe()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment