USB: more autosuspend timer stuff

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 <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Alan Stern 2007-04-05 16:03:49 -04:00 коммит произвёл Greg Kroah-Hartman
Родитель 4fe5354f61
Коммит ef7f6c7084
1 изменённых файлов: 14 добавлений и 4 удалений

Просмотреть файл

@ -983,7 +983,10 @@ static int autosuspend_check(struct usb_device *udev)
#else #else
#define autosuspend_check(udev) 0 static inline int autosuspend_check(struct usb_device *udev)
{
return 0;
}
#endif /* CONFIG_USB_SUSPEND */ #endif /* CONFIG_USB_SUSPEND */
@ -1041,7 +1044,6 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
if (status < 0) if (status < 0)
goto done; goto done;
} }
cancel_delayed_work(&udev->autosuspend);
/* Suspend all the interfaces and then udev itself */ /* Suspend all the interfaces and then udev itself */
if (udev->actconfig) { if (udev->actconfig) {
@ -1062,9 +1064,16 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
usb_resume_interface(intf); 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 */ /* If the suspend succeeded, propagate it up the tree */
} else if (parent) } else {
usb_autosuspend_device(parent); cancel_delayed_work(&udev->autosuspend);
if (parent)
usb_autosuspend_device(parent);
}
done: done:
// dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
@ -1475,6 +1484,7 @@ int usb_external_resume_device(struct usb_device *udev)
usb_pm_lock(udev); usb_pm_lock(udev);
udev->auto_pm = 0; udev->auto_pm = 0;
status = usb_resume_both(udev); status = usb_resume_both(udev);
udev->last_busy = jiffies;
usb_pm_unlock(udev); usb_pm_unlock(udev);
/* Now that the device is awake, we can start trying to autosuspend /* Now that the device is awake, we can start trying to autosuspend