diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2010-05-11 11:44:06 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-20 16:21:45 -0400 |
commit | 89842ae6515c49405e20c0629a6442b6885ad49d (patch) | |
tree | aab7bc2ef74ffaf607ac1bcc5d2dbbfbc94eb13e /drivers/usb/core | |
parent | 54b5acf3acb7a1f83ec281d111d3e2812cd7ad9d (diff) |
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: Alan Stern <stern@rowland.harvard.edu>
Reported-by: Rob Duncan <Robert.Duncan@exar.com>
Tested-by: Rob Duncan <Robert.Duncan@exar.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/driver.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 207146743ea7..ded550eda5d9 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -334,7 +334,8 @@ static int usb_probe_interface(struct device *dev) | |||
334 | usb_cancel_queued_reset(intf); | 334 | usb_cancel_queued_reset(intf); |
335 | 335 | ||
336 | /* Unbound interfaces are always runtime-PM-disabled and -suspended */ | 336 | /* Unbound interfaces are always runtime-PM-disabled and -suspended */ |
337 | pm_runtime_disable(dev); | 337 | if (driver->supports_autosuspend) |
338 | pm_runtime_disable(dev); | ||
338 | pm_runtime_set_suspended(dev); | 339 | pm_runtime_set_suspended(dev); |
339 | 340 | ||
340 | usb_autosuspend_device(udev); | 341 | usb_autosuspend_device(udev); |
@@ -389,7 +390,8 @@ static int usb_unbind_interface(struct device *dev) | |||
389 | intf->needs_remote_wakeup = 0; | 390 | intf->needs_remote_wakeup = 0; |
390 | 391 | ||
391 | /* Unbound interfaces are always runtime-PM-disabled and -suspended */ | 392 | /* Unbound interfaces are always runtime-PM-disabled and -suspended */ |
392 | pm_runtime_disable(dev); | 393 | if (driver->supports_autosuspend) |
394 | pm_runtime_disable(dev); | ||
393 | pm_runtime_set_suspended(dev); | 395 | pm_runtime_set_suspended(dev); |
394 | 396 | ||
395 | /* Undo any residual pm_autopm_get_interface_* calls */ | 397 | /* Undo any residual pm_autopm_get_interface_* calls */ |
@@ -438,14 +440,17 @@ int usb_driver_claim_interface(struct usb_driver *driver, | |||
438 | 440 | ||
439 | iface->condition = USB_INTERFACE_BOUND; | 441 | iface->condition = USB_INTERFACE_BOUND; |
440 | 442 | ||
441 | /* Claimed interfaces are initially inactive (suspended). They are | 443 | /* Claimed interfaces are initially inactive (suspended) and |
442 | * runtime-PM-enabled only if the driver has autosuspend support. | 444 | * runtime-PM-enabled, but only if the driver has autosuspend |
443 | * They are sensitive to their children's power states. | 445 | * support. Otherwise they are marked active, to prevent the |
446 | * device from being autosuspended, but left disabled. In either | ||
447 | * case they are sensitive to their children's power states. | ||
444 | */ | 448 | */ |
445 | pm_runtime_set_suspended(dev); | ||
446 | pm_suspend_ignore_children(dev, false); | 449 | pm_suspend_ignore_children(dev, false); |
447 | if (driver->supports_autosuspend) | 450 | if (driver->supports_autosuspend) |
448 | pm_runtime_enable(dev); | 451 | pm_runtime_enable(dev); |
452 | else | ||
453 | pm_runtime_set_active(dev); | ||
449 | 454 | ||
450 | /* if interface was already added, bind now; else let | 455 | /* if interface was already added, bind now; else let |
451 | * the future device_add() bind it, bypassing probe() | 456 | * the future device_add() bind it, bypassing probe() |