| From c3a05044825197e715453851f8950db61b001125 Mon Sep 17 00:00:00 2001 |
| From: Dmitry Torokhov <dmitry.torokhov@gmail.com> |
| Date: Mon, 21 Oct 2019 11:02:33 -0700 |
| Subject: [PATCH] Input: st1232 - do not reset the chip too early |
| |
| commit efd7bb08a762d4f6322054c6824bd942971ac563 upstream. |
| |
| 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> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c |
| index 1139714e72e2..1c5f8875cb79 100644 |
| --- a/drivers/input/touchscreen/st1232.c |
| +++ b/drivers/input/touchscreen/st1232.c |
| @@ -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; |
| @@ -271,15 +283,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); |
| @@ -329,7 +332,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, |
| -- |
| 2.7.4 |
| |