From: Jaikumar Ganesh Date: Tue, 20 Sep 2011 23:40:43 +0000 (-0700) Subject: HID: Add input_register callback. X-Git-Tag: firefly_0821_release~4090^2~787 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=5925993fe56e1a4ddb26d2085fdd16f6a6153365;p=firefly-linux-kernel-4.4.55.git HID: Add input_register callback. Add input_register callback which gets called after hid_configure_usage is called for all the reports and before the input device is registered. This allows individual drivers to do extra work like input mapping just before device registration. Based on discussions with David Herrmann Change-Id: Idab6fb4f7b1e5e569bd0410967288717e9d34c98 Signed-off-by: Jaikumar Ganesh Changed to add return code to input_configured instead of adding input_register Signed-off-by: Arve Hjønnevåg --- diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 945b8158ec4c..4602d291c9bc 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1321,8 +1321,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) * UGCI) cram a lot of unrelated inputs into the * same interface. */ hidinput->report = report; - if (drv->input_configured) - drv->input_configured(hid, hidinput); + if (drv->input_configured && + drv->input_configured(hid, hidinput)) + goto out_cleanup; if (input_register_device(hidinput->input)) goto out_cleanup; hidinput = NULL; @@ -1343,8 +1344,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) } if (hidinput) { - if (drv->input_configured) - drv->input_configured(hid, hidinput); + if (drv->input_configured && + drv->input_configured(hid, hidinput)) + goto out_cleanup; if (input_register_device(hidinput->input)) goto out_cleanup; } diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index c92de0fb0092..f4b77f4d5fb8 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -780,12 +780,13 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report) mt_sync_frame(td, report->field[0]->hidinput->input); } -static void mt_touch_input_configured(struct hid_device *hdev, +static int mt_touch_input_configured(struct hid_device *hdev, struct hid_input *hi) { struct mt_device *td = hid_get_drvdata(hdev); struct mt_class *cls = &td->mtclass; struct input_dev *input = hi->input; + int ret; if (!td->maxcontacts) td->maxcontacts = MT_DEFAULT_MAXCONTACT; @@ -800,9 +801,12 @@ static void mt_touch_input_configured(struct hid_device *hdev, if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) td->mt_flags |= INPUT_MT_DROP_UNUSED; - input_mt_init_slots(input, td->maxcontacts, td->mt_flags); + ret = input_mt_init_slots(input, td->maxcontacts, td->mt_flags); + if (ret) + return ret; td->mt_flags = 0; + return 0; } static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, @@ -935,19 +939,21 @@ static void mt_post_parse(struct mt_device *td) cls->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; } -static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi) +static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) { struct mt_device *td = hid_get_drvdata(hdev); char *name = kstrdup(hdev->name, GFP_KERNEL); + int ret = 0; if (name) hi->input->name = name; if (hi->report->id == td->mt_report_id) - mt_touch_input_configured(hdev, hi); + ret = mt_touch_input_configured(hdev, hi); if (hi->report->id == td->pen_report_id) mt_pen_input_configured(hdev, hi); + return ret; } static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) diff --git a/include/linux/hid.h b/include/linux/hid.h index 0c48991b0402..8136c6d99037 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -647,8 +647,8 @@ struct hid_driver { int (*input_mapped)(struct hid_device *hdev, struct hid_input *hidinput, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max); - void (*input_configured)(struct hid_device *hdev, - struct hid_input *hidinput); + int (*input_configured)(struct hid_device *hdev, + struct hid_input *hidinput); void (*feature_mapping)(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage);