Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH v1 15/22] iio: light: hid-sensor-als: Get platform data via dev_get_platdata()
From: Andy Shevchenko @ 2024-09-02 22:17 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Andy Shevchenko,
	Michael Hennerich, Antoniu Miclaus, Jinjie Ruan, Lorenzo Bianconi,
	Srinivas Pandruvada, Basavaraj Natikar, linux-input, linux-iio,
	linux-kernel
  Cc: Jiri Kosina, Jonathan Cameron, Lars-Peter Clausen,
	Michael Hennerich, Andy Shevchenko
In-Reply-To: <20240902222824.1145571-1-andy.shevchenko@gmail.com>

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Access to platform data via dev_get_platdata() getter to make code cleaner.

Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/iio/light/hid-sensor-als.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index 260281194f61..0d995bc7877e 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -356,11 +356,11 @@ static int als_parse_report(struct platform_device *pdev,
 /* Function to initialize the processing for usage id */
 static int hid_als_probe(struct platform_device *pdev)
 {
+	struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
 	int ret = 0;
 	static const char *name = "als";
 	struct iio_dev *indio_dev;
 	struct als_state *als_state;
-	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
 
 	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct als_state));
 	if (!indio_dev)
@@ -438,7 +438,7 @@ static int hid_als_probe(struct platform_device *pdev)
 /* Function to deinitialize the processing for usage id */
 static void hid_als_remove(struct platform_device *pdev)
 {
-	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
+	struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct als_state *als_state = iio_priv(indio_dev);
 
-- 
2.46.0


^ permalink raw reply related

* [PATCH v1 11/22] iio: frequency: ad9523: Get platform data via dev_get_platdata()
From: Andy Shevchenko @ 2024-09-02 22:16 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Andy Shevchenko,
	Michael Hennerich, Antoniu Miclaus, Jinjie Ruan, Lorenzo Bianconi,
	Srinivas Pandruvada, Basavaraj Natikar, linux-input, linux-iio,
	linux-kernel
  Cc: Jiri Kosina, Jonathan Cameron, Lars-Peter Clausen,
	Michael Hennerich, Andy Shevchenko
In-Reply-To: <20240902222824.1145571-1-andy.shevchenko@gmail.com>

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Access to platform data via dev_get_platdata() getter to make code cleaner.

Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/iio/frequency/ad9523.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c
index b391c6e27ab0..b1554ced7a26 100644
--- a/drivers/iio/frequency/ad9523.c
+++ b/drivers/iio/frequency/ad9523.c
@@ -970,7 +970,7 @@ static int ad9523_setup(struct iio_dev *indio_dev)
 
 static int ad9523_probe(struct spi_device *spi)
 {
-	struct ad9523_platform_data *pdata = spi->dev.platform_data;
+	struct ad9523_platform_data *pdata = dev_get_platdata(&spi->dev);
 	struct iio_dev *indio_dev;
 	struct ad9523_state *st;
 	int ret;
-- 
2.46.0


^ permalink raw reply related

* [PATCH v1 04/22] iio: adc: ad7887: Get platform data via dev_get_platdata()
From: Andy Shevchenko @ 2024-09-02 22:16 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Andy Shevchenko,
	Michael Hennerich, Antoniu Miclaus, Jinjie Ruan, Lorenzo Bianconi,
	Srinivas Pandruvada, Basavaraj Natikar, linux-input, linux-iio,
	linux-kernel
  Cc: Jiri Kosina, Jonathan Cameron, Lars-Peter Clausen,
	Michael Hennerich, Andy Shevchenko
In-Reply-To: <20240902222824.1145571-1-andy.shevchenko@gmail.com>

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Access to platform data via dev_get_platdata() getter to make code cleaner.

Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/iio/adc/ad7887.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c
index 6265ce7df703..b301da9b88b1 100644
--- a/drivers/iio/adc/ad7887.c
+++ b/drivers/iio/adc/ad7887.c
@@ -234,7 +234,7 @@ static void ad7887_reg_disable(void *data)
 
 static int ad7887_probe(struct spi_device *spi)
 {
-	struct ad7887_platform_data *pdata = spi->dev.platform_data;
+	const struct ad7887_platform_data *pdata = dev_get_platdata(&spi->dev);
 	struct ad7887_state *st;
 	struct iio_dev *indio_dev;
 	uint8_t mode;
-- 
2.46.0


^ permalink raw reply related

* [PATCH v1 07/22] iio: dac: ad5504: Get platform data via dev_get_platdata()
From: Andy Shevchenko @ 2024-09-02 22:16 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Andy Shevchenko,
	Michael Hennerich, Antoniu Miclaus, Jinjie Ruan, Lorenzo Bianconi,
	Srinivas Pandruvada, Basavaraj Natikar, linux-input, linux-iio,
	linux-kernel
  Cc: Jiri Kosina, Jonathan Cameron, Lars-Peter Clausen,
	Michael Hennerich, Andy Shevchenko
In-Reply-To: <20240902222824.1145571-1-andy.shevchenko@gmail.com>

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Access to platform data via dev_get_platdata() getter to make code cleaner.

Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/iio/dac/ad5504.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c
index e6c5be728bb2..305cd58cd257 100644
--- a/drivers/iio/dac/ad5504.c
+++ b/drivers/iio/dac/ad5504.c
@@ -270,7 +270,7 @@ static const struct iio_chan_spec ad5504_channels[] = {
 
 static int ad5504_probe(struct spi_device *spi)
 {
-	struct ad5504_platform_data *pdata = spi->dev.platform_data;
+	const struct ad5504_platform_data *pdata = dev_get_platdata(&spi->dev);
 	struct iio_dev *indio_dev;
 	struct ad5504_state *st;
 	struct regulator *reg;
-- 
2.46.0


^ permalink raw reply related

* [PATCH v1 17/22] iio: light: lm3533-als: Get platform data via dev_get_platdata()
From: Andy Shevchenko @ 2024-09-02 22:17 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Andy Shevchenko,
	Michael Hennerich, Antoniu Miclaus, Jinjie Ruan, Lorenzo Bianconi,
	Srinivas Pandruvada, Basavaraj Natikar, linux-input, linux-iio,
	linux-kernel
  Cc: Jiri Kosina, Jonathan Cameron, Lars-Peter Clausen,
	Michael Hennerich, Andy Shevchenko
In-Reply-To: <20240902222824.1145571-1-andy.shevchenko@gmail.com>

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Access to platform data via dev_get_platdata() getter to make code cleaner.

Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/iio/light/lm3533-als.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c
index 7800f7fa51b7..6429d951ce7f 100644
--- a/drivers/iio/light/lm3533-als.c
+++ b/drivers/iio/light/lm3533-als.c
@@ -754,7 +754,7 @@ static int lm3533_als_set_resistor(struct lm3533_als *als, u8 val)
 }
 
 static int lm3533_als_setup(struct lm3533_als *als,
-			    struct lm3533_als_platform_data *pdata)
+			    const struct lm3533_als_platform_data *pdata)
 {
 	int ret;
 
@@ -828,8 +828,8 @@ static const struct iio_info lm3533_als_info = {
 
 static int lm3533_als_probe(struct platform_device *pdev)
 {
+	const struct lm3533_als_platform_data *pdata;
 	struct lm3533 *lm3533;
-	struct lm3533_als_platform_data *pdata;
 	struct lm3533_als *als;
 	struct iio_dev *indio_dev;
 	int ret;
@@ -838,7 +838,7 @@ static int lm3533_als_probe(struct platform_device *pdev)
 	if (!lm3533)
 		return -EINVAL;
 
-	pdata = pdev->dev.platform_data;
+	pdata = dev_get_platdata(&pdev->dev);
 	if (!pdata) {
 		dev_err(&pdev->dev, "no platform data\n");
 		return -EINVAL;
-- 
2.46.0


^ permalink raw reply related

* [PATCH v1 02/22] iio: adc: ad7266: Get platform data via dev_get_platdata()
From: Andy Shevchenko @ 2024-09-02 22:16 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Andy Shevchenko,
	Michael Hennerich, Antoniu Miclaus, Jinjie Ruan, Lorenzo Bianconi,
	Srinivas Pandruvada, Basavaraj Natikar, linux-input, linux-iio,
	linux-kernel
  Cc: Jiri Kosina, Jonathan Cameron, Lars-Peter Clausen,
	Michael Hennerich, Andy Shevchenko
In-Reply-To: <20240902222824.1145571-1-andy.shevchenko@gmail.com>

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Access to platform data via dev_get_platdata() getter to make code cleaner.

Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/iio/adc/ad7266.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c
index 7949b076fb87..858c8be2ff1a 100644
--- a/drivers/iio/adc/ad7266.c
+++ b/drivers/iio/adc/ad7266.c
@@ -383,7 +383,7 @@ static const char * const ad7266_gpio_labels[] = {
 
 static int ad7266_probe(struct spi_device *spi)
 {
-	struct ad7266_platform_data *pdata = spi->dev.platform_data;
+	const struct ad7266_platform_data *pdata = dev_get_platdata(&spi->dev);
 	struct iio_dev *indio_dev;
 	struct ad7266_state *st;
 	unsigned int i;
-- 
2.46.0


^ permalink raw reply related

* [PATCH v1 12/22] iio: frequency: adf4350: Get platform data via dev_get_platdata()
From: Andy Shevchenko @ 2024-09-02 22:16 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Andy Shevchenko,
	Michael Hennerich, Antoniu Miclaus, Jinjie Ruan, Lorenzo Bianconi,
	Srinivas Pandruvada, Basavaraj Natikar, linux-input, linux-iio,
	linux-kernel
  Cc: Jiri Kosina, Jonathan Cameron, Lars-Peter Clausen,
	Michael Hennerich, Andy Shevchenko
In-Reply-To: <20240902222824.1145571-1-andy.shevchenko@gmail.com>

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Access to platform data via dev_get_platdata() getter to make code cleaner.

Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/iio/frequency/adf4350.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c
index e13e64a5164c..61828e61e275 100644
--- a/drivers/iio/frequency/adf4350.c
+++ b/drivers/iio/frequency/adf4350.c
@@ -603,7 +603,7 @@ static int adf4350_probe(struct spi_device *spi)
 		if (pdata == NULL)
 			return -EINVAL;
 	} else {
-		pdata = spi->dev.platform_data;
+		pdata = dev_get_platdata(&spi->dev);
 	}
 
 	if (!pdata) {
-- 
2.46.0


^ permalink raw reply related

* [PATCH v1 01/22] iio: accel: hid-sensor-accel-3d: Get platform data via dev_get_platdata()
From: Andy Shevchenko @ 2024-09-02 22:16 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Andy Shevchenko,
	Michael Hennerich, Antoniu Miclaus, Jinjie Ruan, Lorenzo Bianconi,
	Srinivas Pandruvada, Basavaraj Natikar, linux-input, linux-iio,
	linux-kernel
  Cc: Jiri Kosina, Jonathan Cameron, Lars-Peter Clausen,
	Michael Hennerich, Andy Shevchenko
In-Reply-To: <20240902222824.1145571-1-andy.shevchenko@gmail.com>

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Access to platform data via dev_get_platdata() getter to make code cleaner.

Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/iio/accel/hid-sensor-accel-3d.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index 9b7a73a4c48a..caa183637422 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -328,6 +328,7 @@ static int accel_3d_parse_report(struct platform_device *pdev,
 /* Function to initialize the processing for usage id */
 static int hid_accel_3d_probe(struct platform_device *pdev)
 {
+	struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
 	int ret = 0;
 	const char *name;
 	struct iio_dev *indio_dev;
@@ -335,8 +336,6 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
 	const struct iio_chan_spec *channel_spec;
 	int channel_size;
 
-	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
-
 	indio_dev = devm_iio_device_alloc(&pdev->dev,
 					  sizeof(struct accel_3d_state));
 	if (indio_dev == NULL)
@@ -424,7 +423,7 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
 /* Function to deinitialize the processing for usage id */
 static void hid_accel_3d_remove(struct platform_device *pdev)
 {
-	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
+	struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct accel_3d_state *accel_state = iio_priv(indio_dev);
 
-- 
2.46.0


^ permalink raw reply related

* [PATCH v1 00/22] iio: use dev_get_platdata() to access platform_data
From: Andy Shevchenko @ 2024-09-02 22:16 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Andy Shevchenko,
	Michael Hennerich, Antoniu Miclaus, Jinjie Ruan, Lorenzo Bianconi,
	Srinivas Pandruvada, Basavaraj Natikar, linux-input, linux-iio,
	linux-kernel
  Cc: Jiri Kosina, Jonathan Cameron, Lars-Peter Clausen,
	Michael Hennerich, Andy Shevchenko

Unify how IIO drivers access platform_data field of struct device.
In simple and straightforward cases constify the local variables.

(Not tested)

Andy Shevchenko (22):
  iio: accel: hid-sensor-accel-3d: Get platform data via
    dev_get_platdata()
  iio: adc: ad7266: Get platform data via dev_get_platdata()
  iio: adc: ad7791: Get platform data via dev_get_platdata()
  iio: adc: ad7887: Get platform data via dev_get_platdata()
  iio: adc: ad7793: Get platform data via dev_get_platdata()
  iio: adc: ltc2497: Get platform data via dev_get_platdata()
  iio: dac: ad5504: Get platform data via dev_get_platdata()
  iio: dac: ad5791: Get platform data via dev_get_platdata()
  iio: dac: m62332: Get platform data via dev_get_platdata()
  iio: dac: max517: Get platform data via dev_get_platdata()
  iio: frequency: ad9523: Get platform data via dev_get_platdata()
  iio: frequency: adf4350: Get platform data via dev_get_platdata()
  iio: gyro: hid-sensor-gyro-3d: Get platform data via
    dev_get_platdata()
  iio: imu: st_lsm6dsx: Get platform data via dev_get_platdata()
  iio: light: hid-sensor-als: Get platform data via dev_get_platdata()
  iio: light: hid-sensor-prox: Get platform data via dev_get_platdata()
  iio: light: lm3533-als: Get platform data via dev_get_platdata()
  iio: magnetometer: hid-sensor-magn-3d: Get platform data via
    dev_get_platdata()
  iio: orientation: hid-sensor-incl-3d: Get platform data via
    dev_get_platdata()
  iio: orientation: hid-sensor-rotation: Get platform data via
    dev_get_platdata()
  iio: position: hid-sensor-custom-intel-hinge: Get platform data via
    dev_get_platdata()
  iio: pressure: hid-sensor-press: Get platform data via
    dev_get_platdata()

 drivers/iio/accel/hid-sensor-accel-3d.c           |  5 ++---
 drivers/iio/adc/ad7266.c                          |  2 +-
 drivers/iio/adc/ad7791.c                          |  4 ++--
 drivers/iio/adc/ad7793.c                          |  2 +-
 drivers/iio/adc/ad7887.c                          |  2 +-
 drivers/iio/adc/ltc2497-core.c                    | 15 +++++----------
 drivers/iio/dac/ad5504.c                          |  2 +-
 drivers/iio/dac/ad5791.c                          |  2 +-
 drivers/iio/dac/m62332.c                          |  2 +-
 drivers/iio/dac/max517.c                          |  4 ++--
 drivers/iio/frequency/ad9523.c                    |  2 +-
 drivers/iio/frequency/adf4350.c                   |  2 +-
 drivers/iio/gyro/hid-sensor-gyro-3d.c             |  4 ++--
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c      | 15 +++++----------
 drivers/iio/light/hid-sensor-als.c                |  4 ++--
 drivers/iio/light/hid-sensor-prox.c               |  4 ++--
 drivers/iio/light/lm3533-als.c                    |  6 +++---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c     |  4 ++--
 drivers/iio/orientation/hid-sensor-incl-3d.c      |  4 ++--
 drivers/iio/orientation/hid-sensor-rotation.c     |  4 ++--
 .../iio/position/hid-sensor-custom-intel-hinge.c  |  4 ++--
 drivers/iio/pressure/hid-sensor-press.c           |  4 ++--
 22 files changed, 43 insertions(+), 54 deletions(-)

-- 
2.46.0


^ permalink raw reply

* [PATCH v1 10/22] iio: dac: max517: Get platform data via dev_get_platdata()
From: Andy Shevchenko @ 2024-09-02 22:16 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Andy Shevchenko,
	Michael Hennerich, Antoniu Miclaus, Jinjie Ruan, Lorenzo Bianconi,
	Srinivas Pandruvada, Basavaraj Natikar, linux-input, linux-iio,
	linux-kernel
  Cc: Jiri Kosina, Jonathan Cameron, Lars-Peter Clausen,
	Michael Hennerich, Andy Shevchenko
In-Reply-To: <20240902222824.1145571-1-andy.shevchenko@gmail.com>

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Access to platform data via dev_get_platdata() getter to make code cleaner.

Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/iio/dac/max517.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c
index 685980184d3c..96781ae04f9d 100644
--- a/drivers/iio/dac/max517.c
+++ b/drivers/iio/dac/max517.c
@@ -143,10 +143,10 @@ static const struct iio_chan_spec max517_channels[] = {
 
 static int max517_probe(struct i2c_client *client)
 {
+	const struct max517_platform_data *platform_data = dev_get_platdata(&client->dev);
 	const struct i2c_device_id *id = i2c_client_get_device_id(client);
 	struct max517_data *data;
 	struct iio_dev *indio_dev;
-	struct max517_platform_data *platform_data = client->dev.platform_data;
 	int chan;
 
 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
@@ -176,7 +176,7 @@ static int max517_probe(struct i2c_client *client)
 
 	/*
 	 * Reference voltage on MAX518 and default is 5V, else take vref_mv
-	 * from platform_data
+	 * from platform_data.
 	 */
 	for (chan = 0; chan < indio_dev->num_channels; chan++) {
 		if (id->driver_data == ID_MAX518 || !platform_data)
-- 
2.46.0


^ permalink raw reply related

* [PATCH v1 05/22] iio: adc: ad7793: Get platform data via dev_get_platdata()
From: Andy Shevchenko @ 2024-09-02 22:16 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Andy Shevchenko,
	Michael Hennerich, Antoniu Miclaus, Jinjie Ruan, Lorenzo Bianconi,
	Srinivas Pandruvada, Basavaraj Natikar, linux-input, linux-iio,
	linux-kernel
  Cc: Jiri Kosina, Jonathan Cameron, Lars-Peter Clausen,
	Michael Hennerich, Andy Shevchenko
In-Reply-To: <20240902222824.1145571-1-andy.shevchenko@gmail.com>

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Access to platform data via dev_get_platdata() getter to make code cleaner.

Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/iio/adc/ad7793.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c
index abebd519cafa..b86e89370e0d 100644
--- a/drivers/iio/adc/ad7793.c
+++ b/drivers/iio/adc/ad7793.c
@@ -770,7 +770,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
 
 static int ad7793_probe(struct spi_device *spi)
 {
-	const struct ad7793_platform_data *pdata = spi->dev.platform_data;
+	const struct ad7793_platform_data *pdata = dev_get_platdata(&spi->dev);
 	struct ad7793_state *st;
 	struct iio_dev *indio_dev;
 	int ret, vref_mv = 0;
-- 
2.46.0


^ permalink raw reply related

* [PATCH HID 7/7] selftests/hid: add test to disable hid-input
From: Benjamin Tissoires @ 2024-09-02 16:14 UTC (permalink / raw)
  To: Jiri Kosina, Peter Hutterer, Vicki Pfau, Shuah Khan,
	Jonathan Corbet
  Cc: linux-input, linux-kselftest, linux-kernel, bpf, linux-doc,
	Benjamin Tissoires
In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org>

Add a test for the newly enabled feature to control the connect_mask
of hid-generic.

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 tools/testing/selftests/hid/hid_bpf.c              | 60 +++++++++++++++++++++-
 tools/testing/selftests/hid/progs/hid.c            |  6 ++-
 .../testing/selftests/hid/progs/hid_bpf_helpers.h  |  2 +
 3 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c
index edc061b38528..41cacc30ef8b 100644
--- a/tools/testing/selftests/hid/hid_bpf.c
+++ b/tools/testing/selftests/hid/hid_bpf.c
@@ -4,6 +4,38 @@
 #include "hid_common.h"
 #include <bpf/bpf.h>
 
+static const __u8 mouse_rdesc[] = {
+	0x05, 0x01,  /* .Usage Page (Generic Desktop)        0  */
+	0x09, 0x02,  /* .Usage (Mouse)                       2  */
+	0xa1, 0x01,  /* .Collection (Application)            4  */
+	0x09, 0x02,  /* ..Usage (Mouse)                      6  */
+	0xa1, 0x02,  /* ..Collection (Logical)               8  */
+	0x09, 0x01,  /* ...Usage (Pointer)                   10 */
+	0xa1, 0x00,  /* ...Collection (Physical)             12 */
+	0x05, 0x09,  /* ....Usage Page (Button)              14 */
+	0x19, 0x01,  /* ....Usage Minimum (1)                16 */
+	0x29, 0x03,  /* ....Usage Maximum (3)                18 */
+	0x15, 0x00,  /* ....Logical Minimum (0)              20 */
+	0x25, 0x01,  /* ....Logical Maximum (1)              22 */
+	0x75, 0x01,  /* ....Report Size (1)                  24 */
+	0x95, 0x03,  /* ....Report Count (3)                 26 */
+	0x81, 0x02,  /* ....Input (Data,Var,Abs)             28 */
+	0x75, 0x05,  /* ....Report Size (5)                  30 */
+	0x95, 0x01,  /* ....Report Count (1)                 32 */
+	0x81, 0x03,  /* ....Input (Cnst,Var,Abs)             34 */
+	0x05, 0x01,  /* ....Usage Page (Generic Desktop)     36 */
+	0x09, 0x30,  /* ....Usage (X)                        38 */
+	0x09, 0x31,  /* ....Usage (Y)                        40 */
+	0x15, 0x81,  /* ....Logical Minimum (-127)           42 */
+	0x25, 0x7f,  /* ....Logical Maximum (127)            44 */
+	0x75, 0x08,  /* ....Report Size (8)                  46 */
+	0x95, 0x02,  /* ....Report Count (2)                 48 */
+	0x81, 0x06,  /* ....Input (Data,Var,Rel)             50 */
+	0xc0,        /* ...End Collection                    52 */
+	0xc0,        /* ..End Collection                     53 */
+	0xc0,        /* .End Collection                      54 */
+};
+
 struct hid_hw_request_syscall_args {
 	__u8 data[10];
 	unsigned int hid;
@@ -59,6 +91,8 @@ struct specific_device {
 	__u16 bus;
 	__u32 vid;
 	__u32 pid;
+	const __u8 *rdesc;
+	const size_t rdesc_size;
 };
 
 FIXTURE_SETUP(hid_bpf)
@@ -72,11 +106,15 @@ FIXTURE_SETUP(hid_bpf)
 		.bus = BUS_BLUETOOTH,
 		.vid = 0x05ac,  /* USB_VENDOR_ID_APPLE */
 		.pid = 0x022c,  /* USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI */
+		.rdesc = mouse_rdesc,
+		.rdesc_size = sizeof(mouse_rdesc),
 	}, {
 		.test_name = "*",
 		.bus = BUS_USB,
 		.vid = 0x0001,
 		.pid = 0x0a36,
+		.rdesc = rdesc,
+		.rdesc_size = sizeof(rdesc),
 	}};
 
 	for (int i = 0; i < ARRAY_SIZE(devices); i++) {
@@ -88,7 +126,7 @@ FIXTURE_SETUP(hid_bpf)
 	ASSERT_OK_PTR(match);
 
 	err = setup_uhid(_metadata, &self->hid, match->bus, match->vid, match->pid,
-			 rdesc, sizeof(rdesc));
+			 match->rdesc, match->rdesc_size);
 	ASSERT_OK(err);
 }
 
@@ -914,6 +952,24 @@ static bool is_using_driver(struct __test_metadata *_metadata, struct uhid_devic
 	return found;
 }
 
+static bool has_hid_input(struct uhid_device *hid)
+{
+	char input[1024];
+	DIR *d;
+
+	sprintf(input, "/sys/bus/hid/devices/%04X:%04X:%04X.%04X/input",
+		hid->bus, hid->vid, hid->pid, hid->hid_id);
+
+	d = opendir(input);
+	if (d) {
+		closedir(d);
+
+		return true;
+	}
+
+	return false;
+}
+
 /*
  * Attach hid_driver_probe to the given uhid device,
  * check that the device is now using hid-generic.
@@ -927,10 +983,12 @@ TEST_F(hid_bpf, test_hid_driver_probe)
 	};
 
 	ASSERT_TRUE(is_using_driver(_metadata, &self->hid, "apple"));
+	ASSERT_TRUE(has_hid_input(&self->hid)) TH_LOG("input node not found");
 
 	LOAD_PROGRAMS(progs);
 
 	ASSERT_TRUE(is_using_driver(_metadata, &self->hid, "hid-generic"));
+	ASSERT_FALSE(has_hid_input(&self->hid)) TH_LOG("input node unexpectly found");
 }
 
 /*
diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selftests/hid/progs/hid.c
index 883d09498351..c81d5eb18211 100644
--- a/tools/testing/selftests/hid/progs/hid.c
+++ b/tools/testing/selftests/hid/progs/hid.c
@@ -606,10 +606,12 @@ void BPF_PROG(hid_test_driver_probe, struct hid_device *hdev, struct hid_bpf_dri
 	static const char hid_generic[] = "hid-generic";
 
 	bpf_printk("test_driver_probe, %s", hdrv->name);
-	if (!__builtin_memcmp(hdrv->name, hid_generic, sizeof(hid_generic)))
+	if (!__builtin_memcmp(hdrv->name, hid_generic, sizeof(hid_generic))) {
 		hdrv->force_driver = 1;
-	else
+		id->driver_data &= ~HID_CONNECT_INPUT;
+	} else {
 		hdrv->ignore_driver = 1;
+	}
 }
 
 SEC("?struct_ops.s/hid_rdesc_fixup")
diff --git a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h
index 6b0f870d0727..9447233d7a3d 100644
--- a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h
+++ b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h
@@ -90,6 +90,8 @@ struct hid_bpf_ops {
 #define BPF_F_BEFORE (1U << 3)
 #endif
 
+#define HID_CONNECT_INPUT (1U << 0)
+
 /* following are kfuncs exported by HID for HID-BPF */
 extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx,
 			      unsigned int offset,

-- 
2.46.0


^ permalink raw reply related

* [PATCH HID 6/7] HID: bpf: Allow to control the connect mask of hid-generic from BPF
From: Benjamin Tissoires @ 2024-09-02 16:14 UTC (permalink / raw)
  To: Jiri Kosina, Peter Hutterer, Vicki Pfau, Shuah Khan,
	Jonathan Corbet
  Cc: linux-input, linux-kselftest, linux-kernel, bpf, linux-doc,
	Benjamin Tissoires
In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org>

We make struct hid_device_id writeable and use the .driver_data field
of hid-generic as the connect mask.

This way, we can control from a HID-BPF program if a device needs to
be exported through hidraw and/or hid-input mainly.

This is useful in case we want to have a third party program that directly
talks to the hidraw node and we don't want regular input events to be
emitted. This third party program can load a BPF program that instructs
hid-generic to rebind on the device with hidraw only and then open the
hidraw node itself.

When the application is closed, the BPF program is unloaded and the normal
driver takes back the control of the device.

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/bpf/hid_bpf_struct_ops.c |  1 +
 drivers/hid/hid-core.c               | 14 ++++++++------
 drivers/hid/hid-generic.c            |  5 +++--
 3 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf_struct_ops.c
index 1e13a22f73a1..bb755edd02f0 100644
--- a/drivers/hid/bpf/hid_bpf_struct_ops.c
+++ b/drivers/hid/bpf/hid_bpf_struct_ops.c
@@ -80,6 +80,7 @@ static int hid_bpf_ops_btf_struct_access(struct bpf_verifier_log *log,
 		WRITE_RANGE(hid_device, name, true),
 		WRITE_RANGE(hid_device, uniq, true),
 		WRITE_RANGE(hid_device, phys, true),
+		WRITE_RANGE(hid_device_id, driver_data, false),
 		WRITE_RANGE(hid_bpf_driver, force_driver, false),
 		WRITE_RANGE(hid_bpf_driver, ignore_driver, false),
 	};
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 7845f0a789ec..2bd279b23aa4 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2637,15 +2637,17 @@ EXPORT_SYMBOL_GPL(hid_compare_device_paths);
 
 static bool hid_check_device_match(struct hid_device *hdev,
 				   struct hid_driver *hdrv,
-				   const struct hid_device_id **id)
+				   struct hid_device_id *id)
 {
+	const struct hid_device_id *_id = hid_match_device(hdev, hdrv);
 	int ret;
 
-	*id = hid_match_device(hdev, hdrv);
-	if (!*id)
+	if (!_id)
 		return false;
 
-	ret = call_hid_bpf_driver_probe(hdev, hdrv, *id);
+	memcpy(id, _id, sizeof(*id));
+
+	ret = call_hid_bpf_driver_probe(hdev, hdrv, id);
 	if (ret)
 		return ret > 0;
 
@@ -2662,7 +2664,7 @@ static bool hid_check_device_match(struct hid_device *hdev,
 
 static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv)
 {
-	const struct hid_device_id *id;
+	struct hid_device_id id;
 	int ret;
 
 	if (!hid_check_device_match(hdev, hdrv, &id))
@@ -2677,7 +2679,7 @@ static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv)
 	hdev->driver = hdrv;
 
 	if (hdrv->probe) {
-		ret = hdrv->probe(hdev, id);
+		ret = hdrv->probe(hdev, &id);
 	} else { /* default probe */
 		ret = hid_open_report(hdev);
 		if (!ret)
diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c
index f9db991d3c5a..5cd1f3a79a4b 100644
--- a/drivers/hid/hid-generic.c
+++ b/drivers/hid/hid-generic.c
@@ -64,11 +64,12 @@ static int hid_generic_probe(struct hid_device *hdev,
 	if (ret)
 		return ret;
 
-	return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+	return hid_hw_start(hdev, id->driver_data);
 }
 
 static const struct hid_device_id hid_table[] = {
-	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, HID_ANY_ID, HID_ANY_ID) },
+	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, HID_ANY_ID, HID_ANY_ID),
+		.driver_data = HID_CONNECT_DEFAULT },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, hid_table);

-- 
2.46.0


^ permalink raw reply related

* [PATCH HID 5/7] selftests/hid: add test for assigning a given device to hid-generic
From: Benjamin Tissoires @ 2024-09-02 16:14 UTC (permalink / raw)
  To: Jiri Kosina, Peter Hutterer, Vicki Pfau, Shuah Khan,
	Jonathan Corbet
  Cc: linux-input, linux-kselftest, linux-kernel, bpf, linux-doc,
	Benjamin Tissoires
In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org>

We use a well known VID/PID on a driver that doesn't need to talk to
the device, ensures we created the device against the target driver,
then load our program and ensure we have unbound to this driver and use
hid-generic instead.

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 tools/testing/selftests/hid/hid_bpf.c              | 80 +++++++++++++++++++++-
 tools/testing/selftests/hid/progs/hid.c            | 29 ++++++++
 .../testing/selftests/hid/progs/hid_bpf_helpers.h  |  2 +
 3 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c
index 7eb15da62bdc..edc061b38528 100644
--- a/tools/testing/selftests/hid/hid_bpf.c
+++ b/tools/testing/selftests/hid/hid_bpf.c
@@ -54,11 +54,41 @@ FIXTURE_TEARDOWN(hid_bpf) {
 	hid_bpf_teardown(_metadata, self, variant); \
 } while (0)
 
+struct specific_device {
+	const char test_name[64];
+	__u16 bus;
+	__u32 vid;
+	__u32 pid;
+};
+
 FIXTURE_SETUP(hid_bpf)
 {
+	const struct specific_device *match = NULL;
 	int err;
 
-	err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a36, rdesc, sizeof(rdesc));
+	const struct specific_device devices[] = {
+	{
+		.test_name = "test_hid_driver_probe",
+		.bus = BUS_BLUETOOTH,
+		.vid = 0x05ac,  /* USB_VENDOR_ID_APPLE */
+		.pid = 0x022c,  /* USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI */
+	}, {
+		.test_name = "*",
+		.bus = BUS_USB,
+		.vid = 0x0001,
+		.pid = 0x0a36,
+	}};
+
+	for (int i = 0; i < ARRAY_SIZE(devices); i++) {
+		match = &devices[i];
+		if (!strncmp(_metadata->name, devices[i].test_name, sizeof(devices[i].test_name)))
+			break;
+	}
+
+	ASSERT_OK_PTR(match);
+
+	err = setup_uhid(_metadata, &self->hid, match->bus, match->vid, match->pid,
+			 rdesc, sizeof(rdesc));
 	ASSERT_OK(err);
 }
 
@@ -855,6 +885,54 @@ TEST_F(hid_bpf, test_hid_attach_flags)
 	ASSERT_EQ(buf[3], 3);
 }
 
+static bool is_using_driver(struct __test_metadata *_metadata, struct uhid_device *hid,
+			    const char *driver)
+{
+	char driver_line[512];
+	char uevent[1024];
+	char temp[512];
+	int fd, nread;
+	bool found = false;
+
+	sprintf(uevent, "/sys/bus/hid/devices/%04X:%04X:%04X.%04X/uevent",
+		hid->bus, hid->vid, hid->pid, hid->hid_id);
+
+	fd = open(uevent, O_RDONLY | O_NONBLOCK);
+	if (fd < 0) {
+		TH_LOG("couldn't open '%s': %d, %d", uevent, fd, errno);
+		return false;
+	}
+
+	sprintf(driver_line, "DRIVER=%s", driver);
+
+	nread = read(fd, temp, ARRAY_SIZE(temp));
+	if (nread > 0 && (strstr(temp, driver_line)) != NULL)
+		found = true;
+
+	close(fd);
+
+	return found;
+}
+
+/*
+ * Attach hid_driver_probe to the given uhid device,
+ * check that the device is now using hid-generic.
+ */
+TEST_F(hid_bpf, test_hid_driver_probe)
+{
+	const struct test_program progs[] = {
+		{
+			.name = "hid_test_driver_probe",
+		},
+	};
+
+	ASSERT_TRUE(is_using_driver(_metadata, &self->hid, "apple"));
+
+	LOAD_PROGRAMS(progs);
+
+	ASSERT_TRUE(is_using_driver(_metadata, &self->hid, "hid-generic"));
+}
+
 /*
  * Attach hid_rdesc_fixup to the given uhid device,
  * retrieve and open the matching hidraw node,
diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selftests/hid/progs/hid.c
index 5ecc845ef792..883d09498351 100644
--- a/tools/testing/selftests/hid/progs/hid.c
+++ b/tools/testing/selftests/hid/progs/hid.c
@@ -598,3 +598,32 @@ SEC(".struct_ops.link")
 struct hid_bpf_ops test_infinite_loop_input_report = {
 	.hid_device_event = (void *)hid_test_infinite_loop_input_report,
 };
+
+SEC("?struct_ops/hid_driver_probe")
+void BPF_PROG(hid_test_driver_probe, struct hid_device *hdev, struct hid_bpf_driver *hdrv,
+				     struct hid_device_id *id)
+{
+	static const char hid_generic[] = "hid-generic";
+
+	bpf_printk("test_driver_probe, %s", hdrv->name);
+	if (!__builtin_memcmp(hdrv->name, hid_generic, sizeof(hid_generic)))
+		hdrv->force_driver = 1;
+	else
+		hdrv->ignore_driver = 1;
+}
+
+SEC("?struct_ops.s/hid_rdesc_fixup")
+int BPF_PROG(hid_rdesc_fixup_2, struct hid_bpf_ctx *hid_ctx)
+{
+	/*
+	 * We need an empty report descriptor fixup to force detach/reattach
+	 * the device when we load the BPF program.
+	 */
+	return 0;
+}
+
+SEC(".struct_ops.link")
+struct hid_bpf_ops test_driver_probe = {
+	.hid_driver_probe = (void *)hid_test_driver_probe,
+	.hid_rdesc_fixup = (void *)hid_rdesc_fixup_2,
+};
diff --git a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h
index e5db897586bb..6b0f870d0727 100644
--- a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h
+++ b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h
@@ -81,6 +81,8 @@ struct hid_bpf_ops {
 			       enum hid_report_type rtype, enum hid_class_request reqtype,
 			       u64 source);
 	int (*hid_hw_output_report)(struct hid_bpf_ctx *ctx, u64 source);
+	void (*hid_driver_probe)(struct hid_device *hdev, struct hid_bpf_driver *hdrv,
+				 struct hid_device_id *id);
 	struct hid_device *hdev;
 };
 

-- 
2.46.0


^ permalink raw reply related

* [PATCH HID 4/7] HID: bpf: allow BPF programs to force using hid-generic
From: Benjamin Tissoires @ 2024-09-02 16:14 UTC (permalink / raw)
  To: Jiri Kosina, Peter Hutterer, Vicki Pfau, Shuah Khan,
	Jonathan Corbet
  Cc: linux-input, linux-kselftest, linux-kernel, bpf, linux-doc,
	Benjamin Tissoires
In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org>

The use case is when we fix a device through HID-BPF, 99% of the cases
we want the device to use hid-generic now instead of a dedicated device.

That's because the dedicated device might also want to change the report
descriptor, or will be handling the device in a different way the new
fixed device is using.

In hid-core, after matching for the device (so that we only call this new
hook on compatible drivers), we call for `.hid_bpf_driver_probe`.
The function can not communicate with the device because it is not yet
started, but it can make educated guesses and decide to:
- let hid-core decide by itself
- force the use of this driver (by comparing the provided name with
  "hid-generic" for instance)
- force hid-core to ignore this driver for this device.

For API stability, we don't rely on a bitfield or a return value for
chosing hid-core behavior. We simply have a couple of writeable fields
in the new struct hid_bpf_driver, and then hid-core can make its educated
decision.

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 Documentation/hid/hid-bpf.rst        |  2 +-
 drivers/hid/bpf/hid_bpf_dispatch.c   | 31 ++++++++++++++++++++++++++++
 drivers/hid/bpf/hid_bpf_struct_ops.c |  3 +++
 drivers/hid/hid-core.c               |  6 ++++++
 include/linux/hid_bpf.h              | 40 ++++++++++++++++++++++++++++++++++++
 5 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/Documentation/hid/hid-bpf.rst b/Documentation/hid/hid-bpf.rst
index 5939eeafb361..05a43f11cdab 100644
--- a/Documentation/hid/hid-bpf.rst
+++ b/Documentation/hid/hid-bpf.rst
@@ -190,7 +190,7 @@ User API data structures available in programs:
 -----------------------------------------------
 
 .. kernel-doc:: include/linux/hid_bpf.h
-   :identifiers: hid_bpf_ctx
+   :identifiers: hid_bpf_ctx hid_bpf_driver
 
 Available API that can be used in all HID-BPF struct_ops programs:
 ------------------------------------------------------------------
diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index a272a086c950..2df136d64152 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -189,6 +189,37 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *s
 }
 EXPORT_SYMBOL_GPL(call_hid_bpf_rdesc_fixup);
 
+int call_hid_bpf_driver_probe(struct hid_device *hdev, struct hid_driver *hdrv,
+			      const struct hid_device_id *id)
+{
+	struct hid_bpf_driver drv = { 0 };
+	struct hid_bpf_ops *e;
+	int idx;
+
+	if (strscpy(drv.name, hdrv->name, sizeof(drv.name)) < 0)
+		return 0;
+
+	idx = srcu_read_lock(&hdev->bpf.srcu);
+	list_for_each_entry_srcu(e, &hdev->bpf.prog_list, list,
+				 srcu_read_lock_held(&hdev->bpf.srcu)) {
+		if (!e->hid_driver_probe)
+			continue;
+
+		e->hid_driver_probe(hdev, &drv, id);
+	}
+
+	srcu_read_unlock(&hdev->bpf.srcu, idx);
+
+	if (drv.force_driver)
+		return 1;
+
+	if (drv.ignore_driver)
+		return -1;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(call_hid_bpf_driver_probe);
+
 static int device_match_id(struct device *dev, const void *id)
 {
 	struct hid_device *hdev = to_hid_device(dev);
diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf_struct_ops.c
index cd696c59ba0f..1e13a22f73a1 100644
--- a/drivers/hid/bpf/hid_bpf_struct_ops.c
+++ b/drivers/hid/bpf/hid_bpf_struct_ops.c
@@ -46,6 +46,7 @@ static int hid_bpf_ops_check_member(const struct btf_type *t,
 	case offsetof(struct hid_bpf_ops, hid_rdesc_fixup):
 	case offsetof(struct hid_bpf_ops, hid_hw_request):
 	case offsetof(struct hid_bpf_ops, hid_hw_output_report):
+	case offsetof(struct hid_bpf_ops, hid_driver_probe):
 		break;
 	default:
 		if (prog->sleepable)
@@ -79,6 +80,8 @@ static int hid_bpf_ops_btf_struct_access(struct bpf_verifier_log *log,
 		WRITE_RANGE(hid_device, name, true),
 		WRITE_RANGE(hid_device, uniq, true),
 		WRITE_RANGE(hid_device, phys, true),
+		WRITE_RANGE(hid_bpf_driver, force_driver, false),
+		WRITE_RANGE(hid_bpf_driver, ignore_driver, false),
 	};
 #undef WRITE_RANGE
 	const struct btf_type *state = NULL;
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 988d0acbdf04..7845f0a789ec 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2639,10 +2639,16 @@ static bool hid_check_device_match(struct hid_device *hdev,
 				   struct hid_driver *hdrv,
 				   const struct hid_device_id **id)
 {
+	int ret;
+
 	*id = hid_match_device(hdev, hdrv);
 	if (!*id)
 		return false;
 
+	ret = call_hid_bpf_driver_probe(hdev, hdrv, *id);
+	if (ret)
+		return ret > 0;
+
 	if (hdrv->match)
 		return hdrv->match(hdev, hid_ignore_special_drivers);
 
diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h
index d4d063cf63b5..20693c218857 100644
--- a/include/linux/hid_bpf.h
+++ b/include/linux/hid_bpf.h
@@ -9,6 +9,7 @@
 #include <uapi/linux/hid.h>
 
 struct hid_device;
+struct hid_driver;
 
 /*
  * The following is the user facing HID BPF API.
@@ -80,6 +81,22 @@ struct hid_ops {
 
 extern struct hid_ops *hid_ops;
 
+/**
+ * struct hid_bpf_driver - User accessible data for the ``hid_bpf_probe``
+ * struct_ops
+ *
+ * @name: the name of the driver currently being treated
+ * @force_driver: set this to ``true`` to force hid-core to use this driver,
+ *		  bypassing any further decision made by this driver
+ * @ignore_driver: set this to ``true`` to force hid-core to ignore this driver,
+ *                bypassing any further decision made by this driver
+ */
+struct hid_bpf_driver {
+	__u8 name[64];
+	bool force_driver;
+	bool ignore_driver;
+};
+
 /**
  * struct hid_bpf_ops - A BPF struct_ops of callbacks allowing to attach HID-BPF
  *			programs to a HID device
@@ -178,6 +195,25 @@ struct hid_bpf_ops {
 	 */
 	int (*hid_hw_output_report)(struct hid_bpf_ctx *ctx, u64 source);
 
+	/**
+	 * @hid_driver_probe: called before the kernel ``.probe()`` function
+	 *
+	 * It has the following arguments:
+	 *
+	 * ``hdev``: The HID device kernel representation
+	 *
+	 * ``hdrv``: A BPF partially writeable representation of a HID driver
+	 *
+	 * ``id``: The device match structure found in the driver
+	 *
+	 * Note that the device has not been started yet, and thus kfuncs like
+	 * ``hid_hw_output_report`` will likely fail.
+	 *
+	 * This function is useful to force/ignore a given supported HID driver,
+	 * by writing ``true`` in ``hdrv->force_driver`` or ``hdrv->ignore_driver``
+	 */
+	void (*hid_driver_probe)(struct hid_device *hdev, struct hid_bpf_driver *hdrv,
+				 const struct hid_device_id *id);
 
 	/* private: do not show up in the docs */
 	struct hid_device *hdev;
@@ -213,6 +249,8 @@ void hid_bpf_disconnect_device(struct hid_device *hdev);
 void hid_bpf_destroy_device(struct hid_device *hid);
 int hid_bpf_device_init(struct hid_device *hid);
 u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *size);
+int call_hid_bpf_driver_probe(struct hid_device *hdev, struct hid_driver *hdrv,
+			      const struct hid_device_id *id);
 #else /* CONFIG_HID_BPF */
 static inline u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_type type,
 						u8 *data, u32 *size, int interrupt,
@@ -228,6 +266,8 @@ static inline int hid_bpf_connect_device(struct hid_device *hdev) { return 0; }
 static inline void hid_bpf_disconnect_device(struct hid_device *hdev) {}
 static inline void hid_bpf_destroy_device(struct hid_device *hid) {}
 static inline int hid_bpf_device_init(struct hid_device *hid) { return 0; }
+static inline int call_hid_bpf_driver_probe(struct hid_device *hdev, struct hid_driver *hdrv,
+					    const struct hid_device_id *id) { return 0; }
 /*
  * This specialized allocator has to be a macro for its allocations to be
  * accounted separately (to have a separate alloc_tag). The typecast is

-- 
2.46.0


^ permalink raw reply related

* [PATCH HID 3/7] selftests/hid: allow to parametrize bus/vid/pid/rdesc on the test device
From: Benjamin Tissoires @ 2024-09-02 16:14 UTC (permalink / raw)
  To: Jiri Kosina, Peter Hutterer, Vicki Pfau, Shuah Khan,
	Jonathan Corbet
  Cc: linux-input, linux-kselftest, linux-kernel, bpf, linux-doc,
	Benjamin Tissoires
In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org>

This will be useful to introduce variants in tests to test the
interactions between HID-BPF and some kernel modules.

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 tools/testing/selftests/hid/hid_bpf.c    |  2 +-
 tools/testing/selftests/hid/hid_common.h | 46 ++++++++++++++++++++------------
 tools/testing/selftests/hid/hidraw.c     |  2 +-
 3 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c
index 17ccbf5ff4b5..7eb15da62bdc 100644
--- a/tools/testing/selftests/hid/hid_bpf.c
+++ b/tools/testing/selftests/hid/hid_bpf.c
@@ -58,7 +58,7 @@ FIXTURE_SETUP(hid_bpf)
 {
 	int err;
 
-	err = setup_uhid(_metadata, &self->hid);
+	err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a36, rdesc, sizeof(rdesc));
 	ASSERT_OK(err);
 }
 
diff --git a/tools/testing/selftests/hid/hid_common.h b/tools/testing/selftests/hid/hid_common.h
index a7d836a35bb1..f77f69c6657d 100644
--- a/tools/testing/selftests/hid/hid_common.h
+++ b/tools/testing/selftests/hid/hid_common.h
@@ -23,6 +23,9 @@ struct uhid_device {
 	int dev_id;		/* uniq (random) number to identify the device */
 	int uhid_fd;
 	int hid_id;		/* HID device id in the system */
+	__u16 bus;
+	__u32 vid;
+	__u32 pid;
 	pthread_t tid;		/* thread for reading uhid events */
 };
 
@@ -129,7 +132,9 @@ static int uhid_write(struct __test_metadata *_metadata, int fd, const struct uh
 	}
 }
 
-static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb)
+static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb,
+		       __u16 bus, __u32 vid, __u32 pid, __u8 *rdesc,
+		       size_t rdesc_size)
 {
 	struct uhid_event ev;
 	char buf[25];
@@ -140,10 +145,10 @@ static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb)
 	ev.type = UHID_CREATE;
 	strcpy((char *)ev.u.create.name, buf);
 	ev.u.create.rd_data = rdesc;
-	ev.u.create.rd_size = sizeof(rdesc);
-	ev.u.create.bus = BUS_USB;
-	ev.u.create.vendor = 0x0001;
-	ev.u.create.product = 0x0a37;
+	ev.u.create.rd_size = rdesc_size;
+	ev.u.create.bus = bus;
+	ev.u.create.vendor = vid;
+	ev.u.create.product = pid;
 	ev.u.create.version = 0;
 	ev.u.create.country = 0;
 
@@ -305,15 +310,17 @@ static int uhid_send_event(struct __test_metadata *_metadata, struct uhid_device
 	return uhid_write(_metadata, hid->uhid_fd, &ev);
 }
 
-static bool match_sysfs_device(int dev_id, const char *workdir, struct dirent *dir)
+static bool match_sysfs_device(struct uhid_device *hid, const char *workdir, struct dirent *dir)
 {
-	const char *target = "0003:0001:0A37.*";
+	char target[20] = "";
 	char phys[512];
 	char uevent[1024];
 	char temp[512];
 	int fd, nread;
 	bool found = false;
 
+	snprintf(target, sizeof(target), "%04X:%04X:%04X.*", hid->bus, hid->vid, hid->pid);
+
 	if (fnmatch(target, dir->d_name, 0))
 		return false;
 
@@ -324,7 +331,7 @@ static bool match_sysfs_device(int dev_id, const char *workdir, struct dirent *d
 	if (fd < 0)
 		return false;
 
-	sprintf(phys, "PHYS=%d", dev_id);
+	sprintf(phys, "PHYS=%d", hid->dev_id);
 
 	nread = read(fd, temp, ARRAY_SIZE(temp));
 	if (nread > 0 && (strstr(temp, phys)) != NULL)
@@ -335,7 +342,7 @@ static bool match_sysfs_device(int dev_id, const char *workdir, struct dirent *d
 	return found;
 }
 
-static int get_hid_id(int dev_id)
+static int get_hid_id(struct uhid_device *hid)
 {
 	const char *workdir = "/sys/devices/virtual/misc/uhid";
 	const char *str_id;
@@ -350,10 +357,10 @@ static int get_hid_id(int dev_id)
 		d = opendir(workdir);
 		if (d) {
 			while ((dir = readdir(d)) != NULL) {
-				if (!match_sysfs_device(dev_id, workdir, dir))
+				if (!match_sysfs_device(hid, workdir, dir))
 					continue;
 
-				str_id = dir->d_name + sizeof("0003:0001:0A37.");
+				str_id = dir->d_name + sizeof("0000:0000:0000.");
 				found = (int)strtol(str_id, NULL, 16);
 
 				break;
@@ -367,7 +374,7 @@ static int get_hid_id(int dev_id)
 	return found;
 }
 
-static int get_hidraw(int dev_id)
+static int get_hidraw(struct uhid_device *hid)
 {
 	const char *workdir = "/sys/devices/virtual/misc/uhid";
 	char sysfs[1024];
@@ -384,7 +391,7 @@ static int get_hidraw(int dev_id)
 			continue;
 
 		while ((dir = readdir(d)) != NULL) {
-			if (!match_sysfs_device(dev_id, workdir, dir))
+			if (!match_sysfs_device(hid, workdir, dir))
 				continue;
 
 			sprintf(sysfs, "%s/%s/hidraw", workdir, dir->d_name);
@@ -416,7 +423,7 @@ static int open_hidraw(struct uhid_device *hid)
 	int hidraw_number;
 	char hidraw_path[64] = { 0 };
 
-	hidraw_number = get_hidraw(hid->dev_id);
+	hidraw_number = get_hidraw(hid);
 	if (hidraw_number < 0)
 		return hidraw_number;
 
@@ -425,7 +432,8 @@ static int open_hidraw(struct uhid_device *hid)
 	return open(hidraw_path, O_RDWR | O_NONBLOCK);
 }
 
-static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid)
+static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid,
+		      __u16 bus, __u32 vid, __u32 pid, const __u8 *rdesc, size_t rdesc_size)
 {
 	const char *path = "/dev/uhid";
 	time_t t;
@@ -435,11 +443,15 @@ static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid
 	srand((unsigned int)time(&t));
 
 	hid->dev_id = rand() % 1024;
+	hid->bus = bus;
+	hid->vid = vid;
+	hid->pid = pid;
 
 	hid->uhid_fd = open(path, O_RDWR | O_CLOEXEC);
 	ASSERT_GE(hid->uhid_fd, 0) TH_LOG("open uhid-cdev failed; %d", hid->uhid_fd);
 
-	ret = uhid_create(_metadata, hid->uhid_fd, hid->dev_id);
+	ret = uhid_create(_metadata, hid->uhid_fd, hid->dev_id, bus, vid, pid,
+			  (__u8 *)rdesc, rdesc_size);
 	ASSERT_EQ(0, ret) {
 		TH_LOG("create uhid device failed: %d", ret);
 		close(hid->uhid_fd);
@@ -447,7 +459,7 @@ static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid
 	}
 
 	/* locate the uevent file of the created device */
-	hid->hid_id = get_hid_id(hid->dev_id);
+	hid->hid_id = get_hid_id(hid);
 	ASSERT_GT(hid->hid_id, 0)
 		TH_LOG("Could not locate uhid device id: %d", hid->hid_id);
 
diff --git a/tools/testing/selftests/hid/hidraw.c b/tools/testing/selftests/hid/hidraw.c
index 5934818b2036..821db37ba4bb 100644
--- a/tools/testing/selftests/hid/hidraw.c
+++ b/tools/testing/selftests/hid/hidraw.c
@@ -36,7 +36,7 @@ FIXTURE_SETUP(hidraw)
 {
 	int err;
 
-	err = setup_uhid(_metadata, &self->hid);
+	err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a37, rdesc, sizeof(rdesc));
 	ASSERT_OK(err);
 
 	self->hidraw_fd = open_hidraw(&self->hid);

-- 
2.46.0


^ permalink raw reply related

* [PATCH HID 2/7] selftests/hid: cleanup C tests by adding a common struct uhid_device
From: Benjamin Tissoires @ 2024-09-02 16:14 UTC (permalink / raw)
  To: Jiri Kosina, Peter Hutterer, Vicki Pfau, Shuah Khan,
	Jonathan Corbet
  Cc: linux-input, linux-kselftest, linux-kernel, bpf, linux-doc,
	Benjamin Tissoires
In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org>

Allows to have an abstract class uhid_device which handles all of the
uhid part without having to mess up with individual fds.

struct attach_prog_args is now never used in hid_bpf.c, so drop it as well

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 tools/testing/selftests/hid/hid_bpf.c    | 77 +++++++++++---------------------
 tools/testing/selftests/hid/hid_common.h | 74 ++++++++++++++++++++----------
 tools/testing/selftests/hid/hidraw.c     | 36 +++++----------
 3 files changed, 87 insertions(+), 100 deletions(-)

diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c
index d10cf6883683..17ccbf5ff4b5 100644
--- a/tools/testing/selftests/hid/hid_bpf.c
+++ b/tools/testing/selftests/hid/hid_bpf.c
@@ -4,13 +4,6 @@
 #include "hid_common.h"
 #include <bpf/bpf.h>
 
-struct attach_prog_args {
-	int prog_fd;
-	unsigned int hid;
-	int retval;
-	int insert_head;
-};
-
 struct hid_hw_request_syscall_args {
 	__u8 data[10];
 	unsigned int hid;
@@ -21,11 +14,8 @@ struct hid_hw_request_syscall_args {
 };
 
 FIXTURE(hid_bpf) {
-	int dev_id;
-	int uhid_fd;
+	struct uhid_device hid;
 	int hidraw_fd;
-	int hid_id;
-	pthread_t tid;
 	struct hid *skel;
 	struct bpf_link *hid_links[3]; /* max number of programs loaded in a single test */
 };
@@ -54,10 +44,10 @@ static void detach_bpf(FIXTURE_DATA(hid_bpf) * self)
 FIXTURE_TEARDOWN(hid_bpf) {
 	void *uhid_err;
 
-	uhid_destroy(_metadata, self->uhid_fd);
+	uhid_destroy(_metadata, &self->hid);
 
 	detach_bpf(self);
-	pthread_join(self->tid, &uhid_err);
+	pthread_join(self->hid.tid, &uhid_err);
 }
 #define TEARDOWN_LOG(fmt, ...) do { \
 	TH_LOG(fmt, ##__VA_ARGS__); \
@@ -66,23 +56,10 @@ FIXTURE_TEARDOWN(hid_bpf) {
 
 FIXTURE_SETUP(hid_bpf)
 {
-	time_t t;
 	int err;
 
-	/* initialize random number generator */
-	srand((unsigned int)time(&t));
-
-	self->dev_id = rand() % 1024;
-
-	self->uhid_fd = setup_uhid(_metadata, self->dev_id);
-
-	/* locate the uev, self, variant);ent file of the created device */
-	self->hid_id = get_hid_id(self->dev_id);
-	ASSERT_GT(self->hid_id, 0)
-		TEARDOWN_LOG("Could not locate uhid device id: %d", self->hid_id);
-
-	err = uhid_start_listener(_metadata, &self->tid, self->uhid_fd);
-	ASSERT_EQ(0, err) TEARDOWN_LOG("could not start udev listener: %d", err);
+	err = setup_uhid(_metadata, &self->hid);
+	ASSERT_OK(err);
 }
 
 struct test_program {
@@ -129,7 +106,7 @@ static void load_programs(const struct test_program programs[],
 		ops_hid_id = bpf_map__initial_value(map, NULL);
 		ASSERT_OK_PTR(ops_hid_id) TH_LOG("unable to retrieve struct_ops data");
 
-		*ops_hid_id = self->hid_id;
+		*ops_hid_id = self->hid.hid_id;
 	}
 
 	/* we disable the auto-attach feature of all maps because we
@@ -157,7 +134,7 @@ static void load_programs(const struct test_program programs[],
 
 	hid__attach(self->skel);
 
-	self->hidraw_fd = open_hidraw(self->dev_id);
+	self->hidraw_fd = open_hidraw(&self->hid);
 	ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw");
 }
 
@@ -192,7 +169,7 @@ TEST_F(hid_bpf, raw_event)
 	/* inject one event */
 	buf[0] = 1;
 	buf[1] = 42;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* check that hid_first_event() was executed */
 	ASSERT_EQ(self->skel->data->callback_check, 42) TH_LOG("callback_check1");
@@ -208,7 +185,7 @@ TEST_F(hid_bpf, raw_event)
 	memset(buf, 0, sizeof(buf));
 	buf[0] = 1;
 	buf[1] = 47;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* check that hid_first_event() was executed */
 	ASSERT_EQ(self->skel->data->callback_check, 47) TH_LOG("callback_check1");
@@ -239,7 +216,7 @@ TEST_F(hid_bpf, subprog_raw_event)
 	/* inject one event */
 	buf[0] = 1;
 	buf[1] = 42;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -252,7 +229,7 @@ TEST_F(hid_bpf, subprog_raw_event)
 	memset(buf, 0, sizeof(buf));
 	buf[0] = 1;
 	buf[1] = 47;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -303,7 +280,7 @@ TEST_F(hid_bpf, test_attach_detach)
 	/* inject one event */
 	buf[0] = 1;
 	buf[1] = 42;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -326,14 +303,14 @@ TEST_F(hid_bpf, test_attach_detach)
 	/* detach the program */
 	detach_bpf(self);
 
-	self->hidraw_fd = open_hidraw(self->dev_id);
+	self->hidraw_fd = open_hidraw(&self->hid);
 	ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw");
 
 	/* inject another event */
 	memset(buf, 0, sizeof(buf));
 	buf[0] = 1;
 	buf[1] = 47;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -352,7 +329,7 @@ TEST_F(hid_bpf, test_attach_detach)
 	memset(buf, 0, sizeof(buf));
 	buf[0] = 1;
 	buf[1] = 42;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -382,7 +359,7 @@ TEST_F(hid_bpf, test_hid_change_report)
 	/* inject one event */
 	buf[0] = 1;
 	buf[1] = 42;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -412,7 +389,7 @@ TEST_F(hid_bpf, test_hid_user_input_report_call)
 
 	LOAD_BPF;
 
-	args.hid = self->hid_id;
+	args.hid = self->hid.hid_id;
 	args.data[0] = 1; /* report ID */
 	args.data[1] = 2; /* report ID */
 	args.data[2] = 42; /* report ID */
@@ -458,7 +435,7 @@ TEST_F(hid_bpf, test_hid_user_output_report_call)
 
 	LOAD_BPF;
 
-	args.hid = self->hid_id;
+	args.hid = self->hid.hid_id;
 	args.data[0] = 1; /* report ID */
 	args.data[1] = 2; /* report ID */
 	args.data[2] = 42; /* report ID */
@@ -506,7 +483,7 @@ TEST_F(hid_bpf, test_hid_user_raw_request_call)
 
 	LOAD_BPF;
 
-	args.hid = self->hid_id;
+	args.hid = self->hid.hid_id;
 	args.data[0] = 1; /* report ID */
 
 	prog_fd = bpf_program__fd(self->skel->progs.hid_user_raw_request);
@@ -539,7 +516,7 @@ TEST_F(hid_bpf, test_hid_filter_raw_request_call)
 	/* inject one event */
 	buf[0] = 1;
 	buf[1] = 42;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -565,7 +542,7 @@ TEST_F(hid_bpf, test_hid_filter_raw_request_call)
 	/* detach the program */
 	detach_bpf(self);
 
-	self->hidraw_fd = open_hidraw(self->dev_id);
+	self->hidraw_fd = open_hidraw(&self->hid);
 	ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw");
 
 	err = ioctl(self->hidraw_fd, HIDIOCGFEATURE(sizeof(buf)), buf);
@@ -641,7 +618,7 @@ TEST_F(hid_bpf, test_hid_filter_output_report_call)
 	/* inject one event */
 	buf[0] = 1;
 	buf[1] = 42;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -667,7 +644,7 @@ TEST_F(hid_bpf, test_hid_filter_output_report_call)
 	/* detach the program */
 	detach_bpf(self);
 
-	self->hidraw_fd = open_hidraw(self->dev_id);
+	self->hidraw_fd = open_hidraw(&self->hid);
 	ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw");
 
 	err = write(self->hidraw_fd, buf, 3);
@@ -742,7 +719,7 @@ TEST_F(hid_bpf, test_multiply_events_wq)
 	/* inject one event */
 	buf[0] = 1;
 	buf[1] = 42;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -780,7 +757,7 @@ TEST_F(hid_bpf, test_multiply_events)
 	/* inject one event */
 	buf[0] = 1;
 	buf[1] = 42;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -816,7 +793,7 @@ TEST_F(hid_bpf, test_hid_infinite_loop_input_report_call)
 	buf[1] = 2;
 	buf[2] = 42;
 
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -867,7 +844,7 @@ TEST_F(hid_bpf, test_hid_attach_flags)
 
 	/* inject one event */
 	buf[0] = 1;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
diff --git a/tools/testing/selftests/hid/hid_common.h b/tools/testing/selftests/hid/hid_common.h
index f151f151a1ed..a7d836a35bb1 100644
--- a/tools/testing/selftests/hid/hid_common.h
+++ b/tools/testing/selftests/hid/hid_common.h
@@ -19,6 +19,13 @@
 	__typeof__(b) _b = (b); \
 	_a < _b ? _a : _b; })
 
+struct uhid_device {
+	int dev_id;		/* uniq (random) number to identify the device */
+	int uhid_fd;
+	int hid_id;		/* HID device id in the system */
+	pthread_t tid;		/* thread for reading uhid events */
+};
+
 static unsigned char rdesc[] = {
 	0x06, 0x00, 0xff,	/* Usage Page (Vendor Defined Page 1) */
 	0x09, 0x21,		/* Usage (Vendor Usage 0x21) */
@@ -146,14 +153,14 @@ static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb)
 	return uhid_write(_metadata, fd, &ev);
 }
 
-static void uhid_destroy(struct __test_metadata *_metadata, int fd)
+static void uhid_destroy(struct __test_metadata *_metadata, struct uhid_device *hid)
 {
 	struct uhid_event ev;
 
 	memset(&ev, 0, sizeof(ev));
 	ev.type = UHID_DESTROY;
 
-	uhid_write(_metadata, fd, &ev);
+	uhid_write(_metadata, hid->uhid_fd, &ev);
 }
 
 static int uhid_event(struct __test_metadata *_metadata, int fd)
@@ -281,7 +288,8 @@ static int uhid_start_listener(struct __test_metadata *_metadata, pthread_t *tid
 	return 0;
 }
 
-static int uhid_send_event(struct __test_metadata *_metadata, int fd, __u8 *buf, size_t size)
+static int uhid_send_event(struct __test_metadata *_metadata, struct uhid_device *hid,
+			   __u8 *buf, size_t size)
 {
 	struct uhid_event ev;
 
@@ -294,25 +302,7 @@ static int uhid_send_event(struct __test_metadata *_metadata, int fd, __u8 *buf,
 
 	memcpy(ev.u.input2.data, buf, size);
 
-	return uhid_write(_metadata, fd, &ev);
-}
-
-static int setup_uhid(struct __test_metadata *_metadata, int rand_nb)
-{
-	int fd;
-	const char *path = "/dev/uhid";
-	int ret;
-
-	fd = open(path, O_RDWR | O_CLOEXEC);
-	ASSERT_GE(fd, 0) TH_LOG("open uhid-cdev failed; %d", fd);
-
-	ret = uhid_create(_metadata, fd, rand_nb);
-	ASSERT_EQ(0, ret) {
-		TH_LOG("create uhid device failed: %d", ret);
-		close(fd);
-	}
-
-	return fd;
+	return uhid_write(_metadata, hid->uhid_fd, &ev);
 }
 
 static bool match_sysfs_device(int dev_id, const char *workdir, struct dirent *dir)
@@ -421,12 +411,12 @@ static int get_hidraw(int dev_id)
 	return found;
 }
 
-static int open_hidraw(int dev_id)
+static int open_hidraw(struct uhid_device *hid)
 {
 	int hidraw_number;
 	char hidraw_path[64] = { 0 };
 
-	hidraw_number = get_hidraw(dev_id);
+	hidraw_number = get_hidraw(hid->dev_id);
 	if (hidraw_number < 0)
 		return hidraw_number;
 
@@ -434,3 +424,39 @@ static int open_hidraw(int dev_id)
 	sprintf(hidraw_path, "/dev/hidraw%d", hidraw_number);
 	return open(hidraw_path, O_RDWR | O_NONBLOCK);
 }
+
+static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid)
+{
+	const char *path = "/dev/uhid";
+	time_t t;
+	int ret;
+
+	/* initialize random number generator */
+	srand((unsigned int)time(&t));
+
+	hid->dev_id = rand() % 1024;
+
+	hid->uhid_fd = open(path, O_RDWR | O_CLOEXEC);
+	ASSERT_GE(hid->uhid_fd, 0) TH_LOG("open uhid-cdev failed; %d", hid->uhid_fd);
+
+	ret = uhid_create(_metadata, hid->uhid_fd, hid->dev_id);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("create uhid device failed: %d", ret);
+		close(hid->uhid_fd);
+		return ret;
+	}
+
+	/* locate the uevent file of the created device */
+	hid->hid_id = get_hid_id(hid->dev_id);
+	ASSERT_GT(hid->hid_id, 0)
+		TH_LOG("Could not locate uhid device id: %d", hid->hid_id);
+
+	ret = uhid_start_listener(_metadata, &hid->tid, hid->uhid_fd);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("could not start udev listener: %d", ret);
+		close(hid->uhid_fd);
+		return ret;
+	}
+
+	return 0;
+}
diff --git a/tools/testing/selftests/hid/hidraw.c b/tools/testing/selftests/hid/hidraw.c
index f8b4f7ff292c..5934818b2036 100644
--- a/tools/testing/selftests/hid/hidraw.c
+++ b/tools/testing/selftests/hid/hidraw.c
@@ -9,11 +9,8 @@
 #endif /* HIDIOCREVOKE */
 
 FIXTURE(hidraw) {
-	int dev_id;
-	int uhid_fd;
+	struct uhid_device hid;
 	int hidraw_fd;
-	int hid_id;
-	pthread_t tid;
 };
 static void close_hidraw(FIXTURE_DATA(hidraw) * self)
 {
@@ -25,10 +22,10 @@ static void close_hidraw(FIXTURE_DATA(hidraw) * self)
 FIXTURE_TEARDOWN(hidraw) {
 	void *uhid_err;
 
-	uhid_destroy(_metadata, self->uhid_fd);
+	uhid_destroy(_metadata, &self->hid);
 
 	close_hidraw(self);
-	pthread_join(self->tid, &uhid_err);
+	pthread_join(self->hid.tid, &uhid_err);
 }
 #define TEARDOWN_LOG(fmt, ...) do { \
 	TH_LOG(fmt, ##__VA_ARGS__); \
@@ -37,25 +34,12 @@ FIXTURE_TEARDOWN(hidraw) {
 
 FIXTURE_SETUP(hidraw)
 {
-	time_t t;
 	int err;
 
-	/* initialize random number generator */
-	srand((unsigned int)time(&t));
+	err = setup_uhid(_metadata, &self->hid);
+	ASSERT_OK(err);
 
-	self->dev_id = rand() % 1024;
-
-	self->uhid_fd = setup_uhid(_metadata, self->dev_id);
-
-	/* locate the uev, self, variant);ent file of the created device */
-	self->hid_id = get_hid_id(self->dev_id);
-	ASSERT_GT(self->hid_id, 0)
-		TEARDOWN_LOG("Could not locate uhid device id: %d", self->hid_id);
-
-	err = uhid_start_listener(_metadata, &self->tid, self->uhid_fd);
-	ASSERT_EQ(0, err) TEARDOWN_LOG("could not start udev listener: %d", err);
-
-	self->hidraw_fd = open_hidraw(self->dev_id);
+	self->hidraw_fd = open_hidraw(&self->hid);
 	ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw");
 }
 
@@ -79,7 +63,7 @@ TEST_F(hidraw, raw_event)
 	/* inject one event */
 	buf[0] = 1;
 	buf[1] = 42;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -101,7 +85,7 @@ TEST_F(hidraw, raw_event_revoked)
 	/* inject one event */
 	buf[0] = 1;
 	buf[1] = 42;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -117,7 +101,7 @@ TEST_F(hidraw, raw_event_revoked)
 	/* inject one other event */
 	buf[0] = 1;
 	buf[1] = 43;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	/* read the data from hidraw */
 	memset(buf, 0, sizeof(buf));
@@ -161,7 +145,7 @@ TEST_F(hidraw, poll_revoked)
 	/* inject one event */
 	buf[0] = 1;
 	buf[1] = 42;
-	uhid_send_event(_metadata, self->uhid_fd, buf, 6);
+	uhid_send_event(_metadata, &self->hid, buf, 6);
 
 	while (true) {
 		ready = poll(pfds, 1, 5000);

-- 
2.46.0


^ permalink raw reply related

* [PATCH HID 1/7] selftests/hid: add dependency on hid_common.h
From: Benjamin Tissoires @ 2024-09-02 16:14 UTC (permalink / raw)
  To: Jiri Kosina, Peter Hutterer, Vicki Pfau, Shuah Khan,
	Jonathan Corbet
  Cc: linux-input, linux-kselftest, linux-kernel, bpf, linux-doc,
	Benjamin Tissoires
In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org>

Allows to recompile the C tests when that file changes

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 tools/testing/selftests/hid/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/hid/Makefile b/tools/testing/selftests/hid/Makefile
index 72be55ac4bdf..9399fa3f2f9d 100644
--- a/tools/testing/selftests/hid/Makefile
+++ b/tools/testing/selftests/hid/Makefile
@@ -229,7 +229,7 @@ $(BPF_SKELS): %.skel.h: %.bpf.o $(BPFTOOL) | $(OUTPUT)
 	$(Q)$(BPFTOOL) gen object $(<:.o=.linked1.o) $<
 	$(Q)$(BPFTOOL) gen skeleton $(<:.o=.linked1.o) name $(notdir $(<:.bpf.o=)) > $@
 
-$(OUTPUT)/%.o: %.c $(BPF_SKELS)
+$(OUTPUT)/%.o: %.c $(BPF_SKELS) hid_common.h
 	$(call msg,CC,,$@)
 	$(Q)$(CC) $(CFLAGS) -c $(filter %.c,$^) $(LDLIBS) -o $@
 

-- 
2.46.0


^ permalink raw reply related

* [PATCH HID 0/7] HID: bpf: add a new hook to control hid-generic
From: Benjamin Tissoires @ 2024-09-02 16:14 UTC (permalink / raw)
  To: Jiri Kosina, Peter Hutterer, Vicki Pfau, Shuah Khan,
	Jonathan Corbet
  Cc: linux-input, linux-kselftest, linux-kernel, bpf, linux-doc,
	Benjamin Tissoires

This is a slight change from the fundamentals of HID-BPF.
In theory, HID-BPF is abstract to the kernel itself, and makes
only changes at the HID level (through report descriptors or
events emitted to/from the device).

However, we have seen a few use cases where HID-BPF might interact with
the running kernel when the target device is already handled by a
specific device.

For example, the XP-Pen/Huion/UC-Logic tablets are handled by
hid-uclogic but this driver is also doing a report descriptor fixup
without checking if the device has already been fixed by HID-BPF.

In the same way, another recent example[0] was when a cheap foot pedal is
used and tricks iPhones and Windows machines by presenting itself as a
known Apple wireless keyboard. The problem is that this fake keyboard is
not presenting a compatible report descriptor and hid-core merges all
device nodes together making libinput ignore the keyboard part for
historical reasons.

Last, there has been a long standing request to allow to disable the
input part of a given gamepad while SDL or Steam opens the device
through hidraw.

This series aims at tackling both of these problems:
- first we had a new hook `hid_bpf_driver_probe` which allows the BPF
  program to decide if the curently probed driver should be used or not
- then this same hook can also change the ->driver_data of the struct
  hid_device_id argument, and we teach hid-generic to use that field as
  the connect mask.

Basically, it means that when we insert a BPF program to fix a device,
we can force hid-generic to handle the device, and thus preventing
any other kernel driver to tamper with our device. We can also
selectively decide to export the hidraw or input nodes when using
hid-generic.

In the SDL/Steam use case, this would means that the gaming application
will load one BPF program per input device it wants to open through
hidraw, that BPF program reassigns the input device to hid-generic and
disables hid-input, then it can open the new hidraw node.
Once that program terminates, the BPF program is removed (either
automatically because no-one has the fd of the links open, or manually
by SDL/Steam), and the normal driver rebinds to the HID device,
restoring full input functionality.

This branch is on top of the for-6.12/hidraw branch of hid.git, mainly
because that branch saw some selftests/hid changes.

[0] https://gitlab.freedesktop.org/libinput/libinput/-/issues/1014

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
Benjamin Tissoires (7):
      selftests/hid: add dependency on hid_common.h
      selftests/hid: cleanup C tests by adding a common struct uhid_device
      selftests/hid: allow to parametrize bus/vid/pid/rdesc on the test device
      HID: bpf: allow BPF programs to force using hid-generic
      selftests/hid: add test for assigning a given device to hid-generic
      HID: bpf: Allow to control the connect mask of hid-generic from BPF
      selftests/hid: add test to disable hid-input

 Documentation/hid/hid-bpf.rst                      |   2 +-
 drivers/hid/bpf/hid_bpf_dispatch.c                 |  31 ++++
 drivers/hid/bpf/hid_bpf_struct_ops.c               |   4 +
 drivers/hid/hid-core.c                             |  18 +-
 drivers/hid/hid-generic.c                          |   5 +-
 include/linux/hid_bpf.h                            |  40 ++++
 tools/testing/selftests/hid/Makefile               |   2 +-
 tools/testing/selftests/hid/hid_bpf.c              | 205 ++++++++++++++++-----
 tools/testing/selftests/hid/hid_common.h           | 112 +++++++----
 tools/testing/selftests/hid/hidraw.c               |  36 +---
 tools/testing/selftests/hid/progs/hid.c            |  31 ++++
 .../testing/selftests/hid/progs/hid_bpf_helpers.h  |   4 +
 12 files changed, 372 insertions(+), 118 deletions(-)
---
base-commit: 321f7798cfb8d834ae0ed0d467c8bf46804243f9
change-id: 20240829-hid-bpf-hid-generic-61579f5b5945

Best regards,
-- 
Benjamin Tissoires <bentiss@kernel.org>


^ permalink raw reply

* Re: [PATCH v2 3/3] dt-bindings: touchscreen: ad7877: add bindings
From: Krzysztof Kozlowski @ 2024-09-02 11:52 UTC (permalink / raw)
  To: Antoniu Miclaus
  Cc: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Michael Hennerich, linux-input, devicetree, linux-kernel
In-Reply-To: <20240902082707.4325-3-antoniu.miclaus@analog.com>

On Mon, Sep 02, 2024 at 11:24:33AM +0300, Antoniu Miclaus wrote:
> Add device tree bindings for the ad7877 driver.
> 
> Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
> ---
> changes in v2:
>  - add only the used properties from touchscreen.yaml
>  - add vendor properties.
>  - update dt example.
>  .../input/touchscreen/adi,ad7877.yaml         | 110 ++++++++++++++++++
>  1 file changed, 110 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/adi,ad7877.yaml
> 
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/adi,ad7877.yaml b/Documentation/devicetree/bindings/input/touchscreen/adi,ad7877.yaml
> new file mode 100644
> index 000000000000..035e2d5bbcb8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/touchscreen/adi,ad7877.yaml
> @@ -0,0 +1,110 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/input/touchscreen/adi,ad7877.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Analog Devices AD7877 Touch Screen Controller
> +
> +maintainers:
> +  - Antoniu Miclaus <antoniu.miclaus@analog.com>
> +
> +description: |
> +  Analog Devices Touch Screen Controller
> +  https://www.analog.com/media/en/technical-documentation/data-sheets/AD7877.pdf
> +
> +allOf:
> +  - $ref: touchscreen.yaml#
> +  - $ref: /schemas/spi/spi-peripheral-props.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - adi,ad7877
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  spi-max-frequency:
> +    description: AD7877 SPI bus clock frequency.
> +    minimum: 10000
> +    maximum: 20000000
> +
> +  adi,stopacq-polarity:
> +    description: The polarity of the signal applied to the STOPACQ pin.
> +                 0 = active low
> +                 1 = active high
> +    $ref: /schemas/types.yaml#/definitions/uint8
> +    enum: [0, 1]

I think I was already commenting on this for analog... If using numbers,
why this is reversed from standard GPIO property? Or maybe this should
be just string.

> +
> +  adi,first-conv-delay:
> +    description: Delay before the first conversion.

No, use proper unit suffix.

> +                 0 = 0.5us
> +                 1 = 128us
> +                 2 = 1ms
> +                 3 = 8ms
> +    $ref: /schemas/types.yaml#/definitions/uint8
> +    enum: [0, 1, 2, 3]
> +
> +  adi,pen-down-acc-interval:

Use proper unit suffix.

> +    description: Enable the ADC to repeatedly perform conversions.
> +                  0 = covert once
> +                  1 = every 0.5 ms
> +                  2 = every 1 ms
> +                  3 = every 8 ms
> +    $ref: /schemas/types.yaml#/definitions/uint8
> +    enum: [0, 1, 2, 3]

How is it supposed to work? These are optional but there are no
defaults?

> +
> +  adi,acquisition-time:
> +    description:  Select acquisition times for the ADC.
> +                  0 = 2us
> +                  1 = 4us
> +                  2 = 8us
> +                  3 = 16us

Same problem

> +    $ref: /schemas/types.yaml#/definitions/uint8
> +    enum: [0, 1, 2, 3]
> +
> +  adi,vref-delay-usecs:
> +    description: Delay required for the SPI transfers depending on the VREF used.
> +    $ref: /schemas/types.yaml#/definitions/uint16
> +
> +  touchscreen-average-samples:
> +    enum: [1, 4, 8, 16]
> +
> +  touchscreen-x-plate-ohms: true
> +  touchscreen-y-plate-ohms: true
> +  touchscreen-min-x: true
> +  touchscreen-min-y: true
> +  touchscreen-max-x: true
> +  touchscreen-max-y: true
> +  touchscreen-max-pressure: true
> +  touchscreen-min-pressure: true
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - touchscreen-average-samples
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    spi {
> +      #address-cells = <1>;
> +      #size-cells = <0>;
> +
> +      touchscreen@0 {
> +        compatible = "adi,ad7877";
> +        reg = <0>;
> +        spi-max-frequency = <20000000>;
> +        interrupts = <21 IRQ_TYPE_EDGE_FALLING>;
> +        interrupt-parent = <&gpio>;
> +        touchscreen-average-samples = <16>;

Make the example complete.

Best regards,
Krzysztof


^ permalink raw reply

* [PATCH v2 3/3] dt-bindings: touchscreen: ad7877: add bindings
From: Antoniu Miclaus @ 2024-09-02  8:24 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Michael Hennerich, Antoniu Miclaus, linux-input, devicetree,
	linux-kernel
In-Reply-To: <20240902082707.4325-1-antoniu.miclaus@analog.com>

Add device tree bindings for the ad7877 driver.

Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
changes in v2:
 - add only the used properties from touchscreen.yaml
 - add vendor properties.
 - update dt example.
 .../input/touchscreen/adi,ad7877.yaml         | 110 ++++++++++++++++++
 1 file changed, 110 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/adi,ad7877.yaml

diff --git a/Documentation/devicetree/bindings/input/touchscreen/adi,ad7877.yaml b/Documentation/devicetree/bindings/input/touchscreen/adi,ad7877.yaml
new file mode 100644
index 000000000000..035e2d5bbcb8
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/adi,ad7877.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/adi,ad7877.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices AD7877 Touch Screen Controller
+
+maintainers:
+  - Antoniu Miclaus <antoniu.miclaus@analog.com>
+
+description: |
+  Analog Devices Touch Screen Controller
+  https://www.analog.com/media/en/technical-documentation/data-sheets/AD7877.pdf
+
+allOf:
+  - $ref: touchscreen.yaml#
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+  compatible:
+    enum:
+      - adi,ad7877
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  spi-max-frequency:
+    description: AD7877 SPI bus clock frequency.
+    minimum: 10000
+    maximum: 20000000
+
+  adi,stopacq-polarity:
+    description: The polarity of the signal applied to the STOPACQ pin.
+                 0 = active low
+                 1 = active high
+    $ref: /schemas/types.yaml#/definitions/uint8
+    enum: [0, 1]
+
+  adi,first-conv-delay:
+    description: Delay before the first conversion.
+                 0 = 0.5us
+                 1 = 128us
+                 2 = 1ms
+                 3 = 8ms
+    $ref: /schemas/types.yaml#/definitions/uint8
+    enum: [0, 1, 2, 3]
+
+  adi,pen-down-acc-interval:
+    description: Enable the ADC to repeatedly perform conversions.
+                  0 = covert once
+                  1 = every 0.5 ms
+                  2 = every 1 ms
+                  3 = every 8 ms
+    $ref: /schemas/types.yaml#/definitions/uint8
+    enum: [0, 1, 2, 3]
+
+  adi,acquisition-time:
+    description:  Select acquisition times for the ADC.
+                  0 = 2us
+                  1 = 4us
+                  2 = 8us
+                  3 = 16us
+    $ref: /schemas/types.yaml#/definitions/uint8
+    enum: [0, 1, 2, 3]
+
+  adi,vref-delay-usecs:
+    description: Delay required for the SPI transfers depending on the VREF used.
+    $ref: /schemas/types.yaml#/definitions/uint16
+
+  touchscreen-average-samples:
+    enum: [1, 4, 8, 16]
+
+  touchscreen-x-plate-ohms: true
+  touchscreen-y-plate-ohms: true
+  touchscreen-min-x: true
+  touchscreen-min-y: true
+  touchscreen-max-x: true
+  touchscreen-max-y: true
+  touchscreen-max-pressure: true
+  touchscreen-min-pressure: true
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - touchscreen-average-samples
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    spi {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      touchscreen@0 {
+        compatible = "adi,ad7877";
+        reg = <0>;
+        spi-max-frequency = <20000000>;
+        interrupts = <21 IRQ_TYPE_EDGE_FALLING>;
+        interrupt-parent = <&gpio>;
+        touchscreen-average-samples = <16>;
+      };
+    };
+...
-- 
2.46.0


^ permalink raw reply related

* [PATCH v2 2/3] input: touchscreen: ad7877: add dt support
From: Antoniu Miclaus @ 2024-09-02  8:24 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Michael Hennerich, Antoniu Miclaus, linux-input, devicetree,
	linux-kernel
In-Reply-To: <20240902082707.4325-1-antoniu.miclaus@analog.com>

Add devicetree support within the driver.

Make the old platform data approach optional.

Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
new in v2.
 drivers/input/touchscreen/ad7877.c | 68 +++++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c
index 7886454a19c6..3fa38043b561 100644
--- a/drivers/input/touchscreen/ad7877.c
+++ b/drivers/input/touchscreen/ad7877.c
@@ -27,6 +27,7 @@
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/pm.h>
+#include <linux/property.h>
 #include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ad7877.h>
@@ -667,6 +668,68 @@ static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts)
 	}
 }
 
+static struct ad7877_platform_data *ad7877_parse_props(struct device *dev)
+{
+	struct ad7877_platform_data *pdata;
+	u32 value, average;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return ERR_PTR(-ENOMEM);
+
+	pdata->model = (uintptr_t)device_get_match_data(dev);
+
+	device_property_read_u8(dev, "adi,stopacq-polarity",
+				&pdata->stopacq_polarity);
+	device_property_read_u8(dev, "adi,first-conv-delay",
+				&pdata->first_conversion_delay);
+	device_property_read_u8(dev, "adi,pen-down-acc-interval",
+				&pdata->pen_down_acc_interval);
+	device_property_read_u8(dev, "adi,acquisition-time",
+				&pdata->acquisition_time);
+
+	device_property_read_u16(dev, "adi,vref-delay-usecs",
+				 &pdata->vref_delay_usecs);
+
+	device_property_read_u32(dev, "touchscreen-x-plate-ohms", &value);
+	pdata->x_plate_ohms = (u16)value;
+	device_property_read_u32(dev, "touchscreen-y-plate-ohms", &value);
+	pdata->y_plate_ohms = (u16)value;
+	device_property_read_u32(dev, "touchscreen-min-x", &value);
+	pdata->x_min = (u16)value;
+	device_property_read_u32(dev, "touchscreen-min-y", &value);
+	pdata->y_min = (u16)value;
+	device_property_read_u32(dev, "touchscreen-max-x", &value);
+	pdata->x_max = (u16)value;
+	device_property_read_u32(dev, "touchscreen-max-y", &value);
+	pdata->y_max = (u16)value;
+	device_property_read_u32(dev, "touchscreen-max-pressure", &value);
+	pdata->pressure_max = (u16)value;
+	device_property_read_u32(dev, "touchscreen-min-pressure", &value);
+	pdata->pressure_min = (u16)value;
+	device_property_read_u32(dev, "touchscreen-average-samples", &average);
+	switch (average) {
+	case 1:
+		pdata->averaging = 0;
+		break;
+	case 4:
+		pdata->averaging = 1;
+		break;
+	case 8:
+		pdata->averaging = 2;
+		break;
+	case 16:
+		pdata->averaging = 3;
+		break;
+	default:
+		dev_err(dev,
+			"touchscreen-average-samples must be 1, 4, 8, or 16\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	return pdata;
+}
+
 static int ad7877_probe(struct spi_device *spi)
 {
 	struct ad7877			*ts;
@@ -681,8 +744,9 @@ static int ad7877_probe(struct spi_device *spi)
 	}
 
 	if (!pdata) {
-		dev_dbg(&spi->dev, "no platform data?\n");
-		return -ENODEV;
+		pdata = ad7877_parse_props(&spi->dev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
 	}
 
 	/* don't exceed max specified SPI CLK frequency */
-- 
2.46.0


^ permalink raw reply related

* [PATCH v2 1/3] input: touchscreem: ad7877: add match table
From: Antoniu Miclaus @ 2024-09-02  8:24 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Michael Hennerich, Antoniu Miclaus, linux-input, devicetree,
	linux-kernel

Add match table for the ad7877 driver and define the compatible string.

Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
no changes in v2.
 drivers/input/touchscreen/ad7877.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c
index a0598e9c7aff..7886454a19c6 100644
--- a/drivers/input/touchscreen/ad7877.c
+++ b/drivers/input/touchscreen/ad7877.c
@@ -805,10 +805,17 @@ static int ad7877_resume(struct device *dev)
 
 static DEFINE_SIMPLE_DEV_PM_OPS(ad7877_pm, ad7877_suspend, ad7877_resume);
 
+static const struct of_device_id ad7877_of_match[] = {
+	{ .compatible = "adi,ad7877", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ad7877_of_match);
+
 static struct spi_driver ad7877_driver = {
 	.driver = {
 		.name		= "ad7877",
 		.dev_groups	= ad7877_groups,
+		.of_match_table = ad7877_of_match,
 		.pm		= pm_sleep_ptr(&ad7877_pm),
 	},
 	.probe		= ad7877_probe,
-- 
2.46.0


^ permalink raw reply related

* Re: [PATCH 00/18] zforse_ts: assorted cleanups
From: Andreas Kemnade @ 2024-09-02  8:08 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Heiko Stübner, linux-input, linux-kernel
In-Reply-To: <20240824055047.1706392-1-dmitry.torokhov@gmail.com>

Hi Dmitry,

Am Fri, 23 Aug 2024 22:50:24 -0700
schrieb Dmitry Torokhov <dmitry.torokhov@gmail.com>:

> 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!
> 
nice cleanup,
I tested a bit on the Toline Shine 2HD without gui (have not rebased my
other stuff to 6.11 yet)

A short move on the touchscreen gives this:
Event: time 1725264307.093542, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 24
Event: time 1725264307.093542, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 1159
Event: time 1725264307.093542, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 596
Event: time 1725264307.093542, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 11
Event: time 1725264307.093542, type 3 (EV_ABS), code 49 (ABS_MT_TOUCH_MINOR), value 11
Event: time 1725264307.093542, type 3 (EV_ABS), code 52 (ABS_MT_ORIENTATION), value 0
Event: time 1725264307.093542, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1725264307.093542, type 3 (EV_ABS), code 0 (ABS_X), value 1159
Event: time 1725264307.093542, type 3 (EV_ABS), code 1 (ABS_Y), value 596
Event: time 1725264307.093542, -------------- SYN_REPORT ------------
Event: time 1725264307.096361, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 1039
Event: time 1725264307.096361, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 607
Event: time 1725264307.096361, type 3 (EV_ABS), code 0 (ABS_X), value 1039
Event: time 1725264307.096361, type 3 (EV_ABS), code 1 (ABS_Y), value 607
Event: time 1725264307.096361, -------------- SYN_REPORT ------------
Event: time 1725264307.112426, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 934
Event: time 1725264307.112426, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 637
Event: time 1725264307.112426, type 3 (EV_ABS), code 0 (ABS_X), value 934
Event: time 1725264307.112426, type 3 (EV_ABS), code 1 (ABS_Y), value 637
Event: time 1725264307.112426, -------------- SYN_REPORT ------------
Event: time 1725264307.131523, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 859
Event: time 1725264307.131523, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 661
Event: time 1725264307.131523, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 12
Event: time 1725264307.131523, type 3 (EV_ABS), code 0 (ABS_X), value 859
Event: time 1725264307.131523, type 3 (EV_ABS), code 1 (ABS_Y), value 661
Event: time 1725264307.131523, -------------- SYN_REPORT ------------
Event: time 1725264307.150540, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 795
Event: time 1725264307.150540, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 671
Event: time 1725264307.150540, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 13
Event: time 1725264307.150540, type 3 (EV_ABS), code 0 (ABS_X), value 795
Event: time 1725264307.150540, type 3 (EV_ABS), code 1 (ABS_Y), value 671
Event: time 1725264307.150540, -------------- SYN_REPORT ------------
Event: time 1725264307.169589, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 760
Event: time 1725264307.169589, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 675
Event: time 1725264307.169589, type 3 (EV_ABS), code 0 (ABS_X), value 760
Event: time 1725264307.169589, type 3 (EV_ABS), code 1 (ABS_Y), value 675
Event: time 1725264307.169589, -------------- SYN_REPORT ------------
Event: time 1725264307.188157, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1
Event: time 1725264307.188157, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0
Event: time 1725264307.188157, -------------- SYN_REPORT ------------

So,

Tested-by: Andreas Kemnade <andreas@kemnade.info> # Tolino Shine2HD

Regards,
Andreas

^ permalink raw reply

* [syzbot] Monthly input report (Sep 2024)
From: syzbot @ 2024-09-02  8:17 UTC (permalink / raw)
  To: linux-input, linux-kernel, syzkaller-bugs

Hello input maintainers/developers,

This is a 31-day syzbot report for the input subsystem.
All related reports/information can be found at:
https://syzkaller.appspot.com/upstream/s/input

During the period, 3 new issues were detected and 0 were fixed.
In total, 18 issues are still open and 57 have been fixed so far.

Some of the still happening issues:

Ref Crashes Repro Title
<1> 702     No    possible deadlock in evdev_pass_values (2)
                  https://syzkaller.appspot.com/bug?extid=13d3cb2a3dc61e6092f5
<2> 392     Yes   INFO: task hung in uhid_char_release
                  https://syzkaller.appspot.com/bug?extid=8fe2d362af0e1cba8735
<3> 353     Yes   WARNING in cm109_urb_irq_callback/usb_submit_urb
                  https://syzkaller.appspot.com/bug?extid=2d6d691af5ab4b7e66df
<4> 23      Yes   WARNING in cm109_input_open/usb_submit_urb (3)
                  https://syzkaller.appspot.com/bug?extid=ac0f9c4cc1e034160492
<5> 21      Yes   possible deadlock in uinput_request_submit
                  https://syzkaller.appspot.com/bug?extid=159077b1355b8cd72757
<6> 19      No    possible deadlock in __input_unregister_device
                  https://syzkaller.appspot.com/bug?extid=3f4bf5c599ee9b16d704
<7> 10      Yes   INFO: rcu detected stall in sendmsg (4)
                  https://syzkaller.appspot.com/bug?extid=9c0539eda655673bdaa4
<8> 9       No    possible deadlock in hid_hw_open
                  https://syzkaller.appspot.com/bug?extid=2313ca2498b9554beeba
<9> 3       Yes   WARNING in bcm5974_start_traffic/usb_submit_urb (2)
                  https://syzkaller.appspot.com/bug?extid=b064b5599f18f7ebb1e1

---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

To disable reminders for individual bugs, reply with the following command:
#syz set <Ref> no-reminders

To change bug's subsystems, reply with:
#syz set <Ref> subsystems: new-subsystem

You may send multiple commands in a single email message.

^ 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