Re: [PATCH V3] input: Fix USB autosuspend on bcm5974
From: Alan Stern <stern@rowland.harvard.edu>
Date: 2011-10-12 15:28:08
On Wed, 12 Oct 2011, Oliver Neukum wrote:
Am Mittwoch, 12. Oktober 2011, 16:33:13 schrieb Alan Stern:quoted
I admit to not being very familiar with the way usbhid handles autosuspend. However in general, if a suspend fails because the driver is busy, then when the driver stops being busy it should initiate the next round of autosuspend. In this case, when the key release has been fully processed, the driver should call usb_put_interface_async() or something similar, which would restart the timer.I see. I can do this although it is not very elegant, because the pm counters at this point ought to be 0 already.
Well, if the usage counter is 0 then you wouldn't want to call usb_put_interface_async(). On the other hand, if the usage counter is 0 then by definition the device isn't in use, so you shouldn't need to fail an autosuspend request -- not unless it races with an I/O event. To anticipate your next question, how should such a race be hanlded? Here's one way: I/O event occurs; interrupt handler is called. Handler sets a device_busy flag. Autosuspend attempt occurs because the usage counter is 0. Suspend routine returns -EBUSY because device_busy is set. Handler calls usb_get_interface_async(). The device is active, so the handler goes on to process the event. Handler calls usb_put_interface_async().
Arguably a driver is the wrong layer to do this.
Are you suggesting the usb_runtime_suspend() should call usb_mark_last_busy() and pm_runtime_autosuspend() if usb_suspend_both() returns -EBUSY or -EAGAIN? This would allow a driver to block autosuspend attempts while leaving the usage counter set to 0. Alan Stern