aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2008-04-15 01:31:57 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2008-04-15 01:31:57 -0400
commite722409445fbe718f09f6d5e03d0ae84cf0954d0 (patch)
tree490d1fd96cec28b3e5a00ab0ce401d52d720f3cb /drivers
parent04021e4e401d7ac2051839dd5b00a701c9119dd9 (diff)
Input: wacom - implement suspend and autosuspend
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/tablet/wacom.h3
-rw-r--r--drivers/input/tablet/wacom_sys.c76
2 files changed, 69 insertions, 10 deletions
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
index acf9830698cb..706619d06f71 100644
--- a/drivers/input/tablet/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -101,8 +101,11 @@ struct wacom {
101 dma_addr_t data_dma; 101 dma_addr_t data_dma;
102 struct input_dev *dev; 102 struct input_dev *dev;
103 struct usb_device *usbdev; 103 struct usb_device *usbdev;
104 struct usb_interface *intf;
104 struct urb *irq; 105 struct urb *irq;
105 struct wacom_wac * wacom_wac; 106 struct wacom_wac * wacom_wac;
107 struct mutex lock;
108 int open:1;
106 char phys[32]; 109 char phys[32];
107}; 110};
108 111
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 41caaef8e2d7..71cc0c140790 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -70,6 +70,7 @@ static void wacom_sys_irq(struct urb *urb)
70 input_sync(get_input_dev(&wcombo)); 70 input_sync(get_input_dev(&wcombo));
71 71
72 exit: 72 exit:
73 usb_mark_last_busy(wacom->usbdev);
73 retval = usb_submit_urb (urb, GFP_ATOMIC); 74 retval = usb_submit_urb (urb, GFP_ATOMIC);
74 if (retval) 75 if (retval)
75 err ("%s - usb_submit_urb failed with result %d", 76 err ("%s - usb_submit_urb failed with result %d",
@@ -124,10 +125,25 @@ static int wacom_open(struct input_dev *dev)
124{ 125{
125 struct wacom *wacom = input_get_drvdata(dev); 126 struct wacom *wacom = input_get_drvdata(dev);
126 127
128 mutex_lock(&wacom->lock);
129
127 wacom->irq->dev = wacom->usbdev; 130 wacom->irq->dev = wacom->usbdev;
128 if (usb_submit_urb(wacom->irq, GFP_KERNEL)) 131
132 if (usb_autopm_get_interface(wacom->intf) < 0) {
133 mutex_unlock(&wacom->lock);
129 return -EIO; 134 return -EIO;
135 }
136
137 if (usb_submit_urb(wacom->irq, GFP_KERNEL)) {
138 usb_autopm_put_interface(wacom->intf);
139 mutex_unlock(&wacom->lock);
140 return -EIO;
141 }
142
143 wacom->open = 1;
144 wacom->intf->needs_remote_wakeup = 1;
130 145
146 mutex_unlock(&wacom->lock);
131 return 0; 147 return 0;
132} 148}
133 149
@@ -135,7 +151,11 @@ static void wacom_close(struct input_dev *dev)
135{ 151{
136 struct wacom *wacom = input_get_drvdata(dev); 152 struct wacom *wacom = input_get_drvdata(dev);
137 153
154 mutex_lock(&wacom->lock);
138 usb_kill_urb(wacom->irq); 155 usb_kill_urb(wacom->irq);
156 wacom->open = 0;
157 wacom->intf->needs_remote_wakeup = 0;
158 mutex_unlock(&wacom->lock);
139} 159}
140 160
141void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 161void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
@@ -243,6 +263,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
243 263
244 wacom->usbdev = dev; 264 wacom->usbdev = dev;
245 wacom->dev = input_dev; 265 wacom->dev = input_dev;
266 wacom->intf = intf;
267 mutex_init(&wacom->lock);
246 usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); 268 usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
247 strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); 269 strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
248 270
@@ -304,23 +326,57 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
304 326
305static void wacom_disconnect(struct usb_interface *intf) 327static void wacom_disconnect(struct usb_interface *intf)
306{ 328{
307 struct wacom *wacom = usb_get_intfdata (intf); 329 struct wacom *wacom = usb_get_intfdata(intf);
308 330
309 usb_set_intfdata(intf, NULL); 331 usb_set_intfdata(intf, NULL);
310 if (wacom) { 332
311 usb_kill_urb(wacom->irq); 333 usb_kill_urb(wacom->irq);
312 input_unregister_device(wacom->dev); 334 input_unregister_device(wacom->dev);
313 usb_free_urb(wacom->irq); 335 usb_free_urb(wacom->irq);
314 usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); 336 usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma);
315 kfree(wacom->wacom_wac); 337 kfree(wacom->wacom_wac);
316 kfree(wacom); 338 kfree(wacom);
317 } 339}
340
341static int wacom_suspend(struct usb_interface *intf, pm_message_t message)
342{
343 struct wacom *wacom = usb_get_intfdata(intf);
344
345 mutex_lock(&wacom->lock);
346 usb_kill_urb(wacom->irq);
347 mutex_unlock(&wacom->lock);
348
349 return 0;
350}
351
352static int wacom_resume(struct usb_interface *intf)
353{
354 struct wacom *wacom = usb_get_intfdata(intf);
355 int rv;
356
357 mutex_lock(&wacom->lock);
358 if (wacom->open)
359 rv = usb_submit_urb(wacom->irq, GFP_NOIO);
360 else
361 rv = 0;
362 mutex_unlock(&wacom->lock);
363
364 return rv;
365}
366
367static int wacom_reset_resume(struct usb_interface *intf)
368{
369 return wacom_resume(intf);
318} 370}
319 371
320static struct usb_driver wacom_driver = { 372static struct usb_driver wacom_driver = {
321 .name = "wacom", 373 .name = "wacom",
322 .probe = wacom_probe, 374 .probe = wacom_probe,
323 .disconnect = wacom_disconnect, 375 .disconnect = wacom_disconnect,
376 .suspend = wacom_suspend,
377 .resume = wacom_resume,
378 .reset_resume = wacom_reset_resume,
379 .supports_autosuspend = 1,
324}; 380};
325 381
326static int __init wacom_init(void) 382static int __init wacom_init(void)