* [PATCH 0/2] HID special drivers converted to devres API @ 2013-07-24 15:29 Benjamin Tissoires 2013-07-24 15:29 ` [PATCH 1/2] HID: trivial devm conversion for special hid drivers Benjamin Tissoires 2013-07-24 15:29 ` [PATCH 2/2] HID: multitouch: devm conversion Benjamin Tissoires 0 siblings, 2 replies; 7+ messages in thread From: Benjamin Tissoires @ 2013-07-24 15:29 UTC (permalink / raw) To: Benjamin Tissoires, Henrik Rydberg, Jiri Kosina, Andy Shevchenko, Stephane Chatty, linux-input, linux-kernel Hi Jiri, It's been a long time since I told you that I was about to work on the devres API... So here are the first patches. My deductions are that it is safe to run devm_* functions within the hid subsystem. With this, we can simplify a little the error path of some drivers. The gain is more visible for hid-multitouch as the function mt_free_input_name() can be entirely dropped. Cheers, Benjamin Benjamin Tissoires (2): HID: trivial devm conversion for special hid drivers HID: multitouch: devm conversion drivers/hid/hid-a4tech.c | 23 +++----------- drivers/hid/hid-apple.c | 16 ++-------- drivers/hid/hid-magicmouse.c | 17 ++--------- drivers/hid/hid-multitouch.c | 71 ++++++++++++++------------------------------ drivers/hid/hid-sony.c | 9 ++---- drivers/hid/hid-zydacron.c | 19 ++---------- 6 files changed, 39 insertions(+), 116 deletions(-) -- 1.8.3.1 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] HID: trivial devm conversion for special hid drivers 2013-07-24 15:29 [PATCH 0/2] HID special drivers converted to devres API Benjamin Tissoires @ 2013-07-24 15:29 ` Benjamin Tissoires 2013-07-24 15:37 ` Andy Shevchenko 2013-07-24 15:29 ` [PATCH 2/2] HID: multitouch: devm conversion Benjamin Tissoires 1 sibling, 1 reply; 7+ messages in thread From: Benjamin Tissoires @ 2013-07-24 15:29 UTC (permalink / raw) To: Benjamin Tissoires, Henrik Rydberg, Jiri Kosina, Andy Shevchenko, Stephane Chatty, linux-input, linux-kernel It is safe to use devres allocation within the hid subsystem: - the devres release is called _after_ the call to .remove(), meaning that no freed pointers will exists while removing the device - if a .probe() fails, devres releases all the allocated ressources before going to the next driver: there will not be ghost ressources attached to a hid device if several drivers are probed. Given that, we can clean up a little some of the HID drivers. These ones are trivial: - there is only one kzalloc in the driver - the .remove() callback contains only one kfree on top of hid_hw_stop() - the error path in the probe is easy enough to be manually checked Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> --- drivers/hid/hid-a4tech.c | 23 ++++------------------- drivers/hid/hid-apple.c | 16 +++------------- drivers/hid/hid-magicmouse.c | 17 +++-------------- drivers/hid/hid-sony.c | 9 +++------ drivers/hid/hid-zydacron.c | 19 +++---------------- 5 files changed, 16 insertions(+), 68 deletions(-) diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c index 7c5507e..8d4e999 100644 --- a/drivers/hid/hid-a4tech.c +++ b/drivers/hid/hid-a4tech.c @@ -90,11 +90,10 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) struct a4tech_sc *a4; int ret; - a4 = kzalloc(sizeof(*a4), GFP_KERNEL); + a4 = devm_kzalloc(&hdev->dev, sizeof(*a4), GFP_KERNEL); if (a4 == NULL) { hid_err(hdev, "can't alloc device descriptor\n"); - ret = -ENOMEM; - goto err_free; + return -ENOMEM; } a4->quirks = id->driver_data; @@ -104,29 +103,16 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { hid_err(hdev, "parse failed\n"); - goto err_free; + return ret; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (ret) { + if (ret) hid_err(hdev, "hw start failed\n"); - goto err_free; - } - return 0; -err_free: - kfree(a4); return ret; } -static void a4_remove(struct hid_device *hdev) -{ - struct a4tech_sc *a4 = hid_get_drvdata(hdev); - - hid_hw_stop(hdev); - kfree(a4); -} - static const struct hid_device_id a4_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU), .driver_data = A4_2WHEEL_MOUSE_HACK_7 }, @@ -144,7 +130,6 @@ static struct hid_driver a4_driver = { .input_mapped = a4_input_mapped, .event = a4_event, .probe = a4_probe, - .remove = a4_remove, }; module_hid_driver(a4_driver); diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index c7710b5..881cf7b 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -349,7 +349,7 @@ static int apple_probe(struct hid_device *hdev, unsigned int connect_mask = HID_CONNECT_DEFAULT; int ret; - asc = kzalloc(sizeof(*asc), GFP_KERNEL); + asc = devm_kzalloc(&hdev->dev, sizeof(*asc), GFP_KERNEL); if (asc == NULL) { hid_err(hdev, "can't alloc apple descriptor\n"); return -ENOMEM; @@ -362,7 +362,7 @@ static int apple_probe(struct hid_device *hdev, ret = hid_parse(hdev); if (ret) { hid_err(hdev, "parse failed\n"); - goto err_free; + return ret; } if (quirks & APPLE_HIDDEV) @@ -373,19 +373,10 @@ static int apple_probe(struct hid_device *hdev, ret = hid_hw_start(hdev, connect_mask); if (ret) { hid_err(hdev, "hw start failed\n"); - goto err_free; + return ret; } return 0; -err_free: - kfree(asc); - return ret; -} - -static void apple_remove(struct hid_device *hdev) -{ - hid_hw_stop(hdev); - kfree(hid_get_drvdata(hdev)); } static const struct hid_device_id apple_devices[] = { @@ -551,7 +542,6 @@ static struct hid_driver apple_driver = { .id_table = apple_devices, .report_fixup = apple_report_fixup, .probe = apple_probe, - .remove = apple_remove, .event = apple_event, .input_mapping = apple_input_mapping, .input_mapped = apple_input_mapped, diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 5bc3734..d393eb7 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -484,7 +484,7 @@ static int magicmouse_probe(struct hid_device *hdev, struct hid_report *report; int ret; - msc = kzalloc(sizeof(*msc), GFP_KERNEL); + msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL); if (msc == NULL) { hid_err(hdev, "can't alloc magicmouse descriptor\n"); return -ENOMEM; @@ -498,13 +498,13 @@ static int magicmouse_probe(struct hid_device *hdev, ret = hid_parse(hdev); if (ret) { hid_err(hdev, "magicmouse hid parse failed\n"); - goto err_free; + return ret; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { hid_err(hdev, "magicmouse hw start failed\n"); - goto err_free; + return ret; } if (!msc->input) { @@ -548,19 +548,9 @@ static int magicmouse_probe(struct hid_device *hdev, return 0; err_stop_hw: hid_hw_stop(hdev); -err_free: - kfree(msc); return ret; } -static void magicmouse_remove(struct hid_device *hdev) -{ - struct magicmouse_sc *msc = hid_get_drvdata(hdev); - - hid_hw_stop(hdev); - kfree(msc); -} - static const struct hid_device_id magic_mice[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 }, @@ -574,7 +564,6 @@ static struct hid_driver magicmouse_driver = { .name = "magicmouse", .id_table = magic_mice, .probe = magicmouse_probe, - .remove = magicmouse_remove, .raw_event = magicmouse_raw_event, .input_mapping = magicmouse_input_mapping, .input_configured = magicmouse_input_configured, diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 87fbe29..30dbb6b 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -624,7 +624,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) struct sony_sc *sc; unsigned int connect_mask = HID_CONNECT_DEFAULT; - sc = kzalloc(sizeof(*sc), GFP_KERNEL); + sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL); if (sc == NULL) { hid_err(hdev, "can't alloc sony descriptor\n"); return -ENOMEM; @@ -636,7 +636,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { hid_err(hdev, "parse failed\n"); - goto err_free; + return ret; } if (sc->quirks & VAIO_RDESC_CONSTANT) @@ -649,7 +649,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_hw_start(hdev, connect_mask); if (ret) { hid_err(hdev, "hw start failed\n"); - goto err_free; + return ret; } if (sc->quirks & SIXAXIS_CONTROLLER_USB) { @@ -669,8 +669,6 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) return 0; err_stop: hid_hw_stop(hdev); -err_free: - kfree(sc); return ret; } @@ -682,7 +680,6 @@ static void sony_remove(struct hid_device *hdev) buzz_remove(hdev); hid_hw_stop(hdev); - kfree(sc); } static const struct hid_device_id sony_devices[] = { diff --git a/drivers/hid/hid-zydacron.c b/drivers/hid/hid-zydacron.c index e4cddec..1a660bd 100644 --- a/drivers/hid/hid-zydacron.c +++ b/drivers/hid/hid-zydacron.c @@ -169,7 +169,7 @@ static int zc_probe(struct hid_device *hdev, const struct hid_device_id *id) int ret; struct zc_device *zc; - zc = kzalloc(sizeof(*zc), GFP_KERNEL); + zc = devm_kzalloc(&hdev->dev, sizeof(*zc), GFP_KERNEL); if (zc == NULL) { hid_err(hdev, "can't alloc descriptor\n"); return -ENOMEM; @@ -180,28 +180,16 @@ static int zc_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { hid_err(hdev, "parse failed\n"); - goto err_free; + return ret; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { hid_err(hdev, "hw start failed\n"); - goto err_free; + return ret; } return 0; -err_free: - kfree(zc); - - return ret; -} - -static void zc_remove(struct hid_device *hdev) -{ - struct zc_device *zc = hid_get_drvdata(hdev); - - hid_hw_stop(hdev); - kfree(zc); } static const struct hid_device_id zc_devices[] = { @@ -217,7 +205,6 @@ static struct hid_driver zc_driver = { .input_mapping = zc_input_mapping, .raw_event = zc_raw_event, .probe = zc_probe, - .remove = zc_remove, }; module_hid_driver(zc_driver); -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] HID: trivial devm conversion for special hid drivers 2013-07-24 15:29 ` [PATCH 1/2] HID: trivial devm conversion for special hid drivers Benjamin Tissoires @ 2013-07-24 15:37 ` Andy Shevchenko 2013-07-24 15:43 ` Benjamin Tissoires 0 siblings, 1 reply; 7+ messages in thread From: Andy Shevchenko @ 2013-07-24 15:37 UTC (permalink / raw) To: Benjamin Tissoires Cc: Benjamin Tissoires, Henrik Rydberg, Jiri Kosina, Stephane Chatty, linux-input, linux-kernel@vger.kernel.org On Wed, Jul 24, 2013 at 6:29 PM, Benjamin Tissoires <benjamin.tissoires@redhat.com> wrote: > It is safe to use devres allocation within the hid subsystem: > - the devres release is called _after_ the call to .remove(), meaning > that no freed pointers will exists while removing the device > - if a .probe() fails, devres releases all the allocated ressources > before going to the next driver: there will not be ghost ressources > attached to a hid device if several drivers are probed. > > Given that, we can clean up a little some of the HID drivers. These ones > are trivial: > - there is only one kzalloc in the driver > - the .remove() callback contains only one kfree on top of hid_hw_stop() > - the error path in the probe is easy enough to be manually checked Thanks for the patch! I'm sorry I didn't find time to do what I was talking about last time. Few comments below. > --- a/drivers/hid/hid-a4tech.c > +++ b/drivers/hid/hid-a4tech.c > @@ -104,29 +103,16 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) > ret = hid_parse(hdev); > if (ret) { > hid_err(hdev, "parse failed\n"); > - goto err_free; > + return ret; > } > > ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); > - if (ret) { > + if (ret) > hid_err(hdev, "hw start failed\n"); > - goto err_free; > - } > > - return 0; Isn't it better to leave explicit return 0? I think it would be fool proof in case someone wants to add anything in the middle. > -err_free: > - kfree(a4); > return ret; > } > -static void a4_remove(struct hid_device *hdev) > -{ > - struct a4tech_sc *a4 = hid_get_drvdata(hdev); > - > - hid_hw_stop(hdev); Is it safe to remove this call? This question is the same for all patched drivers. -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] HID: trivial devm conversion for special hid drivers 2013-07-24 15:37 ` Andy Shevchenko @ 2013-07-24 15:43 ` Benjamin Tissoires 0 siblings, 0 replies; 7+ messages in thread From: Benjamin Tissoires @ 2013-07-24 15:43 UTC (permalink / raw) To: Andy Shevchenko Cc: Benjamin Tissoires, Henrik Rydberg, Jiri Kosina, Stephane Chatty, linux-input, linux-kernel@vger.kernel.org On Wed, Jul 24, 2013 at 5:37 PM, Andy Shevchenko <andy.shevchenko@gmail.com> wrote: > On Wed, Jul 24, 2013 at 6:29 PM, Benjamin Tissoires > <benjamin.tissoires@redhat.com> wrote: >> It is safe to use devres allocation within the hid subsystem: >> - the devres release is called _after_ the call to .remove(), meaning >> that no freed pointers will exists while removing the device >> - if a .probe() fails, devres releases all the allocated ressources >> before going to the next driver: there will not be ghost ressources >> attached to a hid device if several drivers are probed. >> >> Given that, we can clean up a little some of the HID drivers. These ones >> are trivial: >> - there is only one kzalloc in the driver >> - the .remove() callback contains only one kfree on top of hid_hw_stop() >> - the error path in the probe is easy enough to be manually checked > > Thanks for the patch! I'm sorry I didn't find time to do what I was > talking about last time. no problems :) > > Few comments below. > >> --- a/drivers/hid/hid-a4tech.c >> +++ b/drivers/hid/hid-a4tech.c > >> @@ -104,29 +103,16 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) >> ret = hid_parse(hdev); >> if (ret) { >> hid_err(hdev, "parse failed\n"); >> - goto err_free; >> + return ret; >> } >> >> ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); >> - if (ret) { >> + if (ret) >> hid_err(hdev, "hw start failed\n"); >> - goto err_free; >> - } >> >> - return 0; > > Isn't it better to leave explicit return 0? I think it would be fool > proof in case someone wants to add anything in the middle. yes, it might be. At least that's what I've done with the other drivers... > >> -err_free: >> - kfree(a4); >> return ret; >> } > >> -static void a4_remove(struct hid_device *hdev) >> -{ >> - struct a4tech_sc *a4 = hid_get_drvdata(hdev); >> - >> - hid_hw_stop(hdev); > > Is it safe to remove this call? > This question is the same for all patched drivers. It is. Once this call is removed, we use the in-core remove path, which calls hid_hw_stop(). Thanks for the review. Cheers, Benjamin ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] HID: multitouch: devm conversion 2013-07-24 15:29 [PATCH 0/2] HID special drivers converted to devres API Benjamin Tissoires 2013-07-24 15:29 ` [PATCH 1/2] HID: trivial devm conversion for special hid drivers Benjamin Tissoires @ 2013-07-24 15:29 ` Benjamin Tissoires 2013-07-24 15:44 ` Andy Shevchenko 1 sibling, 1 reply; 7+ messages in thread From: Benjamin Tissoires @ 2013-07-24 15:29 UTC (permalink / raw) To: Benjamin Tissoires, Henrik Rydberg, Jiri Kosina, Andy Shevchenko, Stephane Chatty, linux-input, linux-kernel HID special drivers can use safely the devres API. Use it to remove 25 lines of code and to clean up a little the error paths. Besides the pur kzalloc -> devm_kzalloc conversions, I changed the place of the allocation of the new name. Doing this right in mt_input_configured() removes the kstrdup call which was not very helpful and the new way is simpler to understand (and to debug). Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> --- drivers/hid/hid-multitouch.c | 71 ++++++++++++++------------------------------ 1 file changed, 23 insertions(+), 48 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index cb0e361..0fe00e2 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -261,17 +261,6 @@ static struct mt_class mt_classes[] = { { } }; -static void mt_free_input_name(struct hid_input *hi) -{ - struct hid_device *hdev = hi->report->device; - const char *name = hi->input->name; - - if (name != hdev->name) { - hi->input->name = hdev->name; - kfree(name); - } -} - static ssize_t mt_show_quirks(struct device *dev, struct device_attribute *attr, char *buf) @@ -415,13 +404,6 @@ static void mt_pen_report(struct hid_device *hid, struct hid_report *report) static void mt_pen_input_configured(struct hid_device *hdev, struct hid_input *hi) { - char *name = kzalloc(strlen(hi->input->name) + 5, GFP_KERNEL); - if (name) { - sprintf(name, "%s Pen", hi->input->name); - mt_free_input_name(hi); - hi->input->name = name; - } - /* force BTN_STYLUS to allow tablet matching in udev */ __set_bit(BTN_STYLUS, hi->input->keybit); } @@ -928,16 +910,26 @@ static void mt_post_parse(struct mt_device *td) static void 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); - - if (name) - hi->input->name = name; + char *name; + const char *suffix = NULL; if (hi->report->id == td->mt_report_id) mt_touch_input_configured(hdev, hi); - if (hi->report->id == td->pen_report_id) + if (hi->report->field[0]->physical == HID_DG_STYLUS) { + suffix = "Pen"; mt_pen_input_configured(hdev, hi); + } + + if (suffix) { + name = devm_kzalloc(&hi->input->dev, + strlen(hdev->name) + strlen(suffix) + 2, + GFP_KERNEL); + if (name) { + sprintf(name, "%s %s", hdev->name, suffix); + hi->input->name = name; + } + } } static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) @@ -945,7 +937,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) int ret, i; struct mt_device *td; struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ - struct hid_input *hi; for (i = 0; mt_classes[i].name ; i++) { if (id->driver_data == mt_classes[i].name) { @@ -967,7 +958,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) hdev->quirks |= HID_QUIRK_MULTI_INPUT; hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT; - td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); + td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_KERNEL); if (!td) { dev_err(&hdev->dev, "cannot allocate multitouch data\n"); return -ENOMEM; @@ -980,11 +971,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) td->pen_report_id = -1; hid_set_drvdata(hdev, td); - td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL); + td->fields = devm_kzalloc(&hdev->dev, sizeof(struct mt_fields), + GFP_KERNEL); if (!td->fields) { dev_err(&hdev->dev, "cannot allocate multitouch fields data\n"); - ret = -ENOMEM; - goto fail; + return -ENOMEM; } if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID) @@ -992,29 +983,22 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret != 0) - goto fail; + return ret; ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) - goto hid_fail; + return ret; ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); mt_set_maxcontacts(hdev); mt_set_input_mode(hdev); - kfree(td->fields); + /* release .fields memory as it is not used anymore */ + devm_kfree(&hdev->dev, td->fields); td->fields = NULL; return 0; - -hid_fail: - list_for_each_entry(hi, &hdev->inputs, list) - mt_free_input_name(hi); -fail: - kfree(td->fields); - kfree(td); - return ret; } #ifdef CONFIG_PM @@ -1039,17 +1023,8 @@ static int mt_resume(struct hid_device *hdev) static void mt_remove(struct hid_device *hdev) { - struct mt_device *td = hid_get_drvdata(hdev); - struct hid_input *hi; - sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); - list_for_each_entry(hi, &hdev->inputs, list) - mt_free_input_name(hi); - hid_hw_stop(hdev); - - kfree(td); - hid_set_drvdata(hdev, NULL); } static const struct hid_device_id mt_devices[] = { -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] HID: multitouch: devm conversion 2013-07-24 15:29 ` [PATCH 2/2] HID: multitouch: devm conversion Benjamin Tissoires @ 2013-07-24 15:44 ` Andy Shevchenko 2013-07-24 16:43 ` Benjamin Tissoires 0 siblings, 1 reply; 7+ messages in thread From: Andy Shevchenko @ 2013-07-24 15:44 UTC (permalink / raw) To: Benjamin Tissoires Cc: Benjamin Tissoires, Henrik Rydberg, Jiri Kosina, Stephane Chatty, linux-input, linux-kernel@vger.kernel.org On Wed, Jul 24, 2013 at 6:29 PM, Benjamin Tissoires <benjamin.tissoires@redhat.com> wrote: > HID special drivers can use safely the devres API. > Use it to remove 25 lines of code and to clean up a little the error paths. > > Besides the pur kzalloc -> devm_kzalloc conversions, I changed the Typo 'pur' -> 'put' > place of the allocation of the new name. Doing this right in > mt_input_configured() removes the kstrdup call which was not very helpful > and the new way is simpler to understand (and to debug). Thanks for the patch! I'm sorry I didn't find time to do this by myself. Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> > > Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> > --- > drivers/hid/hid-multitouch.c | 71 ++++++++++++++------------------------------ > 1 file changed, 23 insertions(+), 48 deletions(-) > > diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c > index cb0e361..0fe00e2 100644 > --- a/drivers/hid/hid-multitouch.c > +++ b/drivers/hid/hid-multitouch.c > @@ -261,17 +261,6 @@ static struct mt_class mt_classes[] = { > { } > }; > > -static void mt_free_input_name(struct hid_input *hi) > -{ > - struct hid_device *hdev = hi->report->device; > - const char *name = hi->input->name; > - > - if (name != hdev->name) { > - hi->input->name = hdev->name; > - kfree(name); > - } > -} > - > static ssize_t mt_show_quirks(struct device *dev, > struct device_attribute *attr, > char *buf) > @@ -415,13 +404,6 @@ static void mt_pen_report(struct hid_device *hid, struct hid_report *report) > static void mt_pen_input_configured(struct hid_device *hdev, > struct hid_input *hi) > { > - char *name = kzalloc(strlen(hi->input->name) + 5, GFP_KERNEL); > - if (name) { > - sprintf(name, "%s Pen", hi->input->name); > - mt_free_input_name(hi); > - hi->input->name = name; > - } > - > /* force BTN_STYLUS to allow tablet matching in udev */ > __set_bit(BTN_STYLUS, hi->input->keybit); > } > @@ -928,16 +910,26 @@ static void mt_post_parse(struct mt_device *td) > static void 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); > - > - if (name) > - hi->input->name = name; > + char *name; > + const char *suffix = NULL; > > if (hi->report->id == td->mt_report_id) > mt_touch_input_configured(hdev, hi); > > - if (hi->report->id == td->pen_report_id) > + if (hi->report->field[0]->physical == HID_DG_STYLUS) { > + suffix = "Pen"; > mt_pen_input_configured(hdev, hi); > + } > + > + if (suffix) { > + name = devm_kzalloc(&hi->input->dev, > + strlen(hdev->name) + strlen(suffix) + 2, > + GFP_KERNEL); > + if (name) { > + sprintf(name, "%s %s", hdev->name, suffix); > + hi->input->name = name; > + } > + } > } > > static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) > @@ -945,7 +937,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) > int ret, i; > struct mt_device *td; > struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ > - struct hid_input *hi; > > for (i = 0; mt_classes[i].name ; i++) { > if (id->driver_data == mt_classes[i].name) { > @@ -967,7 +958,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) > hdev->quirks |= HID_QUIRK_MULTI_INPUT; > hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT; > > - td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); > + td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_KERNEL); > if (!td) { > dev_err(&hdev->dev, "cannot allocate multitouch data\n"); > return -ENOMEM; > @@ -980,11 +971,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) > td->pen_report_id = -1; > hid_set_drvdata(hdev, td); > > - td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL); > + td->fields = devm_kzalloc(&hdev->dev, sizeof(struct mt_fields), > + GFP_KERNEL); > if (!td->fields) { > dev_err(&hdev->dev, "cannot allocate multitouch fields data\n"); > - ret = -ENOMEM; > - goto fail; > + return -ENOMEM; > } > > if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID) > @@ -992,29 +983,22 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) > > ret = hid_parse(hdev); > if (ret != 0) > - goto fail; > + return ret; > > ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); > if (ret) > - goto hid_fail; > + return ret; > > ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); > > mt_set_maxcontacts(hdev); > mt_set_input_mode(hdev); > > - kfree(td->fields); > + /* release .fields memory as it is not used anymore */ > + devm_kfree(&hdev->dev, td->fields); > td->fields = NULL; > > return 0; > - > -hid_fail: > - list_for_each_entry(hi, &hdev->inputs, list) > - mt_free_input_name(hi); > -fail: > - kfree(td->fields); > - kfree(td); > - return ret; > } > > #ifdef CONFIG_PM > @@ -1039,17 +1023,8 @@ static int mt_resume(struct hid_device *hdev) > > static void mt_remove(struct hid_device *hdev) > { > - struct mt_device *td = hid_get_drvdata(hdev); > - struct hid_input *hi; > - > sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); > - list_for_each_entry(hi, &hdev->inputs, list) > - mt_free_input_name(hi); > - > hid_hw_stop(hdev); > - > - kfree(td); > - hid_set_drvdata(hdev, NULL); > } > > static const struct hid_device_id mt_devices[] = { > -- > 1.8.3.1 > -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] HID: multitouch: devm conversion 2013-07-24 15:44 ` Andy Shevchenko @ 2013-07-24 16:43 ` Benjamin Tissoires 0 siblings, 0 replies; 7+ messages in thread From: Benjamin Tissoires @ 2013-07-24 16:43 UTC (permalink / raw) To: Andy Shevchenko Cc: Benjamin Tissoires, Henrik Rydberg, Jiri Kosina, Stephane Chatty, linux-input, linux-kernel@vger.kernel.org On Wed, Jul 24, 2013 at 5:44 PM, Andy Shevchenko <andy.shevchenko@gmail.com> wrote: > On Wed, Jul 24, 2013 at 6:29 PM, Benjamin Tissoires > <benjamin.tissoires@redhat.com> wrote: >> HID special drivers can use safely the devres API. >> Use it to remove 25 lines of code and to clean up a little the error paths. >> >> Besides the pur kzalloc -> devm_kzalloc conversions, I changed the > > Typo 'pur' -> 'put' oops, sorry. I'll use "basic" in the next version. > >> place of the allocation of the new name. Doing this right in >> mt_input_configured() removes the kstrdup call which was not very helpful >> and the new way is simpler to understand (and to debug). > > Thanks for the patch! I'm sorry I didn't find time to do this by myself. > Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Thanks! Cheers, Benjamin > >> >> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> >> --- >> drivers/hid/hid-multitouch.c | 71 ++++++++++++++------------------------------ >> 1 file changed, 23 insertions(+), 48 deletions(-) >> >> diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c >> index cb0e361..0fe00e2 100644 >> --- a/drivers/hid/hid-multitouch.c >> +++ b/drivers/hid/hid-multitouch.c >> @@ -261,17 +261,6 @@ static struct mt_class mt_classes[] = { >> { } >> }; >> >> -static void mt_free_input_name(struct hid_input *hi) >> -{ >> - struct hid_device *hdev = hi->report->device; >> - const char *name = hi->input->name; >> - >> - if (name != hdev->name) { >> - hi->input->name = hdev->name; >> - kfree(name); >> - } >> -} >> - >> static ssize_t mt_show_quirks(struct device *dev, >> struct device_attribute *attr, >> char *buf) >> @@ -415,13 +404,6 @@ static void mt_pen_report(struct hid_device *hid, struct hid_report *report) >> static void mt_pen_input_configured(struct hid_device *hdev, >> struct hid_input *hi) >> { >> - char *name = kzalloc(strlen(hi->input->name) + 5, GFP_KERNEL); >> - if (name) { >> - sprintf(name, "%s Pen", hi->input->name); >> - mt_free_input_name(hi); >> - hi->input->name = name; >> - } >> - >> /* force BTN_STYLUS to allow tablet matching in udev */ >> __set_bit(BTN_STYLUS, hi->input->keybit); >> } >> @@ -928,16 +910,26 @@ static void mt_post_parse(struct mt_device *td) >> static void 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); >> - >> - if (name) >> - hi->input->name = name; >> + char *name; >> + const char *suffix = NULL; >> >> if (hi->report->id == td->mt_report_id) >> mt_touch_input_configured(hdev, hi); >> >> - if (hi->report->id == td->pen_report_id) >> + if (hi->report->field[0]->physical == HID_DG_STYLUS) { >> + suffix = "Pen"; >> mt_pen_input_configured(hdev, hi); >> + } >> + >> + if (suffix) { >> + name = devm_kzalloc(&hi->input->dev, >> + strlen(hdev->name) + strlen(suffix) + 2, >> + GFP_KERNEL); >> + if (name) { >> + sprintf(name, "%s %s", hdev->name, suffix); >> + hi->input->name = name; >> + } >> + } >> } >> >> static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) >> @@ -945,7 +937,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) >> int ret, i; >> struct mt_device *td; >> struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ >> - struct hid_input *hi; >> >> for (i = 0; mt_classes[i].name ; i++) { >> if (id->driver_data == mt_classes[i].name) { >> @@ -967,7 +958,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) >> hdev->quirks |= HID_QUIRK_MULTI_INPUT; >> hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT; >> >> - td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); >> + td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_KERNEL); >> if (!td) { >> dev_err(&hdev->dev, "cannot allocate multitouch data\n"); >> return -ENOMEM; >> @@ -980,11 +971,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) >> td->pen_report_id = -1; >> hid_set_drvdata(hdev, td); >> >> - td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL); >> + td->fields = devm_kzalloc(&hdev->dev, sizeof(struct mt_fields), >> + GFP_KERNEL); >> if (!td->fields) { >> dev_err(&hdev->dev, "cannot allocate multitouch fields data\n"); >> - ret = -ENOMEM; >> - goto fail; >> + return -ENOMEM; >> } >> >> if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID) >> @@ -992,29 +983,22 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) >> >> ret = hid_parse(hdev); >> if (ret != 0) >> - goto fail; >> + return ret; >> >> ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); >> if (ret) >> - goto hid_fail; >> + return ret; >> >> ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); >> >> mt_set_maxcontacts(hdev); >> mt_set_input_mode(hdev); >> >> - kfree(td->fields); >> + /* release .fields memory as it is not used anymore */ >> + devm_kfree(&hdev->dev, td->fields); >> td->fields = NULL; >> >> return 0; >> - >> -hid_fail: >> - list_for_each_entry(hi, &hdev->inputs, list) >> - mt_free_input_name(hi); >> -fail: >> - kfree(td->fields); >> - kfree(td); >> - return ret; >> } >> >> #ifdef CONFIG_PM >> @@ -1039,17 +1023,8 @@ static int mt_resume(struct hid_device *hdev) >> >> static void mt_remove(struct hid_device *hdev) >> { >> - struct mt_device *td = hid_get_drvdata(hdev); >> - struct hid_input *hi; >> - >> sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); >> - list_for_each_entry(hi, &hdev->inputs, list) >> - mt_free_input_name(hi); >> - >> hid_hw_stop(hdev); >> - >> - kfree(td); >> - hid_set_drvdata(hdev, NULL); >> } >> >> static const struct hid_device_id mt_devices[] = { >> -- >> 1.8.3.1 >> > > > > -- > With Best Regards, > Andy Shevchenko ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-07-24 16:43 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-07-24 15:29 [PATCH 0/2] HID special drivers converted to devres API Benjamin Tissoires 2013-07-24 15:29 ` [PATCH 1/2] HID: trivial devm conversion for special hid drivers Benjamin Tissoires 2013-07-24 15:37 ` Andy Shevchenko 2013-07-24 15:43 ` Benjamin Tissoires 2013-07-24 15:29 ` [PATCH 2/2] HID: multitouch: devm conversion Benjamin Tissoires 2013-07-24 15:44 ` Andy Shevchenko 2013-07-24 16:43 ` Benjamin Tissoires
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).