Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH 01/17] Input: adp5589-keys - use guard notation when acquiring mutex
From: Dmitry Torokhov @ 2024-08-25  5:16 UTC (permalink / raw)
  To: linux-input
  Cc: Michael Hennerich, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Laxman Dewangan, Thierry Reding, Hans de Goede, Tony Lindgren,
	Jeff LaBundy, linux-kernel, imx, linux-arm-kernel, linux-tegra
In-Reply-To: <20240825051627.2848495-1-dmitry.torokhov@gmail.com>

This makes the code more compact and error handling more robust
by ensuring that mutexes are released in all code paths when control
leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/keyboard/adp5589-keys.c | 39 +++++++++++++--------------
 1 file changed, 18 insertions(+), 21 deletions(-)

diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c
index 8996e00cd63a..735d96b056d4 100644
--- a/drivers/input/keyboard/adp5589-keys.c
+++ b/drivers/input/keyboard/adp5589-keys.c
@@ -404,7 +404,7 @@ static void adp5589_gpio_set_value(struct gpio_chip *chip,
 	unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
 	unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
 
-	mutex_lock(&kpad->gpio_lock);
+	guard(mutex)(&kpad->gpio_lock);
 
 	if (val)
 		kpad->dat_out[bank] |= bit;
@@ -413,8 +413,6 @@ static void adp5589_gpio_set_value(struct gpio_chip *chip,
 
 	adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A) +
 		      bank, kpad->dat_out[bank]);
-
-	mutex_unlock(&kpad->gpio_lock);
 }
 
 static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off)
@@ -422,18 +420,13 @@ static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off)
 	struct adp5589_kpad *kpad = gpiochip_get_data(chip);
 	unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
 	unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
-	int ret;
 
-	mutex_lock(&kpad->gpio_lock);
+	guard(mutex)(&kpad->gpio_lock);
 
 	kpad->dir[bank] &= ~bit;
-	ret = adp5589_write(kpad->client,
-			    kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
-			    kpad->dir[bank]);
-
-	mutex_unlock(&kpad->gpio_lock);
-
-	return ret;
+	return adp5589_write(kpad->client,
+			     kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
+			     kpad->dir[bank]);
 }
 
 static int adp5589_gpio_direction_output(struct gpio_chip *chip,
@@ -442,9 +435,9 @@ static int adp5589_gpio_direction_output(struct gpio_chip *chip,
 	struct adp5589_kpad *kpad = gpiochip_get_data(chip);
 	unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
 	unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
-	int ret;
+	int error;
 
-	mutex_lock(&kpad->gpio_lock);
+	guard(mutex)(&kpad->gpio_lock);
 
 	kpad->dir[bank] |= bit;
 
@@ -453,15 +446,19 @@ static int adp5589_gpio_direction_output(struct gpio_chip *chip,
 	else
 		kpad->dat_out[bank] &= ~bit;
 
-	ret = adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A)
-			    + bank, kpad->dat_out[bank]);
-	ret |= adp5589_write(kpad->client,
-			     kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
-			     kpad->dir[bank]);
+	error = adp5589_write(kpad->client,
+			      kpad->var->reg(ADP5589_GPO_DATA_OUT_A) + bank,
+			      kpad->dat_out[bank]);
+	if (error)
+		return error;
 
-	mutex_unlock(&kpad->gpio_lock);
+	error = adp5589_write(kpad->client,
+			      kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
+			      kpad->dir[bank]);
+	if (error)
+		return error;
 
-	return ret;
+	return 0;
 }
 
 static int adp5589_build_gpiomap(struct adp5589_kpad *kpad,
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 00/17] Convert keyboard drivers to use new cleanup facilities
From: Dmitry Torokhov @ 2024-08-25  5:16 UTC (permalink / raw)
  To: linux-input
  Cc: Michael Hennerich, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Laxman Dewangan, Thierry Reding, Hans de Goede, Tony Lindgren,
	Jeff LaBundy, linux-kernel, imx, linux-arm-kernel, linux-tegra

Hi,

This series converts drivers found in drivers/input/keyboard to use new
__free() and guard() cleanup facilities that simplify the code and
ensure that all resources are released appropriately.

Thanks!

Dmitry Torokhov (17):
  Input: adp5589-keys - use guard notation when acquiring mutex
  Input: applespi - use guard notation when acquiring spinlock
  Input: atkbd - use guard notation when acquiring mutex
  Input: ep93xx_keypad - use guard notation when acquiring mutex
  Input: gpio-keys - switch to using cleanup functions
  Input: imx_keypad - use guard notation when acquiring mutex
  Input: ipaq-micro-keys - use guard notation when acquiring mutex and spinlock
  Input: iqs62x-keys - use cleanup facility for fwnodes
  Input: lm8323 - use guard notation when acquiring mutexes
  Input: lpc32xx-keys - use guard notation when acquiring mutex
  Input: matrix_keypad - use guard notation when acquiring spinlock
  Input: omap4-keypad - use guard notation when acquiring mutex
  Input: pmic8xxx-keypad - use guard notation when acquiring mutex
  Input: pxa27x_keypad - use guard notation when acquiring mutex
  Input: spear-keyboard - use guard notation when acquiring mutex
  Input: st-keyscan - use guard notation when acquiring mutex
  Input: tegra-kbc - use guard notation when acquiring mutex and spinlock

 drivers/input/keyboard/adp5589-keys.c    | 39 ++++++-------
 drivers/input/keyboard/applespi.c        | 72 ++++++------------------
 drivers/input/keyboard/atkbd.c           | 37 +++++-------
 drivers/input/keyboard/ep93xx_keypad.c   |  8 +--
 drivers/input/keyboard/gpio_keys.c       | 44 ++++++---------
 drivers/input/keyboard/imx_keypad.c      | 27 ++++-----
 drivers/input/keyboard/ipaq-micro-keys.c | 12 ++--
 drivers/input/keyboard/iqs62x-keys.c     |  7 +--
 drivers/input/keyboard/lm8323.c          | 49 ++++++++--------
 drivers/input/keyboard/lpc32xx-keys.c    | 18 +++---
 drivers/input/keyboard/matrix_keypad.c   | 18 +++---
 drivers/input/keyboard/omap4-keypad.c    |  4 +-
 drivers/input/keyboard/pmic8xxx-keypad.c |  8 +--
 drivers/input/keyboard/pxa27x_keypad.c   | 16 +++---
 drivers/input/keyboard/spear-keyboard.c  |  8 +--
 drivers/input/keyboard/st-keyscan.c      | 19 ++++---
 drivers/input/keyboard/tegra-kbc.c       | 45 +++++++--------
 17 files changed, 169 insertions(+), 262 deletions(-)

-- 
Dmitry

^ permalink raw reply

* [PATCH] Input: matrix-keymap - switch to using __free() cleanup facility
From: Dmitry Torokhov @ 2024-08-24 23:09 UTC (permalink / raw)
  To: linux-input; +Cc: linux-kernel, Benjamin Tissoires, Hans de Goede

Use __free(kfree) cleanup facility in matrix_keypad_parse_keymap() to
automatically free temporarily allocated memory.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/matrix-keymap.c | 25 +++++++++----------------
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c
index 5d93043bad8e..3bea3575a0a9 100644
--- a/drivers/input/matrix-keymap.c
+++ b/drivers/input/matrix-keymap.c
@@ -73,10 +73,9 @@ static int matrix_keypad_parse_keymap(const char *propname,
 	struct device *dev = input_dev->dev.parent;
 	unsigned int row_shift = get_count_order(cols);
 	unsigned int max_keys = rows << row_shift;
-	u32 *keys;
 	int i;
 	int size;
-	int retval;
+	int error;
 
 	if (!propname)
 		propname = "linux,keymap";
@@ -94,30 +93,24 @@ static int matrix_keypad_parse_keymap(const char *propname,
 		return -EINVAL;
 	}
 
-	keys = kmalloc_array(size, sizeof(u32), GFP_KERNEL);
+	u32 *keys __free(kfree) = kmalloc_array(size, sizeof(*keys), GFP_KERNEL);
 	if (!keys)
 		return -ENOMEM;
 
-	retval = device_property_read_u32_array(dev, propname, keys, size);
-	if (retval) {
+	error = device_property_read_u32_array(dev, propname, keys, size);
+	if (error) {
 		dev_err(dev, "failed to read %s property: %d\n",
-			propname, retval);
-		goto out;
+			propname, error);
+		return error;
 	}
 
 	for (i = 0; i < size; i++) {
 		if (!matrix_keypad_map_key(input_dev, rows, cols,
-					   row_shift, keys[i])) {
-			retval = -EINVAL;
-			goto out;
-		}
+					   row_shift, keys[i]))
+			return -EINVAL;
 	}
 
-	retval = 0;
-
-out:
-	kfree(keys);
-	return retval;
+	return 0;
 }
 
 /**
-- 
2.46.0.295.g3b9ea8a38a-goog


-- 
Dmitry

^ permalink raw reply related

* Re: [PATCH] Input: keypad-nomadik-ske - remove the driver
From: Linus Walleij @ 2024-08-24 14:35 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-input, linux-kernel, Arnd Bergmann, Lee Jones,
	linux-arm-kernel
In-Reply-To: <Zr-gX0dfN4te_8VG@google.com>

On Fri, Aug 16, 2024 at 8:54 PM Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:

> The users of this driver were removed in 2013 in commit 28633c54bda6
> ("ARM: ux500: Rip out keypad initialisation which is no longer used").
>
> Remove the driver as well.
>
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

Acked-by: Linus Walleij <linus.walleij@linaro.org>

This was intended for keypad phones based on ux500 and then
the smartphone/touchscreen revolution happened and it was
never used, it's there, but it's always dark silicon.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH 01/18] Input: zforce_ts - use devm_add_action_or_reset()
From: Heiko Stübner @ 2024-08-24 11:13 UTC (permalink / raw)
  To: linux-input, Dmitry Torokhov
  Cc: Sudip Mukherjee, Andreas Kemnade, linux-kernel, Sudip Mukherjee
In-Reply-To: <20240824055047.1706392-2-dmitry.torokhov@gmail.com>

Am Samstag, 24. August 2024, 07:50:25 CEST schrieb Dmitry Torokhov:
> From: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
> 
> If devm_add_action() fails we are explicitly calling the cleanup to free
> the resources allocated. Lets use the helper devm_add_action_or_reset()
> and return directly in case of error, as we know that the cleanup
> function has been already called by the helper if there was any error.
> 
> Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>

mistmatch between From and first Signed-off-by

Other than that:
Reviewed-by: Heiko Stuebner <heiko@sntech.de>

> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
>  drivers/input/touchscreen/zforce_ts.c | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
> index fdf2d1e770c8..ffbd55c6e1d4 100644
> --- a/drivers/input/touchscreen/zforce_ts.c
> +++ b/drivers/input/touchscreen/zforce_ts.c
> @@ -803,15 +803,12 @@ static int zforce_probe(struct i2c_client *client)
>  		udelay(100);
>  	}
>  
> -	ret = devm_add_action(&client->dev, zforce_reset, ts);
> +	ret = devm_add_action_or_reset(&client->dev, zforce_reset, ts);
>  	if (ret) {
>  		dev_err(&client->dev, "failed to register reset action, %d\n",
>  			ret);
>  
>  		/* hereafter the regulator will be disabled by the action */
> -		if (!IS_ERR(ts->reg_vdd))
> -			regulator_disable(ts->reg_vdd);
> -
>  		return ret;
>  	}
>  
> 





^ permalink raw reply

* [PATCH 18/18] Input: zforce_ts - switch to using asynchronous probing
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

The driver waits for the device to boot, which can be a lengthy
process. Switch it to asynchronous probing to allow more devices
to be probed simultaneously.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 5df4f9e8fb2e..4b8c4ebfff96 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -850,6 +850,7 @@ static struct i2c_driver zforce_driver = {
 		.name	= "zforce-ts",
 		.pm	= pm_sleep_ptr(&zforce_pm_ops),
 		.of_match_table	= of_match_ptr(zforce_dt_idtable),
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
 	},
 	.probe		= zforce_probe,
 	.id_table	= zforce_idtable,
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 17/18] Input: zforce_ts - remove assert/deassert wrappers
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

The wrappers are extremely simple, used once, and do not bring much
value. Remove them.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 116f3aa6350c..5df4f9e8fb2e 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -146,16 +146,6 @@ static int zforce_command(struct zforce_ts *ts, u8 cmd)
 	return 0;
 }
 
-static void zforce_reset_assert(struct zforce_ts *ts)
-{
-	gpiod_set_value_cansleep(ts->gpio_rst, 1);
-}
-
-static void zforce_reset_deassert(struct zforce_ts *ts)
-{
-	gpiod_set_value_cansleep(ts->gpio_rst, 0);
-}
-
 static int zforce_send_wait(struct zforce_ts *ts, const char *buf, int len)
 {
 	struct i2c_client *client = ts->client;
@@ -672,7 +662,7 @@ static void zforce_reset(void *data)
 {
 	struct zforce_ts *ts = data;
 
-	zforce_reset_assert(ts);
+	gpiod_set_value_cansleep(ts->gpio_rst, 1);
 	udelay(10);
 }
 
@@ -807,7 +797,7 @@ static int zforce_probe(struct i2c_client *client)
 	i2c_set_clientdata(client, ts);
 
 	/* let the controller boot */
-	zforce_reset_deassert(ts);
+	gpiod_set_value_cansleep(ts->gpio_rst, 0);
 
 	ts->command_waiting = NOTIFICATION_BOOTCOMPLETE;
 	if (wait_for_completion_timeout(&ts->command_done, WAIT_TIMEOUT) == 0)
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 16/18] Input: zforce_ts - do not hardcode interrupt level
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

Stop forcing interrupt to be low level triggered and instead rely on the
platform to define proper trigger to allow flexibility in board designs.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 316901c751c0..116f3aa6350c 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -799,8 +799,7 @@ static int zforce_probe(struct i2c_client *client)
 	 */
 	error = devm_request_threaded_irq(&client->dev, client->irq,
 					  zforce_irq, zforce_irq_thread,
-					  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-					  input_dev->name, ts);
+					  IRQF_ONESHOT, input_dev->name, ts);
 	if (error)
 		return dev_err_probe(&client->dev, error,
 				     "irq %d request failed\n", client->irq);
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 15/18] Input: zforce_ts - switch to using devm_regulator_get_enable()
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

The driver does not actively manage regulator state past probe() time,
so we can use devm_regulator_get_enable() to simplify the code.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index c6b506a01b2a..316901c751c0 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -107,8 +107,6 @@ struct zforce_ts {
 	struct touchscreen_properties prop;
 	char			phys[32];
 
-	struct regulator	*reg_vdd;
-
 	struct gpio_desc	*gpio_int;
 	struct gpio_desc	*gpio_rst;
 
@@ -675,11 +673,7 @@ static void zforce_reset(void *data)
 	struct zforce_ts *ts = data;
 
 	zforce_reset_assert(ts);
-
 	udelay(10);
-
-	if (!IS_ERR(ts->reg_vdd))
-		regulator_disable(ts->reg_vdd);
 }
 
 static void zforce_ts_parse_legacy_properties(struct zforce_ts *ts)
@@ -742,16 +736,11 @@ static int zforce_probe(struct i2c_client *client)
 					     "failed to request reset GPIO\n");
 	}
 
-	ts->reg_vdd = devm_regulator_get(&client->dev, "vdd");
-	error = PTR_ERR_OR_ZERO(ts->gpio_rst);
+	error = devm_regulator_get_enable(&client->dev, "vdd");
 	if (error)
 		return dev_err_probe(&client->dev, error,
 				     "failed to request vdd supply\n");
 
-	error = regulator_enable(ts->reg_vdd);
-	if (error)
-		return error;
-
 	/*
 	 * According to datasheet add 100us grace time after regular
 	 * regulator enable delay.
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 14/18] Input: zforce_ts - stop treating VDD regulator as optional
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

This regulator is not optional from the controller point of view,
so stop treating it as such. For hard-wired designs that omit the
regulator from their device trees regulator subsystem will create
a dummy instance.

This may introduce unnecessary delay of 100us in case of dummy
regulator, but if it is important the driver should be marked as
using asynchronous probing to avoid even longer delays waiting for
the command completions.

Also use usleep_range() instead of udelay() to avoid spinning.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 28 +++++++++++++--------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 2ae079db8884..c6b506a01b2a 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -742,23 +742,21 @@ static int zforce_probe(struct i2c_client *client)
 					     "failed to request reset GPIO\n");
 	}
 
-	ts->reg_vdd = devm_regulator_get_optional(&client->dev, "vdd");
+	ts->reg_vdd = devm_regulator_get(&client->dev, "vdd");
 	error = PTR_ERR_OR_ZERO(ts->gpio_rst);
-	if (error) {
-		if (error != -ENOENT)
-			return dev_err_probe(&client->dev, error,
-					     "failed to request vdd supply\n");
-	} else {
-		error = regulator_enable(ts->reg_vdd);
-		if (error)
-			return error;
+	if (error)
+		return dev_err_probe(&client->dev, error,
+				     "failed to request vdd supply\n");
 
-		/*
-		 * according to datasheet add 100us grace time after regular
-		 * regulator enable delay.
-		 */
-		udelay(100);
-	}
+	error = regulator_enable(ts->reg_vdd);
+	if (error)
+		return error;
+
+	/*
+	 * According to datasheet add 100us grace time after regular
+	 * regulator enable delay.
+	 */
+	usleep_range(100, 200);
 
 	error = devm_add_action_or_reset(&client->dev, zforce_reset, ts);
 	if (error)
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 13/18] Input: zforce_ts - make zforce_idtable constant
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

The I2C ID table is not supposed to change; mark it as const.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 78f561510f8d..2ae079db8884 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -855,7 +855,7 @@ static int zforce_probe(struct i2c_client *client)
 	return 0;
 }
 
-static struct i2c_device_id zforce_idtable[] = {
+static const struct i2c_device_id zforce_idtable[] = {
 	{ "zforce-ts" },
 	{ }
 };
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 12/18] Input: zforce_ts - use dev_err_probe() where appropriate
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

Use dev_err_probe() helper to log deferrals in the devices_deferred
debugfs file and avoid extra messages in the logs.

Also rename "ret" variables holding error codes only to "error".

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 245 ++++++++++++--------------
 1 file changed, 113 insertions(+), 132 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 0d06dda311d4..78f561510f8d 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -171,7 +171,7 @@ static int zforce_send_wait(struct zforce_ts *ts, const char *buf, int len)
 	ret = i2c_master_send(client, buf, len);
 	if (ret < 0) {
 		dev_err(&client->dev, "i2c send data request error: %d\n", ret);
-		return ret;;
+		return ret;
 	}
 
 	dev_dbg(&client->dev, "waiting for result for command 0x%x\n", buf[2]);
@@ -187,7 +187,7 @@ static int zforce_command_wait(struct zforce_ts *ts, u8 cmd)
 {
 	struct i2c_client *client = ts->client;
 	char buf[3];
-	int ret;
+	int error;
 
 	dev_dbg(&client->dev, "%s: 0x%x\n", __func__, cmd);
 
@@ -195,10 +195,11 @@ static int zforce_command_wait(struct zforce_ts *ts, u8 cmd)
 	buf[1] = 1; /* data size, command only */
 	buf[2] = cmd;
 
-	ret = zforce_send_wait(ts, &buf[0], ARRAY_SIZE(buf));
-	if (ret < 0) {
-		dev_err(&client->dev, "i2c send data request error: %d\n", ret);
-		return ret;
+	error = zforce_send_wait(ts, &buf[0], ARRAY_SIZE(buf));
+	if (error) {
+		dev_err(&client->dev, "i2c send data request error: %d\n",
+			error);
+		return error;
 	}
 
 	return 0;
@@ -246,40 +247,40 @@ static int zforce_setconfig(struct zforce_ts *ts, char b1)
 static int zforce_start(struct zforce_ts *ts)
 {
 	struct i2c_client *client = ts->client;
-	int ret;
+	int error;
 
 	dev_dbg(&client->dev, "starting device\n");
 
-	ret = zforce_command_wait(ts, COMMAND_INITIALIZE);
-	if (ret) {
-		dev_err(&client->dev, "Unable to initialize, %d\n", ret);
-		return ret;
+	error = zforce_command_wait(ts, COMMAND_INITIALIZE);
+	if (error) {
+		dev_err(&client->dev, "Unable to initialize, %d\n", error);
+		return error;
 	}
 
-	ret = zforce_resolution(ts, ts->prop.max_x, ts->prop.max_y);
-	if (ret) {
-		dev_err(&client->dev, "Unable to set resolution, %d\n", ret);
-		goto error;
+	error = zforce_resolution(ts, ts->prop.max_x, ts->prop.max_y);
+	if (error) {
+		dev_err(&client->dev, "Unable to set resolution, %d\n", error);
+		goto err_deactivate;
 	}
 
-	ret = zforce_scan_frequency(ts, 10, 50, 50);
-	if (ret) {
+	error = zforce_scan_frequency(ts, 10, 50, 50);
+	if (error) {
 		dev_err(&client->dev, "Unable to set scan frequency, %d\n",
-			ret);
-		goto error;
+			error);
+		goto err_deactivate;
 	}
 
-	ret = zforce_setconfig(ts, SETCONFIG_DUALTOUCH);
-	if (ret) {
+	error = zforce_setconfig(ts, SETCONFIG_DUALTOUCH);
+	if (error) {
 		dev_err(&client->dev, "Unable to set config\n");
-		goto error;
+		goto err_deactivate;
 	}
 
 	/* start sending touch events */
-	ret = zforce_command(ts, COMMAND_DATAREQUEST);
-	if (ret) {
+	error = zforce_command(ts, COMMAND_DATAREQUEST);
+	if (error) {
 		dev_err(&client->dev, "Unable to request data\n");
-		goto error;
+		goto err_deactivate;
 	}
 
 	/*
@@ -290,24 +291,24 @@ static int zforce_start(struct zforce_ts *ts)
 
 	return 0;
 
-error:
+err_deactivate:
 	zforce_command_wait(ts, COMMAND_DEACTIVATE);
-	return ret;
+	return error;
 }
 
 static int zforce_stop(struct zforce_ts *ts)
 {
 	struct i2c_client *client = ts->client;
-	int ret;
+	int error;
 
 	dev_dbg(&client->dev, "stopping device\n");
 
 	/* Deactivates touch sensing and puts the device into sleep. */
-	ret = zforce_command_wait(ts, COMMAND_DEACTIVATE);
-	if (ret != 0) {
+	error = zforce_command_wait(ts, COMMAND_DEACTIVATE);
+	if (error) {
 		dev_err(&client->dev, "could not deactivate device, %d\n",
-			ret);
-		return ret;
+			error);
+		return error;
 	}
 
 	return 0;
@@ -451,7 +452,7 @@ static irqreturn_t zforce_irq_thread(int irq, void *dev_id)
 {
 	struct zforce_ts *ts = dev_id;
 	struct i2c_client *client = ts->client;
-	int ret;
+	int error;
 	u8 payload_buffer[FRAME_MAXSIZE];
 	u8 *payload;
 	bool suspending;
@@ -482,10 +483,10 @@ static irqreturn_t zforce_irq_thread(int irq, void *dev_id)
 	 *    no IRQ any more)
 	 */
 	do {
-		ret = zforce_read_packet(ts, payload_buffer);
-		if (ret < 0) {
+		error = zforce_read_packet(ts, payload_buffer);
+		if (error) {
 			dev_err(&client->dev,
-				"could not read packet, ret: %d\n", ret);
+				"could not read packet, ret: %d\n", error);
 			break;
 		}
 
@@ -570,20 +571,18 @@ static void zforce_input_close(struct input_dev *dev)
 {
 	struct zforce_ts *ts = input_get_drvdata(dev);
 	struct i2c_client *client = ts->client;
-	int ret;
+	int error;
 
-	ret = zforce_stop(ts);
-	if (ret)
+	error = zforce_stop(ts);
+	if (error)
 		dev_warn(&client->dev, "stopping zforce failed\n");
-
-	return;
 }
 
 static int __zforce_suspend(struct zforce_ts *ts)
 {
 	struct i2c_client *client = ts->client;
 	struct input_dev *input = ts->input;
-	int ret;
+	int error;
 
 	guard(mutex)(&input->mutex);
 
@@ -596,9 +595,9 @@ static int __zforce_suspend(struct zforce_ts *ts)
 
 		/* Need to start device, if not open, to be a wakeup source. */
 		if (!input_device_enabled(input)) {
-			ret = zforce_start(ts);
-			if (ret)
-				return ret;
+			error = zforce_start(ts);
+			if (error)
+				return error;
 		}
 
 		enable_irq_wake(client->irq);
@@ -606,9 +605,9 @@ static int __zforce_suspend(struct zforce_ts *ts)
 		dev_dbg(&client->dev,
 			"suspend without being a wakeup source\n");
 
-		ret = zforce_stop(ts);
-		if (ret)
-			return ret;
+		error = zforce_stop(ts);
+		if (error)
+			return error;
 
 		disable_irq(client->irq);
 	}
@@ -639,7 +638,7 @@ static int zforce_resume(struct device *dev)
 	struct i2c_client *client = to_i2c_client(dev);
 	struct zforce_ts *ts = i2c_get_clientdata(client);
 	struct input_dev *input = ts->input;
-	int ret;
+	int error;
 
 	guard(mutex)(&input->mutex);
 
@@ -652,18 +651,18 @@ static int zforce_resume(struct device *dev)
 
 		/* need to stop device if it was not open on suspend */
 		if (!input_device_enabled(input)) {
-			ret = zforce_stop(ts);
-			if (ret)
-				return ret;
+			error = zforce_stop(ts);
+			if (error)
+				return error;
 		}
 	} else if (input_device_enabled(input)) {
 		dev_dbg(&client->dev, "resume without being a wakeup source\n");
 
 		enable_irq(client->irq);
 
-		ret = zforce_start(ts);
-		if (ret < 0)
-			return ret;
+		error = zforce_start(ts);
+		if (error)
+			return error;
 	}
 
 	return 0;
@@ -699,7 +698,7 @@ static int zforce_probe(struct i2c_client *client)
 {
 	struct zforce_ts *ts;
 	struct input_dev *input_dev;
-	int ret;
+	int error;
 
 	ts = devm_kzalloc(&client->dev, sizeof(struct zforce_ts), GFP_KERNEL);
 	if (!ts)
@@ -707,22 +706,18 @@ static int zforce_probe(struct i2c_client *client)
 
 	ts->gpio_rst = devm_gpiod_get_optional(&client->dev, "reset",
 					       GPIOD_OUT_HIGH);
-	if (IS_ERR(ts->gpio_rst)) {
-		ret = PTR_ERR(ts->gpio_rst);
-		dev_err(&client->dev,
-			"failed to request reset GPIO: %d\n", ret);
-		return ret;
-	}
+	error = PTR_ERR_OR_ZERO(ts->gpio_rst);
+	if (error)
+		return dev_err_probe(&client->dev, error,
+				     "failed to request reset GPIO\n");
 
 	if (ts->gpio_rst) {
 		ts->gpio_int = devm_gpiod_get_optional(&client->dev, "irq",
 						       GPIOD_IN);
-		if (IS_ERR(ts->gpio_int)) {
-			ret = PTR_ERR(ts->gpio_int);
-			dev_err(&client->dev,
-				"failed to request interrupt GPIO: %d\n", ret);
-			return ret;
-		}
+		error = PTR_ERR_OR_ZERO(ts->gpio_int);
+		if (error)
+			return dev_err_probe(&client->dev, error,
+					     "failed to request interrupt GPIO\n");
 	} else {
 		/*
 		 * Deprecated GPIO handling for compatibility
@@ -732,33 +727,31 @@ static int zforce_probe(struct i2c_client *client)
 		/* INT GPIO */
 		ts->gpio_int = devm_gpiod_get_index(&client->dev, NULL, 0,
 						    GPIOD_IN);
-		if (IS_ERR(ts->gpio_int)) {
-			ret = PTR_ERR(ts->gpio_int);
-			dev_err(&client->dev,
-				"failed to request interrupt GPIO: %d\n", ret);
-			return ret;
-		}
+
+		error = PTR_ERR_OR_ZERO(ts->gpio_int);
+		if (error)
+			return dev_err_probe(&client->dev, error,
+					     "failed to request interrupt GPIO\n");
 
 		/* RST GPIO */
 		ts->gpio_rst = devm_gpiod_get_index(&client->dev, NULL, 1,
 					    GPIOD_OUT_HIGH);
-		if (IS_ERR(ts->gpio_rst)) {
-			ret = PTR_ERR(ts->gpio_rst);
-			dev_err(&client->dev,
-				"failed to request reset GPIO: %d\n", ret);
-			return ret;
-		}
+		error = PTR_ERR_OR_ZERO(ts->gpio_rst);
+		if (error)
+			return dev_err_probe(&client->dev, error,
+					     "failed to request reset GPIO\n");
 	}
 
 	ts->reg_vdd = devm_regulator_get_optional(&client->dev, "vdd");
-	if (IS_ERR(ts->reg_vdd)) {
-		ret = PTR_ERR(ts->reg_vdd);
-		if (ret != -ENOENT)
-			return ret;
+	error = PTR_ERR_OR_ZERO(ts->gpio_rst);
+	if (error) {
+		if (error != -ENOENT)
+			return dev_err_probe(&client->dev, error,
+					     "failed to request vdd supply\n");
 	} else {
-		ret = regulator_enable(ts->reg_vdd);
-		if (ret)
-			return ret;
+		error = regulator_enable(ts->reg_vdd);
+		if (error)
+			return error;
 
 		/*
 		 * according to datasheet add 100us grace time after regular
@@ -767,23 +760,18 @@ static int zforce_probe(struct i2c_client *client)
 		udelay(100);
 	}
 
-	ret = devm_add_action_or_reset(&client->dev, zforce_reset, ts);
-	if (ret) {
-		dev_err(&client->dev, "failed to register reset action, %d\n",
-			ret);
-
-		/* hereafter the regulator will be disabled by the action */
-		return ret;
-	}
+	error = devm_add_action_or_reset(&client->dev, zforce_reset, ts);
+	if (error)
+		return dev_err_probe(&client->dev, error,
+				     "failed to register reset action\n");
 
 	snprintf(ts->phys, sizeof(ts->phys),
 		 "%s/input0", dev_name(&client->dev));
 
 	input_dev = devm_input_allocate_device(&client->dev);
-	if (!input_dev) {
-		dev_err(&client->dev, "could not allocate input device\n");
-		return -ENOMEM;
-	}
+	if (!input_dev)
+		return dev_err_probe(&client->dev, -ENOMEM,
+				     "could not allocate input device\n");
 
 	ts->client = client;
 	ts->input = input_dev;
@@ -797,10 +785,8 @@ static int zforce_probe(struct i2c_client *client)
 
 	zforce_ts_parse_legacy_properties(ts);
 	touchscreen_parse_properties(input_dev, true, &ts->prop);
-	if (ts->prop.max_x == 0 || ts->prop.max_y == 0) {
-		dev_err(&client->dev, "no size specified\n");
-		return -EINVAL;
-	}
+	if (ts->prop.max_x == 0 || ts->prop.max_y == 0)
+		return dev_err_probe(&client->dev, -EINVAL, "no size specified");
 
 	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0,
 			     ZFORCE_MAX_AREA, 0, 0);
@@ -808,10 +794,10 @@ static int zforce_probe(struct i2c_client *client)
 			     ZFORCE_MAX_AREA, 0, 0);
 	input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0);
 
-	ret = input_mt_init_slots(input_dev, ZFORCE_REPORT_POINTS,
+	error = input_mt_init_slots(input_dev, ZFORCE_REPORT_POINTS,
 				  INPUT_MT_DIRECT);
-	if (ret)
-		return ret;
+	if (error)
+		return error;
 
 	input_set_drvdata(ts->input, ts);
 
@@ -824,14 +810,13 @@ static int zforce_probe(struct i2c_client *client)
 	 * Therefore we can trigger the interrupt anytime it is low and do
 	 * not need to limit it to the interrupt edge.
 	 */
-	ret = devm_request_threaded_irq(&client->dev, client->irq,
-					zforce_irq, zforce_irq_thread,
-					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-					input_dev->name, ts);
-	if (ret) {
-		dev_err(&client->dev, "irq %d request failed\n", client->irq);
-		return ret;
-	}
+	error = devm_request_threaded_irq(&client->dev, client->irq,
+					  zforce_irq, zforce_irq_thread,
+					  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					  input_dev->name, ts);
+	if (error)
+		return dev_err_probe(&client->dev, error,
+				     "irq %d request failed\n", client->irq);
 
 	i2c_set_clientdata(client, ts);
 
@@ -843,33 +828,29 @@ static int zforce_probe(struct i2c_client *client)
 		dev_warn(&client->dev, "bootcomplete timed out\n");
 
 	/* need to start device to get version information */
-	ret = zforce_command_wait(ts, COMMAND_INITIALIZE);
-	if (ret) {
-		dev_err(&client->dev, "unable to initialize, %d\n", ret);
-		return ret;
-	}
+	error = zforce_command_wait(ts, COMMAND_INITIALIZE);
+	if (error)
+		return dev_err_probe(&client->dev, error, "unable to initialize\n");
 
 	/* this gets the firmware version among other information */
-	ret = zforce_command_wait(ts, COMMAND_STATUS);
-	if (ret < 0) {
-		dev_err(&client->dev, "couldn't get status, %d\n", ret);
+	error = zforce_command_wait(ts, COMMAND_STATUS);
+	if (error) {
+		dev_err_probe(&client->dev, error, "couldn't get status\n");
 		zforce_stop(ts);
-		return ret;
+		return error;
 	}
 
 	/* stop device and put it into sleep until it is opened */
-	ret = zforce_stop(ts);
-	if (ret < 0)
-		return ret;
+	error = zforce_stop(ts);
+	if (error)
+		return error;
 
 	device_set_wakeup_capable(&client->dev, true);
 
-	ret = input_register_device(input_dev);
-	if (ret) {
-		dev_err(&client->dev, "could not register input device, %d\n",
-			ret);
-		return ret;
-	}
+	error = input_register_device(input_dev);
+	if (error)
+		return dev_err_probe(&client->dev, error,
+				     "could not register input device\n");
 
 	return 0;
 }
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 11/18] Input: zforce_ts - do not ignore errors when acquiring regulator
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

We should abort probe on any error besides -ENOENT which signifies that
the regulator is not defined in device tree or elsewhere, not only
when we see -EPROBE_DEFER.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index c5b4c85359b4..0d06dda311d4 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -753,7 +753,7 @@ static int zforce_probe(struct i2c_client *client)
 	ts->reg_vdd = devm_regulator_get_optional(&client->dev, "vdd");
 	if (IS_ERR(ts->reg_vdd)) {
 		ret = PTR_ERR(ts->reg_vdd);
-		if (ret == -EPROBE_DEFER)
+		if (ret != -ENOENT)
 			return ret;
 	} else {
 		ret = regulator_enable(ts->reg_vdd);
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 10/18] Input: zforce_ts - make parsing of contacts less confusing
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

Zforce touch data packet consists of a byte representing number of
contacts followed by several chunks with length of 9 bytes representing
each contact. Instead of accounting for the leading byte by increasing
offset of each field in contacts by one introduce a pointer to contact
data and point it appropriately. This avoids awkward constructs like:

	point.prblty = payload[9 * i + 9];

which makes it seem like there is off-by-one error, in favor of more
straightforward:

	point.prblty = p[8];

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 32f3d74bd339..c5b4c85359b4 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -318,6 +318,7 @@ static int zforce_touch_event(struct zforce_ts *ts, u8 *payload)
 	struct i2c_client *client = ts->client;
 	struct zforce_point point;
 	int count, i, num = 0;
+	u8 *p;
 
 	count = payload[0];
 	if (count > ZFORCE_REPORT_POINTS) {
@@ -328,8 +329,10 @@ static int zforce_touch_event(struct zforce_ts *ts, u8 *payload)
 	}
 
 	for (i = 0; i < count; i++) {
-		point.coord_x = get_unaligned_le16(&payload[9 * i + 1]);
-		point.coord_y = get_unaligned_le16(&payload[9 * i + 3]);
+		p = &payload[i * 9 + 1];
+
+		point.coord_x = get_unaligned_le16(&p[0]);
+		point.coord_y = get_unaligned_le16(&p[2]);
 
 		if (point.coord_x > ts->prop.max_x ||
 		    point.coord_y > ts->prop.max_y) {
@@ -338,18 +341,16 @@ static int zforce_touch_event(struct zforce_ts *ts, u8 *payload)
 			point.coord_x = point.coord_y = 0;
 		}
 
-		point.state = payload[9 * i + 5] & 0x0f;
-		point.id = (payload[9 * i + 5] & 0xf0) >> 4;
+		point.state = p[4] & 0x0f;
+		point.id = (p[4] & 0xf0) >> 4;
 
 		/* determine touch major, minor and orientation */
-		point.area_major = max(payload[9 * i + 6],
-					  payload[9 * i + 7]);
-		point.area_minor = min(payload[9 * i + 6],
-					  payload[9 * i + 7]);
-		point.orientation = payload[9 * i + 6] > payload[9 * i + 7];
-
-		point.pressure = payload[9 * i + 8];
-		point.prblty = payload[9 * i + 9];
+		point.area_major = max(p[5], p[6]);
+		point.area_minor = min(p[5], p[6]);
+		point.orientation = p[5] > p[6];
+
+		point.pressure = p[7];
+		point.prblty = p[8];
 
 		dev_dbg(&client->dev,
 			"point %d/%d: state %d, id %d, pressure %d, prblty %d, x %d, y %d, amajor %d, aminor %d, ori %d\n",
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 09/18] Input: zforce_ts - switch to using get_unaligned_le16
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

Instead of doing conversion from little-endian data to CPU endianness
by hand use existing helpers.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 0dea389594bd..32f3d74bd339 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -22,6 +22,7 @@
 #include <linux/property.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
+#include <asm/unaligned.h>
 
 #define WAIT_TIMEOUT		msecs_to_jiffies(1000)
 
@@ -327,10 +328,8 @@ static int zforce_touch_event(struct zforce_ts *ts, u8 *payload)
 	}
 
 	for (i = 0; i < count; i++) {
-		point.coord_x =
-			payload[9 * i + 2] << 8 | payload[9 * i + 1];
-		point.coord_y =
-			payload[9 * i + 4] << 8 | payload[9 * i + 3];
+		point.coord_x = get_unaligned_le16(&payload[9 * i + 1]);
+		point.coord_y = get_unaligned_le16(&payload[9 * i + 3]);
 
 		if (point.coord_x > ts->prop.max_x ||
 		    point.coord_y > ts->prop.max_y) {
@@ -521,14 +520,15 @@ static irqreturn_t zforce_irq_thread(int irq, void *dev_id)
 			 * Version Payload Results
 			 * [2:major] [2:minor] [2:build] [2:rev]
 			 */
-			ts->version_major = (payload[RESPONSE_DATA + 1] << 8) |
-						payload[RESPONSE_DATA];
-			ts->version_minor = (payload[RESPONSE_DATA + 3] << 8) |
-						payload[RESPONSE_DATA + 2];
-			ts->version_build = (payload[RESPONSE_DATA + 5] << 8) |
-						payload[RESPONSE_DATA + 4];
-			ts->version_rev   = (payload[RESPONSE_DATA + 7] << 8) |
-						payload[RESPONSE_DATA + 6];
+			ts->version_major =
+				get_unaligned_le16(&payload[RESPONSE_DATA]);
+			ts->version_minor =
+				get_unaligned_le16(&payload[RESPONSE_DATA + 2]);
+			ts->version_build =
+				get_unaligned_le16(&payload[RESPONSE_DATA + 4]);
+			ts->version_rev =
+				get_unaligned_le16(&payload[RESPONSE_DATA + 6]);
+
 			dev_dbg(&ts->client->dev,
 				"Firmware Version %04x:%04x %04x:%04x\n",
 				ts->version_major, ts->version_minor,
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 08/18] Input: zforce_ts - use guard notation when acquiring mutexes
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

Guard notation allows for simpler code and ensures that mutexes are
automatically released in all code paths.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 45 ++++++++++++++-------------
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 004ef728fb90..0dea389594bd 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -578,17 +578,13 @@ static void zforce_input_close(struct input_dev *dev)
 	return;
 }
 
-static int zforce_suspend(struct device *dev)
+static int __zforce_suspend(struct zforce_ts *ts)
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct zforce_ts *ts = i2c_get_clientdata(client);
+	struct i2c_client *client = ts->client;
 	struct input_dev *input = ts->input;
-	int ret = 0;
-
-	mutex_lock(&input->mutex);
+	int ret;
 
-	WRITE_ONCE(ts->suspending, true);
-	smp_mb();
+	guard(mutex)(&input->mutex);
 
 	/*
 	 * When configured as a wakeup source device should always wake
@@ -601,7 +597,7 @@ static int zforce_suspend(struct device *dev)
 		if (!input_device_enabled(input)) {
 			ret = zforce_start(ts);
 			if (ret)
-				goto unlock;
+				return ret;
 		}
 
 		enable_irq_wake(client->irq);
@@ -611,18 +607,28 @@ static int zforce_suspend(struct device *dev)
 
 		ret = zforce_stop(ts);
 		if (ret)
-			goto unlock;
+			return ret;
 
 		disable_irq(client->irq);
 	}
 
 	ts->suspended = true;
+	return 0;
+}
 
-unlock:
+static int zforce_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct zforce_ts *ts = i2c_get_clientdata(client);
+	int ret;
+
+	WRITE_ONCE(ts->suspending, true);
 	smp_mb();
-	WRITE_ONCE(ts->suspending, false);
 
-	mutex_unlock(&input->mutex);
+	ret = __zforce_suspend(ts);
+
+	smp_mb();
+	WRITE_ONCE(ts->suspending, false);
 
 	return ret;
 }
@@ -632,9 +638,9 @@ static int zforce_resume(struct device *dev)
 	struct i2c_client *client = to_i2c_client(dev);
 	struct zforce_ts *ts = i2c_get_clientdata(client);
 	struct input_dev *input = ts->input;
-	int ret = 0;
+	int ret;
 
-	mutex_lock(&input->mutex);
+	guard(mutex)(&input->mutex);
 
 	ts->suspended = false;
 
@@ -647,7 +653,7 @@ static int zforce_resume(struct device *dev)
 		if (!input_device_enabled(input)) {
 			ret = zforce_stop(ts);
 			if (ret)
-				goto unlock;
+				return ret;
 		}
 	} else if (input_device_enabled(input)) {
 		dev_dbg(&client->dev, "resume without being a wakeup source\n");
@@ -656,13 +662,10 @@ static int zforce_resume(struct device *dev)
 
 		ret = zforce_start(ts);
 		if (ret < 0)
-			goto unlock;
+			return ret;
 	}
 
-unlock:
-	mutex_unlock(&input->mutex);
-
-	return ret;
+	return 0;
 }
 
 static DEFINE_SIMPLE_DEV_PM_OPS(zforce_pm_ops, zforce_suspend, zforce_resume);
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 07/18] Input: zforce_ts - ensure that pm_stay_awake() and pm_relax() are balanced
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

There is a small chance that ts->suspending flag may change while the
interrupt handler is running. To make sure call to pm_relax() is not
skipped on accident use a temporary to hold the original value at the
beginning of interrupt. Use READ_ONCE() so that the value is actually
fetched at the right time.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index afeafa589928..004ef728fb90 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -454,6 +454,7 @@ static irqreturn_t zforce_irq_thread(int irq, void *dev_id)
 	int ret;
 	u8 payload_buffer[FRAME_MAXSIZE];
 	u8 *payload;
+	bool suspending;
 
 	/*
 	 * When still suspended, return.
@@ -467,7 +468,8 @@ static irqreturn_t zforce_irq_thread(int irq, void *dev_id)
 	dev_dbg(&client->dev, "handling interrupt\n");
 
 	/* Don't emit wakeup events from commands run by zforce_suspend */
-	if (!ts->suspending && device_may_wakeup(&client->dev))
+	suspending = READ_ONCE(ts->suspending);
+	if (!suspending && device_may_wakeup(&client->dev))
 		pm_stay_awake(&client->dev);
 
 	/*
@@ -495,7 +497,7 @@ static irqreturn_t zforce_irq_thread(int irq, void *dev_id)
 			 * Always report touch-events received while
 			 * suspending, when being a wakeup source
 			 */
-			if (ts->suspending && device_may_wakeup(&client->dev))
+			if (suspending && device_may_wakeup(&client->dev))
 				pm_wakeup_event(&client->dev, 500);
 			zforce_touch_event(ts, &payload[RESPONSE_DATA]);
 			break;
@@ -548,7 +550,7 @@ static irqreturn_t zforce_irq_thread(int irq, void *dev_id)
 		}
 	} while (gpiod_get_value_cansleep(ts->gpio_int));
 
-	if (!ts->suspending && device_may_wakeup(&client->dev))
+	if (!suspending && device_may_wakeup(&client->dev))
 		pm_relax(&client->dev);
 
 	dev_dbg(&client->dev, "finished interrupt\n");
@@ -584,7 +586,9 @@ static int zforce_suspend(struct device *dev)
 	int ret = 0;
 
 	mutex_lock(&input->mutex);
-	ts->suspending = true;
+
+	WRITE_ONCE(ts->suspending, true);
+	smp_mb();
 
 	/*
 	 * When configured as a wakeup source device should always wake
@@ -615,7 +619,9 @@ static int zforce_suspend(struct device *dev)
 	ts->suspended = true;
 
 unlock:
-	ts->suspending = false;
+	smp_mb();
+	WRITE_ONCE(ts->suspending, false);
+
 	mutex_unlock(&input->mutex);
 
 	return ret;
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 06/18] Input: zforce_ts - remove unneeded locking
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

There is no need to have a lock around calls to i2c_master_send() and
i2c_master_recv() as they are not issued concurrently and they are not
sharing any buffers. Also there is no need for command_mutex as all
commands are issued sequentially.

Remove both.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 47 +++++----------------------
 1 file changed, 9 insertions(+), 38 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index a4956f1eebb2..afeafa589928 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -95,9 +95,7 @@ struct zforce_point {
  * @suspending		in the process of going to suspend (don't emit wakeup
  *			events for commands executed to suspend the device)
  * @suspended		device suspended
- * @access_mutex	serialize i2c-access, to keep multipart reads together
  * @command_done	completion to wait for the command result
- * @command_mutex	serialize commands sent to the ic
  * @command_waiting	the id of the command that is currently waiting
  *			for a result
  * @command_result	returned result of the command
@@ -123,10 +121,7 @@ struct zforce_ts {
 	u16			version_build;
 	u16			version_rev;
 
-	struct mutex		access_mutex;
-
 	struct completion	command_done;
-	struct mutex		command_mutex;
 	int			command_waiting;
 	int			command_result;
 };
@@ -143,9 +138,7 @@ static int zforce_command(struct zforce_ts *ts, u8 cmd)
 	buf[1] = 1; /* data size, command only */
 	buf[2] = cmd;
 
-	mutex_lock(&ts->access_mutex);
 	ret = i2c_master_send(client, &buf[0], ARRAY_SIZE(buf));
-	mutex_unlock(&ts->access_mutex);
 	if (ret < 0) {
 		dev_err(&client->dev, "i2c send data request error: %d\n", ret);
 		return ret;
@@ -169,37 +162,24 @@ static int zforce_send_wait(struct zforce_ts *ts, const char *buf, int len)
 	struct i2c_client *client = ts->client;
 	int ret;
 
-	ret = mutex_trylock(&ts->command_mutex);
-	if (!ret) {
-		dev_err(&client->dev, "already waiting for a command\n");
-		return -EBUSY;
-	}
-
 	dev_dbg(&client->dev, "sending %d bytes for command 0x%x\n",
 		buf[1], buf[2]);
 
 	ts->command_waiting = buf[2];
 
-	mutex_lock(&ts->access_mutex);
 	ret = i2c_master_send(client, buf, len);
-	mutex_unlock(&ts->access_mutex);
 	if (ret < 0) {
 		dev_err(&client->dev, "i2c send data request error: %d\n", ret);
-		goto unlock;
+		return ret;;
 	}
 
 	dev_dbg(&client->dev, "waiting for result for command 0x%x\n", buf[2]);
 
-	if (wait_for_completion_timeout(&ts->command_done, WAIT_TIMEOUT) == 0) {
-		ret = -ETIME;
-		goto unlock;
-	}
+	if (wait_for_completion_timeout(&ts->command_done, WAIT_TIMEOUT) == 0)
+		return -ETIME;
 
 	ret = ts->command_result;
-
-unlock:
-	mutex_unlock(&ts->command_mutex);
-	return ret;
+	return 0;
 }
 
 static int zforce_command_wait(struct zforce_ts *ts, u8 cmd)
@@ -412,41 +392,35 @@ static int zforce_read_packet(struct zforce_ts *ts, u8 *buf)
 	struct i2c_client *client = ts->client;
 	int ret;
 
-	mutex_lock(&ts->access_mutex);
-
 	/* read 2 byte message header */
 	ret = i2c_master_recv(client, buf, 2);
 	if (ret < 0) {
 		dev_err(&client->dev, "error reading header: %d\n", ret);
-		goto unlock;
+		return ret;
 	}
 
 	if (buf[PAYLOAD_HEADER] != FRAME_START) {
 		dev_err(&client->dev, "invalid frame start: %d\n", buf[0]);
-		ret = -EIO;
-		goto unlock;
+		return -EIO;
 	}
 
 	if (buf[PAYLOAD_LENGTH] == 0) {
 		dev_err(&client->dev, "invalid payload length: %d\n",
 			buf[PAYLOAD_LENGTH]);
-		ret = -EIO;
-		goto unlock;
+		return -EIO;
 	}
 
 	/* read the message */
 	ret = i2c_master_recv(client, &buf[PAYLOAD_BODY], buf[PAYLOAD_LENGTH]);
 	if (ret < 0) {
 		dev_err(&client->dev, "error reading payload: %d\n", ret);
-		goto unlock;
+		return ret;
 	}
 
 	dev_dbg(&client->dev, "read %d bytes for response command 0x%x\n",
 		buf[PAYLOAD_LENGTH], buf[PAYLOAD_BODY]);
 
-unlock:
-	mutex_unlock(&ts->access_mutex);
-	return ret;
+	return 0;
 }
 
 static void zforce_complete(struct zforce_ts *ts, int cmd, int result)
@@ -801,9 +775,6 @@ static int zforce_probe(struct i2c_client *client)
 		return -ENOMEM;
 	}
 
-	mutex_init(&ts->access_mutex);
-	mutex_init(&ts->command_mutex);
-
 	ts->client = client;
 	ts->input = input_dev;
 
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 05/18] Input: zforce_ts - handle errors from input_mt_init_sots()
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

input_mt_init_slots() can potentially return error which needs to be
handled.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index a6f6cc5d8a3f..a4956f1eebb2 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -826,7 +826,11 @@ static int zforce_probe(struct i2c_client *client)
 	input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, 0,
 			     ZFORCE_MAX_AREA, 0, 0);
 	input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0);
-	input_mt_init_slots(input_dev, ZFORCE_REPORT_POINTS, INPUT_MT_DIRECT);
+
+	ret = input_mt_init_slots(input_dev, ZFORCE_REPORT_POINTS,
+				  INPUT_MT_DIRECT);
+	if (ret)
+		return ret;
 
 	input_set_drvdata(ts->input, ts);
 
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 04/18] Input: zforce_ts - do not explicitly set EV_SYN, etc bits
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

Input core and various helpers already do that for us, so drop the code
setting these bits explicitly.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 5a8f79b800e6..a6f6cc5d8a3f 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -814,10 +814,6 @@ static int zforce_probe(struct i2c_client *client)
 	input_dev->open = zforce_input_open;
 	input_dev->close = zforce_input_close;
 
-	__set_bit(EV_KEY, input_dev->evbit);
-	__set_bit(EV_SYN, input_dev->evbit);
-	__set_bit(EV_ABS, input_dev->evbit);
-
 	zforce_ts_parse_legacy_properties(ts);
 	touchscreen_parse_properties(input_dev, true, &ts->prop);
 	if (ts->prop.max_x == 0 || ts->prop.max_y == 0) {
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 03/18] Input: zforce_ts - remove support for platfrom data
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

There are no in-tree users of platform data and any new ones should
either use device tree or static device properties, so let's remove
platform data support.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c   | 56 +++++++------------------
 include/linux/platform_data/zforce_ts.h | 15 -------
 2 files changed, 16 insertions(+), 55 deletions(-)
 delete mode 100644 include/linux/platform_data/zforce_ts.h

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 350cec8508a3..5a8f79b800e6 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -9,21 +9,19 @@
  * Author: Pieter Truter<ptruter@intrinsyc.com>
  */
 
-#include <linux/module.h>
-#include <linux/hrtimer.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
 #include <linux/delay.h>
-#include <linux/gpio/consumer.h>
 #include <linux/device.h>
-#include <linux/sysfs.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
 #include <linux/input/mt.h>
 #include <linux/input/touchscreen.h>
-#include <linux/platform_data/zforce_ts.h>
-#include <linux/regulator/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 
 #define WAIT_TIMEOUT		msecs_to_jiffies(1000)
 
@@ -108,7 +106,6 @@ struct zforce_ts {
 	struct i2c_client	*client;
 	struct input_dev	*input;
 	struct touchscreen_properties prop;
-	const struct zforce_ts_platdata *pdata;
 	char			phys[32];
 
 	struct regulator	*reg_vdd;
@@ -702,39 +699,24 @@ static void zforce_reset(void *data)
 		regulator_disable(ts->reg_vdd);
 }
 
-static struct zforce_ts_platdata *zforce_parse_dt(struct device *dev)
+static void zforce_ts_parse_legacy_properties(struct zforce_ts *ts)
 {
-	struct zforce_ts_platdata *pdata;
-	struct device_node *np = dev->of_node;
-
-	if (!np)
-		return ERR_PTR(-ENOENT);
+	u32 x_max = 0;
+	u32 y_max = 0;
 
-	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
-	if (!pdata) {
-		dev_err(dev, "failed to allocate platform data\n");
-		return ERR_PTR(-ENOMEM);
-	}
-
-	of_property_read_u32(np, "x-size", &pdata->x_max);
-	of_property_read_u32(np, "y-size", &pdata->y_max);
+	device_property_read_u32(&ts->client->dev, "x-size", &x_max);
+	input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, x_max, 0, 0);
 
-	return pdata;
+	device_property_read_u32(&ts->client->dev, "y-size", &y_max);
+	input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, y_max, 0, 0);
 }
 
 static int zforce_probe(struct i2c_client *client)
 {
-	const struct zforce_ts_platdata *pdata = dev_get_platdata(&client->dev);
 	struct zforce_ts *ts;
 	struct input_dev *input_dev;
 	int ret;
 
-	if (!pdata) {
-		pdata = zforce_parse_dt(&client->dev);
-		if (IS_ERR(pdata))
-			return PTR_ERR(pdata);
-	}
-
 	ts = devm_kzalloc(&client->dev, sizeof(struct zforce_ts), GFP_KERNEL);
 	if (!ts)
 		return -ENOMEM;
@@ -822,7 +804,6 @@ static int zforce_probe(struct i2c_client *client)
 	mutex_init(&ts->access_mutex);
 	mutex_init(&ts->command_mutex);
 
-	ts->pdata = pdata;
 	ts->client = client;
 	ts->input = input_dev;
 
@@ -837,12 +818,7 @@ static int zforce_probe(struct i2c_client *client)
 	__set_bit(EV_SYN, input_dev->evbit);
 	__set_bit(EV_ABS, input_dev->evbit);
 
-	/* For multi touch */
-	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,
-			     pdata->x_max, 0, 0);
-	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
-			     pdata->y_max, 0, 0);
-
+	zforce_ts_parse_legacy_properties(ts);
 	touchscreen_parse_properties(input_dev, true, &ts->prop);
 	if (ts->prop.max_x == 0 || ts->prop.max_y == 0) {
 		dev_err(&client->dev, "no size specified\n");
diff --git a/include/linux/platform_data/zforce_ts.h b/include/linux/platform_data/zforce_ts.h
deleted file mode 100644
index 2463a4a856a6..000000000000
--- a/include/linux/platform_data/zforce_ts.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/* drivers/input/touchscreen/zforce.c
- *
- * Copyright (C) 2012-2013 MundoReader S.L.
- */
-
-#ifndef _LINUX_INPUT_ZFORCE_TS_H
-#define _LINUX_INPUT_ZFORCE_TS_H
-
-struct zforce_ts_platdata {
-	unsigned int x_max;
-	unsigned int y_max;
-};
-
-#endif /* _LINUX_INPUT_ZFORCE_TS_H */
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 02/18] Input: zforce_ts - simplify reporting of slot state
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

input_mt_report_slot_state() returns true if slot is active, so we can
combine checks for point.state != STATE_UP.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index ffbd55c6e1d4..350cec8508a3 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -386,10 +386,8 @@ static int zforce_touch_event(struct zforce_ts *ts, u8 *payload)
 		/* the zforce id starts with "1", so needs to be decreased */
 		input_mt_slot(ts->input, point.id - 1);
 
-		input_mt_report_slot_state(ts->input, MT_TOOL_FINGER,
-						point.state != STATE_UP);
-
-		if (point.state != STATE_UP) {
+		if (input_mt_report_slot_state(ts->input, MT_TOOL_FINGER,
+					       point.state != STATE_UP)) {
 			touchscreen_report_pos(ts->input, &ts->prop,
 					       point.coord_x, point.coord_y,
 					       true);
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 01/18] Input: zforce_ts - use devm_add_action_or_reset()
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input
  Cc: Sudip Mukherjee, Andreas Kemnade, linux-kernel, Sudip Mukherjee
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

From: Sudip Mukherjee <sudipm.mukherjee@gmail.com>

If devm_add_action() fails we are explicitly calling the cleanup to free
the resources allocated. Lets use the helper devm_add_action_or_reset()
and return directly in case of error, as we know that the cleanup
function has been already called by the helper if there was any error.

Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/zforce_ts.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index fdf2d1e770c8..ffbd55c6e1d4 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -803,15 +803,12 @@ static int zforce_probe(struct i2c_client *client)
 		udelay(100);
 	}
 
-	ret = devm_add_action(&client->dev, zforce_reset, ts);
+	ret = devm_add_action_or_reset(&client->dev, zforce_reset, ts);
 	if (ret) {
 		dev_err(&client->dev, "failed to register reset action, %d\n",
 			ret);
 
 		/* hereafter the regulator will be disabled by the action */
-		if (!IS_ERR(ts->reg_vdd))
-			regulator_disable(ts->reg_vdd);
-
 		return ret;
 	}
 
-- 
2.46.0.295.g3b9ea8a38a-goog


^ permalink raw reply related

* [PATCH 00/18] zforse_ts: assorted cleanups
From: Dmitry Torokhov @ 2024-08-24  5:50 UTC (permalink / raw)
  To: Heiko Stübner, linux-input; +Cc: Andreas Kemnade, linux-kernel

Hi,

This is a set of somewhat random cleanups for the zforce_ts driver. 

Heiko, Andreas, if you still have access to the hardware it would be
great if you could give it a spin.

Thanks!

Dmitry Torokhov (17):
  Input: zforce_ts - simplify reporting of slot state
  Input: zforce_ts - remove support for platfrom data
  Input: zforce_ts - do not explicitly set EV_SYN, etc bits
  Input: zforce_ts - handle errors from input_mt_init_sots()
  Input: zforce_ts - remove unneeded locking
  Input: zforce_ts - ensure that pm_stay_awake() and pm_relax() are balanced
  Input: zforce_ts - use guard notation when acquiring mutexes
  Input: zforce_ts - switch to using get_unaligned_le16
  Input: zforce_ts - make parsing of contacts less confusing
  Input: zforce_ts - do not ignore errors when acquiring regulator
  Input: zforce_ts - use dev_err_probe() where appropriate
  Input: zforce_ts - make zforce_idtable constant
  Input: zforce_ts - stop treating VDD regulator as optional
  Input: zforce_ts - switch to using devm_regulator_get_enable()
  Input: zforce_ts - do not hardcode interrupt level
  Input: zforce_ts - remove assert/deassert wrappers
  Input: zforce_ts - switch to using asynchronous probing

Sudip Mukherjee (1):
  Input: zforce_ts - use devm_add_action_or_reset()

 drivers/input/touchscreen/zforce_ts.c   | 474 ++++++++++--------------
 include/linux/platform_data/zforce_ts.h |  15 -
 2 files changed, 192 insertions(+), 297 deletions(-)
 delete mode 100644 include/linux/platform_data/zforce_ts.h

-- 
Dmitry


^ permalink raw reply

* Re: [git pull] Input updates for v6.11-rc4
From: pr-tracker-bot @ 2024-08-24  0:19 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Linus Torvalds, linux-kernel, linux-input
In-Reply-To: <ZsjxnTwQWOaTnPpY@google.com>

The pull request you sent on Fri, 23 Aug 2024 13:31:25 -0700:

> git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git tags/input-for-v6.11-rc4

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/7eb61cc674ee0f597e7954d38e4e08fe8c5b19ba

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox