Input: st1232 - do not reset the chip too early
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 21 Oct 2019 18:02:33 +0000 (11:02 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 29 Oct 2019 04:01:46 +0000 (21:01 -0700)
We should not be putting the chip into reset while interrupts are enabled
and ISR may be running. Fix this by installing a custom devm action and
powering off the device/resetting GPIO line from there. This ensures proper
ordering.

Tested-by: Matthias Fend <Matthias.Fend@wolfvision.net>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/touchscreen/st1232.c

index bb116f41f1c0fc89398f5cf04fbdf91c68c04187..bfea02202ded71d031c8f862a695f4fd53da7bb3 100644 (file)
@@ -149,6 +149,11 @@ static void st1232_ts_power(struct st1232_ts_data *ts, bool poweron)
                gpiod_set_value_cansleep(ts->reset_gpio, !poweron);
 }
 
+static void st1232_ts_power_off(void *data)
+{
+       st1232_ts_power(data, false);
+}
+
 static const struct st_chip_info st1232_chip_info = {
        .have_z         = true,
        .max_x          = 0x31f, /* 800 - 1 */
@@ -229,6 +234,13 @@ static int st1232_ts_probe(struct i2c_client *client,
 
        st1232_ts_power(ts, true);
 
+       error = devm_add_action_or_reset(&client->dev, st1232_ts_power_off, ts);
+       if (error) {
+               dev_err(&client->dev,
+                       "Failed to install power off action: %d\n", error);
+               return error;
+       }
+
        input_dev->name = "st1232-touchscreen";
        input_dev->id.bustype = BUS_I2C;
        input_dev->dev.parent = &client->dev;
@@ -270,15 +282,6 @@ static int st1232_ts_probe(struct i2c_client *client,
        return 0;
 }
 
-static int st1232_ts_remove(struct i2c_client *client)
-{
-       struct st1232_ts_data *ts = i2c_get_clientdata(client);
-
-       st1232_ts_power(ts, false);
-
-       return 0;
-}
-
 static int __maybe_unused st1232_ts_suspend(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
@@ -324,7 +327,6 @@ MODULE_DEVICE_TABLE(of, st1232_ts_dt_ids);
 
 static struct i2c_driver st1232_ts_driver = {
        .probe          = st1232_ts_probe,
-       .remove         = st1232_ts_remove,
        .id_table       = st1232_ts_id,
        .driver = {
                .name   = ST1232_TS_NAME,