diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2013-07-15 13:10:13 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-07-31 04:31:21 -0400 |
commit | bfde79cb3541170f8413bc8be34406f86c49392a (patch) | |
tree | f08ae0b039cfaa1bd48978902fb518a6368735da | |
parent | 60682284e40be070a4a13df2cb332286b4750f8a (diff) |
HID: usbhid: use generic hidinput_input_event()
HID core provides the same functionality as we do, so drop the custom
hidinput_input_event() handler.
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 74 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbhid.h | 3 |
2 files changed, 3 insertions, 74 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 62b51316176c..8c3235705679 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -649,72 +649,6 @@ static void usbhid_submit_report(struct hid_device *hid, struct hid_report *repo | |||
649 | spin_unlock_irqrestore(&usbhid->lock, flags); | 649 | spin_unlock_irqrestore(&usbhid->lock, flags); |
650 | } | 650 | } |
651 | 651 | ||
652 | /* Workqueue routine to send requests to change LEDs */ | ||
653 | static void hid_led(struct work_struct *work) | ||
654 | { | ||
655 | struct usbhid_device *usbhid = | ||
656 | container_of(work, struct usbhid_device, led_work); | ||
657 | struct hid_device *hid = usbhid->hid; | ||
658 | struct hid_field *field; | ||
659 | unsigned long flags; | ||
660 | |||
661 | field = hidinput_get_led_field(hid); | ||
662 | if (!field) { | ||
663 | hid_warn(hid, "LED event field not found\n"); | ||
664 | return; | ||
665 | } | ||
666 | |||
667 | /* | ||
668 | * field->report is accessed unlocked regarding HID core. So there might | ||
669 | * be another incoming SET-LED request from user-space, which changes | ||
670 | * the LED state while we assemble our outgoing buffer. However, this | ||
671 | * doesn't matter as hid_output_report() correctly converts it into a | ||
672 | * boolean value no matter what information is currently set on the LED | ||
673 | * field (even garbage). So the remote device will always get a valid | ||
674 | * request. | ||
675 | * And in case we send a wrong value, a next hid_led() worker is spawned | ||
676 | * for every SET-LED request so the following hid_led() worker will send | ||
677 | * the correct value, guaranteed! | ||
678 | */ | ||
679 | |||
680 | spin_lock_irqsave(&usbhid->lock, flags); | ||
681 | if (!test_bit(HID_DISCONNECTED, &usbhid->iofl)) { | ||
682 | usbhid->ledcount = hidinput_count_leds(hid); | ||
683 | hid_dbg(usbhid->hid, "New ledcount = %u\n", usbhid->ledcount); | ||
684 | __usbhid_submit_report(hid, field->report, USB_DIR_OUT); | ||
685 | } | ||
686 | spin_unlock_irqrestore(&usbhid->lock, flags); | ||
687 | } | ||
688 | |||
689 | static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | ||
690 | { | ||
691 | struct hid_device *hid = input_get_drvdata(dev); | ||
692 | struct usbhid_device *usbhid = hid->driver_data; | ||
693 | struct hid_field *field; | ||
694 | int offset; | ||
695 | |||
696 | if (type == EV_FF) | ||
697 | return input_ff_event(dev, type, code, value); | ||
698 | |||
699 | if (type != EV_LED) | ||
700 | return -1; | ||
701 | |||
702 | if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) { | ||
703 | hid_warn(dev, "event field not found\n"); | ||
704 | return -1; | ||
705 | } | ||
706 | |||
707 | hid_set_field(field, offset, value); | ||
708 | |||
709 | /* | ||
710 | * Defer performing requested LED action. | ||
711 | * This is more likely gather all LED changes into a single URB. | ||
712 | */ | ||
713 | schedule_work(&usbhid->led_work); | ||
714 | |||
715 | return 0; | ||
716 | } | ||
717 | |||
718 | static int usbhid_wait_io(struct hid_device *hid) | 652 | static int usbhid_wait_io(struct hid_device *hid) |
719 | { | 653 | { |
720 | struct usbhid_device *usbhid = hid->driver_data; | 654 | struct usbhid_device *usbhid = hid->driver_data; |
@@ -1283,7 +1217,6 @@ static struct hid_ll_driver usb_hid_driver = { | |||
1283 | .open = usbhid_open, | 1217 | .open = usbhid_open, |
1284 | .close = usbhid_close, | 1218 | .close = usbhid_close, |
1285 | .power = usbhid_power, | 1219 | .power = usbhid_power, |
1286 | .hidinput_input_event = usb_hidinput_input_event, | ||
1287 | .request = usbhid_request, | 1220 | .request = usbhid_request, |
1288 | .wait = usbhid_wait_io, | 1221 | .wait = usbhid_wait_io, |
1289 | .idle = usbhid_idle, | 1222 | .idle = usbhid_idle, |
@@ -1377,8 +1310,6 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * | |||
1377 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); | 1310 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); |
1378 | spin_lock_init(&usbhid->lock); | 1311 | spin_lock_init(&usbhid->lock); |
1379 | 1312 | ||
1380 | INIT_WORK(&usbhid->led_work, hid_led); | ||
1381 | |||
1382 | ret = hid_add_device(hid); | 1313 | ret = hid_add_device(hid); |
1383 | if (ret) { | 1314 | if (ret) { |
1384 | if (ret != -ENODEV) | 1315 | if (ret != -ENODEV) |
@@ -1411,7 +1342,6 @@ static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid) | |||
1411 | { | 1342 | { |
1412 | del_timer_sync(&usbhid->io_retry); | 1343 | del_timer_sync(&usbhid->io_retry); |
1413 | cancel_work_sync(&usbhid->reset_work); | 1344 | cancel_work_sync(&usbhid->reset_work); |
1414 | cancel_work_sync(&usbhid->led_work); | ||
1415 | } | 1345 | } |
1416 | 1346 | ||
1417 | static void hid_cease_io(struct usbhid_device *usbhid) | 1347 | static void hid_cease_io(struct usbhid_device *usbhid) |
@@ -1531,15 +1461,17 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message) | |||
1531 | struct usbhid_device *usbhid = hid->driver_data; | 1461 | struct usbhid_device *usbhid = hid->driver_data; |
1532 | int status = 0; | 1462 | int status = 0; |
1533 | bool driver_suspended = false; | 1463 | bool driver_suspended = false; |
1464 | unsigned int ledcount; | ||
1534 | 1465 | ||
1535 | if (PMSG_IS_AUTO(message)) { | 1466 | if (PMSG_IS_AUTO(message)) { |
1467 | ledcount = hidinput_count_leds(hid); | ||
1536 | spin_lock_irq(&usbhid->lock); /* Sync with error handler */ | 1468 | spin_lock_irq(&usbhid->lock); /* Sync with error handler */ |
1537 | if (!test_bit(HID_RESET_PENDING, &usbhid->iofl) | 1469 | if (!test_bit(HID_RESET_PENDING, &usbhid->iofl) |
1538 | && !test_bit(HID_CLEAR_HALT, &usbhid->iofl) | 1470 | && !test_bit(HID_CLEAR_HALT, &usbhid->iofl) |
1539 | && !test_bit(HID_OUT_RUNNING, &usbhid->iofl) | 1471 | && !test_bit(HID_OUT_RUNNING, &usbhid->iofl) |
1540 | && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl) | 1472 | && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl) |
1541 | && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl) | 1473 | && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl) |
1542 | && (!usbhid->ledcount || ignoreled)) | 1474 | && (!ledcount || ignoreled)) |
1543 | { | 1475 | { |
1544 | set_bit(HID_SUSPENDED, &usbhid->iofl); | 1476 | set_bit(HID_SUSPENDED, &usbhid->iofl); |
1545 | spin_unlock_irq(&usbhid->lock); | 1477 | spin_unlock_irq(&usbhid->lock); |
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index dbb6af699135..f633c24ce28b 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h | |||
@@ -92,9 +92,6 @@ struct usbhid_device { | |||
92 | unsigned int retry_delay; /* Delay length in ms */ | 92 | unsigned int retry_delay; /* Delay length in ms */ |
93 | struct work_struct reset_work; /* Task context for resets */ | 93 | struct work_struct reset_work; /* Task context for resets */ |
94 | wait_queue_head_t wait; /* For sleeping */ | 94 | wait_queue_head_t wait; /* For sleeping */ |
95 | int ledcount; /* counting the number of active leds */ | ||
96 | |||
97 | struct work_struct led_work; /* Task context for setting LEDs */ | ||
98 | }; | 95 | }; |
99 | 96 | ||
100 | #define hid_to_usb_dev(hid_dev) \ | 97 | #define hid_to_usb_dev(hid_dev) \ |