summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index d63c7bb56de..7298926a75c 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1943,9 +1943,23 @@ static int mxt_acquire_irq(struct mxt_data *data)
{
int error;
- enable_irq(data->irq);
+ if (!data->irq) {
+ error = request_threaded_irq(data->client->irq, NULL,
+ mxt_interrupt,
+ data->pdata->irqflags | IRQF_ONESHOT,
+ data->client->name, data);
+ if (error) {
+ dev_err(&data->client->dev, "Error requesting irq\n");
+ return error;
+ }
+
+ /* Presence of data->irq means IRQ initialised */
+ data->irq = data->client->irq;
+ } else {
+ enable_irq(data->irq);
+ }
- if (data->use_retrigen_workaround) {
+ if (data->object_table && data->use_retrigen_workaround) {
error = mxt_process_messages_until_invalid(data);
if (error)
return error;
@@ -3022,7 +3036,9 @@ static int mxt_load_fw(struct device *dev)
goto release_firmware;
}
- enable_irq(data->irq);
+ ret = mxt_acquire_irq(data);
+ if (ret)
+ goto release_firmware;
/* Poll after 0.1s if no interrupt received */
schedule_delayed_work(&data->flash->work, HZ / 10);
@@ -3485,7 +3501,6 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
data->client = client;
data->pdata = pdata;
- data->irq = client->irq;
i2c_set_clientdata(client, data);
if (data->pdata->cfg_name)
@@ -3499,21 +3514,17 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
init_completion(&data->chg_completion);
mutex_init(&data->debug_msg_lock);
- error = request_threaded_irq(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_mem;
- }
-
if (pdata->suspend_mode == MXT_SUSPEND_REGULATOR) {
+ error = mxt_acquire_irq(data);
+ if (error)
+ goto err_free_mem;
+
error = mxt_probe_regulators(data);
if (error)
goto err_free_irq;
- }
- disable_irq(data->irq);
+ disable_irq(data->irq);
+ }
error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
if (error) {
@@ -3548,7 +3559,8 @@ err_remove_mem_access:
err_remove_sysfs_group:
sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
err_free_irq:
- free_irq(client->irq, data);
+ if (data->irq)
+ free_irq(data->irq, data);
err_free_mem:
kfree(data);
return error;
@@ -3563,7 +3575,10 @@ static int mxt_remove(struct i2c_client *client)
&data->mem_access_attr);
sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
- free_irq(data->irq, data);
+
+ if (data->irq)
+ free_irq(data->irq, data);
+
regulator_put(data->reg_avdd);
regulator_put(data->reg_vdd);
mxt_free_input_device(data);