]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/hid/usbhid/hid-core.c
Merge branches 'for-3.12/devm', 'for-3.12/i2c-hid', 'for-3.12/i2c-hid-dt', 'for-3...
[karo-tx-linux.git] / drivers / hid / usbhid / hid-core.c
index ada164e1b3a1fd909c8c6a437dc2cc5cb424a845..44df131d390a0e5cbb92d5701cab2f01a872fc9a 100644 (file)
@@ -648,62 +648,6 @@ static void usbhid_submit_report(struct hid_device *hid, struct hid_report *repo
        spin_unlock_irqrestore(&usbhid->lock, flags);
 }
 
-/* Workqueue routine to send requests to change LEDs */
-static void hid_led(struct work_struct *work)
-{
-       struct usbhid_device *usbhid =
-               container_of(work, struct usbhid_device, led_work);
-       struct hid_device *hid = usbhid->hid;
-       struct hid_field *field;
-       unsigned long flags;
-
-       field = hidinput_get_led_field(hid);
-       if (!field) {
-               hid_warn(hid, "LED event field not found\n");
-               return;
-       }
-
-       spin_lock_irqsave(&usbhid->lock, flags);
-       if (!test_bit(HID_DISCONNECTED, &usbhid->iofl)) {
-               usbhid->ledcount = hidinput_count_leds(hid);
-               hid_dbg(usbhid->hid, "New ledcount = %u\n", usbhid->ledcount);
-               __usbhid_submit_report(hid, field->report, USB_DIR_OUT);
-       }
-       spin_unlock_irqrestore(&usbhid->lock, flags);
-}
-
-static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
-{
-       struct hid_device *hid = input_get_drvdata(dev);
-       struct usbhid_device *usbhid = hid->driver_data;
-       struct hid_field *field;
-       unsigned long flags;
-       int offset;
-
-       if (type == EV_FF)
-               return input_ff_event(dev, type, code, value);
-
-       if (type != EV_LED)
-               return -1;
-
-       if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) {
-               hid_warn(dev, "event field not found\n");
-               return -1;
-       }
-
-       spin_lock_irqsave(&usbhid->lock, flags);
-       hid_set_field(field, offset, value);
-       spin_unlock_irqrestore(&usbhid->lock, flags);
-
-       /*
-        * Defer performing requested LED action.
-        * This is more likely gather all LED changes into a single URB.
-        */
-       schedule_work(&usbhid->led_work);
-
-       return 0;
-}
-
 static int usbhid_wait_io(struct hid_device *hid)
 {
        struct usbhid_device *usbhid = hid->driver_data;
@@ -806,12 +750,17 @@ void usbhid_init_reports(struct hid_device *hid)
 {
        struct hid_report *report;
        struct usbhid_device *usbhid = hid->driver_data;
+       struct hid_report_enum *report_enum;
        int err, ret;
 
-       list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list)
-               usbhid_submit_report(hid, report, USB_DIR_IN);
+       if (!(hid->quirks & HID_QUIRK_NO_INIT_INPUT_REPORTS)) {
+               report_enum = &hid->report_enum[HID_INPUT_REPORT];
+               list_for_each_entry(report, &report_enum->report_list, list)
+                       usbhid_submit_report(hid, report, USB_DIR_IN);
+       }
 
-       list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
+       report_enum = &hid->report_enum[HID_FEATURE_REPORT];
+       list_for_each_entry(report, &report_enum->report_list, list)
                usbhid_submit_report(hid, report, USB_DIR_IN);
 
        err = 0;
@@ -856,7 +805,7 @@ static int hid_find_field_early(struct hid_device *hid, unsigned int page,
        return -1;
 }
 
-void usbhid_set_leds(struct hid_device *hid)
+static void usbhid_set_leds(struct hid_device *hid)
 {
        struct hid_field *field;
        int offset;
@@ -866,7 +815,6 @@ void usbhid_set_leds(struct hid_device *hid)
                usbhid_submit_report(hid, field->report, USB_DIR_OUT);
        }
 }
-EXPORT_SYMBOL_GPL(usbhid_set_leds);
 
 /*
  * Traverse the supplied list of reports and find the longest
@@ -1273,7 +1221,6 @@ static struct hid_ll_driver usb_hid_driver = {
        .open = usbhid_open,
        .close = usbhid_close,
        .power = usbhid_power,
-       .hidinput_input_event = usb_hidinput_input_event,
        .request = usbhid_request,
        .wait = usbhid_wait_io,
        .idle = usbhid_idle,
@@ -1367,8 +1314,6 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
        setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
        spin_lock_init(&usbhid->lock);
 
-       INIT_WORK(&usbhid->led_work, hid_led);
-
        ret = hid_add_device(hid);
        if (ret) {
                if (ret != -ENODEV)
@@ -1401,7 +1346,6 @@ static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
 {
        del_timer_sync(&usbhid->io_retry);
        cancel_work_sync(&usbhid->reset_work);
-       cancel_work_sync(&usbhid->led_work);
 }
 
 static void hid_cease_io(struct usbhid_device *usbhid)
@@ -1521,15 +1465,17 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
        struct usbhid_device *usbhid = hid->driver_data;
        int status = 0;
        bool driver_suspended = false;
+       unsigned int ledcount;
 
        if (PMSG_IS_AUTO(message)) {
+               ledcount = hidinput_count_leds(hid);
                spin_lock_irq(&usbhid->lock);   /* Sync with error handler */
                if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
                    && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
                    && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)
                    && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl)
                    && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl)
-                   && (!usbhid->ledcount || ignoreled))
+                   && (!ledcount || ignoreled))
                {
                        set_bit(HID_SUSPENDED, &usbhid->iofl);
                        spin_unlock_irq(&usbhid->lock);