summaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
authorFugang Duan <fugang.duan@nxp.com>2019-01-02 10:57:06 +0530
committerDong Aisheng <aisheng.dong@nxp.com>2019-11-25 16:28:59 +0800
commite7aca899a52e122bc099428f87b23e8d686b4a2f (patch)
tree8ea4d272533e1172e796d04b8658f588d7e8dba7 /drivers/input/touchscreen
parent30931ccb0fdbbe3c27f8323f85607f0defb7e865 (diff)
MLK-17779 input: egalax_ts: free irq resource before request the line as GPIO
If GPIO is connected to an IRQ then it should not request it as GPIO function only when free its IRQ resource. Tested-by: Haibo Chen <haibo.chen@nxp.com> Signed-off-by: Fugang Duan <fugang.duan@nxp.com> Signed-off-by: Anson Huang <Anson.Huang@nxp.com> Signed-off-by: Robin Gong <yibin.gong@nxp.com> Signed-off-by: Vipul Kumar <vipul_kumar@mentor.com>
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/egalax_ts.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c
index 5e35ca5edc7b..48b607c8a031 100644
--- a/drivers/input/touchscreen/egalax_ts.c
+++ b/drivers/input/touchscreen/egalax_ts.c
@@ -116,6 +116,26 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static int egalax_irq_request(struct egalax_ts *ts)
+{
+ int ret;
+ struct i2c_client *client = ts->client;
+
+ ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+ egalax_ts_interrupt,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ "egalax_ts", ts);
+ if (ret < 0)
+ dev_err(&client->dev, "Failed to register interrupt\n");
+
+ return ret;
+}
+
+static void egalax_free_irq(struct egalax_ts *ts)
+{
+ devm_free_irq(&ts->client->dev, ts->client->irq, ts);
+}
+
/* wake up controller by an falling edge of interrupt gpio. */
static int egalax_wake_up_device(struct i2c_client *client)
{
@@ -225,14 +245,9 @@ static int egalax_ts_probe(struct i2c_client *client,
ABS_MT_POSITION_Y, 0, EGALAX_MAX_Y, 0, 0);
input_mt_init_slots(input_dev, MAX_SUPPORT_POINTS, 0);
- error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
- egalax_ts_interrupt,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- "egalax_ts", ts);
- if (error < 0) {
- dev_err(&client->dev, "Failed to register interrupt\n");
+ error = egalax_irq_request(ts);
+ if (error)
return error;
- }
error = input_register_device(ts->input_dev);
if (error)
@@ -253,11 +268,10 @@ static int __maybe_unused egalax_ts_suspend(struct device *dev)
0x3, 0x6, 0xa, 0x3, 0x36, 0x3f, 0x2, 0, 0, 0
};
struct i2c_client *client = to_i2c_client(dev);
+ struct egalax_ts *ts = i2c_get_clientdata(client);
int ret;
- if (device_may_wakeup(dev))
- return enable_irq_wake(client->irq);
-
+ egalax_free_irq(ts);
ret = i2c_master_send(client, suspend_cmd, MAX_I2C_DATA_LEN);
return ret > 0 ? 0 : ret;
}
@@ -265,11 +279,14 @@ static int __maybe_unused egalax_ts_suspend(struct device *dev)
static int __maybe_unused egalax_ts_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
+ struct egalax_ts *ts = i2c_get_clientdata(client);
+ int ret;
- if (device_may_wakeup(dev))
- return disable_irq_wake(client->irq);
+ ret = egalax_wake_up_device(client);
+ if (!ret)
+ ret = egalax_irq_request(ts);
- return egalax_wake_up_device(client);
+ return ret;
}
static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume);