Linux Input/HID development
 help / color / mirror / Atom feed
* [git pull] Input updates for v5.3-rc3
From: Dmitry Torokhov @ 2019-08-09 22:20 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-input

Hi Linus,

Please pull from:

	git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus

to receive updates for the input subsystem. You will get:

- newer systems with Elan touchpads will be switched over to SMBus
- HP Spectre X360 will be using SMbus/RMI4
- checks for invalid USB descriptors in kbtab and iforce
- build fixes for applespi driver (misconfigs)

Thanks!

Changelog:
---------

Arnd Bergmann (1):
      Input: applespi - select CRC16 module

Dmitry Torokhov (2):
      Input: elantech - annotate fall-through case in elantech_use_host_notify()
      Input: synaptics - enable RMI mode for HP Spectre X360

Gustavo A. R. Silva (1):
      Input: applespi - use struct_size() helper

Kai-Heng Feng (1):
      Input: elantech - enable SMBus on new (2018+) systems

Nikolas Nyby (1):
      Input: applespi - fix trivial typo in struct description

Oliver Neukum (3):
      Input: usbtouchscreen - initialize PM mutex before using it
      Input: kbtab - sanity check for endpoint type
      Input: iforce - add sanity checks

Ronald Tschalär (1):
      Input: applespi - fix warnings detected by sparse

YueHaibing (1):
      Input: applespi - add dependency on LEDS_CLASS

Diffstat:
--------

 drivers/input/joystick/iforce/iforce-usb.c |  5 +++
 drivers/input/keyboard/Kconfig             |  2 ++
 drivers/input/keyboard/applespi.c          | 29 +++++++++-------
 drivers/input/mouse/elantech.c             | 55 ++++++++++++++----------------
 drivers/input/mouse/synaptics.c            |  1 +
 drivers/input/tablet/kbtab.c               |  6 ++--
 drivers/input/touchscreen/usbtouchscreen.c |  2 ++
 7 files changed, 56 insertions(+), 44 deletions(-)

Thanks.


-- 
Dmitry

^ permalink raw reply

* Re: [git pull] Input updates for v5.3-rc3
From: pr-tracker-bot @ 2019-08-09 22:35 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Linus Torvalds, linux-kernel, linux-input
In-Reply-To: <20190809222030.GA20442@dtor-ws>

The pull request you sent on Fri, 9 Aug 2019 15:20:30 -0700:

> git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/15abf14202a2fe7e5c5fc0e815587f45de4fd500

Thank you!

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

^ permalink raw reply

* [PATCH 00/11] Face lift for bu21013_ts driver
From: Dmitry Torokhov @ 2019-08-10  0:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-input, linux-kernel

Hi Linus,

So your patch has prompted me to take a look at the driver and
try to clean it up. I am sure I screwed up somewhere, but you said
you have the device, so please take a look at the series and
see if you can salvage them

Thanks!

Dmitry Torokhov (10):
  ARM: ux500: improve BU21013 touchpad bindings
  Input: bu21013_ts - rename some variables
  Input: bu21013_ts - annotate supend/resume methods as __maybe_unused
  Input: bu21013_ts - remove useless comments
  Input: bu21013_ts - convert to using managed resources
  Input: bu21013_ts - remove support for platform data
  Input: bu21013_ts - use interrupt from I2C client
  Input: bu21013_ts - fix suspend when wake source
  Input: bu21013_ts - switch to using MT-B (slotted) protocol
  Input: bu21013_ts - switch to using standard touchscreen properties

Linus Walleij (1):
  Input: bu21013_ts - convert to use GPIO descriptors

 .../bindings/input/touchscreen/bu21013.txt    |  27 +-
 arch/arm/boot/dts/ste-hrefprev60-stuib.dts    |  14 +-
 arch/arm/boot/dts/ste-hrefv60plus-stuib.dts   |  14 +-
 drivers/input/touchscreen/bu21013_ts.c        | 740 ++++++++----------
 include/linux/input/bu21013.h                 |  34 -
 5 files changed, 362 insertions(+), 467 deletions(-)
 delete mode 100644 include/linux/input/bu21013.h

-- 
Dmitry

^ permalink raw reply

* [PATCH 01/11] ARM: ux500: improve BU21013 touchpad bindings
From: Dmitry Torokhov @ 2019-08-10  0:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-input, linux-kernel
In-Reply-To: <20190810002039.95876-1-dmitry.torokhov@gmail.com>

In preparation to update to bu21013_tp driver properly annotate GPIOs
property (the INT GPIOs are active low, not open drain), and also define
interrupt lines so we do not have to have special conversion in the driver.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 arch/arm/boot/dts/ste-hrefprev60-stuib.dts  | 14 ++++++++++----
 arch/arm/boot/dts/ste-hrefv60plus-stuib.dts | 14 ++++++++++----
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/ste-hrefprev60-stuib.dts b/arch/arm/boot/dts/ste-hrefprev60-stuib.dts
index aed940bd65a8..b78be5f4c212 100644
--- a/arch/arm/boot/dts/ste-hrefprev60-stuib.dts
+++ b/arch/arm/boot/dts/ste-hrefprev60-stuib.dts
@@ -4,6 +4,8 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 #include "ste-hrefprev60.dtsi"
 #include "ste-href-stuib.dtsi"
 
@@ -23,12 +25,16 @@
 		i2c@80110000 {
 			/* Only one of these will be used */
 			bu21013_tp@5c {
-				touch-gpio = <&gpio2 12 0x4>;
-				reset-gpio = <&tc3589x_gpio 13 0x4>;
+				interrupt-parent = <&gpio2>;
+				interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
+				touch-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+				reset-gpios = <&tc3589x_gpio 13 GPIO_LINE_OPEN_DRAIN>;
 			};
 			bu21013_tp@5d {
-				touch-gpio = <&gpio2 12 0x4>;
-				reset-gpio = <&tc3589x_gpio 13 0x4>;
+				interrupt-parent = <&gpio2>;
+				interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
+				touch-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+				reset-gpios = <&tc3589x_gpio 13 GPIO_LINE_OPEN_DRAIN>;
 			};
 		};
 	};
diff --git a/arch/arm/boot/dts/ste-hrefv60plus-stuib.dts b/arch/arm/boot/dts/ste-hrefv60plus-stuib.dts
index 0f3c3b86bb20..9be513aad549 100644
--- a/arch/arm/boot/dts/ste-hrefv60plus-stuib.dts
+++ b/arch/arm/boot/dts/ste-hrefv60plus-stuib.dts
@@ -6,6 +6,8 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 #include "ste-hrefv60plus.dtsi"
 #include "ste-href-stuib.dtsi"
 
@@ -25,12 +27,16 @@
 		i2c@80110000 {
 			/* Only one of these will be used */
 			bu21013_tp@5c {
-				touch-gpio = <&gpio2 20 0x4>;
-				reset-gpio = <&gpio4 17 0x4>;
+				interrupt-parent = <&gpio2>;
+				interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+				touch-gpios = <&gpio2 20 GPIO_ACTIVE_LOW>;
+				reset-gpios = <&gpio4 17 GPIO_LINE_OPEN_DRAIN>;
 			};
 			bu21013_tp@5d {
-				touch-gpio = <&gpio2 20 0x4>;
-				reset-gpio = <&gpio4 17 0x4>;
+				interrupt-parent = <&gpio2>;
+				interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+				touch-gpios = <&gpio2 20 GPIO_ACTIVE_LOW>;
+				reset-gpios = <&gpio4 17 GPIO_LINE_OPEN_DRAIN>;
 			};
 		};
 	};
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related

* [PATCH 02/11] Input: bu21013_ts - convert to use GPIO descriptors
From: Dmitry Torokhov @ 2019-08-10  0:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-input, linux-kernel
In-Reply-To: <20190810002039.95876-1-dmitry.torokhov@gmail.com>

From: Linus Walleij <linus.walleij@linaro.org>

This driver can use GPIO descriptors rather than GPIO numbers
without any problems, convert it. Name the field variables after
the actual pins on the chip rather than the "reset" and "touch"
names from the devicetree bindings that are vaguely inaccurate.

No in-tree users pass GPIO numbers in platform data so drop
this. Descriptor tables can be used to get these GPIOs from a board
file if need be.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 .../bindings/input/touchscreen/bu21013.txt    |  5 +-
 drivers/input/touchscreen/bu21013_ts.c        | 86 ++++++++-----------
 include/linux/input/bu21013.h                 |  4 -
 3 files changed, 41 insertions(+), 54 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt b/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt
index 56d835242af2..43899fc36ecf 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt
@@ -2,10 +2,11 @@
 
 Required properties:
  - compatible              : "rohm,bu21013_tp"
- - reg                     :  I2C device address
+ - reg                     : I2C device address
+ - reset-gpios             : GPIO pin enabling (selecting) chip (CS)
 
 Optional properties:
- - touch-gpio              : GPIO pin registering a touch event
+ - touch-gpios             : GPIO pin registering a touch event
  - <supply_name>-supply    : Phandle to a regulator supply
  - rohm,touch-max-x        : Maximum outward permitted limit in the X axis
  - rohm,touch-max-y        : Maximum outward permitted limit in the Y axis
diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c
index 1d703e230ac3..c20f86f98ffc 100644
--- a/drivers/input/touchscreen/bu21013_ts.c
+++ b/drivers/input/touchscreen/bu21013_ts.c
@@ -14,11 +14,9 @@
 #include <linux/slab.h>
 #include <linux/regulator/consumer.h>
 #include <linux/module.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/of.h>
-#include <linux/of_gpio.h>
 
-#define PEN_DOWN_INTR	0
 #define MAX_FINGERS	2
 #define RESET_DELAY	30
 #define PENUP_TIMEOUT	(10)
@@ -143,8 +141,9 @@
  * @touch_stopped: touch stop flag
  * @chip: pointer to the touch panel controller
  * @in_dev: pointer to the input device structure
- * @intr_pin: interrupt pin value
  * @regulator: pointer to the Regulator used for touch screen
+ * @cs_gpiod: chip select GPIO line
+ * @int_gpiod: touch interrupt GPIO line
  *
  * Touch panel device data structure
  */
@@ -154,8 +153,9 @@ struct bu21013_ts_data {
 	const struct bu21013_platform_device *chip;
 	struct input_dev *in_dev;
 	struct regulator *regulator;
+	struct gpio_desc *cs_gpiod;
+	struct gpio_desc *int_gpiod;
 	unsigned int irq;
-	unsigned int intr_pin;
 	bool touch_stopped;
 };
 
@@ -257,20 +257,21 @@ static irqreturn_t bu21013_gpio_irq(int irq, void *device_data)
 {
 	struct bu21013_ts_data *data = device_data;
 	struct i2c_client *i2c = data->client;
+	int keep_polling;
 	int retval;
 
 	do {
 		retval = bu21013_do_touch_report(data);
 		if (retval < 0) {
 			dev_err(&i2c->dev, "bu21013_do_touch_report failed\n");
-			return IRQ_NONE;
+			break;
 		}
 
-		data->intr_pin = gpio_get_value(data->chip->touch_pin);
-		if (data->intr_pin == PEN_DOWN_INTR)
+		keep_polling = gpiod_get_value(data->int_gpiod);
+		if (keep_polling)
 			wait_event_timeout(data->wait, data->touch_stopped,
 					   msecs_to_jiffies(2));
-	} while (!data->intr_pin && !data->touch_stopped);
+	} while (keep_polling && !data->touch_stopped);
 
 	return IRQ_HANDLED;
 }
@@ -425,28 +426,6 @@ static void bu21013_free_irq(struct bu21013_ts_data *bu21013_data)
 	free_irq(bu21013_data->irq, bu21013_data);
 }
 
-/**
- * bu21013_cs_disable() - deconfigures the touch panel controller
- * @bu21013_data: device structure pointer
- *
- * This function is used to deconfigure the chip selection
- * for touch panel controller.
- */
-static void bu21013_cs_disable(struct bu21013_ts_data *bu21013_data)
-{
-	int error;
-
-	error = gpio_direction_output(bu21013_data->chip->cs_pin, 0);
-	if (error < 0)
-		dev_warn(&bu21013_data->client->dev,
-			 "%s: gpio direction failed, error: %d\n",
-			 __func__, error);
-	else
-		gpio_set_value(bu21013_data->chip->cs_pin, 0);
-
-	gpio_free(bu21013_data->chip->cs_pin);
-}
-
 #ifdef CONFIG_OF
 static const struct bu21013_platform_device *
 bu21013_parse_dt(struct device *dev)
@@ -471,9 +450,6 @@ bu21013_parse_dt(struct device *dev)
 	of_property_read_u32(np, "rohm,touch-max-x", &pdata->touch_x_max);
 	of_property_read_u32(np, "rohm,touch-max-y", &pdata->touch_y_max);
 
-	pdata->touch_pin = of_get_named_gpio(np, "touch-gpio", 0);
-	pdata->cs_pin = of_get_named_gpio(np, "reset-gpio", 0);
-
 	pdata->ext_clk = false;
 
 	return pdata;
@@ -516,11 +492,6 @@ static int bu21013_probe(struct i2c_client *client,
 			return PTR_ERR(pdata);
 	}
 
-	if (!gpio_is_valid(pdata->touch_pin)) {
-		dev_err(&client->dev, "invalid touch_pin supplied\n");
-		return -EINVAL;
-	}
-
 	bu21013_data = kzalloc(sizeof(struct bu21013_ts_data), GFP_KERNEL);
 	in_dev = input_allocate_device();
 	if (!bu21013_data || !in_dev) {
@@ -529,16 +500,26 @@ static int bu21013_probe(struct i2c_client *client,
 		goto err_free_mem;
 	}
 
+	/* Named "INT" on the chip, DT binding is "touch" */
+	bu21013_data->int_gpiod = gpiod_get(&client->dev, "touch", GPIOD_IN);
+	error = PTR_ERR_OR_ZERO(bu21013_data->int_gpiod);
+	if (error) {
+		if (error != -EPROBE_DEFER)
+			dev_err(&client->dev, "failed to get INT GPIO\n");
+		goto err_free_mem;
+	}
+	gpiod_set_consumer_name(bu21013_data->int_gpiod, "BU21013 INT");
+
 	bu21013_data->in_dev = in_dev;
 	bu21013_data->chip = pdata;
 	bu21013_data->client = client;
-	bu21013_data->irq = gpio_to_irq(pdata->touch_pin);
+	bu21013_data->irq = gpiod_to_irq(bu21013_data->int_gpiod);
 
 	bu21013_data->regulator = regulator_get(&client->dev, "avdd");
 	if (IS_ERR(bu21013_data->regulator)) {
 		dev_err(&client->dev, "regulator_get failed\n");
 		error = PTR_ERR(bu21013_data->regulator);
-		goto err_free_mem;
+		goto err_put_int_gpio;
 	}
 
 	error = regulator_enable(bu21013_data->regulator);
@@ -550,13 +531,16 @@ static int bu21013_probe(struct i2c_client *client,
 	bu21013_data->touch_stopped = false;
 	init_waitqueue_head(&bu21013_data->wait);
 
-	/* configure the gpio pins */
-	error = gpio_request_one(pdata->cs_pin, GPIOF_OUT_INIT_HIGH,
-				 "touchp_reset");
-	if (error < 0) {
-		dev_err(&client->dev, "Unable to request gpio reset_pin\n");
+	/* Named "CS" on the chip, DT binding is "reset" */
+	bu21013_data->cs_gpiod = gpiod_get(&client->dev, "reset",
+					   GPIOD_OUT_HIGH);
+	error = PTR_ERR_OR_ZERO(bu21013_data->cs_gpiod);
+	if (error) {
+		if (error != -EPROBE_DEFER)
+			dev_err(&client->dev, "failed to get CS GPIO\n");
 		goto err_disable_regulator;
 	}
+	gpiod_set_consumer_name(bu21013_data->cs_gpiod, "BU21013 CS");
 
 	/* configure the touch panel controller */
 	error = bu21013_init_chip(bu21013_data);
@@ -604,11 +588,14 @@ static int bu21013_probe(struct i2c_client *client,
 err_free_irq:
 	bu21013_free_irq(bu21013_data);
 err_cs_disable:
-	bu21013_cs_disable(bu21013_data);
+	gpiod_set_value(bu21013_data->cs_gpiod, 0);
+	gpiod_put(bu21013_data->cs_gpiod);
 err_disable_regulator:
 	regulator_disable(bu21013_data->regulator);
 err_put_regulator:
 	regulator_put(bu21013_data->regulator);
+err_put_int_gpio:
+	gpiod_put(bu21013_data->int_gpiod);
 err_free_mem:
 	input_free_device(in_dev);
 	kfree(bu21013_data);
@@ -628,13 +615,16 @@ static int bu21013_remove(struct i2c_client *client)
 
 	bu21013_free_irq(bu21013_data);
 
-	bu21013_cs_disable(bu21013_data);
+	gpiod_set_value(bu21013_data->cs_gpiod, 0);
+	gpiod_put(bu21013_data->cs_gpiod);
 
 	input_unregister_device(bu21013_data->in_dev);
 
 	regulator_disable(bu21013_data->regulator);
 	regulator_put(bu21013_data->regulator);
 
+	gpiod_put(bu21013_data->int_gpiod);
+
 	kfree(bu21013_data);
 
 	return 0;
diff --git a/include/linux/input/bu21013.h b/include/linux/input/bu21013.h
index 7e5b7e978e8a..58b1a9d44443 100644
--- a/include/linux/input/bu21013.h
+++ b/include/linux/input/bu21013.h
@@ -11,8 +11,6 @@
  * struct bu21013_platform_device - Handle the platform data
  * @touch_x_max: touch x max
  * @touch_y_max: touch y max
- * @cs_pin: chip select pin
- * @touch_pin: touch gpio pin
  * @ext_clk: external clock flag
  * @x_flip: x flip flag
  * @y_flip: y flip flag
@@ -23,8 +21,6 @@
 struct bu21013_platform_device {
 	int touch_x_max;
 	int touch_y_max;
-	unsigned int cs_pin;
-	unsigned int touch_pin;
 	bool ext_clk;
 	bool x_flip;
 	bool y_flip;
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related

* [PATCH 03/11] Input: bu21013_ts - rename some variables
From: Dmitry Torokhov @ 2019-08-10  0:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-input, linux-kernel
In-Reply-To: <20190810002039.95876-1-dmitry.torokhov@gmail.com>

"bu21013_data" and "struct bu21013_ts_data" are a tad long, let's call them
"ts" and "struct bu21013_ts".

Also rename retval to error in bu21013_init_chip() and adjust formatting;
i2c_smbus_write_byte_data() returns negative on error and 0 on success, so
we simply test if whether erro is 0 or not.

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

diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c
index c20f86f98ffc..e9cb020ed725 100644
--- a/drivers/input/touchscreen/bu21013_ts.c
+++ b/drivers/input/touchscreen/bu21013_ts.c
@@ -135,7 +135,7 @@
 #define DRIVER_TP	"bu21013_tp"
 
 /**
- * struct bu21013_ts_data - touch panel data structure
+ * struct bu21013_ts - touch panel data structure
  * @client: pointer to the i2c client
  * @wait: variable to wait_queue_head_t structure
  * @touch_stopped: touch stop flag
@@ -147,7 +147,7 @@
  *
  * Touch panel device data structure
  */
-struct bu21013_ts_data {
+struct bu21013_ts {
 	struct i2c_client *client;
 	wait_queue_head_t wait;
 	const struct bu21013_platform_device *chip;
@@ -161,34 +161,35 @@ struct bu21013_ts_data {
 
 /**
  * bu21013_read_block_data(): read the touch co-ordinates
- * @data: bu21013_ts_data structure pointer
+ * @data: bu21013_ts structure pointer
  * @buf: byte pointer
  *
  * Read the touch co-ordinates using i2c read block into buffer
  * and returns integer.
  */
-static int bu21013_read_block_data(struct bu21013_ts_data *data, u8 *buf)
+static int bu21013_read_block_data(struct bu21013_ts *ts, u8 *buf)
 {
 	int ret, i;
 
 	for (i = 0; i < I2C_RETRY_COUNT; i++) {
-		ret = i2c_smbus_read_i2c_block_data
-			(data->client, BU21013_SENSORS_BTN_0_7_REG,
-				LENGTH_OF_BUFFER, buf);
+		ret = i2c_smbus_read_i2c_block_data(ts->client,
+						    BU21013_SENSORS_BTN_0_7_REG,
+						    LENGTH_OF_BUFFER, buf);
 		if (ret == LENGTH_OF_BUFFER)
 			return 0;
 	}
+
 	return -EINVAL;
 }
 
 /**
  * bu21013_do_touch_report(): Get the touch co-ordinates
- * @data: bu21013_ts_data structure pointer
+ * @data: bu21013_ts structure pointer
  *
  * Get the touch co-ordinates from touch sensor registers and writes
  * into device structure and returns integer.
  */
-static int bu21013_do_touch_report(struct bu21013_ts_data *data)
+static int bu21013_do_touch_report(struct bu21013_ts *ts)
 {
 	u8	buf[LENGTH_OF_BUFFER];
 	unsigned int pos_x[2], pos_y[2];
@@ -196,10 +197,7 @@ static int bu21013_do_touch_report(struct bu21013_ts_data *data)
 	int	finger_down_count = 0;
 	int	i;
 
-	if (data == NULL)
-		return -EINVAL;
-
-	if (bu21013_read_block_data(data, buf) < 0)
+	if (bu21013_read_block_data(ts, buf) < 0)
 		return -EINVAL;
 
 	has_x_sensors = hweight32(buf[0] & BU21013_SENSORS_EN_0_7);
@@ -227,21 +225,21 @@ static int bu21013_do_touch_report(struct bu21013_ts_data *data)
 		}
 
 		for (i = 0; i < finger_down_count; i++) {
-			if (data->chip->x_flip)
-				pos_x[i] = data->chip->touch_x_max - pos_x[i];
-			if (data->chip->y_flip)
-				pos_y[i] = data->chip->touch_y_max - pos_y[i];
+			if (ts->chip->x_flip)
+				pos_x[i] = ts->chip->touch_x_max - pos_x[i];
+			if (ts->chip->y_flip)
+				pos_y[i] = ts->chip->touch_y_max - pos_y[i];
 
-			input_report_abs(data->in_dev,
+			input_report_abs(ts->in_dev,
 					 ABS_MT_POSITION_X, pos_x[i]);
-			input_report_abs(data->in_dev,
+			input_report_abs(ts->in_dev,
 					 ABS_MT_POSITION_Y, pos_y[i]);
-			input_mt_sync(data->in_dev);
+			input_mt_sync(ts->in_dev);
 		}
 	} else
-		input_mt_sync(data->in_dev);
+		input_mt_sync(ts->in_dev);
 
-	input_sync(data->in_dev);
+	input_sync(ts->in_dev);
 
 	return 0;
 }
@@ -255,23 +253,22 @@ static int bu21013_do_touch_report(struct bu21013_ts_data *data)
  */
 static irqreturn_t bu21013_gpio_irq(int irq, void *device_data)
 {
-	struct bu21013_ts_data *data = device_data;
-	struct i2c_client *i2c = data->client;
+	struct bu21013_ts *ts = device_data;
 	int keep_polling;
-	int retval;
+	int error;
 
 	do {
-		retval = bu21013_do_touch_report(data);
-		if (retval < 0) {
-			dev_err(&i2c->dev, "bu21013_do_touch_report failed\n");
+		error = bu21013_do_touch_report(ts);
+		if (error) {
+			dev_err(&ts->client->dev, "%s failed\n", __func__);
 			break;
 		}
 
-		keep_polling = gpiod_get_value(data->int_gpiod);
+		keep_polling = gpiod_get_value(ts->int_gpiod);
 		if (keep_polling)
-			wait_event_timeout(data->wait, data->touch_stopped,
+			wait_event_timeout(ts->wait, ts->touch_stopped,
 					   msecs_to_jiffies(2));
-	} while (keep_polling && !data->touch_stopped);
+	} while (keep_polling && !ts->touch_stopped);
 
 	return IRQ_HANDLED;
 }
@@ -283,130 +280,138 @@ static irqreturn_t bu21013_gpio_irq(int irq, void *device_data)
  * This function is used to power on
  * the bu21013 controller and returns integer.
  */
-static int bu21013_init_chip(struct bu21013_ts_data *data)
+static int bu21013_init_chip(struct bu21013_ts *ts)
 {
-	int retval;
-	struct i2c_client *i2c = data->client;
+	struct i2c_client *client = ts->client;
+	int error;
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_RESET_REG,
-					BU21013_RESET_ENABLE);
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_RESET reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_RESET_REG,
+					  BU21013_RESET_ENABLE);
+	if (error) {
+		dev_err(&client->dev, "BU21013_RESET reg write failed\n");
+		return error;
 	}
 	msleep(RESET_DELAY);
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_0_7_REG,
-					BU21013_SENSORS_EN_0_7);
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_SENSOR_0_7 reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_SENSOR_0_7_REG,
+					  BU21013_SENSORS_EN_0_7);
+	if (error) {
+		dev_err(&client->dev, "BU21013_SENSOR_0_7 reg write failed\n");
+		return error;
 	}
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_8_15_REG,
-						BU21013_SENSORS_EN_8_15);
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_SENSOR_8_15 reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_SENSOR_8_15_REG,
+					  BU21013_SENSORS_EN_8_15);
+	if (error) {
+		dev_err(&client->dev, "BU21013_SENSOR_8_15 reg write failed\n");
+		return error;
 	}
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_16_23_REG,
-						BU21013_SENSORS_EN_16_23);
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_SENSOR_16_23 reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_SENSOR_16_23_REG,
+					  BU21013_SENSORS_EN_16_23);
+	if (error) {
+		dev_err(&client->dev, "BU21013_SENSOR_16_23 reg write failed\n");
+		return error;
 	}
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_POS_MODE1_REG,
-				(BU21013_POS_MODE1_0 | BU21013_POS_MODE1_1));
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_POS_MODE1 reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_POS_MODE1_REG,
+					  BU21013_POS_MODE1_0 |
+						BU21013_POS_MODE1_1);
+	if (error) {
+		dev_err(&client->dev, "BU21013_POS_MODE1 reg write failed\n");
+		return error;
 	}
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_POS_MODE2_REG,
-			(BU21013_POS_MODE2_ZERO | BU21013_POS_MODE2_AVG1 |
-			BU21013_POS_MODE2_AVG2 | BU21013_POS_MODE2_EN_RAW |
-			BU21013_POS_MODE2_MULTI));
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_POS_MODE2 reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_POS_MODE2_REG,
+					  BU21013_POS_MODE2_ZERO |
+						BU21013_POS_MODE2_AVG1 |
+						BU21013_POS_MODE2_AVG2 |
+						BU21013_POS_MODE2_EN_RAW |
+						BU21013_POS_MODE2_MULTI);
+	if (error) {
+		dev_err(&client->dev, "BU21013_POS_MODE2 reg write failed\n");
+		return error;
 	}
 
-	if (data->chip->ext_clk)
-		retval = i2c_smbus_write_byte_data(i2c, BU21013_CLK_MODE_REG,
-			(BU21013_CLK_MODE_EXT | BU21013_CLK_MODE_CALIB));
+	if (ts->chip->ext_clk)
+		error = i2c_smbus_write_byte_data(client, BU21013_CLK_MODE_REG,
+						  BU21013_CLK_MODE_EXT |
+							BU21013_CLK_MODE_CALIB);
 	else
-		retval = i2c_smbus_write_byte_data(i2c, BU21013_CLK_MODE_REG,
-			(BU21013_CLK_MODE_DIV | BU21013_CLK_MODE_CALIB));
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_CLK_MODE reg write failed\n");
-		return retval;
+		error = i2c_smbus_write_byte_data(client, BU21013_CLK_MODE_REG,
+						  BU21013_CLK_MODE_DIV |
+							BU21013_CLK_MODE_CALIB);
+	if (error) {
+		dev_err(&client->dev, "BU21013_CLK_MODE reg write failed\n");
+		return error;
 	}
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_IDLE_REG,
-				(BU21013_IDLET_0 | BU21013_IDLE_INTERMIT_EN));
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_IDLE reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_IDLE_REG,
+					  BU21013_IDLET_0 |
+						BU21013_IDLE_INTERMIT_EN);
+	if (error) {
+		dev_err(&client->dev, "BU21013_IDLE reg write failed\n");
+		return error;
 	}
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_INT_MODE_REG,
-						BU21013_INT_MODE_LEVEL);
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_INT_MODE reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_INT_MODE_REG,
+					  BU21013_INT_MODE_LEVEL);
+	if (error) {
+		dev_err(&client->dev, "BU21013_INT_MODE reg write failed\n");
+		return error;
 	}
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_FILTER_REG,
-						(BU21013_DELTA_0_6 |
-							BU21013_FILTER_EN));
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_FILTER reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_FILTER_REG,
+					  BU21013_DELTA_0_6 |
+						BU21013_FILTER_EN);
+	if (error) {
+		dev_err(&client->dev, "BU21013_FILTER reg write failed\n");
+		return error;
 	}
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_ON_REG,
-					BU21013_TH_ON_5);
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_TH_ON reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_TH_ON_REG,
+					  BU21013_TH_ON_5);
+	if (error) {
+		dev_err(&client->dev, "BU21013_TH_ON reg write failed\n");
+		return error;
 	}
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_OFF_REG,
-				BU21013_TH_OFF_4 | BU21013_TH_OFF_3);
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_TH_OFF reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_TH_OFF_REG,
+					  BU21013_TH_OFF_4 | BU21013_TH_OFF_3);
+	if (error) {
+		dev_err(&client->dev, "BU21013_TH_OFF reg write failed\n");
+		return error;
 	}
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_GAIN_REG,
-					(BU21013_GAIN_0 | BU21013_GAIN_1));
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_GAIN reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_GAIN_REG,
+					  BU21013_GAIN_0 | BU21013_GAIN_1);
+	if (error) {
+		dev_err(&client->dev, "BU21013_GAIN reg write failed\n");
+		return error;
 	}
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_OFFSET_MODE_REG,
-					BU21013_OFFSET_MODE_DEFAULT);
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_OFFSET_MODE reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_OFFSET_MODE_REG,
+					  BU21013_OFFSET_MODE_DEFAULT);
+	if (error) {
+		dev_err(&client->dev, "BU21013_OFFSET_MODE reg write failed\n");
+		return error;
 	}
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_XY_EDGE_REG,
-				(BU21013_X_EDGE_0 | BU21013_X_EDGE_2 |
-				BU21013_Y_EDGE_1 | BU21013_Y_EDGE_3));
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_XY_EDGE reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_XY_EDGE_REG,
+					  BU21013_X_EDGE_0 |
+						BU21013_X_EDGE_2 |
+						BU21013_Y_EDGE_1 |
+						BU21013_Y_EDGE_3);
+	if (error) {
+		dev_err(&client->dev, "BU21013_XY_EDGE reg write failed\n");
+		return error;
 	}
 
-	retval = i2c_smbus_write_byte_data(i2c, BU21013_DONE_REG,
-							BU21013_DONE);
-	if (retval < 0) {
-		dev_err(&i2c->dev, "BU21013_REG_DONE reg write failed\n");
-		return retval;
+	error = i2c_smbus_write_byte_data(client, BU21013_DONE_REG,
+					  BU21013_DONE);
+	if (error) {
+		dev_err(&client->dev, "BU21013_REG_DONE reg write failed\n");
+		return error;
 	}
 
 	return 0;
@@ -414,16 +419,16 @@ static int bu21013_init_chip(struct bu21013_ts_data *data)
 
 /**
  * bu21013_free_irq() - frees IRQ registered for touchscreen
- * @bu21013_data: device structure pointer
+ * @ts: device structure pointer
  *
  * This function signals interrupt thread to stop processing and
  * frees interrupt.
  */
-static void bu21013_free_irq(struct bu21013_ts_data *bu21013_data)
+static void bu21013_free_irq(struct bu21013_ts *ts)
 {
-	bu21013_data->touch_stopped = true;
-	wake_up(&bu21013_data->wait);
-	free_irq(bu21013_data->irq, bu21013_data);
+	ts->touch_stopped = true;
+	wake_up(&ts->wait);
+	free_irq(ts->irq, ts);
 }
 
 #ifdef CONFIG_OF
@@ -476,12 +481,12 @@ static int bu21013_probe(struct i2c_client *client,
 {
 	const struct bu21013_platform_device *pdata =
 					dev_get_platdata(&client->dev);
-	struct bu21013_ts_data *bu21013_data;
+	struct bu21013_ts *ts;
 	struct input_dev *in_dev;
 	int error;
 
 	if (!i2c_check_functionality(client->adapter,
-					I2C_FUNC_SMBUS_BYTE_DATA)) {
+				     I2C_FUNC_SMBUS_BYTE_DATA)) {
 		dev_err(&client->dev, "i2c smbus byte data not supported\n");
 		return -EIO;
 	}
@@ -492,58 +497,57 @@ static int bu21013_probe(struct i2c_client *client,
 			return PTR_ERR(pdata);
 	}
 
-	bu21013_data = kzalloc(sizeof(struct bu21013_ts_data), GFP_KERNEL);
+	ts = kzalloc(sizeof(*ts), GFP_KERNEL);
 	in_dev = input_allocate_device();
-	if (!bu21013_data || !in_dev) {
+	if (!ts || !in_dev) {
 		dev_err(&client->dev, "device memory alloc failed\n");
 		error = -ENOMEM;
 		goto err_free_mem;
 	}
 
 	/* Named "INT" on the chip, DT binding is "touch" */
-	bu21013_data->int_gpiod = gpiod_get(&client->dev, "touch", GPIOD_IN);
-	error = PTR_ERR_OR_ZERO(bu21013_data->int_gpiod);
+	ts->int_gpiod = gpiod_get(&client->dev, "touch", GPIOD_IN);
+	error = PTR_ERR_OR_ZERO(ts->int_gpiod);
 	if (error) {
 		if (error != -EPROBE_DEFER)
 			dev_err(&client->dev, "failed to get INT GPIO\n");
 		goto err_free_mem;
 	}
-	gpiod_set_consumer_name(bu21013_data->int_gpiod, "BU21013 INT");
+	gpiod_set_consumer_name(ts->int_gpiod, "BU21013 INT");
 
-	bu21013_data->in_dev = in_dev;
-	bu21013_data->chip = pdata;
-	bu21013_data->client = client;
-	bu21013_data->irq = gpiod_to_irq(bu21013_data->int_gpiod);
+	ts->in_dev = in_dev;
+	ts->chip = pdata;
+	ts->client = client;
+	ts->irq = gpiod_to_irq(ts->int_gpiod);
 
-	bu21013_data->regulator = regulator_get(&client->dev, "avdd");
-	if (IS_ERR(bu21013_data->regulator)) {
+	ts->regulator = regulator_get(&client->dev, "avdd");
+	if (IS_ERR(ts->regulator)) {
 		dev_err(&client->dev, "regulator_get failed\n");
-		error = PTR_ERR(bu21013_data->regulator);
+		error = PTR_ERR(ts->regulator);
 		goto err_put_int_gpio;
 	}
 
-	error = regulator_enable(bu21013_data->regulator);
+	error = regulator_enable(ts->regulator);
 	if (error < 0) {
 		dev_err(&client->dev, "regulator enable failed\n");
 		goto err_put_regulator;
 	}
 
-	bu21013_data->touch_stopped = false;
-	init_waitqueue_head(&bu21013_data->wait);
+	ts->touch_stopped = false;
+	init_waitqueue_head(&ts->wait);
 
 	/* Named "CS" on the chip, DT binding is "reset" */
-	bu21013_data->cs_gpiod = gpiod_get(&client->dev, "reset",
-					   GPIOD_OUT_HIGH);
-	error = PTR_ERR_OR_ZERO(bu21013_data->cs_gpiod);
+	ts->cs_gpiod = gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
+	error = PTR_ERR_OR_ZERO(ts->cs_gpiod);
 	if (error) {
 		if (error != -EPROBE_DEFER)
 			dev_err(&client->dev, "failed to get CS GPIO\n");
 		goto err_disable_regulator;
 	}
-	gpiod_set_consumer_name(bu21013_data->cs_gpiod, "BU21013 CS");
+	gpiod_set_consumer_name(ts->cs_gpiod, "BU21013 CS");
 
 	/* configure the touch panel controller */
-	error = bu21013_init_chip(bu21013_data);
+	error = bu21013_init_chip(ts);
 	if (error) {
 		dev_err(&client->dev, "error in bu21013 config\n");
 		goto err_cs_disable;
@@ -558,19 +562,19 @@ static int bu21013_probe(struct i2c_client *client,
 	__set_bit(EV_KEY, in_dev->evbit);
 	__set_bit(EV_ABS, in_dev->evbit);
 
-	input_set_abs_params(in_dev, ABS_MT_POSITION_X, 0,
-						pdata->touch_x_max, 0, 0);
-	input_set_abs_params(in_dev, ABS_MT_POSITION_Y, 0,
-						pdata->touch_y_max, 0, 0);
-	input_set_drvdata(in_dev, bu21013_data);
+	input_set_abs_params(in_dev, ABS_MT_POSITION_X,
+			     0, pdata->touch_x_max, 0, 0);
+	input_set_abs_params(in_dev, ABS_MT_POSITION_Y,
+			     0, pdata->touch_y_max, 0, 0);
+	input_set_drvdata(in_dev, ts);
 
-	error = request_threaded_irq(bu21013_data->irq, NULL, bu21013_gpio_irq,
+	error = request_threaded_irq(ts->irq, NULL, bu21013_gpio_irq,
 				     IRQF_TRIGGER_FALLING | IRQF_SHARED |
 					IRQF_ONESHOT,
-				     DRIVER_TP, bu21013_data);
+				     DRIVER_TP, ts);
 	if (error) {
 		dev_err(&client->dev, "request irq %d failed\n",
-			bu21013_data->irq);
+			ts->irq);
 		goto err_cs_disable;
 	}
 
@@ -581,24 +585,24 @@ static int bu21013_probe(struct i2c_client *client,
 	}
 
 	device_init_wakeup(&client->dev, pdata->wakeup);
-	i2c_set_clientdata(client, bu21013_data);
+	i2c_set_clientdata(client, ts);
 
 	return 0;
 
 err_free_irq:
-	bu21013_free_irq(bu21013_data);
+	bu21013_free_irq(ts);
 err_cs_disable:
-	gpiod_set_value(bu21013_data->cs_gpiod, 0);
-	gpiod_put(bu21013_data->cs_gpiod);
+	gpiod_set_value(ts->cs_gpiod, 0);
+	gpiod_put(ts->cs_gpiod);
 err_disable_regulator:
-	regulator_disable(bu21013_data->regulator);
+	regulator_disable(ts->regulator);
 err_put_regulator:
-	regulator_put(bu21013_data->regulator);
+	regulator_put(ts->regulator);
 err_put_int_gpio:
-	gpiod_put(bu21013_data->int_gpiod);
+	gpiod_put(ts->int_gpiod);
 err_free_mem:
 	input_free_device(in_dev);
-	kfree(bu21013_data);
+	kfree(ts);
 
 	return error;
 }
@@ -611,21 +615,21 @@ static int bu21013_probe(struct i2c_client *client,
  */
 static int bu21013_remove(struct i2c_client *client)
 {
-	struct bu21013_ts_data *bu21013_data = i2c_get_clientdata(client);
+	struct bu21013_ts *ts = i2c_get_clientdata(client);
 
-	bu21013_free_irq(bu21013_data);
+	bu21013_free_irq(ts);
 
-	gpiod_set_value(bu21013_data->cs_gpiod, 0);
-	gpiod_put(bu21013_data->cs_gpiod);
+	gpiod_set_value(ts->cs_gpiod, 0);
+	gpiod_put(ts->cs_gpiod);
 
-	input_unregister_device(bu21013_data->in_dev);
+	input_unregister_device(ts->in_dev);
 
-	regulator_disable(bu21013_data->regulator);
-	regulator_put(bu21013_data->regulator);
+	regulator_disable(ts->regulator);
+	regulator_put(ts->regulator);
 
-	gpiod_put(bu21013_data->int_gpiod);
+	gpiod_put(ts->int_gpiod);
 
-	kfree(bu21013_data);
+	kfree(ts);
 
 	return 0;
 }
@@ -640,16 +644,16 @@ static int bu21013_remove(struct i2c_client *client)
  */
 static int bu21013_suspend(struct device *dev)
 {
-	struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev);
-	struct i2c_client *client = bu21013_data->client;
+	struct bu21013_ts *ts = dev_get_drvdata(dev);
+	struct i2c_client *client = ts->client;
 
-	bu21013_data->touch_stopped = true;
+	ts->touch_stopped = true;
 	if (device_may_wakeup(&client->dev))
-		enable_irq_wake(bu21013_data->irq);
+		enable_irq_wake(ts->irq);
 	else
-		disable_irq(bu21013_data->irq);
+		disable_irq(ts->irq);
 
-	regulator_disable(bu21013_data->regulator);
+	regulator_disable(ts->regulator);
 
 	return 0;
 }
@@ -663,28 +667,28 @@ static int bu21013_suspend(struct device *dev)
  */
 static int bu21013_resume(struct device *dev)
 {
-	struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev);
-	struct i2c_client *client = bu21013_data->client;
+	struct bu21013_ts *ts = dev_get_drvdata(dev);
+	struct i2c_client *client = ts->client;
 	int retval;
 
-	retval = regulator_enable(bu21013_data->regulator);
+	retval = regulator_enable(ts->regulator);
 	if (retval < 0) {
 		dev_err(&client->dev, "bu21013 regulator enable failed\n");
 		return retval;
 	}
 
-	retval = bu21013_init_chip(bu21013_data);
+	retval = bu21013_init_chip(ts);
 	if (retval < 0) {
 		dev_err(&client->dev, "bu21013 controller config failed\n");
 		return retval;
 	}
 
-	bu21013_data->touch_stopped = false;
+	ts->touch_stopped = false;
 
 	if (device_may_wakeup(&client->dev))
-		disable_irq_wake(bu21013_data->irq);
+		disable_irq_wake(ts->irq);
 	else
-		enable_irq(bu21013_data->irq);
+		enable_irq(ts->irq);
 
 	return 0;
 }
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related

* [PATCH 04/11] Input: bu21013_ts - annotate supend/resume methods as __maybe_unused
From: Dmitry Torokhov @ 2019-08-10  0:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-input, linux-kernel
In-Reply-To: <20190810002039.95876-1-dmitry.torokhov@gmail.com>

Instead if #ifdef-ing out suspend and resume methods, let's mark
them as __maybe_unused to get better compile time coverage.

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

diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c
index e9cb020ed725..0bdadd24296f 100644
--- a/drivers/input/touchscreen/bu21013_ts.c
+++ b/drivers/input/touchscreen/bu21013_ts.c
@@ -634,7 +634,6 @@ static int bu21013_remove(struct i2c_client *client)
 	return 0;
 }
 
-#ifdef CONFIG_PM
 /**
  * bu21013_suspend() - suspend the touch screen controller
  * @dev: pointer to device structure
@@ -642,7 +641,7 @@ static int bu21013_remove(struct i2c_client *client)
  * This function is used to suspend the
  * touch panel controller and returns integer
  */
-static int bu21013_suspend(struct device *dev)
+static int __maybe_unused bu21013_suspend(struct device *dev)
 {
 	struct bu21013_ts *ts = dev_get_drvdata(dev);
 	struct i2c_client *client = ts->client;
@@ -665,7 +664,7 @@ static int bu21013_suspend(struct device *dev)
  * This function is used to resume the touch panel
  * controller and returns integer.
  */
-static int bu21013_resume(struct device *dev)
+static int __maybe_unused bu21013_resume(struct device *dev)
 {
 	struct bu21013_ts *ts = dev_get_drvdata(dev);
 	struct i2c_client *client = ts->client;
@@ -693,11 +692,7 @@ static int bu21013_resume(struct device *dev)
 	return 0;
 }
 
-static const struct dev_pm_ops bu21013_dev_pm_ops = {
-	.suspend = bu21013_suspend,
-	.resume  = bu21013_resume,
-};
-#endif
+static SIMPLE_DEV_PM_OPS(bu21013_dev_pm_ops, bu21013_suspend, bu21013_resume);
 
 static const struct i2c_device_id bu21013_id[] = {
 	{ DRIVER_TP, 0 },
@@ -708,9 +703,7 @@ MODULE_DEVICE_TABLE(i2c, bu21013_id);
 static struct i2c_driver bu21013_driver = {
 	.driver	= {
 		.name	=	DRIVER_TP,
-#ifdef CONFIG_PM
 		.pm	=	&bu21013_dev_pm_ops,
-#endif
 	},
 	.probe		=	bu21013_probe,
 	.remove		=	bu21013_remove,
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related

* [PATCH 05/11] Input: bu21013_ts - remove useless comments
From: Dmitry Torokhov @ 2019-08-10  0:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-input, linux-kernel
In-Reply-To: <20190810002039.95876-1-dmitry.torokhov@gmail.com>

The comments for individual functions in the driver do not provide any
additional information beyond what function names indicate.

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

diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c
index 0bdadd24296f..a5230f6ea5f0 100644
--- a/drivers/input/touchscreen/bu21013_ts.c
+++ b/drivers/input/touchscreen/bu21013_ts.c
@@ -159,14 +159,6 @@ struct bu21013_ts {
 	bool touch_stopped;
 };
 
-/**
- * bu21013_read_block_data(): read the touch co-ordinates
- * @data: bu21013_ts structure pointer
- * @buf: byte pointer
- *
- * Read the touch co-ordinates using i2c read block into buffer
- * and returns integer.
- */
 static int bu21013_read_block_data(struct bu21013_ts *ts, u8 *buf)
 {
 	int ret, i;
@@ -182,13 +174,6 @@ static int bu21013_read_block_data(struct bu21013_ts *ts, u8 *buf)
 	return -EINVAL;
 }
 
-/**
- * bu21013_do_touch_report(): Get the touch co-ordinates
- * @data: bu21013_ts structure pointer
- *
- * Get the touch co-ordinates from touch sensor registers and writes
- * into device structure and returns integer.
- */
 static int bu21013_do_touch_report(struct bu21013_ts *ts)
 {
 	u8	buf[LENGTH_OF_BUFFER];
@@ -243,14 +228,7 @@ static int bu21013_do_touch_report(struct bu21013_ts *ts)
 
 	return 0;
 }
-/**
- * bu21013_gpio_irq() - gpio thread function for touch interrupt
- * @irq: irq value
- * @device_data: void pointer
- *
- * This gpio thread function for touch interrupt
- * and returns irqreturn_t.
- */
+
 static irqreturn_t bu21013_gpio_irq(int irq, void *device_data)
 {
 	struct bu21013_ts *ts = device_data;
@@ -273,13 +251,6 @@ static irqreturn_t bu21013_gpio_irq(int irq, void *device_data)
 	return IRQ_HANDLED;
 }
 
-/**
- * bu21013_init_chip() - power on sequence for the bu21013 controller
- * @data: device structure pointer
- *
- * This function is used to power on
- * the bu21013 controller and returns integer.
- */
 static int bu21013_init_chip(struct bu21013_ts *ts)
 {
 	struct i2c_client *client = ts->client;
@@ -468,14 +439,6 @@ bu21013_parse_dt(struct device *dev)
 }
 #endif
 
-/**
- * bu21013_probe() - initializes the i2c-client touchscreen driver
- * @client: i2c client structure pointer
- * @id: i2c device id pointer
- *
- * This function used to initializes the i2c-client touchscreen
- * driver and returns integer.
- */
 static int bu21013_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
@@ -606,13 +569,7 @@ static int bu21013_probe(struct i2c_client *client,
 
 	return error;
 }
-/**
- * bu21013_remove() - removes the i2c-client touchscreen driver
- * @client: i2c client structure pointer
- *
- * This function uses to remove the i2c-client
- * touchscreen driver and returns integer.
- */
+
 static int bu21013_remove(struct i2c_client *client)
 {
 	struct bu21013_ts *ts = i2c_get_clientdata(client);
@@ -634,13 +591,6 @@ static int bu21013_remove(struct i2c_client *client)
 	return 0;
 }
 
-/**
- * bu21013_suspend() - suspend the touch screen controller
- * @dev: pointer to device structure
- *
- * This function is used to suspend the
- * touch panel controller and returns integer
- */
 static int __maybe_unused bu21013_suspend(struct device *dev)
 {
 	struct bu21013_ts *ts = dev_get_drvdata(dev);
@@ -657,13 +607,6 @@ static int __maybe_unused bu21013_suspend(struct device *dev)
 	return 0;
 }
 
-/**
- * bu21013_resume() - resume the touch screen controller
- * @dev: pointer to device structure
- *
- * This function is used to resume the touch panel
- * controller and returns integer.
- */
 static int __maybe_unused bu21013_resume(struct device *dev)
 {
 	struct bu21013_ts *ts = dev_get_drvdata(dev);
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related

* [PATCH 06/11] Input: bu21013_ts - convert to using managed resources
From: Dmitry Torokhov @ 2019-08-10  0:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-input, linux-kernel
In-Reply-To: <20190810002039.95876-1-dmitry.torokhov@gmail.com>

This allows trimming error unwinding and device removal handling.

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

diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c
index a5230f6ea5f0..4b6f9544e94a 100644
--- a/drivers/input/touchscreen/bu21013_ts.c
+++ b/drivers/input/touchscreen/bu21013_ts.c
@@ -137,7 +137,6 @@
 /**
  * struct bu21013_ts - touch panel data structure
  * @client: pointer to the i2c client
- * @wait: variable to wait_queue_head_t structure
  * @touch_stopped: touch stop flag
  * @chip: pointer to the touch panel controller
  * @in_dev: pointer to the input device structure
@@ -149,7 +148,6 @@
  */
 struct bu21013_ts {
 	struct i2c_client *client;
-	wait_queue_head_t wait;
 	const struct bu21013_platform_device *chip;
 	struct input_dev *in_dev;
 	struct regulator *regulator;
@@ -242,11 +240,13 @@ static irqreturn_t bu21013_gpio_irq(int irq, void *device_data)
 			break;
 		}
 
+		if (unlikely(ts->touch_stopped))
+			break;
+
 		keep_polling = gpiod_get_value(ts->int_gpiod);
 		if (keep_polling)
-			wait_event_timeout(ts->wait, ts->touch_stopped,
-					   msecs_to_jiffies(2));
-	} while (keep_polling && !ts->touch_stopped);
+			usleep_range(2000, 2500);
+	} while (keep_polling);
 
 	return IRQ_HANDLED;
 }
@@ -388,20 +388,6 @@ static int bu21013_init_chip(struct bu21013_ts *ts)
 	return 0;
 }
 
-/**
- * bu21013_free_irq() - frees IRQ registered for touchscreen
- * @ts: device structure pointer
- *
- * This function signals interrupt thread to stop processing and
- * frees interrupt.
- */
-static void bu21013_free_irq(struct bu21013_ts *ts)
-{
-	ts->touch_stopped = true;
-	wake_up(&ts->wait);
-	free_irq(ts->irq, ts);
-}
-
 #ifdef CONFIG_OF
 static const struct bu21013_platform_device *
 bu21013_parse_dt(struct device *dev)
@@ -439,6 +425,20 @@ bu21013_parse_dt(struct device *dev)
 }
 #endif
 
+static void bu21013_power_off(void *_ts)
+{
+	struct bu21013_ts *ts = ts;
+
+	regulator_disable(ts->regulator);
+}
+
+static void bu21013_disable_chip(void *_ts)
+{
+	struct bu21013_ts *ts = ts;
+
+	gpiod_set_value(ts->cs_gpiod, 0);
+}
+
 static int bu21013_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
@@ -460,133 +460,119 @@ static int bu21013_probe(struct i2c_client *client,
 			return PTR_ERR(pdata);
 	}
 
-	ts = kzalloc(sizeof(*ts), GFP_KERNEL);
-	in_dev = input_allocate_device();
-	if (!ts || !in_dev) {
+	ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
+	if (!ts)
+		return -ENOMEM;
+
+	ts->chip = pdata;
+	ts->client = client;
+
+	in_dev = devm_input_allocate_device(&client->dev);
+	if (!in_dev) {
 		dev_err(&client->dev, "device memory alloc failed\n");
-		error = -ENOMEM;
-		goto err_free_mem;
+		return -ENOMEM;
 	}
+	ts->in_dev = in_dev;
 
-	/* Named "INT" on the chip, DT binding is "touch" */
-	ts->int_gpiod = gpiod_get(&client->dev, "touch", GPIOD_IN);
-	error = PTR_ERR_OR_ZERO(ts->int_gpiod);
-	if (error) {
-		if (error != -EPROBE_DEFER)
-			dev_err(&client->dev, "failed to get INT GPIO\n");
-		goto err_free_mem;
-	}
-	gpiod_set_consumer_name(ts->int_gpiod, "BU21013 INT");
+	/* register the device to input subsystem */
+	in_dev->name = DRIVER_TP;
+	in_dev->id.bustype = BUS_I2C;
 
-	ts->in_dev = in_dev;
-	ts->chip = pdata;
-	ts->client = client;
-	ts->irq = gpiod_to_irq(ts->int_gpiod);
+	__set_bit(EV_SYN, in_dev->evbit);
+	__set_bit(EV_KEY, in_dev->evbit);
+	__set_bit(EV_ABS, in_dev->evbit);
+
+	input_set_abs_params(in_dev, ABS_MT_POSITION_X,
+			     0, pdata->touch_x_max, 0, 0);
+	input_set_abs_params(in_dev, ABS_MT_POSITION_Y,
+			     0, pdata->touch_y_max, 0, 0);
+	input_set_drvdata(in_dev, ts);
 
-	ts->regulator = regulator_get(&client->dev, "avdd");
+	ts->regulator = devm_regulator_get(&client->dev, "avdd");
 	if (IS_ERR(ts->regulator)) {
 		dev_err(&client->dev, "regulator_get failed\n");
-		error = PTR_ERR(ts->regulator);
-		goto err_put_int_gpio;
+		return PTR_ERR(ts->regulator);
 	}
 
 	error = regulator_enable(ts->regulator);
-	if (error < 0) {
+	if (error) {
 		dev_err(&client->dev, "regulator enable failed\n");
-		goto err_put_regulator;
+		return error;
 	}
 
-	ts->touch_stopped = false;
-	init_waitqueue_head(&ts->wait);
+	error = devm_add_action_or_reset(&client->dev, bu21013_power_off, ts);
+	if (error) {
+		dev_err(&client->dev, "failed to install power off handler\n");
+		return error;
+	}
 
 	/* Named "CS" on the chip, DT binding is "reset" */
-	ts->cs_gpiod = gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
+	ts->cs_gpiod = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
 	error = PTR_ERR_OR_ZERO(ts->cs_gpiod);
 	if (error) {
 		if (error != -EPROBE_DEFER)
 			dev_err(&client->dev, "failed to get CS GPIO\n");
-		goto err_disable_regulator;
+		return error;
 	}
 	gpiod_set_consumer_name(ts->cs_gpiod, "BU21013 CS");
 
+	error = devm_add_action_or_reset(&client->dev,
+					 bu21013_disable_chip, ts);
+	if (error) {
+		dev_err(&client->dev,
+			"failed to install chip disable handler\n");
+		return error;
+	}
+
+	/* Named "INT" on the chip, DT binding is "touch" */
+	ts->int_gpiod = devm_gpiod_get(&client->dev, "touch", GPIOD_IN);
+	error = PTR_ERR_OR_ZERO(ts->int_gpiod);
+	if (error) {
+		if (error != -EPROBE_DEFER)
+			dev_err(&client->dev, "failed to get INT GPIO\n");
+		return error;
+	}
+	gpiod_set_consumer_name(ts->int_gpiod, "BU21013 INT");
+
 	/* configure the touch panel controller */
 	error = bu21013_init_chip(ts);
 	if (error) {
 		dev_err(&client->dev, "error in bu21013 config\n");
-		goto err_cs_disable;
+		return error;
 	}
 
-	/* register the device to input subsystem */
-	in_dev->name = DRIVER_TP;
-	in_dev->id.bustype = BUS_I2C;
-	in_dev->dev.parent = &client->dev;
-
-	__set_bit(EV_SYN, in_dev->evbit);
-	__set_bit(EV_KEY, in_dev->evbit);
-	__set_bit(EV_ABS, in_dev->evbit);
-
-	input_set_abs_params(in_dev, ABS_MT_POSITION_X,
-			     0, pdata->touch_x_max, 0, 0);
-	input_set_abs_params(in_dev, ABS_MT_POSITION_Y,
-			     0, pdata->touch_y_max, 0, 0);
-	input_set_drvdata(in_dev, ts);
-
-	error = request_threaded_irq(ts->irq, NULL, bu21013_gpio_irq,
-				     IRQF_TRIGGER_FALLING | IRQF_SHARED |
-					IRQF_ONESHOT,
-				     DRIVER_TP, ts);
+	ts->irq = gpiod_to_irq(ts->int_gpiod);
+	error = devm_request_threaded_irq(&client->dev, ts->irq,
+					  NULL, bu21013_gpio_irq,
+					  IRQF_TRIGGER_FALLING |
+						IRQF_SHARED |
+						IRQF_ONESHOT,
+					  DRIVER_TP, ts);
 	if (error) {
 		dev_err(&client->dev, "request irq %d failed\n",
 			ts->irq);
-		goto err_cs_disable;
+		return error;
 	}
 
 	error = input_register_device(in_dev);
 	if (error) {
 		dev_err(&client->dev, "failed to register input device\n");
-		goto err_free_irq;
+		return error;
 	}
 
 	device_init_wakeup(&client->dev, pdata->wakeup);
 	i2c_set_clientdata(client, ts);
 
 	return 0;
-
-err_free_irq:
-	bu21013_free_irq(ts);
-err_cs_disable:
-	gpiod_set_value(ts->cs_gpiod, 0);
-	gpiod_put(ts->cs_gpiod);
-err_disable_regulator:
-	regulator_disable(ts->regulator);
-err_put_regulator:
-	regulator_put(ts->regulator);
-err_put_int_gpio:
-	gpiod_put(ts->int_gpiod);
-err_free_mem:
-	input_free_device(in_dev);
-	kfree(ts);
-
-	return error;
 }
 
 static int bu21013_remove(struct i2c_client *client)
 {
 	struct bu21013_ts *ts = i2c_get_clientdata(client);
 
-	bu21013_free_irq(ts);
-
-	gpiod_set_value(ts->cs_gpiod, 0);
-	gpiod_put(ts->cs_gpiod);
-
-	input_unregister_device(ts->in_dev);
-
-	regulator_disable(ts->regulator);
-	regulator_put(ts->regulator);
-
-	gpiod_put(ts->int_gpiod);
-
-	kfree(ts);
+	/* Make sure IRQ will exit quickly even if there is contact */
+	ts->touch_stopped = true;
+	/* The resources will be freed by devm */
 
 	return 0;
 }
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related

* [PATCH 07/11] Input: bu21013_ts - remove support for platform data
From: Dmitry Torokhov @ 2019-08-10  0:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-input, linux-kernel
In-Reply-To: <20190810002039.95876-1-dmitry.torokhov@gmail.com>

There are no current users of the platform data in the tree, and
any new users should either use device tree, or static device
properties to describe the device.

This change drop the platform data definition and handling and moves the
driver over to generic device properties API. We also drop support for the
external clock. If it is needed we will have to extend the bindings to
supply the clock reference and handle it properly in the driver.

Also, wakeup setting should be coming from I2C client.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/bu21013_ts.c | 109 +++++++++----------------
 include/linux/input/bu21013.h          |  30 -------
 2 files changed, 37 insertions(+), 102 deletions(-)
 delete mode 100644 include/linux/input/bu21013.h

diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c
index 4b6f9544e94a..79de7327a460 100644
--- a/drivers/input/touchscreen/bu21013_ts.c
+++ b/drivers/input/touchscreen/bu21013_ts.c
@@ -4,18 +4,18 @@
  * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson
  */
 
-#include <linux/kernel.h>
+#include <linux/bitops.h>
 #include <linux/delay.h>
-#include <linux/interrupt.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
-#include <linux/workqueue.h>
 #include <linux/input.h>
-#include <linux/input/bu21013.h>
-#include <linux/slab.h>
-#include <linux/regulator/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/gpio/consumer.h>
-#include <linux/of.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/types.h>
 
 #define MAX_FINGERS	2
 #define RESET_DELAY	30
@@ -137,23 +137,32 @@
 /**
  * struct bu21013_ts - touch panel data structure
  * @client: pointer to the i2c client
- * @touch_stopped: touch stop flag
- * @chip: pointer to the touch panel controller
  * @in_dev: pointer to the input device structure
  * @regulator: pointer to the Regulator used for touch screen
  * @cs_gpiod: chip select GPIO line
  * @int_gpiod: touch interrupt GPIO line
+ * @irq: interrupt number the device is using
+ * @touch_x_max: maximum X coordinate reported by the device
+ * @touch_y_max: maximum Y coordinate reported by the device
+ * @x_flip: indicates that the driver should invert X coordinate before
+ *	reporting
+ * @y_flip: indicates that the driver should invert Y coordinate before
+ *	reporting
+ * @touch_stopped: touch stop flag
  *
  * Touch panel device data structure
  */
 struct bu21013_ts {
 	struct i2c_client *client;
-	const struct bu21013_platform_device *chip;
 	struct input_dev *in_dev;
 	struct regulator *regulator;
 	struct gpio_desc *cs_gpiod;
 	struct gpio_desc *int_gpiod;
 	unsigned int irq;
+	u32 touch_x_max;
+	u32 touch_y_max;
+	bool x_flip;
+	bool y_flip;
 	bool touch_stopped;
 };
 
@@ -208,10 +217,10 @@ static int bu21013_do_touch_report(struct bu21013_ts *ts)
 		}
 
 		for (i = 0; i < finger_down_count; i++) {
-			if (ts->chip->x_flip)
-				pos_x[i] = ts->chip->touch_x_max - pos_x[i];
-			if (ts->chip->y_flip)
-				pos_y[i] = ts->chip->touch_y_max - pos_y[i];
+			if (ts->x_flip)
+				pos_x[i] = ts->touch_x_max - pos_x[i];
+			if (ts->y_flip)
+				pos_y[i] = ts->touch_y_max - pos_y[i];
 
 			input_report_abs(ts->in_dev,
 					 ABS_MT_POSITION_X, pos_x[i]);
@@ -304,14 +313,9 @@ static int bu21013_init_chip(struct bu21013_ts *ts)
 		return error;
 	}
 
-	if (ts->chip->ext_clk)
-		error = i2c_smbus_write_byte_data(client, BU21013_CLK_MODE_REG,
-						  BU21013_CLK_MODE_EXT |
-							BU21013_CLK_MODE_CALIB);
-	else
-		error = i2c_smbus_write_byte_data(client, BU21013_CLK_MODE_REG,
-						  BU21013_CLK_MODE_DIV |
-							BU21013_CLK_MODE_CALIB);
+	error = i2c_smbus_write_byte_data(client, BU21013_CLK_MODE_REG,
+					  BU21013_CLK_MODE_DIV |
+						BU21013_CLK_MODE_CALIB);
 	if (error) {
 		dev_err(&client->dev, "BU21013_CLK_MODE reg write failed\n");
 		return error;
@@ -388,43 +392,6 @@ static int bu21013_init_chip(struct bu21013_ts *ts)
 	return 0;
 }
 
-#ifdef CONFIG_OF
-static const struct bu21013_platform_device *
-bu21013_parse_dt(struct device *dev)
-{
-	struct device_node *np = dev->of_node;
-	struct bu21013_platform_device *pdata;
-
-	if (!np) {
-		dev_err(dev, "no device tree or platform data\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
-	if (!pdata)
-		return ERR_PTR(-ENOMEM);
-
-	pdata->y_flip = pdata->x_flip = false;
-
-	pdata->x_flip = of_property_read_bool(np, "rohm,flip-x");
-	pdata->y_flip = of_property_read_bool(np, "rohm,flip-y");
-
-	of_property_read_u32(np, "rohm,touch-max-x", &pdata->touch_x_max);
-	of_property_read_u32(np, "rohm,touch-max-y", &pdata->touch_y_max);
-
-	pdata->ext_clk = false;
-
-	return pdata;
-}
-#else
-static inline const struct bu21013_platform_device *
-bu21013_parse_dt(struct device *dev)
-{
-	dev_err(dev, "no platform data available\n");
-	return ERR_PTR(-EINVAL);
-}
-#endif
-
 static void bu21013_power_off(void *_ts)
 {
 	struct bu21013_ts *ts = ts;
@@ -442,8 +409,6 @@ static void bu21013_disable_chip(void *_ts)
 static int bu21013_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
-	const struct bu21013_platform_device *pdata =
-					dev_get_platdata(&client->dev);
 	struct bu21013_ts *ts;
 	struct input_dev *in_dev;
 	int error;
@@ -454,19 +419,20 @@ static int bu21013_probe(struct i2c_client *client,
 		return -EIO;
 	}
 
-	if (!pdata) {
-		pdata = bu21013_parse_dt(&client->dev);
-		if (IS_ERR(pdata))
-			return PTR_ERR(pdata);
-	}
-
 	ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
 	if (!ts)
 		return -ENOMEM;
 
-	ts->chip = pdata;
 	ts->client = client;
 
+	ts->x_flip = device_property_read_bool(&client->dev, "rohm,flip-x");
+	ts->y_flip = device_property_read_bool(&client->dev, "rohm,flip-y");
+
+	device_property_read_u32(&client->dev, "rohm,touch-max-x",
+				 &ts->touch_x_max);
+	device_property_read_u32(&client->dev, "rohm,touch-max-y",
+				 &ts->touch_y_max);
+
 	in_dev = devm_input_allocate_device(&client->dev);
 	if (!in_dev) {
 		dev_err(&client->dev, "device memory alloc failed\n");
@@ -483,9 +449,9 @@ static int bu21013_probe(struct i2c_client *client,
 	__set_bit(EV_ABS, in_dev->evbit);
 
 	input_set_abs_params(in_dev, ABS_MT_POSITION_X,
-			     0, pdata->touch_x_max, 0, 0);
+			     0, ts->touch_x_max, 0, 0);
 	input_set_abs_params(in_dev, ABS_MT_POSITION_Y,
-			     0, pdata->touch_y_max, 0, 0);
+			     0, ts->touch_y_max, 0, 0);
 	input_set_drvdata(in_dev, ts);
 
 	ts->regulator = devm_regulator_get(&client->dev, "avdd");
@@ -560,7 +526,6 @@ static int bu21013_probe(struct i2c_client *client,
 		return error;
 	}
 
-	device_init_wakeup(&client->dev, pdata->wakeup);
 	i2c_set_clientdata(client, ts);
 
 	return 0;
diff --git a/include/linux/input/bu21013.h b/include/linux/input/bu21013.h
deleted file mode 100644
index 58b1a9d44443..000000000000
--- a/include/linux/input/bu21013.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) ST-Ericsson SA 2010
- * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson
- */
-
-#ifndef _BU21013_H
-#define _BU21013_H
-
-/**
- * struct bu21013_platform_device - Handle the platform data
- * @touch_x_max: touch x max
- * @touch_y_max: touch y max
- * @ext_clk: external clock flag
- * @x_flip: x flip flag
- * @y_flip: y flip flag
- * @wakeup: wakeup flag
- *
- * This is used to handle the platform data
- */
-struct bu21013_platform_device {
-	int touch_x_max;
-	int touch_y_max;
-	bool ext_clk;
-	bool x_flip;
-	bool y_flip;
-	bool wakeup;
-};
-
-#endif
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related

* [PATCH 08/11] Input: bu21013_ts - use interrupt from I2C client
From: Dmitry Torokhov @ 2019-08-10  0:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-input, linux-kernel
In-Reply-To: <20190810002039.95876-1-dmitry.torokhov@gmail.com>

Instead of trying to map INT GPIO to interrupt, let's use one supplied by
I2C client. If there is none - bail. This will also allow us to treat INT
GPIO as optional, as per the binding.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 .../bindings/input/touchscreen/bu21013.txt    |  6 +++-
 drivers/input/touchscreen/bu21013_ts.c        | 35 ++++++++++---------
 2 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt b/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt
index 43899fc36ecf..7ddb5de8343d 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt
@@ -4,6 +4,8 @@ Required properties:
  - compatible              : "rohm,bu21013_tp"
  - reg                     : I2C device address
  - reset-gpios             : GPIO pin enabling (selecting) chip (CS)
+ - interrupt-parent        : the phandle for the gpio controller
+ - interrupts              : (gpio) interrupt to which the chip is connected
 
 Optional properties:
  - touch-gpios             : GPIO pin registering a touch event
@@ -19,7 +21,9 @@ Example:
 		bu21013_tp@5c {
 			compatible = "rohm,bu21013_tp";
 			reg = <0x5c>;
-			touch-gpio = <&gpio2 20 0x4>;
+			interrupt-parent = <&gpio2>;
+			interrupts <&20 IRQ_TYPE_LEVEL_LOW>;
+			touch-gpio = <&gpio2 20 GPIO_ACTIVE_LOW>;
 			avdd-supply = <&ab8500_ldo_aux1_reg>;
 
 			rohm,touch-max-x = <384>;
diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c
index 79de7327a460..d745643861cb 100644
--- a/drivers/input/touchscreen/bu21013_ts.c
+++ b/drivers/input/touchscreen/bu21013_ts.c
@@ -141,7 +141,6 @@
  * @regulator: pointer to the Regulator used for touch screen
  * @cs_gpiod: chip select GPIO line
  * @int_gpiod: touch interrupt GPIO line
- * @irq: interrupt number the device is using
  * @touch_x_max: maximum X coordinate reported by the device
  * @touch_y_max: maximum Y coordinate reported by the device
  * @x_flip: indicates that the driver should invert X coordinate before
@@ -158,7 +157,6 @@ struct bu21013_ts {
 	struct regulator *regulator;
 	struct gpio_desc *cs_gpiod;
 	struct gpio_desc *int_gpiod;
-	unsigned int irq;
 	u32 touch_x_max;
 	u32 touch_y_max;
 	bool x_flip;
@@ -252,7 +250,8 @@ static irqreturn_t bu21013_gpio_irq(int irq, void *device_data)
 		if (unlikely(ts->touch_stopped))
 			break;
 
-		keep_polling = gpiod_get_value(ts->int_gpiod);
+		keep_polling = ts->int_gpiod ?
+			gpiod_get_value(ts->int_gpiod) : false;
 		if (keep_polling)
 			usleep_range(2000, 2500);
 	} while (keep_polling);
@@ -419,6 +418,11 @@ static int bu21013_probe(struct i2c_client *client,
 		return -EIO;
 	}
 
+	if (!client->irq) {
+		dev_err(&client->dev, "No IRQ set up\n");
+		return -EINVAL;
+	}
+
 	ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
 	if (!ts)
 		return -ENOMEM;
@@ -491,14 +495,17 @@ static int bu21013_probe(struct i2c_client *client,
 	}
 
 	/* Named "INT" on the chip, DT binding is "touch" */
-	ts->int_gpiod = devm_gpiod_get(&client->dev, "touch", GPIOD_IN);
+	ts->int_gpiod = devm_gpiod_get_optional(&client->dev,
+						"touch", GPIOD_IN);
 	error = PTR_ERR_OR_ZERO(ts->int_gpiod);
 	if (error) {
 		if (error != -EPROBE_DEFER)
 			dev_err(&client->dev, "failed to get INT GPIO\n");
 		return error;
 	}
-	gpiod_set_consumer_name(ts->int_gpiod, "BU21013 INT");
+
+	if (ts->int_gpiod)
+		gpiod_set_consumer_name(ts->int_gpiod, "BU21013 INT");
 
 	/* configure the touch panel controller */
 	error = bu21013_init_chip(ts);
@@ -507,16 +514,12 @@ static int bu21013_probe(struct i2c_client *client,
 		return error;
 	}
 
-	ts->irq = gpiod_to_irq(ts->int_gpiod);
-	error = devm_request_threaded_irq(&client->dev, ts->irq,
+	error = devm_request_threaded_irq(&client->dev, client->irq,
 					  NULL, bu21013_gpio_irq,
-					  IRQF_TRIGGER_FALLING |
-						IRQF_SHARED |
-						IRQF_ONESHOT,
-					  DRIVER_TP, ts);
+					  IRQF_ONESHOT, DRIVER_TP, ts);
 	if (error) {
 		dev_err(&client->dev, "request irq %d failed\n",
-			ts->irq);
+			client->irq);
 		return error;
 	}
 
@@ -549,9 +552,9 @@ static int __maybe_unused bu21013_suspend(struct device *dev)
 
 	ts->touch_stopped = true;
 	if (device_may_wakeup(&client->dev))
-		enable_irq_wake(ts->irq);
+		enable_irq_wake(client->irq);
 	else
-		disable_irq(ts->irq);
+		disable_irq(client->irq);
 
 	regulator_disable(ts->regulator);
 
@@ -579,9 +582,9 @@ static int __maybe_unused bu21013_resume(struct device *dev)
 	ts->touch_stopped = false;
 
 	if (device_may_wakeup(&client->dev))
-		disable_irq_wake(ts->irq);
+		disable_irq_wake(client->irq);
 	else
-		enable_irq(ts->irq);
+		enable_irq(client->irq);
 
 	return 0;
 }
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related

* [PATCH 09/11] Input: bu21013_ts - fix suspend when wake source
From: Dmitry Torokhov @ 2019-08-10  0:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-input, linux-kernel
In-Reply-To: <20190810002039.95876-1-dmitry.torokhov@gmail.com>

If the touchscreen is configured as wakeup source we should not be cutting
off power to it.

Also, now that the driver relies on I2C client to supply IRQ, we do not
need to explicitly enable and disable IRQ for wakeup: if device is created
as wakeup source, I2C core will mark interrupt as wakeup one.

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

diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c
index d745643861cb..d7e16e915743 100644
--- a/drivers/input/touchscreen/bu21013_ts.c
+++ b/drivers/input/touchscreen/bu21013_ts.c
@@ -547,44 +547,44 @@ static int bu21013_remove(struct i2c_client *client)
 
 static int __maybe_unused bu21013_suspend(struct device *dev)
 {
-	struct bu21013_ts *ts = dev_get_drvdata(dev);
-	struct i2c_client *client = ts->client;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct bu21013_ts *ts = i2c_get_clientdata(client);
 
 	ts->touch_stopped = true;
-	if (device_may_wakeup(&client->dev))
-		enable_irq_wake(client->irq);
-	else
-		disable_irq(client->irq);
+	mb();
+	disable_irq(client->irq);
 
-	regulator_disable(ts->regulator);
+	if (!device_may_wakeup(&client->dev))
+		regulator_disable(ts->regulator);
 
 	return 0;
 }
 
 static int __maybe_unused bu21013_resume(struct device *dev)
 {
-	struct bu21013_ts *ts = dev_get_drvdata(dev);
-	struct i2c_client *client = ts->client;
-	int retval;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct bu21013_ts *ts = i2c_get_clientdata(client);
+	int error;
 
-	retval = regulator_enable(ts->regulator);
-	if (retval < 0) {
-		dev_err(&client->dev, "bu21013 regulator enable failed\n");
-		return retval;
-	}
+	if (!device_may_wakeup(&client->dev)) {
+		error = regulator_enable(ts->regulator);
+		if (error) {
+			dev_err(&client->dev,
+				"failed to re-enable regulator when resuming\n");
+			return error;
+		}
 
-	retval = bu21013_init_chip(ts);
-	if (retval < 0) {
-		dev_err(&client->dev, "bu21013 controller config failed\n");
-		return retval;
+		error = bu21013_init_chip(ts);
+		if (error) {
+			dev_err(&client->dev,
+				"failed to reinitialize chip when resuming\n");
+			return error;
+		}
 	}
 
 	ts->touch_stopped = false;
-
-	if (device_may_wakeup(&client->dev))
-		disable_irq_wake(client->irq);
-	else
-		enable_irq(client->irq);
+	mb();
+	enable_irq(client->irq);
 
 	return 0;
 }
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related

* [PATCH 10/11] Input: bu21013_ts - switch to using MT-B (slotted) protocol
From: Dmitry Torokhov @ 2019-08-10  0:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-input, linux-kernel
In-Reply-To: <20190810002039.95876-1-dmitry.torokhov@gmail.com>

MT-B protocol is more efficient and everyone expects it. We use in-kernel
tracking to identify contacts.

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

diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c
index d7e16e915743..2c534aa61687 100644
--- a/drivers/input/touchscreen/bu21013_ts.c
+++ b/drivers/input/touchscreen/bu21013_ts.c
@@ -9,6 +9,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
+#include <linux/input/mt.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -181,11 +182,13 @@ static int bu21013_read_block_data(struct bu21013_ts *ts, u8 *buf)
 
 static int bu21013_do_touch_report(struct bu21013_ts *ts)
 {
-	u8	buf[LENGTH_OF_BUFFER];
-	unsigned int pos_x[2], pos_y[2];
-	bool	has_x_sensors, has_y_sensors;
-	int	finger_down_count = 0;
-	int	i;
+	struct input_dev *input = ts->in_dev;
+	struct input_mt_pos pos[MAX_FINGERS];
+	int slots[MAX_FINGERS];
+	u8 buf[LENGTH_OF_BUFFER];
+	bool has_x_sensors, has_y_sensors;
+	int finger_down_count = 0;
+	int i;
 
 	if (bu21013_read_block_data(ts, buf) < 0)
 		return -EINVAL;
@@ -197,39 +200,38 @@ static int bu21013_do_touch_report(struct bu21013_ts *ts)
 		return 0;
 
 	for (i = 0; i < MAX_FINGERS; i++) {
-		const u8 *p = &buf[4 * i + 3];
-		unsigned int x = p[0] << SHIFT_2 | (p[1] & MASK_BITS);
-		unsigned int y = p[2] << SHIFT_2 | (p[3] & MASK_BITS);
-		if (x == 0 || y == 0)
+		const u8 *data = &buf[4 * i + 3];
+		struct input_mt_pos *p = &pos[finger_down_count];
+
+		p->x = data[0] << SHIFT_2 | (data[1] & MASK_BITS);
+		p->y = data[2] << SHIFT_2 | (data[3] & MASK_BITS);
+		if (p->x == 0 || p->y == 0)
 			continue;
-		pos_x[finger_down_count] = x;
-		pos_y[finger_down_count] = y;
+
 		finger_down_count++;
+
+		if (ts->x_flip)
+			p->x = ts->touch_x_max - p->x;
+		if (ts->y_flip)
+			p->y = ts->touch_y_max - p->y;
 	}
 
-	if (finger_down_count) {
-		if (finger_down_count == 2 &&
-		    (abs(pos_x[0] - pos_x[1]) < DELTA_MIN ||
-		     abs(pos_y[0] - pos_y[1]) < DELTA_MIN)) {
-			return 0;
-		}
+	if (finger_down_count == 2 &&
+	    (abs(pos[0].x - pos[1].x) < DELTA_MIN ||
+	     abs(pos[0].y - pos[1].y) < DELTA_MIN)) {
+		return 0;
+	}
 
-		for (i = 0; i < finger_down_count; i++) {
-			if (ts->x_flip)
-				pos_x[i] = ts->touch_x_max - pos_x[i];
-			if (ts->y_flip)
-				pos_y[i] = ts->touch_y_max - pos_y[i];
-
-			input_report_abs(ts->in_dev,
-					 ABS_MT_POSITION_X, pos_x[i]);
-			input_report_abs(ts->in_dev,
-					 ABS_MT_POSITION_Y, pos_y[i]);
-			input_mt_sync(ts->in_dev);
-		}
-	} else
-		input_mt_sync(ts->in_dev);
+	input_mt_assign_slots(input, slots, pos, finger_down_count, DELTA_MIN);
+	for (i = 0; i < finger_down_count; i++) {
+		input_mt_slot(input, slots[i]);
+		input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
+		input_report_abs(input, ABS_MT_POSITION_X, pos[i].x);
+		input_report_abs(input, ABS_MT_POSITION_Y, pos[i].y);
+	}
 
-	input_sync(ts->in_dev);
+	input_mt_sync_frame(input);
+	input_sync(input);
 
 	return 0;
 }
@@ -443,20 +445,24 @@ static int bu21013_probe(struct i2c_client *client,
 		return -ENOMEM;
 	}
 	ts->in_dev = in_dev;
+	input_set_drvdata(in_dev, ts);
 
 	/* register the device to input subsystem */
 	in_dev->name = DRIVER_TP;
 	in_dev->id.bustype = BUS_I2C;
 
-	__set_bit(EV_SYN, in_dev->evbit);
-	__set_bit(EV_KEY, in_dev->evbit);
-	__set_bit(EV_ABS, in_dev->evbit);
-
 	input_set_abs_params(in_dev, ABS_MT_POSITION_X,
 			     0, ts->touch_x_max, 0, 0);
 	input_set_abs_params(in_dev, ABS_MT_POSITION_Y,
 			     0, ts->touch_y_max, 0, 0);
-	input_set_drvdata(in_dev, ts);
+
+	error = input_mt_init_slots(in_dev, MAX_FINGERS,
+				    INPUT_MT_DIRECT | INPUT_MT_TRACK |
+					INPUT_MT_DROP_UNUSED);
+	if (error) {
+		dev_err(&client->dev, "failed to initialize MT slots");
+		return error;
+	}
 
 	ts->regulator = devm_regulator_get(&client->dev, "avdd");
 	if (IS_ERR(ts->regulator)) {
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related

* [PATCH 11/11] Input: bu21013_ts - switch to using standard touchscreen properties
From: Dmitry Torokhov @ 2019-08-10  0:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-input, linux-kernel
In-Reply-To: <20190810002039.95876-1-dmitry.torokhov@gmail.com>

This switches the driver over to the standard touchscreen properties for
coordinate transformation, while keeping old bindings working as well.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 .../bindings/input/touchscreen/bu21013.txt    | 16 ++++--
 drivers/input/touchscreen/bu21013_ts.c        | 54 +++++++++++--------
 2 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt b/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt
index 7ddb5de8343d..da4c9d8b99b1 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt
@@ -10,6 +10,16 @@ Required properties:
 Optional properties:
  - touch-gpios             : GPIO pin registering a touch event
  - <supply_name>-supply    : Phandle to a regulator supply
+ - touchscreen-size-x      : General touchscreen binding, see [1].
+ - touchscreen-size-y      : General touchscreen binding, see [1].
+ - touchscreen-inverted-x  : General touchscreen binding, see [1].
+ - touchscreen-inverted-y  : General touchscreen binding, see [1].
+ - touchscreen-swapped-x-y : General touchscreen binding, see [1].
+
+[1] All general touchscreen properties are described in
+    Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt.
+
+Deprecated properties:
  - rohm,touch-max-x        : Maximum outward permitted limit in the X axis
  - rohm,touch-max-y        : Maximum outward permitted limit in the Y axis
  - rohm,flip-x             : Flip touch coordinates on the X axis
@@ -26,8 +36,8 @@ Example:
 			touch-gpio = <&gpio2 20 GPIO_ACTIVE_LOW>;
 			avdd-supply = <&ab8500_ldo_aux1_reg>;
 
-			rohm,touch-max-x = <384>;
-			rohm,touch-max-y = <704>;
-			rohm,flip-y;
+			touchscreen-size-x = <384>;
+			touchscreen-size-y = <704>;
+			touchscreen-inverted-y;
 		};
 	};
diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c
index 2c534aa61687..c89a00a6e67c 100644
--- a/drivers/input/touchscreen/bu21013_ts.c
+++ b/drivers/input/touchscreen/bu21013_ts.c
@@ -10,6 +10,7 @@
 #include <linux/i2c.h>
 #include <linux/input.h>
 #include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -139,6 +140,7 @@
  * struct bu21013_ts - touch panel data structure
  * @client: pointer to the i2c client
  * @in_dev: pointer to the input device structure
+ * @props: the device coordinate transformation properties
  * @regulator: pointer to the Regulator used for touch screen
  * @cs_gpiod: chip select GPIO line
  * @int_gpiod: touch interrupt GPIO line
@@ -155,6 +157,7 @@
 struct bu21013_ts {
 	struct i2c_client *client;
 	struct input_dev *in_dev;
+	struct touchscreen_properties props;
 	struct regulator *regulator;
 	struct gpio_desc *cs_gpiod;
 	struct gpio_desc *int_gpiod;
@@ -201,19 +204,13 @@ static int bu21013_do_touch_report(struct bu21013_ts *ts)
 
 	for (i = 0; i < MAX_FINGERS; i++) {
 		const u8 *data = &buf[4 * i + 3];
-		struct input_mt_pos *p = &pos[finger_down_count];
+		unsigned int x, y;
 
-		p->x = data[0] << SHIFT_2 | (data[1] & MASK_BITS);
-		p->y = data[2] << SHIFT_2 | (data[3] & MASK_BITS);
-		if (p->x == 0 || p->y == 0)
-			continue;
-
-		finger_down_count++;
-
-		if (ts->x_flip)
-			p->x = ts->touch_x_max - p->x;
-		if (ts->y_flip)
-			p->y = ts->touch_y_max - p->y;
+		x = data[0] << SHIFT_2 | (data[1] & MASK_BITS);
+		y = data[2] << SHIFT_2 | (data[3] & MASK_BITS);
+		if (x != 0 && y != 0)
+			touchscreen_set_mt_pos(&pos[finger_down_count++],
+					       &ts->props, x, y);
 	}
 
 	if (finger_down_count == 2 &&
@@ -412,6 +409,8 @@ static int bu21013_probe(struct i2c_client *client,
 {
 	struct bu21013_ts *ts;
 	struct input_dev *in_dev;
+	struct input_absinfo *info;
+	u32 max_x = 0, max_y = 0;
 	int error;
 
 	if (!i2c_check_functionality(client->adapter,
@@ -434,11 +433,6 @@ static int bu21013_probe(struct i2c_client *client,
 	ts->x_flip = device_property_read_bool(&client->dev, "rohm,flip-x");
 	ts->y_flip = device_property_read_bool(&client->dev, "rohm,flip-y");
 
-	device_property_read_u32(&client->dev, "rohm,touch-max-x",
-				 &ts->touch_x_max);
-	device_property_read_u32(&client->dev, "rohm,touch-max-y",
-				 &ts->touch_y_max);
-
 	in_dev = devm_input_allocate_device(&client->dev);
 	if (!in_dev) {
 		dev_err(&client->dev, "device memory alloc failed\n");
@@ -451,10 +445,28 @@ static int bu21013_probe(struct i2c_client *client,
 	in_dev->name = DRIVER_TP;
 	in_dev->id.bustype = BUS_I2C;
 
-	input_set_abs_params(in_dev, ABS_MT_POSITION_X,
-			     0, ts->touch_x_max, 0, 0);
-	input_set_abs_params(in_dev, ABS_MT_POSITION_Y,
-			     0, ts->touch_y_max, 0, 0);
+	device_property_read_u32(&client->dev, "rohm,touch-max-x", &max_x);
+	device_property_read_u32(&client->dev, "rohm,touch-max-y", &max_y);
+
+	input_set_abs_params(in_dev, ABS_MT_POSITION_X, 0, max_x, 0, 0);
+	input_set_abs_params(in_dev, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
+
+	touchscreen_parse_properties(in_dev, true, &ts->props);
+
+	/* Adjust for the legacy "flip" properties, if present */
+	if (!ts->props.invert_x &&
+	    device_property_read_bool(&client->dev, "rohm,flip-x")) {
+		info = &in_dev->absinfo[ABS_MT_POSITION_X];
+		info->maximum -= info->minimum;
+		info->minimum = 0;
+	}
+
+	if (!ts->props.invert_y &&
+	    device_property_read_bool(&client->dev, "rohm,flip-y")) {
+		info = &in_dev->absinfo[ABS_MT_POSITION_Y];
+		info->maximum -= info->minimum;
+		info->minimum = 0;
+	}
 
 	error = input_mt_init_slots(in_dev, MAX_FINGERS,
 				    INPUT_MT_DIRECT | INPUT_MT_TRACK |
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related

* Re: [PATCH 00/16] ARM: remove ks8695 and w90x900 platforms
From: Greg Kroah-Hartman @ 2019-08-10  7:29 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: soc, Wanzongshun (Vincent), Greg Ungerer, linux-serial,
	Dmitry Torokhov, linux-input, Linus Walleij, linux-gpio,
	David S. Miller, netdev, Guenter Roeck, Mark Brown, alsa-devel,
	linux-spi, Bartlomiej Zolnierkiewicz, linux-fbdev, Miquel Raynal,
	linux-mtd, linux-arm-kernel, linux-kernel
In-Reply-To: <20190809202749.742267-1-arnd@arndb.de>

On Fri, Aug 09, 2019 at 10:27:28PM +0200, Arnd Bergmann wrote:
> As discussed previously, these two ARM platforms have no
> known remaining users, let's remove them completely.
> 
> Subsystem maintainers: feel free to take the driver removals
> through your respective trees, they are all independent of
> one another. We can merge any remaining patches through the
> soc tree.

Serial and USB host controller driver patches applied, thanks!

greg k-h

^ permalink raw reply

* Re: [PATCH v4 8/9] MIPS: SGI-IP27: fix readb/writeb addressing
From: Andy Shevchenko @ 2019-08-10 13:22 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
	Lee Jones, David S. Miller, Srinivas Kandagatla, Alessandro Zummo,
	Alexandre Belloni, Greg Kroah-Hartman, Jiri Slaby,
	Evgeniy Polyakov, linux-mips, Linux Kernel Mailing List,
	linux-input, netdev, open list:REAL TIME CLOCK (RTC) SUBSYSTEM,
	"open list:SERIAL DRIVERS" <linux-seri>
In-Reply-To: <20190809103235.16338-9-tbogendoerfer@suse.de>

On Fri, Aug 9, 2019 at 1:34 PM Thomas Bogendoerfer
<tbogendoerfer@suse.de> wrote:
>
> Our chosen byte swapping, which is what firmware already uses, is to
> do readl/writel by normal lw/sw intructions (data invariance). This
> also means we need to mangle addresses for u8 and u16 accesses. The
> mangling for 16bit has been done aready, but 8bit one was missing.
> Correcting this causes different addresses for accesses to the
> SuperIO and local bus of the IOC3 chip. This is fixed by changing
> byte order in ioc3 and m48rtc_rtc structs.

>  /* serial port register map */
>  struct ioc3_serialregs {
> -       uint32_t        sscr;
> -       uint32_t        stpir;
> -       uint32_t        stcir;
> -       uint32_t        srpir;
> -       uint32_t        srcir;
> -       uint32_t        srtr;
> -       uint32_t        shadow;
> +       u32     sscr;
> +       u32     stpir;
> +       u32     stcir;
> +       u32     srpir;
> +       u32     srcir;
> +       u32     srtr;
> +       u32     shadow;
>  };

Isn't it a churn? AFAIU kernel documentation the uint32_t is okay to
use, just be consistent inside one module / driver.
Am I mistaken?


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* Re: [PATCH v4 8/9] MIPS: SGI-IP27: fix readb/writeb addressing
From: Greg Kroah-Hartman @ 2019-08-11  7:29 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Thomas Bogendoerfer, Ralf Baechle, Paul Burton, James Hogan,
	Dmitry Torokhov, Lee Jones, David S. Miller, Srinivas Kandagatla,
	Alessandro Zummo, Alexandre Belloni, Jiri Slaby, Evgeniy Polyakov,
	linux-mips, Linux Kernel Mailing List, linux-input, netdev,
	open list:REAL TIME CLOCK (RTC) SUBSYSTEM,
	open list:SERIAL DRIVERS
In-Reply-To: <CAHp75Vd_083R9sRsspVuJ3ZMTxpVR79PF5Lg-bpnMxRfN+b7wA@mail.gmail.com>

On Sat, Aug 10, 2019 at 04:22:23PM +0300, Andy Shevchenko wrote:
> On Fri, Aug 9, 2019 at 1:34 PM Thomas Bogendoerfer
> <tbogendoerfer@suse.de> wrote:
> >
> > Our chosen byte swapping, which is what firmware already uses, is to
> > do readl/writel by normal lw/sw intructions (data invariance). This
> > also means we need to mangle addresses for u8 and u16 accesses. The
> > mangling for 16bit has been done aready, but 8bit one was missing.
> > Correcting this causes different addresses for accesses to the
> > SuperIO and local bus of the IOC3 chip. This is fixed by changing
> > byte order in ioc3 and m48rtc_rtc structs.
> 
> >  /* serial port register map */
> >  struct ioc3_serialregs {
> > -       uint32_t        sscr;
> > -       uint32_t        stpir;
> > -       uint32_t        stcir;
> > -       uint32_t        srpir;
> > -       uint32_t        srcir;
> > -       uint32_t        srtr;
> > -       uint32_t        shadow;
> > +       u32     sscr;
> > +       u32     stpir;
> > +       u32     stcir;
> > +       u32     srpir;
> > +       u32     srcir;
> > +       u32     srtr;
> > +       u32     shadow;
> >  };
> 
> Isn't it a churn? AFAIU kernel documentation the uint32_t is okay to
> use, just be consistent inside one module / driver.
> Am I mistaken?

No, but really it uint* shouldn't be used anywhere in the kernel source
as it does not make sense.

thanks,

greg k-h

^ permalink raw reply

* [PATCH] Input: ili210x - switch to using threaded IRQ
From: Dmitry Torokhov @ 2019-08-11 16:11 UTC (permalink / raw)
  To: linux-input; +Cc: Marek Vasut, linux-kernel

Let's switch the driver to using threaded IRQ so that we do not need to
manage the interrupt and work separately, and we do not acknowledge
interrupt until we finished handling it completely.

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

diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
index e9006407c9bc..5a37d1eff2af 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -1,20 +1,20 @@
 // SPDX-License-Identifier: GPL-2.0-only
-#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/input/mt.h>
 #include <linux/input/touchscreen.h>
-#include <linux/delay.h>
-#include <linux/workqueue.h>
-#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #define ILI210X_TOUCHES		2
 #define ILI251X_TOUCHES		10
-#define DEFAULT_POLL_PERIOD	20
+
+#define ILI2XXX_POLL_PERIOD	20
 
 /* Touchscreen commands */
 #define REG_TOUCHDATA		0x10
@@ -36,12 +36,11 @@ enum ili2xxx_model {
 struct ili210x {
 	struct i2c_client *client;
 	struct input_dev *input;
-	unsigned int poll_period;
-	struct delayed_work dwork;
 	struct gpio_desc *reset_gpio;
 	struct touchscreen_properties prop;
 	enum ili2xxx_model model;
 	unsigned int max_touches;
+	bool stop;
 };
 
 static int ili210x_read_reg(struct i2c_client *client, u8 reg, void *buf,
@@ -170,43 +169,36 @@ static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata)
 	return contact;
 }
 
-static void ili210x_work(struct work_struct *work)
+static irqreturn_t ili210x_irq(int irq, void *irq_data)
 {
-	struct ili210x *priv = container_of(work, struct ili210x,
-					    dwork.work);
+	struct ili210x *priv = irq_data;
 	struct i2c_client *client = priv->client;
 	u8 touchdata[64] = { 0 };
 	bool touch;
-	int error = -EINVAL;
-
-	if (priv->model == MODEL_ILI210X) {
-		error = ili210x_read_reg(client, REG_TOUCHDATA,
-					 touchdata, sizeof(touchdata));
-	} else if (priv->model == MODEL_ILI251X) {
-		error = ili210x_read_reg(client, REG_TOUCHDATA,
-					 touchdata, 31);
-		if (!error && touchdata[0] == 2)
-			error = ili210x_read(client, &touchdata[31], 20);
-	}
-
-	if (error) {
-		dev_err(&client->dev,
-			"Unable to get touchdata, err = %d\n", error);
-		return;
-	}
-
-	touch = ili210x_report_events(priv, touchdata);
+	int error;
 
-	if (touch)
-		schedule_delayed_work(&priv->dwork,
-				      msecs_to_jiffies(priv->poll_period));
-}
+	do {
+		if (priv->model == MODEL_ILI210X) {
+			error = ili210x_read_reg(client, REG_TOUCHDATA,
+						 touchdata, sizeof(touchdata));
+		} else if (priv->model == MODEL_ILI251X) {
+			error = ili210x_read_reg(client, REG_TOUCHDATA,
+						 touchdata, 31);
+			if (!error && touchdata[0] == 2)
+				error = ili210x_read(client,
+						     &touchdata[31], 20);
+		}
 
-static irqreturn_t ili210x_irq(int irq, void *irq_data)
-{
-	struct ili210x *priv = irq_data;
+		if (error) {
+			dev_err(&client->dev,
+				"Unable to get touchdata, err = %d\n", error);
+			break;
+		}
 
-	schedule_delayed_work(&priv->dwork, 0);
+		touch = ili210x_report_events(priv, touchdata);
+		if (touch)
+			msleep(ILI2XXX_POLL_PERIOD);
+	} while (!priv->stop && touch);
 
 	return IRQ_HANDLED;
 }
@@ -253,11 +245,12 @@ static void ili210x_power_down(void *data)
 	gpiod_set_value_cansleep(reset_gpio, 1);
 }
 
-static void ili210x_cancel_work(void *data)
+static void ili210x_stop(void *data)
 {
 	struct ili210x *priv = data;
 
-	cancel_delayed_work_sync(&priv->dwork);
+	/* Tell ISR to quit even if there is a contact. */
+	priv->stop = true;
 }
 
 static int ili210x_i2c_probe(struct i2c_client *client,
@@ -305,8 +298,6 @@ static int ili210x_i2c_probe(struct i2c_client *client,
 
 	priv->client = client;
 	priv->input = input;
-	priv->poll_period = DEFAULT_POLL_PERIOD;
-	INIT_DELAYED_WORK(&priv->dwork, ili210x_work);
 	priv->reset_gpio = reset_gpio;
 	priv->model = model;
 	if (model == MODEL_ILI210X)
@@ -336,18 +327,18 @@ static int ili210x_i2c_probe(struct i2c_client *client,
 	touchscreen_parse_properties(input, true, &priv->prop);
 	input_mt_init_slots(input, priv->max_touches, INPUT_MT_DIRECT);
 
-	error = devm_add_action(dev, ili210x_cancel_work, priv);
-	if (error)
-		return error;
-
-	error = devm_request_irq(dev, client->irq, ili210x_irq, 0,
-				 client->name, priv);
+	error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq,
+					  IRQF_ONESHOT, client->name, priv);
 	if (error) {
 		dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n",
 			error);
 		return error;
 	}
 
+	error = devm_add_action_or_reset(dev, ili210x_stop, priv);
+	if (error)
+		return error;
+
 	error = devm_device_add_group(dev, &ili210x_attr_group);
 	if (error) {
 		dev_err(dev, "Unable to create sysfs attributes, err: %d\n",
-- 
2.23.0.rc1.153.gdeed80330f-goog


-- 
Dmitry

^ permalink raw reply related

* Re: KASAN: slab-out-of-bounds Read in hidraw_ioctl
From: syzbot @ 2019-08-11 20:46 UTC (permalink / raw)
  To: andreyknvl, benjamin.tissoires, jikos, linux-input, linux-kernel,
	linux-usb, syzkaller-bugs
In-Reply-To: <00000000000008b8c6058ee52407@google.com>

syzbot has found a reproducer for the following crash on:

HEAD commit:    e96407b4 usb-fuzzer: main usb gadget fuzzer driver
git tree:       https://github.com/google/kasan.git usb-fuzzer
console output: https://syzkaller.appspot.com/x/log.txt?x=150426ba600000
kernel config:  https://syzkaller.appspot.com/x/.config?x=cfa2c18fb6a8068e
dashboard link: https://syzkaller.appspot.com/bug?extid=5a6c4ec678a0c6ee84ba
compiler:       gcc (GCC) 9.0.0 20181231 (experimental)
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=12725c02600000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=162163c2600000

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+5a6c4ec678a0c6ee84ba@syzkaller.appspotmail.com

==================================================================
BUG: KASAN: slab-out-of-bounds in strlen+0x79/0x90 lib/string.c:525
Read of size 1 at addr ffff8881d29bdf38 by task syz-executor201/1726

CPU: 1 PID: 1726 Comm: syz-executor201 Not tainted 5.3.0-rc2+ #25
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  
Google 01/01/2011
Call Trace:
  __dump_stack lib/dump_stack.c:77 [inline]
  dump_stack+0xca/0x13e lib/dump_stack.c:113
  print_address_description+0x6a/0x32c mm/kasan/report.c:351
  __kasan_report.cold+0x1a/0x33 mm/kasan/report.c:482
  kasan_report+0xe/0x12 mm/kasan/common.c:612
  strlen+0x79/0x90 lib/string.c:525
  strlen include/linux/string.h:281 [inline]
  hidraw_ioctl+0x245/0xae0 drivers/hid/hidraw.c:446
  vfs_ioctl fs/ioctl.c:46 [inline]
  file_ioctl fs/ioctl.c:509 [inline]
  do_vfs_ioctl+0xd2d/0x1330 fs/ioctl.c:696
  ksys_ioctl+0x9b/0xc0 fs/ioctl.c:713
  __do_sys_ioctl fs/ioctl.c:720 [inline]
  __se_sys_ioctl fs/ioctl.c:718 [inline]
  __x64_sys_ioctl+0x6f/0xb0 fs/ioctl.c:718
  do_syscall_64+0xb7/0x580 arch/x86/entry/common.c:296
  entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x445679
Code: e8 5c ad 02 00 48 83 c4 18 c3 0f 1f 80 00 00 00 00 48 89 f8 48 89 f7  
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff  
ff 0f 83 9b cd fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007ffc8514f3a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 0000000000445679
RDX: 0000000000000000 RSI: 0000000080404805 RDI: 0000000000000004
RBP: 00000000006d0018 R08: 000000000000000b R09: 00000000004002e0
R10: 000000000000000f R11: 0000000000000246 R12: 00000000004028a0
R13: 0000000000402930 R14: 0000000000000000 R15: 0000000000000000

Allocated by task 0:
(stack is not available)

Freed by task 0:
(stack is not available)

The buggy address belongs to the object at ffff8881d29bde60
  which belongs to the cache shmem_inode_cache of size 1168
The buggy address is located 216 bytes inside of
  1168-byte region [ffff8881d29bde60, ffff8881d29be2f0)
The buggy address belongs to the page:
page:ffffea00074a6f00 refcount:1 mapcount:0 mapping:ffff8881da115180  
index:0x0 compound_mapcount: 0
flags: 0x200000000010200(slab|head)
raw: 0200000000010200 dead000000000100 dead000000000122 ffff8881da115180
raw: 0000000000000000 00000000800c000c 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
  ffff8881d29bde00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  ffff8881d29bde80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> ffff8881d29bdf00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
                                         ^
  ffff8881d29bdf80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  ffff8881d29be000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================

^ permalink raw reply

* Re: [PATCH v4 1/3] mfd: mc13xxx: Add mc34708 adc support
From: Lee Jones @ 2019-08-12 10:08 UTC (permalink / raw)
  To: Lukasz Majewski
  Cc: linux-kernel, Dmitry Torokhov, Sascha Hauer, Enrico Weigelt,
	Thomas Gleixner, Kate Stewart, linux-input
In-Reply-To: <20190725182020.3948c8d9@jawa>

On Thu, 25 Jul 2019, Lukasz Majewski wrote:
> > On Thu, 18 Jul 2019, Lukasz Majewski wrote:
> > 
> > > From: Sascha Hauer <s.hauer@pengutronix.de>
> > > 
> > > The mc34708 has an improved adc. The older variants will always
> > > convert a fixed order of channels. The mc34708 can do up to eight
> > > conversions in arbitrary channel order. Currently this extended
> > > feature is not supported. We only support touchscreen conversions
> > > now, which will be sampled in a data format compatible to the older
> > > chips in order to keep the API between the mfd and the touchscreen
> > > driver.
> > > 
> > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > Signed-off-by: Lukasz Majewski <lukma@denx.de>
> > > 
> > > ---
> > > Changes for v4:
> > > - None
> > > 
> > > Changes for v3:
> > > - None
> > > 
> > > Changes for v2:
> > > - Change the return code patch when the mc13xxx ADC is performing
> > > conversion
> > > - Introduce new include/linux/mfd/mc34708.h header file for mc34708
> > > specific defines
> > > 
> > > Changes from the original patches:
> > > - ADC conversion functions prototypes added to fix build error
> > > - Adjustments to make checkpatch clean (-ENOSYS, line over 80 char)
> > > 
> > > This patch applies on top of v5.2 - SHA1:
> > > 0ecfebd2b52404ae0c54a878c872bb93363ada36 ---
> > >  drivers/mfd/mc13xxx-core.c  | 102
> > > +++++++++++++++++++++++++++++++++++++++++++-
> > > drivers/mfd/mc13xxx.h       |   3 ++ include/linux/mfd/mc34708.h |
> > > 37 ++++++++++++++++ 3 files changed, 141 insertions(+), 1
> > > deletion(-) create mode 100644 include/linux/mfd/mc34708.h
> > > 
> > > diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
> > > index 1abe7432aad8..01473d6fda21 100644
> > > --- a/drivers/mfd/mc13xxx-core.c
> > > +++ b/drivers/mfd/mc13xxx-core.c
> > > @@ -12,6 +12,7 @@
> > >  #include <linux/of_device.h>
> > >  #include <linux/platform_device.h>
> > >  #include <linux/mfd/core.h>
> > > +#include <linux/mfd/mc34708.h>
> > >  
> > >  #include "mc13xxx.h"
> > >  
> > > @@ -45,6 +46,8 @@
> > >  
> > >  #define MC13XXX_ADC2		45
> > >  
> > > +#define MC13XXX_ADC_WORKING		(1 << 0)  
> > 
> > BIT(0) ?
> 
> The same convention - i.e. (1 << 0) is used in the rest of the file.

Very well, but please consider converting it subsequently.

> > >  void mc13xxx_lock(struct mc13xxx *mc13xxx)
> > >  {
> > >  	if (!mutex_trylock(&mc13xxx->lock)) {
> > > @@ -198,22 +201,30 @@ static void mc34708_print_revision(struct
> > > mc13xxx *mc13xxx, u32 revision) maskval(revision,
> > > MC34708_REVISION_FAB)); }
> > >  
> > > +static int mc13xxx_adc_conversion(struct mc13xxx *, unsigned int,
> > > +				  unsigned int, u8, bool, unsigned
> > > int *); +static int mc34708_adc_conversion(struct mc13xxx *,
> > > unsigned int,
> > > +				  unsigned int, u8, bool, unsigned
> > > int *); +
> > >  /* These are only exported for mc13xxx-i2c and mc13xxx-spi */
> > >  struct mc13xxx_variant mc13xxx_variant_mc13783 = {
> > >  	.name = "mc13783",
> > >  	.print_revision = mc13xxx_print_revision,
> > > +	.adc_do_conversion = mc13xxx_adc_conversion,
> > >  };
> > >  EXPORT_SYMBOL_GPL(mc13xxx_variant_mc13783);  
> > 
> > I'd prefer to keep the call-back functions as close to zero as
> > possible.
> 
> If I may ask - what is wrong with having per device callback(s) ?

Call-backs are ugly and hard to read/debug.

If they can be avoided, they should be, IMHO>

> > It would be better to turn mc13xxx_adc_conversion() in to the catch
> > function
> 
> Could you share any example? 

Just put the code doing the conversion into mc13xxx_adc_conversion()
and remove the call-back.

> > choose an execution route based on some platform matching.
> > 
> 
> Could you help me with giving a hint of how shall I do the "platform
> matching" in this particular driver ? 

We normally match on some platform ID, rather than passing around
pointers to structures containing pointers to device specific
functions.

> The mc13xxx driver seems rather complex with SPI and I2C support and in
> which the subdevices are added (e.g. rtc, adc, etc).

Not sure I follow your point?

> This particular patch just follows current driver design and fixes its
> usability for mc13708 drvice.

Right, but it is the current driver design that I'm trying to change.

> > If you could do the same for print_revision too, that would be even
> > better.
> 
> I would prefer to fix the driver (for mc13708) without the need to
> change the working code.

Okay, but no additional call-backs please.

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* KMSAN: uninit-value in gtco_probe
From: syzbot @ 2019-08-12 12:08 UTC (permalink / raw)
  To: dmitry.torokhov, glider, granthernandez, linux-input,
	linux-kernel, syzkaller-bugs

Hello,

syzbot found the following crash on:

HEAD commit:    61ccdad1 Revert "drm/bochs: Use shadow buffer for bochs fr..
git tree:       kmsan
console output: https://syzkaller.appspot.com/x/log.txt?x=15e29b26600000
kernel config:  https://syzkaller.appspot.com/x/.config?x=27abc558ecb16a3b
dashboard link: https://syzkaller.appspot.com/bug?extid=bb54195a43a54b1e5e5e
compiler:       clang version 9.0.0 (/home/glider/llvm/clang  
80fee25776c2fb61e74c1ecb1a523375c2500b69)

Unfortunately, I don't have any reproducer for this crash yet.

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+bb54195a43a54b1e5e5e@syzkaller.appspotmail.com

usb 6-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
usb 6-1: config 0 descriptor??
gtco 6-1:0.219: Collection level already at zero
==================================================================
BUG: KMSAN: uninit-value in parse_hid_report_descriptor  
drivers/input/tablet/gtco.c:297 [inline]
BUG: KMSAN: uninit-value in gtco_probe+0x18c7/0x3520  
drivers/input/tablet/gtco.c:938
CPU: 1 PID: 12046 Comm: kworker/1:0 Not tainted 5.3.0-rc3+ #17
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  
Google 01/01/2011
Workqueue: usb_hub_wq hub_event
Call Trace:
  __dump_stack lib/dump_stack.c:77 [inline]
  dump_stack+0x191/0x1f0 lib/dump_stack.c:113
  kmsan_report+0x162/0x2d0 mm/kmsan/kmsan_report.c:109
  __msan_warning+0x75/0xe0 mm/kmsan/kmsan_instr.c:294
  parse_hid_report_descriptor drivers/input/tablet/gtco.c:297 [inline]
  gtco_probe+0x18c7/0x3520 drivers/input/tablet/gtco.c:938
  usb_probe_interface+0xd19/0x1310 drivers/usb/core/driver.c:361
  really_probe+0x1373/0x1dc0 drivers/base/dd.c:552
  driver_probe_device+0x1ba/0x510 drivers/base/dd.c:709
  __device_attach_driver+0x5b8/0x790 drivers/base/dd.c:816
  bus_for_each_drv+0x28e/0x3b0 drivers/base/bus.c:454
  __device_attach+0x489/0x750 drivers/base/dd.c:882
  device_initial_probe+0x4a/0x60 drivers/base/dd.c:929
  bus_probe_device+0x131/0x390 drivers/base/bus.c:514
  device_add+0x25b5/0x2df0 drivers/base/core.c:2114
  usb_set_configuration+0x309f/0x3710 drivers/usb/core/message.c:2027
  generic_probe+0xe7/0x280 drivers/usb/core/generic.c:210
  usb_probe_device+0x146/0x200 drivers/usb/core/driver.c:266
  really_probe+0x1373/0x1dc0 drivers/base/dd.c:552
  driver_probe_device+0x1ba/0x510 drivers/base/dd.c:709
  __device_attach_driver+0x5b8/0x790 drivers/base/dd.c:816
  bus_for_each_drv+0x28e/0x3b0 drivers/base/bus.c:454
  __device_attach+0x489/0x750 drivers/base/dd.c:882
  device_initial_probe+0x4a/0x60 drivers/base/dd.c:929
  bus_probe_device+0x131/0x390 drivers/base/bus.c:514
  device_add+0x25b5/0x2df0 drivers/base/core.c:2114
  usb_new_device+0x23e5/0x2fb0 drivers/usb/core/hub.c:2536
  hub_port_connect drivers/usb/core/hub.c:5098 [inline]
  hub_port_connect_change drivers/usb/core/hub.c:5213 [inline]
  port_event drivers/usb/core/hub.c:5359 [inline]
  hub_event+0x581d/0x72f0 drivers/usb/core/hub.c:5441
  process_one_work+0x1572/0x1ef0 kernel/workqueue.c:2269
  worker_thread+0x111b/0x2460 kernel/workqueue.c:2415
  kthread+0x4b5/0x4f0 kernel/kthread.c:256
  ret_from_fork+0x35/0x40 arch/x86/entry/entry_64.S:355

Uninit was stored to memory at:
  kmsan_save_stack_with_flags mm/kmsan/kmsan.c:187 [inline]
  kmsan_internal_chain_origin+0xcc/0x150 mm/kmsan/kmsan.c:345
  __msan_chain_origin+0x6b/0xe0 mm/kmsan/kmsan_instr.c:190
  parse_hid_report_descriptor drivers/input/tablet/gtco.c:298 [inline]
  gtco_probe+0x1a7c/0x3520 drivers/input/tablet/gtco.c:938
  usb_probe_interface+0xd19/0x1310 drivers/usb/core/driver.c:361
  really_probe+0x1373/0x1dc0 drivers/base/dd.c:552
  driver_probe_device+0x1ba/0x510 drivers/base/dd.c:709
  __device_attach_driver+0x5b8/0x790 drivers/base/dd.c:816
  bus_for_each_drv+0x28e/0x3b0 drivers/base/bus.c:454
  __device_attach+0x489/0x750 drivers/base/dd.c:882
  device_initial_probe+0x4a/0x60 drivers/base/dd.c:929
  bus_probe_device+0x131/0x390 drivers/base/bus.c:514
  device_add+0x25b5/0x2df0 drivers/base/core.c:2114
  usb_set_configuration+0x309f/0x3710 drivers/usb/core/message.c:2027
  generic_probe+0xe7/0x280 drivers/usb/core/generic.c:210
  usb_probe_device+0x146/0x200 drivers/usb/core/driver.c:266
  really_probe+0x1373/0x1dc0 drivers/base/dd.c:552
  driver_probe_device+0x1ba/0x510 drivers/base/dd.c:709
  __device_attach_driver+0x5b8/0x790 drivers/base/dd.c:816
  bus_for_each_drv+0x28e/0x3b0 drivers/base/bus.c:454
  __device_attach+0x489/0x750 drivers/base/dd.c:882
  device_initial_probe+0x4a/0x60 drivers/base/dd.c:929
  bus_probe_device+0x131/0x390 drivers/base/bus.c:514
  device_add+0x25b5/0x2df0 drivers/base/core.c:2114
  usb_new_device+0x23e5/0x2fb0 drivers/usb/core/hub.c:2536
  hub_port_connect drivers/usb/core/hub.c:5098 [inline]
  hub_port_connect_change drivers/usb/core/hub.c:5213 [inline]
  port_event drivers/usb/core/hub.c:5359 [inline]
  hub_event+0x581d/0x72f0 drivers/usb/core/hub.c:5441
  process_one_work+0x1572/0x1ef0 kernel/workqueue.c:2269
  worker_thread+0x111b/0x2460 kernel/workqueue.c:2415
  kthread+0x4b5/0x4f0 kernel/kthread.c:256
  ret_from_fork+0x35/0x40 arch/x86/entry/entry_64.S:355

Local variable description: ----globalval.i@gtco_probe
Variable was created at:
  parse_hid_report_descriptor drivers/input/tablet/gtco.c:221 [inline]
  gtco_probe+0xcd6/0x3520 drivers/input/tablet/gtco.c:938
  usb_probe_interface+0xd19/0x1310 drivers/usb/core/driver.c:361
==================================================================


---
This bug 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.

syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

^ permalink raw reply

* KASAN: slab-out-of-bounds Write in ax_probe
From: syzbot @ 2019-08-12 12:18 UTC (permalink / raw)
  To: andreyknvl, benjamin.tissoires, jikos, linux-input, linux-kernel,
	linux-usb, syzkaller-bugs

Hello,

syzbot found the following crash on:

HEAD commit:    e96407b4 usb-fuzzer: main usb gadget fuzzer driver
git tree:       https://github.com/google/kasan.git usb-fuzzer
console output: https://syzkaller.appspot.com/x/log.txt?x=15356402600000
kernel config:  https://syzkaller.appspot.com/x/.config?x=cfa2c18fb6a8068e
dashboard link: https://syzkaller.appspot.com/bug?extid=1e86e2ccce227cca899b
compiler:       gcc (GCC) 9.0.0 20181231 (experimental)
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=1564a0a6600000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=149a199a600000

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+1e86e2ccce227cca899b@syzkaller.appspotmail.com

usb 1-1: config 0 interface 0 altsetting 0 has 1 endpoint descriptor,  
different from the interface descriptor's value: 9
usb 1-1: New USB device found, idVendor=1a34, idProduct=f705, bcdDevice=  
0.40
usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
usb 1-1: config 0 descriptor??
acrux 0003:1A34:F705.0001: hidraw0: USB HID v0.00 Device [HID 1a34:f705] on  
usb-dummy_hcd.0-1/input0
==================================================================
BUG: KASAN: slab-out-of-bounds in set_bit  
include/asm-generic/bitops-instrumented.h:28 [inline]
BUG: KASAN: slab-out-of-bounds in axff_init drivers/hid/hid-axff.c:96  
[inline]
BUG: KASAN: slab-out-of-bounds in ax_probe+0x369/0x540  
drivers/hid/hid-axff.c:138
Write of size 8 at addr ffff8881d5749bc0 by task kworker/0:1/12

CPU: 0 PID: 12 Comm: kworker/0:1 Not tainted 5.3.0-rc2+ #25
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  
Google 01/01/2011
Workqueue: usb_hub_wq hub_event
Call Trace:
  __dump_stack lib/dump_stack.c:77 [inline]
  dump_stack+0xca/0x13e lib/dump_stack.c:113
  print_address_description+0x6a/0x32c mm/kasan/report.c:351
  __kasan_report.cold+0x1a/0x33 mm/kasan/report.c:482
  kasan_report+0xe/0x12 mm/kasan/common.c:612
  check_memory_region_inline mm/kasan/generic.c:185 [inline]
  check_memory_region+0x128/0x190 mm/kasan/generic.c:192
  set_bit include/asm-generic/bitops-instrumented.h:28 [inline]
  axff_init drivers/hid/hid-axff.c:96 [inline]
  ax_probe+0x369/0x540 drivers/hid/hid-axff.c:138
  hid_device_probe+0x2be/0x3f0 drivers/hid/hid-core.c:2209
  really_probe+0x281/0x650 drivers/base/dd.c:548
  driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
  __device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
  bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
  __device_attach+0x217/0x360 drivers/base/dd.c:882
  bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
  device_add+0xae6/0x16f0 drivers/base/core.c:2114
  hid_add_device+0x33c/0x990 drivers/hid/hid-core.c:2365
  usbhid_probe+0xa81/0xfa0 drivers/hid/usbhid/hid-core.c:1386
  usb_probe_interface+0x305/0x7a0 drivers/usb/core/driver.c:361
  really_probe+0x281/0x650 drivers/base/dd.c:548
  driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
  __device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
  bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
  __device_attach+0x217/0x360 drivers/base/dd.c:882
  bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
  device_add+0xae6/0x16f0 drivers/base/core.c:2114
  usb_set_configuration+0xdf6/0x1670 drivers/usb/core/message.c:2023
  generic_probe+0x9d/0xd5 drivers/usb/core/generic.c:210
  usb_probe_device+0x99/0x100 drivers/usb/core/driver.c:266
  really_probe+0x281/0x650 drivers/base/dd.c:548
  driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
  __device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
  bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
  __device_attach+0x217/0x360 drivers/base/dd.c:882
  bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
  device_add+0xae6/0x16f0 drivers/base/core.c:2114
  usb_new_device.cold+0x6a4/0xe79 drivers/usb/core/hub.c:2536
  hub_port_connect drivers/usb/core/hub.c:5098 [inline]
  hub_port_connect_change drivers/usb/core/hub.c:5213 [inline]
  port_event drivers/usb/core/hub.c:5359 [inline]
  hub_event+0x1b5c/0x3640 drivers/usb/core/hub.c:5441
  process_one_work+0x92b/0x1530 kernel/workqueue.c:2269
  worker_thread+0x96/0xe20 kernel/workqueue.c:2415
  kthread+0x318/0x420 kernel/kthread.c:255
  ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352

Allocated by task 12:
  save_stack+0x1b/0x80 mm/kasan/common.c:69
  set_track mm/kasan/common.c:77 [inline]
  __kasan_kmalloc mm/kasan/common.c:487 [inline]
  __kasan_kmalloc.constprop.0+0xbf/0xd0 mm/kasan/common.c:460
  kmalloc include/linux/slab.h:552 [inline]
  kzalloc include/linux/slab.h:748 [inline]
  hidraw_connect+0x4b/0x3e0 drivers/hid/hidraw.c:513
  hid_connect+0x5c7/0xbb0 drivers/hid/hid-core.c:1885
  hid_hw_start drivers/hid/hid-core.c:1981 [inline]
  hid_hw_start+0xa2/0x130 drivers/hid/hid-core.c:1972
  ax_probe+0x52/0x540 drivers/hid/hid-axff.c:132
  hid_device_probe+0x2be/0x3f0 drivers/hid/hid-core.c:2209
  really_probe+0x281/0x650 drivers/base/dd.c:548
  driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
  __device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
  bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
  __device_attach+0x217/0x360 drivers/base/dd.c:882
  bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
  device_add+0xae6/0x16f0 drivers/base/core.c:2114
  hid_add_device+0x33c/0x990 drivers/hid/hid-core.c:2365
  usbhid_probe+0xa81/0xfa0 drivers/hid/usbhid/hid-core.c:1386
  usb_probe_interface+0x305/0x7a0 drivers/usb/core/driver.c:361
  really_probe+0x281/0x650 drivers/base/dd.c:548
  driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
  __device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
  bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
  __device_attach+0x217/0x360 drivers/base/dd.c:882
  bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
  device_add+0xae6/0x16f0 drivers/base/core.c:2114
  usb_set_configuration+0xdf6/0x1670 drivers/usb/core/message.c:2023
  generic_probe+0x9d/0xd5 drivers/usb/core/generic.c:210
  usb_probe_device+0x99/0x100 drivers/usb/core/driver.c:266
  really_probe+0x281/0x650 drivers/base/dd.c:548
  driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
  __device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
  bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
  __device_attach+0x217/0x360 drivers/base/dd.c:882
  bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
  device_add+0xae6/0x16f0 drivers/base/core.c:2114
  usb_new_device.cold+0x6a4/0xe79 drivers/usb/core/hub.c:2536
  hub_port_connect drivers/usb/core/hub.c:5098 [inline]
  hub_port_connect_change drivers/usb/core/hub.c:5213 [inline]
  port_event drivers/usb/core/hub.c:5359 [inline]
  hub_event+0x1b5c/0x3640 drivers/usb/core/hub.c:5441
  process_one_work+0x92b/0x1530 kernel/workqueue.c:2269
  worker_thread+0x96/0xe20 kernel/workqueue.c:2415
  kthread+0x318/0x420 kernel/kthread.c:255
  ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352

Freed by task 1:
  save_stack+0x1b/0x80 mm/kasan/common.c:69
  set_track mm/kasan/common.c:77 [inline]
  __kasan_slab_free+0x130/0x180 mm/kasan/common.c:449
  slab_free_hook mm/slub.c:1423 [inline]
  slab_free_freelist_hook mm/slub.c:1470 [inline]
  slab_free mm/slub.c:3012 [inline]
  kfree+0xe4/0x2f0 mm/slub.c:3953
  urb_destroy drivers/usb/core/urb.c:26 [inline]
  kref_put include/linux/kref.h:65 [inline]
  usb_free_urb.part.0+0x7a/0xc0 drivers/usb/core/urb.c:95
  usb_free_urb+0x1b/0x30 drivers/usb/core/urb.c:94
  usb_start_wait_urb+0x1e5/0x2b0 drivers/usb/core/message.c:79
  usb_internal_control_msg drivers/usb/core/message.c:101 [inline]
  usb_control_msg+0x31c/0x4a0 drivers/usb/core/message.c:152
  set_port_feature+0x69/0x90 drivers/usb/core/hub.c:428
  hub_power_on+0xca/0x280 drivers/usb/core/hub.c:913
  hub_activate+0xfb7/0x1570 drivers/usb/core/hub.c:1068
  hub_configure drivers/usb/core/hub.c:1671 [inline]
  hub_probe.cold+0x21f8/0x2201 drivers/usb/core/hub.c:1864
  usb_probe_interface+0x305/0x7a0 drivers/usb/core/driver.c:361
  really_probe+0x281/0x650 drivers/base/dd.c:548
  driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
  __device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
  bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
  __device_attach+0x217/0x360 drivers/base/dd.c:882
  bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
  device_add+0xae6/0x16f0 drivers/base/core.c:2114
  usb_set_configuration+0xdf6/0x1670 drivers/usb/core/message.c:2023
  generic_probe+0x9d/0xd5 drivers/usb/core/generic.c:210
  usb_probe_device+0x99/0x100 drivers/usb/core/driver.c:266
  really_probe+0x281/0x650 drivers/base/dd.c:548
  driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
  __device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
  bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
  __device_attach+0x217/0x360 drivers/base/dd.c:882
  bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
  device_add+0xae6/0x16f0 drivers/base/core.c:2114
  usb_new_device.cold+0x6a4/0xe79 drivers/usb/core/hub.c:2536
  register_root_hub drivers/usb/core/hcd.c:1108 [inline]
  usb_add_hcd.cold+0x10d5/0x15c5 drivers/usb/core/hcd.c:2893
  vhci_hcd_probe+0xf6/0x230 drivers/usb/usbip/vhci_hcd.c:1340
  platform_drv_probe+0xce/0x1a0 drivers/base/platform.c:616
  really_probe+0x281/0x650 drivers/base/dd.c:548
  driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
  __device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
  bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
  __device_attach+0x217/0x360 drivers/base/dd.c:882
  bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
  device_add+0xae6/0x16f0 drivers/base/core.c:2114
  platform_device_add+0x34d/0x6c0 drivers/base/platform.c:453
  vhci_hcd_init+0x344/0x488 drivers/usb/usbip/vhci_hcd.c:1524
  do_one_initcall+0xf0/0x614 init/main.c:939
  do_initcall_level init/main.c:1007 [inline]
  do_initcalls init/main.c:1015 [inline]
  do_basic_setup init/main.c:1032 [inline]
  kernel_init_freeable+0x4a9/0x596 init/main.c:1192
  kernel_init+0xd/0x1bf init/main.c:1110
  ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352

The buggy address belongs to the object at ffff8881d5749b00
  which belongs to the cache kmalloc-192 of size 192
The buggy address is located 0 bytes to the right of
  192-byte region [ffff8881d5749b00, ffff8881d5749bc0)
The buggy address belongs to the page:
page:ffffea000755d240 refcount:1 mapcount:0 mapping:ffff8881da002a00  
index:0x0
flags: 0x200000000000200(slab)
raw: 0200000000000200 ffffea000755c3c0 0000000400000004 ffff8881da002a00
raw: 0000000000000000 0000000080100010 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
  ffff8881d5749a80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
  ffff8881d5749b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> ffff8881d5749b80: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc
                                            ^
  ffff8881d5749c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  ffff8881d5749c80: 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc fc
====


---
This bug 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.

syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
syzbot can test patches for this bug, for details see:
https://goo.gl/tpsmEJ#testing-patches

^ permalink raw reply

* Re: KASAN: use-after-free Read in usbhid_raw_request
From: Andrey Konovalov @ 2019-08-12 12:48 UTC (permalink / raw)
  To: syzbot
  Cc: Benjamin Tissoires, Jiri Kosina, linux-input, LKML, USB list,
	syzkaller-bugs
In-Reply-To: <0000000000005ff828058f9a5480@google.com>

On Thu, Aug 8, 2019 at 2:38 PM syzbot
<syzbot+75e6910bf03e266a277f@syzkaller.appspotmail.com> wrote:
>
> Hello,
>
> syzbot found the following crash on:
>
> HEAD commit:    e96407b4 usb-fuzzer: main usb gadget fuzzer driver
> git tree:       https://github.com/google/kasan.git usb-fuzzer
> console output: https://syzkaller.appspot.com/x/log.txt?x=16000516600000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=cfa2c18fb6a8068e
> dashboard link: https://syzkaller.appspot.com/bug?extid=75e6910bf03e266a277f
> compiler:       gcc (GCC) 9.0.0 20181231 (experimental)
>
> Unfortunately, I don't have any reproducer for this crash yet.
>
> IMPORTANT: if you fix the bug, please add the following tag to the commit:
> Reported-by: syzbot+75e6910bf03e266a277f@syzkaller.appspotmail.com
>
> ==================================================================
> BUG: KASAN: use-after-free in usbhid_get_raw_report
> drivers/hid/usbhid/hid-core.c:865 [inline]
> BUG: KASAN: use-after-free in usbhid_raw_request+0x5f2/0x640
> drivers/hid/usbhid/hid-core.c:1263
> Read of size 8 at addr ffff8881c8702270 by task syz-executor.4/8993
>
> CPU: 0 PID: 8993 Comm: syz-executor.4 Not tainted 5.3.0-rc2+ #25
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
> Google 01/01/2011
> Call Trace:
>   __dump_stack lib/dump_stack.c:77 [inline]
>   dump_stack+0xca/0x13e lib/dump_stack.c:113
>   print_address_description+0x6a/0x32c mm/kasan/report.c:351
>   __kasan_report.cold+0x1a/0x33 mm/kasan/report.c:482
>   kasan_report+0xe/0x12 mm/kasan/common.c:612
>   usbhid_get_raw_report drivers/hid/usbhid/hid-core.c:865 [inline]
>   usbhid_raw_request+0x5f2/0x640 drivers/hid/usbhid/hid-core.c:1263
>   hid_hw_raw_request include/linux/hid.h:1079 [inline]
>   hidraw_get_report drivers/hid/hidraw.c:228 [inline]
>   hidraw_ioctl+0x936/0xae0 drivers/hid/hidraw.c:426

#syz dup: WARNING in usbhid_raw_request/usb_submit_urb

>   vfs_ioctl fs/ioctl.c:46 [inline]
>   file_ioctl fs/ioctl.c:509 [inline]
>   do_vfs_ioctl+0xd2d/0x1330 fs/ioctl.c:696
>   ksys_ioctl+0x9b/0xc0 fs/ioctl.c:713
>   __do_sys_ioctl fs/ioctl.c:720 [inline]
>   __se_sys_ioctl fs/ioctl.c:718 [inline]
>   __x64_sys_ioctl+0x6f/0xb0 fs/ioctl.c:718
>   do_syscall_64+0xb7/0x580 arch/x86/entry/common.c:296
>   entry_SYSCALL_64_after_hwframe+0x49/0xbe
> RIP: 0033:0x459829
> Code: fd b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7
> 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff
> ff 0f 83 cb b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00
> RSP: 002b:00007f7f49878c78 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
> RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000459829
> RDX: 0000000020000180 RSI: 00000000c0404807 RDI: 0000000000000004
> RBP: 000000000075bf20 R08: 0000000000000000 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000246 R12: 00007f7f498796d4
> R13: 00000000004c2152 R14: 00000000004d54f8 R15: 00000000ffffffff
>
> Allocated by task 83:
>   save_stack+0x1b/0x80 mm/kasan/common.c:69
>   set_track mm/kasan/common.c:77 [inline]
>   __kasan_kmalloc mm/kasan/common.c:487 [inline]
>   __kasan_kmalloc.constprop.0+0xbf/0xd0 mm/kasan/common.c:460
>   kmalloc include/linux/slab.h:552 [inline]
>   kzalloc include/linux/slab.h:748 [inline]
>   usb_set_configuration+0x2c4/0x1670 drivers/usb/core/message.c:1846
>   generic_probe+0x9d/0xd5 drivers/usb/core/generic.c:210
>   usb_probe_device+0x99/0x100 drivers/usb/core/driver.c:266
>   really_probe+0x281/0x650 drivers/base/dd.c:548
>   driver_probe_device+0x101/0x1b0 drivers/base/dd.c:709
>   __device_attach_driver+0x1c2/0x220 drivers/base/dd.c:816
>   bus_for_each_drv+0x15c/0x1e0 drivers/base/bus.c:454
>   __device_attach+0x217/0x360 drivers/base/dd.c:882
>   bus_probe_device+0x1e4/0x290 drivers/base/bus.c:514
>   device_add+0xae6/0x16f0 drivers/base/core.c:2114
>   usb_new_device.cold+0x6a4/0xe79 drivers/usb/core/hub.c:2536
>   hub_port_connect drivers/usb/core/hub.c:5098 [inline]
>   hub_port_connect_change drivers/usb/core/hub.c:5213 [inline]
>   port_event drivers/usb/core/hub.c:5359 [inline]
>   hub_event+0x1b5c/0x3640 drivers/usb/core/hub.c:5441
>   process_one_work+0x92b/0x1530 kernel/workqueue.c:2269
>   worker_thread+0x96/0xe20 kernel/workqueue.c:2415
>   kthread+0x318/0x420 kernel/kthread.c:255
>   ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352
>
> Freed by task 83:
>   save_stack+0x1b/0x80 mm/kasan/common.c:69
>   set_track mm/kasan/common.c:77 [inline]
>   __kasan_slab_free+0x130/0x180 mm/kasan/common.c:449
>   slab_free_hook mm/slub.c:1423 [inline]
>   slab_free_freelist_hook mm/slub.c:1470 [inline]
>   slab_free mm/slub.c:3012 [inline]
>   kfree+0xe4/0x2f0 mm/slub.c:3953
>   device_release+0x71/0x200 drivers/base/core.c:1064
>   kobject_cleanup lib/kobject.c:693 [inline]
>   kobject_release lib/kobject.c:722 [inline]
>   kref_put include/linux/kref.h:65 [inline]
>   kobject_put+0x171/0x280 lib/kobject.c:739
>   put_device+0x1b/0x30 drivers/base/core.c:2213
>   usb_disable_device+0x2ce/0x690 drivers/usb/core/message.c:1244
>   usb_disconnect+0x284/0x8d0 drivers/usb/core/hub.c:2199
>   hub_port_connect drivers/usb/core/hub.c:4949 [inline]
>   hub_port_connect_change drivers/usb/core/hub.c:5213 [inline]
>   port_event drivers/usb/core/hub.c:5359 [inline]
>   hub_event+0x1454/0x3640 drivers/usb/core/hub.c:5441
>   process_one_work+0x92b/0x1530 kernel/workqueue.c:2269
>   worker_thread+0x96/0xe20 kernel/workqueue.c:2415
>   kthread+0x318/0x420 kernel/kthread.c:255
>   ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352
>
> The buggy address belongs to the object at ffff8881c8702200
>   which belongs to the cache kmalloc-2k of size 2048
> The buggy address is located 112 bytes inside of
>   2048-byte region [ffff8881c8702200, ffff8881c8702a00)
> The buggy address belongs to the page:
> page:ffffea000721c000 refcount:1 mapcount:0 mapping:ffff8881da00c000
> index:0x0 compound_mapcount: 0
> flags: 0x200000000010200(slab|head)
> raw: 0200000000010200 dead000000000100 dead000000000122 ffff8881da00c000
> raw: 0000000000000000 00000000000f000f 00000001ffffffff 0000000000000000
> page dumped because: kasan: bad access detected
>
> Memory state around the buggy address:
>   ffff8881c8702100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>   ffff8881c8702180: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> > ffff8881c8702200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>                                                               ^
>   ffff8881c8702280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>   ffff8881c8702300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ==================================================================
>
>
> ---
> This bug 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.
>
> syzbot will keep track of this bug report. See:
> https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

^ permalink raw reply

* [PATCH v3 1/3] HID: core: reformat and reduce hid_printk macros
From: stillcompiling @ 2019-08-12 15:20 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, open list:HID CORE LAYER,
	open list
  Cc: Joe Perches, Joshua Clayton
In-Reply-To: <20190812152022.27963-1-stillcompiling@gmail.com>

From: Joshua Clayton <stillcompiling@gmail.com>

Reformat hid_printk macros to use standard __VA_ARGS__ syntax.
Per Joe Perches hid_printk(), hid_emerg(), hid_crit(), and hid_alert() are
unlikely ever to be used. Remove them.

Signed-off-by: Joshua Clayton <stillcompiling@gmail.com>

diff --git a/include/linux/hid.h b/include/linux/hid.h
index d770ab1a0479..e6c7efdb0458 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1154,29 +1154,21 @@ int hid_pidff_init(struct hid_device *hid);
 #define hid_pidff_init NULL
 #endif
 
-#define dbg_hid(format, arg...)						\
+#define dbg_hid(fmt, ...)						\
 do {									\
 	if (hid_debug)							\
-		printk(KERN_DEBUG "%s: " format, __FILE__, ##arg);	\
+		printk(KERN_DEBUG "%s: " fmt, __FILE__, ##__VA_ARGS__);	\
 } while (0)
 
-#define hid_printk(level, hid, fmt, arg...)		\
-	dev_printk(level, &(hid)->dev, fmt, ##arg)
-#define hid_emerg(hid, fmt, arg...)			\
-	dev_emerg(&(hid)->dev, fmt, ##arg)
-#define hid_crit(hid, fmt, arg...)			\
-	dev_crit(&(hid)->dev, fmt, ##arg)
-#define hid_alert(hid, fmt, arg...)			\
-	dev_alert(&(hid)->dev, fmt, ##arg)
-#define hid_err(hid, fmt, arg...)			\
-	dev_err(&(hid)->dev, fmt, ##arg)
-#define hid_notice(hid, fmt, arg...)			\
-	dev_notice(&(hid)->dev, fmt, ##arg)
-#define hid_warn(hid, fmt, arg...)			\
-	dev_warn(&(hid)->dev, fmt, ##arg)
-#define hid_info(hid, fmt, arg...)			\
-	dev_info(&(hid)->dev, fmt, ##arg)
-#define hid_dbg(hid, fmt, arg...)			\
-	dev_dbg(&(hid)->dev, fmt, ##arg)
+#define hid_err(hid, fmt, ...)				\
+	dev_err(&(hid)->dev, fmt, ##__VA_ARGS__)
+#define hid_notice(hid, fmt, ...)			\
+	dev_notice(&(hid)->dev, fmt, ##__VA_ARGS__)
+#define hid_warn(hid, fmt, ...)				\
+	dev_warn(&(hid)->dev, fmt, ##__VA_ARGS__)
+#define hid_info(hid, fmt, ...)				\
+	dev_info(&(hid)->dev, fmt, ##__VA_ARGS__)
+#define hid_dbg(hid, fmt, ...)				\
+	dev_dbg(&(hid)->dev, fmt, ##__VA_ARGS__)
 
 #endif
-- 
2.21.0

^ permalink raw reply related

* [PATCH v3 2/3] HID: core: Add printk_once variants to hid_warn() etc
From: stillcompiling @ 2019-08-12 15:20 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, open list:HID CORE LAYER,
	open list
  Cc: Joe Perches, Joshua Clayton
In-Reply-To: <20190812152022.27963-1-stillcompiling@gmail.com>

From: Joshua Clayton <stillcompiling@gmail.com>

hid_warn_once() is needed. Add the others as part of the block.

Signed-off-by: Joshua Clayton <stillcompiling@gmail.com>

diff --git a/include/linux/hid.h b/include/linux/hid.h
index e6c7efdb0458..cd41f209043f 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1171,4 +1171,15 @@ do {									\
 #define hid_dbg(hid, fmt, ...)				\
 	dev_dbg(&(hid)->dev, fmt, ##__VA_ARGS__)
 
+#define hid_err_once(hid, fmt, ...)			\
+	dev_err_once(&(hid)->dev, fmt, ##__VA_ARGS__)
+#define hid_notice_once(hid, fmt, ...)			\
+	dev_notice_once(&(hid)->dev, fmt, ##__VA_ARGS__)
+#define hid_warn_once(hid, fmt, ...)			\
+	dev_warn_once(&(hid)->dev, fmt, ##__VA_ARGS__)
+#define hid_info_once(hid, fmt, ...)			\
+	dev_info_once(&(hid)->dev, fmt, ##__VA_ARGS__)
+#define hid_dbg_once(hid, fmt, ...)			\
+	dev_dbg_once(&(hid)->dev, fmt, ##__VA_ARGS__)
+
 #endif
-- 
2.21.0

^ permalink raw reply related


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