On Wed, 5 May 2010, Rob Duncan wrote: > On May 5, 2010, at 2:24 PM, Alan Stern wrote: > > > Note that there are no debugging printk's in > > usb_autopm_put_interface_no_suspend() or > > usb_autopm_get_interface_no_resume(). I guess I should add some. > > Anyway, you'll want to see if they are getting called. > > I added some tracing and they are not being called. > > > If that doesn't show anything then you'll need to print out the values > > of all the interfaces' dev.power.usage_count fields at some strategic > > spots, like in usb_autoresume_device() and usb_autosuspend_device(). > > I also added some debug printing to usb_autosuspend_device() immediately > after the existing log message. I see pm_runtime_put_sync() return -EBUSY > for the device (apparently because child_count > 0), but the usage_count > for each of my interfaces is 0. > > May 5 15:01:30 localhost kernel: usb 3-3: __pm_runtime_idle !pm_children_suspended power.usage_count=0 power.ignore_children=0 power.child_count=1 > May 5 15:01:30 localhost kernel: usb 3-3: usb_autosuspend_device: cnt 0 -> -16 > May 5 15:01:30 localhost kernel: usb 3-3: usb_autosuspend_device intf 0 usage_count=0 > May 5 15:01:30 localhost kernel: usb 3-3: usb_autosuspend_device intf 1 usage_count=0 > > It at appears that the device's child_count is incremented when > usb_probe_interface() calls pm_runtime_set_active(), and is never > decremented again. Okay, I see what the problem is. It's a subtle thing, involving the difference between the runtime PM state and the usage_count. It also involves what the driver does: If it doesn't ever call usb_autopm_get_interface() or usb_autopm_put_interface(), should the device be autosuspended? I guess it should. This patch ought to fix the problem. Alan Stern Index: usb-2.6/drivers/usb/core/driver.c =================================================================== --- usb-2.6.orig/drivers/usb/core/driver.c +++ usb-2.6/drivers/usb/core/driver.c @@ -302,13 +302,15 @@ static int usb_probe_interface(struct de intf->condition = USB_INTERFACE_BINDING; - /* Probed interfaces are initially active. They are - * runtime-PM-enabled only if the driver has autosuspend support. - * They are sensitive to their children's power states. + /* If the driver does not have autosuspend support then we suppress + * autosuspends by making its interfaces active and leaving them + * runtime-PM-disabled, otherwise we do the reverse. In either case, + * the interfaces are sensitive to their children's power states. */ - pm_runtime_set_active(dev); pm_suspend_ignore_children(dev, false); - if (driver->supports_autosuspend) + if (!driver->supports_autosuspend) + pm_runtime_set_active(dev); + else pm_runtime_enable(dev); /* Carry out a deferred switch to altsetting 0 */ @@ -438,13 +440,15 @@ int usb_driver_claim_interface(struct us iface->condition = USB_INTERFACE_BOUND; - /* Claimed interfaces are initially inactive (suspended). They are - * runtime-PM-enabled only if the driver has autosuspend support. - * They are sensitive to their children's power states. + /* If the driver does not have autosuspend support then we suppress + * autosuspends by making its interfaces active and leaving them + * runtime-PM-disabled, otherwise we do the reverse. In either case, + * the interfaces are sensitive to their children's power states. */ - pm_runtime_set_suspended(dev); pm_suspend_ignore_children(dev, false); - if (driver->supports_autosuspend) + if (!driver->supports_autosuspend) + pm_runtime_set_active(dev); + else pm_runtime_enable(dev); /* if interface was already added, bind now; else let -- 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