aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorStephen Warren <swarren@wwwdotorg.org>2014-09-10 13:01:10 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-09-10 13:27:31 -0400
commit58e4aeee39917c75da8e5dca0f1c42be8dc29f9e (patch)
tree1fa7d72e71f1abdb0cc563212ffe6767bf9dbdc5 /drivers/input
parent5715fc764f7753d464dbe094b5ef9cffa6e479a4 (diff)
Input: atmel_mxt_ts - fix double free of input device
[Nick Dyer: reworked to move free of input device into separate function and only call in paths that require it.] Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index d954b81243fe..aaacf8bfa61f 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1379,11 +1379,16 @@ static int mxt_get_info(struct mxt_data *data)
1379 return 0; 1379 return 0;
1380} 1380}
1381 1381
1382static void mxt_free_object_table(struct mxt_data *data) 1382static void mxt_free_input_device(struct mxt_data *data)
1383{ 1383{
1384 input_unregister_device(data->input_dev); 1384 if (data->input_dev) {
1385 data->input_dev = NULL; 1385 input_unregister_device(data->input_dev);
1386 data->input_dev = NULL;
1387 }
1388}
1386 1389
1390static void mxt_free_object_table(struct mxt_data *data)
1391{
1387 kfree(data->object_table); 1392 kfree(data->object_table);
1388 data->object_table = NULL; 1393 data->object_table = NULL;
1389 kfree(data->msg_buf); 1394 kfree(data->msg_buf);
@@ -1962,11 +1967,13 @@ static int mxt_load_fw(struct device *dev, const char *fn)
1962 ret = mxt_lookup_bootloader_address(data, 0); 1967 ret = mxt_lookup_bootloader_address(data, 0);
1963 if (ret) 1968 if (ret)
1964 goto release_firmware; 1969 goto release_firmware;
1970
1971 mxt_free_input_device(data);
1972 mxt_free_object_table(data);
1965 } else { 1973 } else {
1966 enable_irq(data->irq); 1974 enable_irq(data->irq);
1967 } 1975 }
1968 1976
1969 mxt_free_object_table(data);
1970 reinit_completion(&data->bl_completion); 1977 reinit_completion(&data->bl_completion);
1971 1978
1972 ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false); 1979 ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false);
@@ -2215,6 +2222,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
2215 return 0; 2222 return 0;
2216 2223
2217err_free_object: 2224err_free_object:
2225 mxt_free_input_device(data);
2218 mxt_free_object_table(data); 2226 mxt_free_object_table(data);
2219err_free_irq: 2227err_free_irq:
2220 free_irq(client->irq, data); 2228 free_irq(client->irq, data);
@@ -2229,7 +2237,7 @@ static int mxt_remove(struct i2c_client *client)
2229 2237
2230 sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); 2238 sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
2231 free_irq(data->irq, data); 2239 free_irq(data->irq, data);
2232 input_unregister_device(data->input_dev); 2240 mxt_free_input_device(data);
2233 mxt_free_object_table(data); 2241 mxt_free_object_table(data);
2234 kfree(data); 2242 kfree(data);
2235 2243