HID: usbhid: defer LED setting to a workqueue

Defer LED setting action to a workqueue.
This is more likely to send all LED change events in a single URB.

Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
Acked-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
Daniel Kurtz 2011-11-17 19:23:50 +08:00 committed by Jiri Kosina
parent f0befcd64b
commit 4371ea8202
4 changed files with 82 additions and 11 deletions

View file

@ -976,6 +976,48 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int
}
EXPORT_SYMBOL_GPL(hidinput_find_field);
struct hid_field *hidinput_get_led_field(struct hid_device *hid)
{
struct hid_report *report;
struct hid_field *field;
int i, j;
list_for_each_entry(report,
&hid->report_enum[HID_OUTPUT_REPORT].report_list,
list) {
for (i = 0; i < report->maxfield; i++) {
field = report->field[i];
for (j = 0; j < field->maxusage; j++)
if (field->usage[j].type == EV_LED)
return field;
}
}
return NULL;
}
EXPORT_SYMBOL_GPL(hidinput_get_led_field);
unsigned int hidinput_count_leds(struct hid_device *hid)
{
struct hid_report *report;
struct hid_field *field;
int i, j;
unsigned int count = 0;
list_for_each_entry(report,
&hid->report_enum[HID_OUTPUT_REPORT].report_list,
list) {
for (i = 0; i < report->maxfield; i++) {
field = report->field[i];
for (j = 0; j < field->maxusage; j++)
if (field->usage[j].type == EV_LED &&
field->value[j])
count += 1;
}
}
return count;
}
EXPORT_SYMBOL_GPL(hidinput_count_leds);
static int hidinput_open(struct input_dev *dev)
{
struct hid_device *hid = input_get_drvdata(dev);