MLK-17779 input: egalax_ts: free irq resource before request the line as GPIO
authorFugang Duan <fugang.duan@nxp.com>
Fri, 30 Mar 2018 08:45:26 +0000 (16:45 +0800)
committerHaibo Chen <haibo.chen@nxp.com>
Thu, 12 Apr 2018 10:46:37 +0000 (18:46 +0800)
If GPIO is connected to an IRQ then it should not request it as
GPIO function only when free its IRQ resouce.

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
drivers/input/touchscreen/egalax_ts.c

index d5f41cb..9479992 100644 (file)
@@ -119,6 +119,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)
 {
@@ -230,14 +250,9 @@ static int egalax_ts_probe(struct i2c_client *client,
 
        input_set_drvdata(input_dev, ts);
 
-       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)
@@ -259,8 +274,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;
 
+       egalax_free_irq(ts);
        ret = i2c_master_send(client, suspend_cmd, MAX_I2C_DATA_LEN);
        return ret > 0 ? 0 : ret;
 }
@@ -268,8 +285,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;
+
+       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);