aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorOliver Neukum <oneukum@suse.de>2010-12-22 09:33:40 -0500
committerJiri Kosina <jkosina@suse.cz>2010-12-22 13:06:53 -0500
commit68229689b6dc950bea4b81dd60563884f4a7e1c5 (patch)
tree492329a1d82af8b4be881da356f4b1f67b13a343 /drivers/hid
parent1874542d952bbea01997191aee868b472555fd9a (diff)
HID: usbhid: base runtime PM on modern API
This patch doesn't alter functionality, but removes a dedicated kernel thread. Signed-off-by: Oliver Neukum <oneukum@suse.de> Tested-by: Maulik Mankad <x0082077@ti.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/usbhid/hid-core.c57
-rw-r--r--drivers/hid/usbhid/usbhid.h1
2 files changed, 19 insertions, 39 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 276758f53ab5..b336dd84036f 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -67,7 +67,6 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
67 * Input submission and I/O error handler. 67 * Input submission and I/O error handler.
68 */ 68 */
69static DEFINE_MUTEX(hid_open_mut); 69static DEFINE_MUTEX(hid_open_mut);
70static struct workqueue_struct *resumption_waker;
71 70
72static void hid_io_error(struct hid_device *hid); 71static void hid_io_error(struct hid_device *hid);
73static int hid_submit_out(struct hid_device *hid); 72static int hid_submit_out(struct hid_device *hid);
@@ -300,10 +299,19 @@ static int hid_submit_out(struct hid_device *hid)
300 struct hid_report *report; 299 struct hid_report *report;
301 char *raw_report; 300 char *raw_report;
302 struct usbhid_device *usbhid = hid->driver_data; 301 struct usbhid_device *usbhid = hid->driver_data;
302 int r;
303 303
304 report = usbhid->out[usbhid->outtail].report; 304 report = usbhid->out[usbhid->outtail].report;
305 raw_report = usbhid->out[usbhid->outtail].raw_report; 305 raw_report = usbhid->out[usbhid->outtail].raw_report;
306 306
307 r = usb_autopm_get_interface_async(usbhid->intf);
308 if (r < 0)
309 return -1;
310
311 /*
312 * if the device hasn't been woken, we leave the output
313 * to resume()
314 */
307 if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) { 315 if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
308 usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); 316 usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
309 usbhid->urbout->dev = hid_to_usb_dev(hid); 317 usbhid->urbout->dev = hid_to_usb_dev(hid);
@@ -314,16 +322,10 @@ static int hid_submit_out(struct hid_device *hid)
314 322
315 if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) { 323 if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
316 hid_err(hid, "usb_submit_urb(out) failed\n"); 324 hid_err(hid, "usb_submit_urb(out) failed\n");
325 usb_autopm_put_interface_async(usbhid->intf);
317 return -1; 326 return -1;
318 } 327 }
319 usbhid->last_out = jiffies; 328 usbhid->last_out = jiffies;
320 } else {
321 /*
322 * queue work to wake up the device.
323 * as the work queue is freezeable, this is safe
324 * with respect to STD and STR
325 */
326 queue_work(resumption_waker, &usbhid->restart_work);
327 } 329 }
328 330
329 return 0; 331 return 0;
@@ -334,13 +336,16 @@ static int hid_submit_ctrl(struct hid_device *hid)
334 struct hid_report *report; 336 struct hid_report *report;
335 unsigned char dir; 337 unsigned char dir;
336 char *raw_report; 338 char *raw_report;
337 int len; 339 int len, r;
338 struct usbhid_device *usbhid = hid->driver_data; 340 struct usbhid_device *usbhid = hid->driver_data;
339 341
340 report = usbhid->ctrl[usbhid->ctrltail].report; 342 report = usbhid->ctrl[usbhid->ctrltail].report;
341 raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report; 343 raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
342 dir = usbhid->ctrl[usbhid->ctrltail].dir; 344 dir = usbhid->ctrl[usbhid->ctrltail].dir;
343 345
346 r = usb_autopm_get_interface_async(usbhid->intf);
347 if (r < 0)
348 return -1;
344 if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) { 349 if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
345 len = ((report->size - 1) >> 3) + 1 + (report->id > 0); 350 len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
346 if (dir == USB_DIR_OUT) { 351 if (dir == USB_DIR_OUT) {
@@ -375,17 +380,11 @@ static int hid_submit_ctrl(struct hid_device *hid)
375 usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength); 380 usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
376 381
377 if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) { 382 if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
383 usb_autopm_put_interface_async(usbhid->intf);
378 hid_err(hid, "usb_submit_urb(ctrl) failed\n"); 384 hid_err(hid, "usb_submit_urb(ctrl) failed\n");
379 return -1; 385 return -1;
380 } 386 }
381 usbhid->last_ctrl = jiffies; 387 usbhid->last_ctrl = jiffies;
382 } else {
383 /*
384 * queue work to wake up the device.
385 * as the work queue is freezeable, this is safe
386 * with respect to STD and STR
387 */
388 queue_work(resumption_waker, &usbhid->restart_work);
389 } 388 }
390 389
391 return 0; 390 return 0;
@@ -435,6 +434,7 @@ static void hid_irq_out(struct urb *urb)
435 434
436 clear_bit(HID_OUT_RUNNING, &usbhid->iofl); 435 clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
437 spin_unlock_irqrestore(&usbhid->lock, flags); 436 spin_unlock_irqrestore(&usbhid->lock, flags);
437 usb_autopm_put_interface_async(usbhid->intf);
438 wake_up(&usbhid->wait); 438 wake_up(&usbhid->wait);
439} 439}
440 440
@@ -480,11 +480,13 @@ static void hid_ctrl(struct urb *urb)
480 wake_up(&usbhid->wait); 480 wake_up(&usbhid->wait);
481 } 481 }
482 spin_unlock(&usbhid->lock); 482 spin_unlock(&usbhid->lock);
483 usb_autopm_put_interface_async(usbhid->intf);
483 return; 484 return;
484 } 485 }
485 486
486 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); 487 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
487 spin_unlock(&usbhid->lock); 488 spin_unlock(&usbhid->lock);
489 usb_autopm_put_interface_async(usbhid->intf);
488 wake_up(&usbhid->wait); 490 wake_up(&usbhid->wait);
489} 491}
490 492
@@ -655,7 +657,7 @@ int usbhid_open(struct hid_device *hid)
655 mutex_lock(&hid_open_mut); 657 mutex_lock(&hid_open_mut);
656 if (!hid->open++) { 658 if (!hid->open++) {
657 res = usb_autopm_get_interface(usbhid->intf); 659 res = usb_autopm_get_interface(usbhid->intf);
658 /* the device must be awake to reliable request remote wakeup */ 660 /* the device must be awake to reliably request remote wakeup */
659 if (res < 0) { 661 if (res < 0) {
660 hid->open--; 662 hid->open--;
661 mutex_unlock(&hid_open_mut); 663 mutex_unlock(&hid_open_mut);
@@ -856,18 +858,6 @@ static void usbhid_restart_queues(struct usbhid_device *usbhid)
856 usbhid_restart_ctrl_queue(usbhid); 858 usbhid_restart_ctrl_queue(usbhid);
857} 859}
858 860
859static void __usbhid_restart_queues(struct work_struct *work)
860{
861 struct usbhid_device *usbhid =
862 container_of(work, struct usbhid_device, restart_work);
863 int r;
864
865 r = usb_autopm_get_interface(usbhid->intf);
866 if (r < 0)
867 return;
868 usb_autopm_put_interface(usbhid->intf);
869}
870
871static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) 861static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
872{ 862{
873 struct usbhid_device *usbhid = hid->driver_data; 863 struct usbhid_device *usbhid = hid->driver_data;
@@ -1204,7 +1194,6 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
1204 1194
1205 init_waitqueue_head(&usbhid->wait); 1195 init_waitqueue_head(&usbhid->wait);
1206 INIT_WORK(&usbhid->reset_work, hid_reset); 1196 INIT_WORK(&usbhid->reset_work, hid_reset);
1207 INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
1208 setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); 1197 setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
1209 spin_lock_init(&usbhid->lock); 1198 spin_lock_init(&usbhid->lock);
1210 1199
@@ -1239,7 +1228,6 @@ static void usbhid_disconnect(struct usb_interface *intf)
1239static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid) 1228static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
1240{ 1229{
1241 del_timer_sync(&usbhid->io_retry); 1230 del_timer_sync(&usbhid->io_retry);
1242 cancel_work_sync(&usbhid->restart_work);
1243 cancel_work_sync(&usbhid->reset_work); 1231 cancel_work_sync(&usbhid->reset_work);
1244} 1232}
1245 1233
@@ -1260,7 +1248,6 @@ static int hid_pre_reset(struct usb_interface *intf)
1260 spin_lock_irq(&usbhid->lock); 1248 spin_lock_irq(&usbhid->lock);
1261 set_bit(HID_RESET_PENDING, &usbhid->iofl); 1249 set_bit(HID_RESET_PENDING, &usbhid->iofl);
1262 spin_unlock_irq(&usbhid->lock); 1250 spin_unlock_irq(&usbhid->lock);
1263 cancel_work_sync(&usbhid->restart_work);
1264 hid_cease_io(usbhid); 1251 hid_cease_io(usbhid);
1265 1252
1266 return 0; 1253 return 0;
@@ -1459,9 +1446,6 @@ static int __init hid_init(void)
1459{ 1446{
1460 int retval = -ENOMEM; 1447 int retval = -ENOMEM;
1461 1448
1462 resumption_waker = create_freezeable_workqueue("usbhid_resumer");
1463 if (!resumption_waker)
1464 goto no_queue;
1465 retval = hid_register_driver(&hid_usb_driver); 1449 retval = hid_register_driver(&hid_usb_driver);
1466 if (retval) 1450 if (retval)
1467 goto hid_register_fail; 1451 goto hid_register_fail;
@@ -1479,8 +1463,6 @@ usb_register_fail:
1479usbhid_quirks_init_fail: 1463usbhid_quirks_init_fail:
1480 hid_unregister_driver(&hid_usb_driver); 1464 hid_unregister_driver(&hid_usb_driver);
1481hid_register_fail: 1465hid_register_fail:
1482 destroy_workqueue(resumption_waker);
1483no_queue:
1484 return retval; 1466 return retval;
1485} 1467}
1486 1468
@@ -1489,7 +1471,6 @@ static void __exit hid_exit(void)
1489 usb_deregister(&hid_driver); 1471 usb_deregister(&hid_driver);
1490 usbhid_quirks_exit(); 1472 usbhid_quirks_exit();
1491 hid_unregister_driver(&hid_usb_driver); 1473 hid_unregister_driver(&hid_usb_driver);
1492 destroy_workqueue(resumption_waker);
1493} 1474}
1494 1475
1495module_init(hid_init); 1476module_init(hid_init);
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
index 89d2e847dcc6..1673cac93d77 100644
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -95,7 +95,6 @@ struct usbhid_device {
95 unsigned long stop_retry; /* Time to give up, in jiffies */ 95 unsigned long stop_retry; /* Time to give up, in jiffies */
96 unsigned int retry_delay; /* Delay length in ms */ 96 unsigned int retry_delay; /* Delay length in ms */
97 struct work_struct reset_work; /* Task context for resets */ 97 struct work_struct reset_work; /* Task context for resets */
98 struct work_struct restart_work; /* waking up for output to be done in a task */
99 wait_queue_head_t wait; /* For sleeping */ 98 wait_queue_head_t wait; /* For sleeping */
100 int ledcount; /* counting the number of active leds */ 99 int ledcount; /* counting the number of active leds */
101}; 100};