Skip to content

Commit

Permalink
Input: wacom - implement suspend and autosuspend
Browse files Browse the repository at this point in the history
This implements suspend and autosuspend support for wacom devices.
It works by using the usb last busy functionality triggered in the
completion callback.

Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Ping Cheng <pingc@wacom.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
  • Loading branch information
Oliver Neukum authored and Dmitry Torokhov committed Apr 15, 2008
1 parent 04021e4 commit e722409
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 10 deletions.
3 changes: 3 additions & 0 deletions drivers/input/tablet/wacom.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,11 @@ struct wacom {
dma_addr_t data_dma;
struct input_dev *dev;
struct usb_device *usbdev;
struct usb_interface *intf;
struct urb *irq;
struct wacom_wac * wacom_wac;
struct mutex lock;
int open:1;
char phys[32];
};

Expand Down
76 changes: 66 additions & 10 deletions drivers/input/tablet/wacom_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ static void wacom_sys_irq(struct urb *urb)
input_sync(get_input_dev(&wcombo));

exit:
usb_mark_last_busy(wacom->usbdev);
retval = usb_submit_urb (urb, GFP_ATOMIC);
if (retval)
err ("%s - usb_submit_urb failed with result %d",
Expand Down Expand Up @@ -124,18 +125,37 @@ static int wacom_open(struct input_dev *dev)
{
struct wacom *wacom = input_get_drvdata(dev);

mutex_lock(&wacom->lock);

wacom->irq->dev = wacom->usbdev;
if (usb_submit_urb(wacom->irq, GFP_KERNEL))

if (usb_autopm_get_interface(wacom->intf) < 0) {
mutex_unlock(&wacom->lock);
return -EIO;
}

if (usb_submit_urb(wacom->irq, GFP_KERNEL)) {
usb_autopm_put_interface(wacom->intf);
mutex_unlock(&wacom->lock);
return -EIO;
}

wacom->open = 1;
wacom->intf->needs_remote_wakeup = 1;

mutex_unlock(&wacom->lock);
return 0;
}

static void wacom_close(struct input_dev *dev)
{
struct wacom *wacom = input_get_drvdata(dev);

mutex_lock(&wacom->lock);
usb_kill_urb(wacom->irq);
wacom->open = 0;
wacom->intf->needs_remote_wakeup = 0;
mutex_unlock(&wacom->lock);
}

void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
Expand Down Expand Up @@ -243,6 +263,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i

wacom->usbdev = dev;
wacom->dev = input_dev;
wacom->intf = intf;
mutex_init(&wacom->lock);
usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
strlcat(wacom->phys, "/input0", sizeof(wacom->phys));

Expand Down Expand Up @@ -304,23 +326,57 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i

static void wacom_disconnect(struct usb_interface *intf)
{
struct wacom *wacom = usb_get_intfdata (intf);
struct wacom *wacom = usb_get_intfdata(intf);

usb_set_intfdata(intf, NULL);
if (wacom) {
usb_kill_urb(wacom->irq);
input_unregister_device(wacom->dev);
usb_free_urb(wacom->irq);
usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma);
kfree(wacom->wacom_wac);
kfree(wacom);
}

usb_kill_urb(wacom->irq);
input_unregister_device(wacom->dev);
usb_free_urb(wacom->irq);
usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma);
kfree(wacom->wacom_wac);
kfree(wacom);
}

static int wacom_suspend(struct usb_interface *intf, pm_message_t message)
{
struct wacom *wacom = usb_get_intfdata(intf);

mutex_lock(&wacom->lock);
usb_kill_urb(wacom->irq);
mutex_unlock(&wacom->lock);

return 0;
}

static int wacom_resume(struct usb_interface *intf)
{
struct wacom *wacom = usb_get_intfdata(intf);
int rv;

mutex_lock(&wacom->lock);
if (wacom->open)
rv = usb_submit_urb(wacom->irq, GFP_NOIO);
else
rv = 0;
mutex_unlock(&wacom->lock);

return rv;
}

static int wacom_reset_resume(struct usb_interface *intf)
{
return wacom_resume(intf);
}

static struct usb_driver wacom_driver = {
.name = "wacom",
.probe = wacom_probe,
.disconnect = wacom_disconnect,
.suspend = wacom_suspend,
.resume = wacom_resume,
.reset_resume = wacom_reset_resume,
.supports_autosuspend = 1,
};

static int __init wacom_init(void)
Expand Down

0 comments on commit e722409

Please sign in to comment.