2013-09-16 14:50:16

by Manish Badarkhe

[permalink] [raw]
Subject: [PATCH] Input: atmel_mxt_ts - update to devm_* API

Update the code to use devm_* API so that driver core will manage
resources.

Signed-off-by: Manish Badarkhe <[email protected]>
---
This is just clean up of code to manage resources using "devm_"
funtions. Not tested on hardware.

:100644 100644 59aa240... 73c5ad0... M drivers/input/touchscreen/atmel_mxt_ts.c
drivers/input/touchscreen/atmel_mxt_ts.c | 27 +++++++++++----------------
1 file changed, 11 insertions(+), 16 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 59aa240..73c5ad0 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1139,12 +1139,12 @@ static int mxt_probe(struct i2c_client *client,
if (!pdata)
return -EINVAL;

- data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
- input_dev = input_allocate_device();
+ data = devm_kzalloc(&client->dev, sizeof(struct mxt_data), GFP_KERNEL);
+ input_dev = devm_input_allocate_device(&client->dev);
if (!data || !input_dev) {
dev_err(&client->dev, "Failed to allocate memory\n");
error = -ENOMEM;
- goto err_free_mem;
+ goto err_out;
}

data->is_tp = pdata && pdata->is_tp;
@@ -1170,7 +1170,7 @@ static int mxt_probe(struct i2c_client *client,

error = mxt_initialize(data);
if (error)
- goto err_free_mem;
+ goto err_out;

__set_bit(EV_ABS, input_dev->evbit);
__set_bit(EV_KEY, input_dev->evbit);
@@ -1224,9 +1224,10 @@ static int mxt_probe(struct i2c_client *client,
input_set_drvdata(input_dev, data);
i2c_set_clientdata(client, data);

- error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
- pdata->irqflags | IRQF_ONESHOT,
- client->name, data);
+ error = devm_request_threaded_irq(&client->dev,
+ client->irq, NULL, mxt_interrupt,
+ pdata->irqflags | IRQF_ONESHOT,
+ client->name, data);
if (error) {
dev_err(&client->dev, "Failed to register interrupt\n");
goto err_free_object;
@@ -1234,11 +1235,11 @@ static int mxt_probe(struct i2c_client *client,

error = mxt_make_highchg(data);
if (error)
- goto err_free_irq;
+ goto err_free_object;

error = input_register_device(input_dev);
if (error)
- goto err_free_irq;
+ goto err_free_object;

error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
if (error)
@@ -1249,13 +1250,9 @@ static int mxt_probe(struct i2c_client *client,
err_unregister_device:
input_unregister_device(input_dev);
input_dev = NULL;
-err_free_irq:
- free_irq(client->irq, data);
err_free_object:
kfree(data->object_table);
-err_free_mem:
- input_free_device(input_dev);
- kfree(data);
+err_out:
return error;
}

@@ -1264,10 +1261,8 @@ static int mxt_remove(struct i2c_client *client)
struct mxt_data *data = i2c_get_clientdata(client);

sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
- free_irq(data->irq, data);
input_unregister_device(data->input_dev);
kfree(data->object_table);
- kfree(data);

return 0;
}
--
1.7.10.4


2013-09-16 15:07:04

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH] Input: atmel_mxt_ts - update to devm_* API

Hi Manish,

On Mon, Sep 16, 2013 at 08:20:16PM +0530, Manish Badarkhe wrote:
> @@ -1264,10 +1261,8 @@ static int mxt_remove(struct i2c_client *client)
> struct mxt_data *data = i2c_get_clientdata(client);
>
> sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
> - free_irq(data->irq, data);
> input_unregister_device(data->input_dev);
> kfree(data->object_table);
> - kfree(data);

YOu need to be _very_ careful when mixing devm_* and non-devm-managed
resources, especially when interrupt is involved. In this particular
case you are offloading freeing of the interrupt (and disabling it) to
devm, which will happen later, bu you are freeing object table
immediately. This may cause driver crash if interrupt comes while device
is being unbound.

That said, there is a large outstanding series to the driver from Nick
Dryer that I am trying to merge, you may want to coordinate this change
with him.

Thanks.

--
Dmitry