Input: usbtouchscreen - implement runtime power management
This implement USB autosuspend while the device is opened for devices that do remote wakeup with a fallback to open/close for those devices that don't. Devices that require the host to constantly poll them are never autosuspended. Signed-off-by: Oliver Neukum <oneukum@suse.de> Tested-by: Petr Štetiar <ynezz@true.cz> Tested-by: Ondrej Zary <linux@rainbow-software.org> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
committed by
Dmitry Torokhov
parent
ed4299e1b1
commit
5d9efc59e6
@@ -1268,6 +1268,7 @@ static void usbtouch_irq(struct urb *urb)
|
|||||||
usbtouch->type->process_pkt(usbtouch, usbtouch->data, urb->actual_length);
|
usbtouch->type->process_pkt(usbtouch, usbtouch->data, urb->actual_length);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
usb_mark_last_busy(interface_to_usbdev(usbtouch->interface));
|
||||||
retval = usb_submit_urb(urb, GFP_ATOMIC);
|
retval = usb_submit_urb(urb, GFP_ATOMIC);
|
||||||
if (retval)
|
if (retval)
|
||||||
err("%s - usb_submit_urb failed with result: %d",
|
err("%s - usb_submit_urb failed with result: %d",
|
||||||
@@ -1277,23 +1278,39 @@ exit:
|
|||||||
static int usbtouch_open(struct input_dev *input)
|
static int usbtouch_open(struct input_dev *input)
|
||||||
{
|
{
|
||||||
struct usbtouch_usb *usbtouch = input_get_drvdata(input);
|
struct usbtouch_usb *usbtouch = input_get_drvdata(input);
|
||||||
|
int r;
|
||||||
|
|
||||||
usbtouch->irq->dev = interface_to_usbdev(usbtouch->interface);
|
usbtouch->irq->dev = interface_to_usbdev(usbtouch->interface);
|
||||||
|
|
||||||
|
r = usb_autopm_get_interface(usbtouch->interface) ? -EIO : 0;
|
||||||
|
if (r < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (!usbtouch->type->irq_always) {
|
if (!usbtouch->type->irq_always) {
|
||||||
if (usb_submit_urb(usbtouch->irq, GFP_KERNEL))
|
if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) {
|
||||||
return -EIO;
|
r = -EIO;
|
||||||
|
goto out_put;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
usbtouch->interface->needs_remote_wakeup = 1;
|
||||||
|
out_put:
|
||||||
|
usb_autopm_put_interface(usbtouch->interface);
|
||||||
|
out:
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usbtouch_close(struct input_dev *input)
|
static void usbtouch_close(struct input_dev *input)
|
||||||
{
|
{
|
||||||
struct usbtouch_usb *usbtouch = input_get_drvdata(input);
|
struct usbtouch_usb *usbtouch = input_get_drvdata(input);
|
||||||
|
int r;
|
||||||
|
|
||||||
if (!usbtouch->type->irq_always)
|
if (!usbtouch->type->irq_always)
|
||||||
usb_kill_urb(usbtouch->irq);
|
usb_kill_urb(usbtouch->irq);
|
||||||
|
r = usb_autopm_get_interface(usbtouch->interface);
|
||||||
|
usbtouch->interface->needs_remote_wakeup = 0;
|
||||||
|
if (!r)
|
||||||
|
usb_autopm_put_interface(usbtouch->interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usbtouch_suspend
|
static int usbtouch_suspend
|
||||||
@@ -1457,8 +1474,11 @@ static int usbtouch_probe(struct usb_interface *intf,
|
|||||||
usb_set_intfdata(intf, usbtouch);
|
usb_set_intfdata(intf, usbtouch);
|
||||||
|
|
||||||
if (usbtouch->type->irq_always) {
|
if (usbtouch->type->irq_always) {
|
||||||
|
/* this can't fail */
|
||||||
|
usb_autopm_get_interface(intf);
|
||||||
err = usb_submit_urb(usbtouch->irq, GFP_KERNEL);
|
err = usb_submit_urb(usbtouch->irq, GFP_KERNEL);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
usb_autopm_put_interface(intf);
|
||||||
err("%s - usb_submit_urb failed with result: %d",
|
err("%s - usb_submit_urb failed with result: %d",
|
||||||
__func__, err);
|
__func__, err);
|
||||||
goto out_unregister_input;
|
goto out_unregister_input;
|
||||||
@@ -1512,6 +1532,7 @@ static struct usb_driver usbtouch_driver = {
|
|||||||
.suspend = usbtouch_suspend,
|
.suspend = usbtouch_suspend,
|
||||||
.resume = usbtouch_resume,
|
.resume = usbtouch_resume,
|
||||||
.id_table = usbtouch_devices,
|
.id_table = usbtouch_devices,
|
||||||
|
.supports_autosuspend = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init usbtouch_init(void)
|
static int __init usbtouch_init(void)
|
||||||
|
Reference in New Issue
Block a user