From stern@rowland.harvard.edu Thu Apr 5 13:03:59 2007 From: Alan Stern Date: Thu, 5 Apr 2007 16:03:49 -0400 (EDT) Subject: [PATCH 2/11] USB: more autosuspend timer stuff To: Greg KH Cc: USB development list Message-ID: This patch (as879) ties up some loose ends from an earlier patch. These are things I didn't think to include at the time but which clearly belonged there. If an autosuspend fails because driver activity races with the autosuspend call, restart the autosuspend timer. When a device is resumed by an external request, it counts as device activity and should update the last_busy time so that the next autoresume won't occur immediately. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -983,7 +983,10 @@ static int autosuspend_check(struct usb_ #else -#define autosuspend_check(udev) 0 +static inline int autosuspend_check(struct usb_device *udev) +{ + return 0; +} #endif /* CONFIG_USB_SUSPEND */ @@ -1041,7 +1044,6 @@ static int usb_suspend_both(struct usb_d if (status < 0) goto done; } - cancel_delayed_work(&udev->autosuspend); /* Suspend all the interfaces and then udev itself */ if (udev->actconfig) { @@ -1062,9 +1064,16 @@ static int usb_suspend_both(struct usb_d usb_resume_interface(intf); } + /* Try another autosuspend when the interfaces aren't busy */ + if (udev->auto_pm) + autosuspend_check(udev); + /* If the suspend succeeded, propagate it up the tree */ - } else if (parent) - usb_autosuspend_device(parent); + } else { + cancel_delayed_work(&udev->autosuspend); + if (parent) + usb_autosuspend_device(parent); + } done: // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); @@ -1475,6 +1484,7 @@ int usb_external_resume_device(struct us usb_pm_lock(udev); udev->auto_pm = 0; status = usb_resume_both(udev); + udev->last_busy = jiffies; usb_pm_unlock(udev); /* Now that the device is awake, we can start trying to autosuspend