Linux Input/HID development
 help / color / mirror / Atom feed
* Re: [PATCH] Input: psmouse-smbus - schedule deferred rescan when adapter present but device not ready
From: sashiko-bot @ 2026-06-04 13:27 UTC (permalink / raw)
  To: Raphaël Larocque; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260604131211.9442-1-rlarocque@disroot.org>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Infinite unbind/rebind loop breaks the PS/2 fallback if the SMBus companion device never responds.
--

commit 18a210ed3c950add4486fdb9a71222e2b1590d6a
Author: Raphaël Larocque <rlarocque@disroot.org>

Input: psmouse-smbus - schedule deferred rescan when adapter present but device not ready

This commit addresses an issue where the SMBus adapter is registered early
but the companion device is not yet responsive. It schedules a deferred
rescan using a delayed work queue to retry the probe without blocking boot.

> diff --git a/drivers/input/mouse/psmouse-smbus.c b/drivers/input/mouse/psmouse-smbus.c
> index 7fb4cbb2aca2f..704d8c2a028ba 100644
> --- a/drivers/input/mouse/psmouse-smbus.c
> +++ b/drivers/input/mouse/psmouse-smbus.c

[ ... ]

> +static void psmouse_smbus_rescan_work_fn(struct work_struct *work)
> +{
> +	struct psmouse_smbus_dev *smbdev =
> +		container_of(to_delayed_work(work),
> +			     struct psmouse_smbus_dev, rescan_work);
>  
>  	guard(mutex)(&psmouse_smbus_mutex);
>  
> +	if (!smbdev->dead && !smbdev->client) {
> +		psmouse_dbg(smbdev->psmouse,
> +			    "SMBus adapter present but device not yet ready, retrying\n");
> +		serio_rescan(smbdev->psmouse->ps2dev.serio);

[Severity: High]
Does this serio_rescan() call introduce an infinite unbind/rebind loop if the
SMBus companion device never responds?

When serio_rescan() triggers, it tears down the PS/2 driver and initiates a
reprobe. During the reprobe, psmouse_smbus_init() runs again.

> +	}
> +}

[ ... ]

> @@ -290,6 +372,18 @@ int psmouse_smbus_init(struct psmouse *psmouse,
>  		}
>  
>  		kfree(smbdev);
> +	} else if (smbdev->adapter_seen) {
> +		/*
> +		 * A HOST_NOTIFY-capable adapter was already registered when we
> +		 * scanned (so BUS_NOTIFY_ADD_DEVICE has already fired for it
> +		 * and won't fire again), but the companion device at 0x2c was
> +		 * not yet responsive — typical of a cold boot on machines like
> +		 * the ThinkPad T440p.  Schedule a deferred rescan so we retry
> +		 * without blocking the boot path, mirroring what
> +		 * psmouse_smbus_check_adapter() does for late-arriving adapters.
> +		 */
> +		queue_delayed_work(psmouse_smbus_wq, &smbdev->rescan_work,
> +				   msecs_to_jiffies(PSMOUSE_SMBUS_RESCAN_DELAY_MS));
>  	}
>  
>  	return error < 0 ? error : -EAGAIN;

[Severity: High]
If the I2C device is permanently unresponsive (e.g. the hardware is physically
wired only for PS/2 despite firmware capabilities), won't the reprobe hit this
path again?

Since a new smbdev is allocated on every probe and there is no persistent
state tracking the retry count, this appears to unconditionally queue the
rescan again.

This would repeatedly destroy and recreate the PS/2 fallback every 1 second,
rendering the touchpad unusable. Can we limit the number of retry attempts or
track the state to avoid this loop?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260604131211.9442-1-rlarocque@disroot.org?part=1

^ permalink raw reply

* [PATCH] Input: psmouse-smbus - schedule deferred rescan when adapter present but device not ready
From: Raphaël Larocque @ 2026-06-04 13:12 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: linux-input, linux-kernel, kees, marco.crivellari,
	Raphaël Larocque

On some machines (e.g.: ThinkPad T440p 20AWS0H800) the Intel LPSS I2C
adapter that hosts the Synaptics RMI4 touchpad is already registered
by the time psmouse probes during early boot.  psmouse_smbus_init()
finds that adapter via i2c_for_each_dev(), but i2c_new_scanned_device()
fails because the device at 0x2c is not yet responsive; -EAGAIN is
returned with breadcrumbs left in psmouse_smbus_list.

Because the adapter is already registered, BUS_NOTIFY_ADD_DEVICE has
already fired for it and will not fire again.  The breadcrumb sits
idle until some other HOST_NOTIFY-capable adapter happens to appear
later and incidentally triggers psmouse_smbus_check_adapter().  When
this happens is non-deterministic: on one boot the rescan fires at
~11 s, on another at ~200 s, on a third never within the observation
window.  The touchpad falls back to PS/2 mode in the interim.

Fix this by scheduling a one-shot deferred serio_rescan() from
psmouse_smbus_init() whenever a HOST_NOTIFY adapter was found but the
companion device was not yet ready.  The work fires asynchronously
(1 s delay) without blocking the boot path, exactly as
psmouse_smbus_check_adapter() already does for late-arriving adapters.
If the device is still not ready on that attempt, a fresh breadcrumb
is left and the work is re-queued, retrying until the device responds.

rescan_work is always INIT_DELAYED_WORK'd so that
cancel_delayed_work_sync() is safe to call unconditionally in all
cleanup paths.  All paths that free a psmouse_smbus_dev are
restructured to release psmouse_smbus_mutex before calling
cancel_delayed_work_sync(), preventing a deadlock with the work
function which also acquires that mutex.

Fixes: 2a02f6c8af14 ("Input: psmouse - fix SMBus companion")
Tested-by: Raphaël Larocque <rlarocque@disroot.org>
Signed-off-by: Raphaël Larocque <rlarocque@disroot.org>
---
 drivers/input/mouse/psmouse-smbus.c | 168 ++++++++++++++++++++++------
 1 file changed, 131 insertions(+), 37 deletions(-)

diff --git a/drivers/input/mouse/psmouse-smbus.c b/drivers/input/mouse/psmouse-smbus.c
index 7fb4cbb2aca2..704d8c2a028b 100644
--- a/drivers/input/mouse/psmouse-smbus.c
+++ b/drivers/input/mouse/psmouse-smbus.c
@@ -21,6 +21,8 @@ struct psmouse_smbus_dev {
 	struct list_head node;
 	bool dead;
 	bool need_deactivate;
+	bool adapter_seen;		/* HOST_NOTIFY adapter found, device not yet ready */
+	struct delayed_work rescan_work;
 };
 
 static LIST_HEAD(psmouse_smbus_list);
@@ -28,6 +30,13 @@ static DEFINE_MUTEX(psmouse_smbus_mutex);
 
 static struct workqueue_struct *psmouse_smbus_wq;
 
+/*
+ * Delay before re-scanning after a HOST_NOTIFY adapter was present but the
+ * companion device did not respond.  The rescan is asynchronous so this does
+ * not add latency to the boot path.
+ */
+#define PSMOUSE_SMBUS_RESCAN_DELAY_MS	1000
+
 static void psmouse_smbus_check_adapter(struct i2c_adapter *adapter)
 {
 	struct psmouse_smbus_dev *smbdev;
@@ -57,32 +66,68 @@ static void psmouse_smbus_check_adapter(struct i2c_adapter *adapter)
 	}
 }
 
-static void psmouse_smbus_detach_i2c_client(struct i2c_client *client)
+/*
+ * psmouse_smbus_rescan_work_fn - deferred rescan when adapter was present
+ * but companion device was not yet ready during psmouse_smbus_init().
+ *
+ * On some machines (e.g. ThinkPad T440p) the LPSS I2C adapter is already
+ * registered by the time psmouse probes, so BUS_NOTIFY_ADD_DEVICE has
+ * already fired and will not fire again.  If the RMI4 device at 0x2c was
+ * not yet responsive at probe time, nothing would ever trigger a rescan.
+ * This work item closes that gap by calling serio_rescan() asynchronously,
+ * exactly as psmouse_smbus_check_adapter() does for late-arriving adapters.
+ */
+static void psmouse_smbus_rescan_work_fn(struct work_struct *work)
 {
-	struct psmouse_smbus_dev *smbdev, *tmp;
+	struct psmouse_smbus_dev *smbdev =
+		container_of(to_delayed_work(work),
+			     struct psmouse_smbus_dev, rescan_work);
 
 	guard(mutex)(&psmouse_smbus_mutex);
 
-	list_for_each_entry_safe(smbdev, tmp, &psmouse_smbus_list, node) {
-		if (smbdev->client != client)
-			continue;
+	if (!smbdev->dead && !smbdev->client) {
+		psmouse_dbg(smbdev->psmouse,
+			    "SMBus adapter present but device not yet ready, retrying\n");
+		serio_rescan(smbdev->psmouse->ps2dev.serio);
+	}
+}
 
-		kfree(client->dev.platform_data);
-		client->dev.platform_data = NULL;
+static void psmouse_smbus_detach_i2c_client(struct i2c_client *client)
+{
+	struct psmouse_smbus_dev *smbdev, *tmp;
+	LIST_HEAD(orphans);
 
-		if (!smbdev->dead) {
-			psmouse_dbg(smbdev->psmouse,
-				    "Marking SMBus companion %s as gone\n",
-				    dev_name(&smbdev->client->dev));
-			smbdev->dead = true;
-			device_link_remove(&smbdev->client->dev,
-					   &smbdev->psmouse->ps2dev.serio->dev);
-			serio_rescan(smbdev->psmouse->ps2dev.serio);
-		} else {
-			list_del(&smbdev->node);
-			kfree(smbdev);
+	scoped_guard(mutex, &psmouse_smbus_mutex) {
+		list_for_each_entry_safe(smbdev, tmp, &psmouse_smbus_list, node) {
+			if (smbdev->client != client)
+				continue;
+
+			kfree(client->dev.platform_data);
+			client->dev.platform_data = NULL;
+
+			if (!smbdev->dead) {
+				psmouse_dbg(smbdev->psmouse,
+					    "Marking SMBus companion %s as gone\n",
+					    dev_name(&smbdev->client->dev));
+				smbdev->dead = true;
+				device_link_remove(&smbdev->client->dev,
+						   &smbdev->psmouse->ps2dev.serio->dev);
+				serio_rescan(smbdev->psmouse->ps2dev.serio);
+			} else {
+				list_del(&smbdev->node);
+				list_add_tail(&smbdev->node, &orphans);
+			}
 		}
 	}
+
+	/*
+	 * Cancel any pending rescan work and free outside the mutex to avoid
+	 * a potential deadlock with the work function.
+	 */
+	list_for_each_entry_safe(smbdev, tmp, &orphans, node) {
+		cancel_delayed_work_sync(&smbdev->rescan_work);
+		kfree(smbdev);
+	}
 }
 
 static int psmouse_smbus_notifier_call(struct notifier_block *nb,
@@ -166,23 +211,29 @@ static void psmouse_smbus_schedule_remove(struct i2c_client *client)
 static void psmouse_smbus_disconnect(struct psmouse *psmouse)
 {
 	struct psmouse_smbus_dev *smbdev = psmouse->private;
+	struct psmouse_smbus_dev *free_smbdev = NULL;
 
-	guard(mutex)(&psmouse_smbus_mutex);
+	scoped_guard(mutex, &psmouse_smbus_mutex) {
+		if (smbdev->dead) {
+			list_del(&smbdev->node);
+			free_smbdev = smbdev;
+		} else {
+			smbdev->dead = true;
+			device_link_remove(&smbdev->client->dev,
+					   &psmouse->ps2dev.serio->dev);
+			psmouse_dbg(smbdev->psmouse,
+				    "posting removal request for SMBus companion %s\n",
+				    dev_name(&smbdev->client->dev));
+			psmouse_smbus_schedule_remove(smbdev->client);
+		}
 
-	if (smbdev->dead) {
-		list_del(&smbdev->node);
-		kfree(smbdev);
-	} else {
-		smbdev->dead = true;
-		device_link_remove(&smbdev->client->dev,
-				   &psmouse->ps2dev.serio->dev);
-		psmouse_dbg(smbdev->psmouse,
-			    "posting removal request for SMBus companion %s\n",
-			    dev_name(&smbdev->client->dev));
-		psmouse_smbus_schedule_remove(smbdev->client);
+		psmouse->private = NULL;
 	}
 
-	psmouse->private = NULL;
+	if (free_smbdev) {
+		cancel_delayed_work_sync(&free_smbdev->rescan_work);
+		kfree(free_smbdev);
+	}
 }
 
 static int psmouse_smbus_create_companion(struct device *dev, void *data)
@@ -199,6 +250,14 @@ static int psmouse_smbus_create_companion(struct device *dev, void *data)
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HOST_NOTIFY))
 		return 0;
 
+	/*
+	 * Remember that a suitable adapter was seen; if the device scan
+	 * below fails (device not yet ready), we know to schedule a deferred
+	 * rescan rather than relying solely on BUS_NOTIFY_ADD_DEVICE (which
+	 * won't fire again for an already-registered adapter).
+	 */
+	smbdev->adapter_seen = true;
+
 	client = i2c_new_scanned_device(adapter, &smbdev->board,
 					addr_list, NULL);
 	if (IS_ERR(client))
@@ -212,15 +271,32 @@ static int psmouse_smbus_create_companion(struct device *dev, void *data)
 void psmouse_smbus_cleanup(struct psmouse *psmouse)
 {
 	struct psmouse_smbus_dev *smbdev, *tmp;
+	LIST_HEAD(orphans);
 
-	guard(mutex)(&psmouse_smbus_mutex);
-
-	list_for_each_entry_safe(smbdev, tmp, &psmouse_smbus_list, node) {
-		if (psmouse == smbdev->psmouse) {
-			list_del(&smbdev->node);
-			kfree(smbdev);
+	scoped_guard(mutex, &psmouse_smbus_mutex) {
+		list_for_each_entry_safe(smbdev, tmp, &psmouse_smbus_list, node) {
+			if (psmouse == smbdev->psmouse) {
+				/*
+				 * Prevent the work function from calling
+				 * serio_rescan() after we release the mutex.
+				 */
+				smbdev->dead = true;
+				list_del(&smbdev->node);
+				list_add_tail(&smbdev->node, &orphans);
+			}
 		}
 	}
+
+	/*
+	 * Cancel any pending rescan work outside the mutex.  The work
+	 * function also takes psmouse_smbus_mutex, so calling
+	 * cancel_delayed_work_sync() under it would deadlock if the work
+	 * happened to be running concurrently.
+	 */
+	list_for_each_entry_safe(smbdev, tmp, &orphans, node) {
+		cancel_delayed_work_sync(&smbdev->rescan_work);
+		kfree(smbdev);
+	}
 }
 
 int psmouse_smbus_init(struct psmouse *psmouse,
@@ -249,6 +325,12 @@ int psmouse_smbus_init(struct psmouse *psmouse,
 		}
 	}
 
+	/*
+	 * Always initialise the delayed work so cancel_delayed_work_sync()
+	 * is safe to call unconditionally in all cleanup paths.
+	 */
+	INIT_DELAYED_WORK(&smbdev->rescan_work, psmouse_smbus_rescan_work_fn);
+
 	if (need_deactivate)
 		psmouse_deactivate(psmouse);
 
@@ -290,6 +372,18 @@ int psmouse_smbus_init(struct psmouse *psmouse,
 		}
 
 		kfree(smbdev);
+	} else if (smbdev->adapter_seen) {
+		/*
+		 * A HOST_NOTIFY-capable adapter was already registered when we
+		 * scanned (so BUS_NOTIFY_ADD_DEVICE has already fired for it
+		 * and won't fire again), but the companion device at 0x2c was
+		 * not yet responsive — typical of a cold boot on machines like
+		 * the ThinkPad T440p.  Schedule a deferred rescan so we retry
+		 * without blocking the boot path, mirroring what
+		 * psmouse_smbus_check_adapter() does for late-arriving adapters.
+		 */
+		queue_delayed_work(psmouse_smbus_wq, &smbdev->rescan_work,
+				   msecs_to_jiffies(PSMOUSE_SMBUS_RESCAN_DELAY_MS));
 	}
 
 	return error < 0 ? error : -EAGAIN;
-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH v14 1/2] HID: cp2112: Add fwnode support
From: Bartosz Golaszewski @ 2026-06-04 12:45 UTC (permalink / raw)
  To: Danny Kaehn
  Cc: Jiri Kosina, linux-input, Dmitry Torokhov, Ethan Twardy,
	linux-i2c, linux-kernel, Leo Huang, Arun D Patil, Willie Thai,
	Ting-Kai Chen, Bartosz Golaszewski, Benjamin Tissoires,
	Andy Shevchenko, Andi Shyti, Conor Dooley
In-Reply-To: <20260520-cp2112-dt-v14-1-b1b4b6734b6f@plexus.com>

On Wed, 20 May 2026 18:13:06 +0200, Danny Kaehn <danny.kaehn@plexus.com> said:
> Support describing the CP2112's I2C and GPIO interfaces in firmware.
>
> Bindings between the firmware nodes and the functions of the device
> are distinct between ACPI and DeviceTree.
>
> For ACPI, the i2c_adapter will use the child with _ADR equal to Zero
> and the gpio_chip will use the child with _ADR equal to One.
>
> For DeviceTree, the i2c_adapter will use the child with name "i2c",
> but the gpio_chip will share a firmware node with the CP2112.
>
> Signed-off-by: Danny Kaehn <danny.kaehn@plexus.com>
> ---

Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

^ permalink raw reply

* [dtor-input:next] BUILD SUCCESS c6f1363abbff69e5bd1cd1fcf060e1510e8d6d31
From: kernel test robot @ 2026-06-04 11:09 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
branch HEAD: c6f1363abbff69e5bd1cd1fcf060e1510e8d6d31  Input: userio - allow setting other id values

elapsed time: 2118m

configs tested: 223
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig    gcc-15.2.0
alpha                            allyesconfig    gcc-15.2.0
alpha                               defconfig    gcc-16.1.0
arc                              allmodconfig    clang-17
arc                              allmodconfig    gcc-15.2.0
arc                               allnoconfig    gcc-15.2.0
arc                              allyesconfig    clang-23
arc                              allyesconfig    gcc-15.2.0
arc                                 defconfig    gcc-16.1.0
arc                   randconfig-001-20260604    clang-17
arc                   randconfig-002-20260604    clang-17
arm                               allnoconfig    clang-23
arm                               allnoconfig    gcc-15.2.0
arm                              allyesconfig    clang-17
arm                              allyesconfig    gcc-15.2.0
arm                                 defconfig    gcc-16.1.0
arm                   randconfig-001-20260604    clang-17
arm                   randconfig-002-20260604    clang-17
arm                   randconfig-003-20260604    clang-17
arm                   randconfig-004-20260604    clang-17
arm64                            allmodconfig    clang-19
arm64                            allmodconfig    clang-23
arm64                             allnoconfig    gcc-15.2.0
arm64                               defconfig    gcc-16.1.0
arm64                 randconfig-001-20260604    clang-17
arm64                 randconfig-002-20260604    clang-17
arm64                 randconfig-003-20260604    clang-17
arm64                 randconfig-004-20260604    clang-17
csky                             allmodconfig    gcc-15.2.0
csky                             allmodconfig    gcc-16.1.0
csky                              allnoconfig    gcc-15.2.0
csky                                defconfig    gcc-16.1.0
csky                  randconfig-001-20260604    clang-17
csky                  randconfig-002-20260604    clang-17
hexagon                          allmodconfig    clang-17
hexagon                          allmodconfig    gcc-15.2.0
hexagon                           allnoconfig    clang-23
hexagon                           allnoconfig    gcc-15.2.0
hexagon                             defconfig    gcc-16.1.0
hexagon                        randconfig-001    gcc-11.5.0
hexagon               randconfig-001-20260604    gcc-11.5.0
hexagon                        randconfig-002    gcc-11.5.0
hexagon               randconfig-002-20260604    gcc-11.5.0
i386                             allmodconfig    gcc-14
i386                              allnoconfig    gcc-14
i386                              allnoconfig    gcc-15.2.0
i386        buildonly-randconfig-001-20260604    clang-20
i386        buildonly-randconfig-002-20260604    clang-20
i386        buildonly-randconfig-003-20260604    clang-20
i386        buildonly-randconfig-004-20260604    clang-20
i386        buildonly-randconfig-005-20260604    clang-20
i386        buildonly-randconfig-006-20260604    clang-20
i386                                defconfig    gcc-16.1.0
i386                  randconfig-001-20260604    clang-20
i386                  randconfig-002-20260604    clang-20
i386                  randconfig-003-20260604    clang-20
i386                  randconfig-004-20260604    clang-20
i386                  randconfig-005-20260604    clang-20
i386                  randconfig-006-20260604    clang-20
i386                  randconfig-007-20260604    clang-20
i386                  randconfig-011-20260604    gcc-14
i386                  randconfig-012-20260604    gcc-14
i386                  randconfig-013-20260604    gcc-14
i386                  randconfig-014-20260604    gcc-14
i386                  randconfig-015-20260604    gcc-14
i386                  randconfig-016-20260604    gcc-14
i386                  randconfig-017-20260604    gcc-14
loongarch                        allmodconfig    clang-19
loongarch                        allmodconfig    clang-23
loongarch                         allnoconfig    clang-23
loongarch                         allnoconfig    gcc-15.2.0
loongarch                           defconfig    clang-23
loongarch                      randconfig-001    gcc-11.5.0
loongarch             randconfig-001-20260604    gcc-11.5.0
loongarch                      randconfig-002    gcc-11.5.0
loongarch             randconfig-002-20260604    gcc-11.5.0
m68k                             allmodconfig    gcc-15.2.0
m68k                             allmodconfig    gcc-16.1.0
m68k                              allnoconfig    gcc-15.2.0
m68k                             allyesconfig    clang-17
m68k                             allyesconfig    gcc-15.2.0
m68k                                defconfig    clang-23
microblaze                        allnoconfig    gcc-15.2.0
microblaze                       allyesconfig    gcc-15.2.0
microblaze                       allyesconfig    gcc-16.1.0
microblaze                          defconfig    clang-23
mips                             allmodconfig    gcc-15.2.0
mips                              allnoconfig    gcc-15.2.0
mips                             allyesconfig    gcc-15.2.0
mips                             allyesconfig    gcc-16.1.0
nios2                            allmodconfig    gcc-11.5.0
nios2                             allnoconfig    clang-17
nios2                             allnoconfig    gcc-11.5.0
nios2                               defconfig    clang-23
nios2                          randconfig-001    gcc-11.5.0
nios2                 randconfig-001-20260604    gcc-11.5.0
nios2                          randconfig-002    gcc-11.5.0
nios2                 randconfig-002-20260604    gcc-11.5.0
openrisc                         allmodconfig    gcc-16.1.0
openrisc                          allnoconfig    clang-17
openrisc                          allnoconfig    gcc-15.2.0
openrisc                            defconfig    gcc-16.1.0
parisc                           allmodconfig    gcc-15.2.0
parisc                            allnoconfig    clang-17
parisc                            allnoconfig    gcc-15.2.0
parisc                           allyesconfig    clang-19
parisc                           allyesconfig    gcc-15.2.0
parisc                              defconfig    gcc-16.1.0
parisc                         randconfig-001    gcc-8.5.0
parisc                randconfig-001-20260604    gcc-8.5.0
parisc                         randconfig-002    gcc-8.5.0
parisc                randconfig-002-20260604    gcc-8.5.0
parisc64                            defconfig    clang-23
powerpc                          allmodconfig    gcc-15.2.0
powerpc                           allnoconfig    clang-17
powerpc                           allnoconfig    gcc-15.2.0
powerpc                        randconfig-001    gcc-8.5.0
powerpc               randconfig-001-20260604    gcc-8.5.0
powerpc                        randconfig-002    gcc-8.5.0
powerpc               randconfig-002-20260604    gcc-8.5.0
powerpc64                      randconfig-001    gcc-8.5.0
powerpc64             randconfig-001-20260604    gcc-8.5.0
powerpc64                      randconfig-002    gcc-8.5.0
powerpc64             randconfig-002-20260604    gcc-8.5.0
riscv                            allmodconfig    clang-23
riscv                             allnoconfig    clang-17
riscv                             allnoconfig    gcc-15.2.0
riscv                            allyesconfig    clang-16
riscv                            allyesconfig    clang-17
riscv                               defconfig    gcc-16.1.0
riscv                          randconfig-001    clang-17
riscv                 randconfig-001-20260604    clang-17
riscv                          randconfig-002    clang-17
riscv                 randconfig-002-20260604    clang-17
s390                             allmodconfig    clang-18
s390                             allmodconfig    clang-19
s390                              allnoconfig    clang-17
s390                              allnoconfig    clang-23
s390                             allyesconfig    gcc-15.2.0
s390                                defconfig    gcc-16.1.0
s390                           randconfig-001    clang-17
s390                  randconfig-001-20260604    clang-17
s390                           randconfig-002    clang-17
s390                  randconfig-002-20260604    clang-17
sh                               allmodconfig    gcc-15.2.0
sh                                allnoconfig    clang-17
sh                                allnoconfig    gcc-15.2.0
sh                               allyesconfig    clang-19
sh                               allyesconfig    gcc-15.2.0
sh                                  defconfig    gcc-14
sh                             randconfig-001    clang-17
sh                    randconfig-001-20260604    clang-17
sh                             randconfig-002    clang-17
sh                    randconfig-002-20260604    clang-17
sh                          urquell_defconfig    gcc-16.1.0
sparc                             allnoconfig    clang-17
sparc                             allnoconfig    gcc-15.2.0
sparc                               defconfig    gcc-16.1.0
sparc                          randconfig-001    gcc-11.5.0
sparc                 randconfig-001-20260604    gcc-11.5.0
sparc                          randconfig-002    gcc-11.5.0
sparc                 randconfig-002-20260604    gcc-11.5.0
sparc64                          allmodconfig    clang-20
sparc64                             defconfig    gcc-14
sparc64                        randconfig-001    gcc-11.5.0
sparc64               randconfig-001-20260604    gcc-11.5.0
sparc64                        randconfig-002    gcc-11.5.0
sparc64               randconfig-002-20260604    gcc-11.5.0
um                               allmodconfig    clang-19
um                                allnoconfig    clang-17
um                                allnoconfig    clang-23
um                               allyesconfig    gcc-14
um                               allyesconfig    gcc-15.2.0
um                                  defconfig    gcc-14
um                             i386_defconfig    gcc-14
um                             randconfig-001    gcc-11.5.0
um                    randconfig-001-20260604    gcc-11.5.0
um                             randconfig-002    gcc-11.5.0
um                    randconfig-002-20260604    gcc-11.5.0
um                           x86_64_defconfig    gcc-14
x86_64                           allmodconfig    clang-20
x86_64                            allnoconfig    clang-17
x86_64                            allnoconfig    clang-20
x86_64                           allyesconfig    clang-20
x86_64      buildonly-randconfig-001-20260604    gcc-14
x86_64      buildonly-randconfig-002-20260604    gcc-14
x86_64      buildonly-randconfig-003-20260604    gcc-14
x86_64      buildonly-randconfig-004-20260604    gcc-14
x86_64      buildonly-randconfig-005-20260604    gcc-14
x86_64      buildonly-randconfig-006-20260604    gcc-14
x86_64                              defconfig    gcc-14
x86_64                                  kexec    clang-22
x86_64                randconfig-001-20260604    clang-20
x86_64                randconfig-002-20260604    clang-20
x86_64                randconfig-003-20260604    clang-20
x86_64                randconfig-004-20260604    clang-20
x86_64                randconfig-005-20260604    clang-20
x86_64                randconfig-006-20260604    clang-20
x86_64                randconfig-011-20260604    clang-22
x86_64                randconfig-012-20260604    clang-22
x86_64                randconfig-013-20260604    clang-22
x86_64                randconfig-014-20260604    clang-22
x86_64                randconfig-015-20260604    clang-22
x86_64                randconfig-016-20260604    clang-22
x86_64                randconfig-071-20260604    clang-22
x86_64                randconfig-072-20260604    clang-22
x86_64                randconfig-073-20260604    clang-22
x86_64                randconfig-074-20260604    clang-22
x86_64                randconfig-075-20260604    clang-22
x86_64                randconfig-076-20260604    clang-22
x86_64                               rhel-9.4    clang-22
x86_64                           rhel-9.4-bpf    gcc-14
x86_64                          rhel-9.4-func    clang-22
x86_64                    rhel-9.4-kselftests    clang-22
x86_64                         rhel-9.4-kunit    gcc-14
x86_64                           rhel-9.4-ltp    gcc-14
x86_64                          rhel-9.4-rust    clang-20
xtensa                            allnoconfig    clang-17
xtensa                            allnoconfig    gcc-15.2.0
xtensa                         randconfig-001    gcc-11.5.0
xtensa                randconfig-001-20260604    gcc-11.5.0
xtensa                         randconfig-002    gcc-11.5.0
xtensa                randconfig-002-20260604    gcc-11.5.0

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [linux-5.15.y 2/3] HID: pass the buffer size to hid_report_raw_event
From: sashiko-bot @ 2026-06-04  9:39 UTC (permalink / raw)
  To: Lee Jones; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260604092659.3953067-2-lee@kernel.org>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] The patch fails to resolve the short report rejection regression for most HID devices because `hid_input_report()` unconditionally sets `bufsize = size`.
- [High] Incorrect `bufsize` argument in `wacom_wac_queue_flush` defeats the mitigation for short reports.
- [Low] Format string mismatch for `size_t` variable `bsize` causes compiler warnings and potential build failures on 32-bit platforms.
--

commit 410a0d731bb14f8c3685faa86ca65503898cc6f0
Author: Benjamin Tissoires <bentiss@kernel.org>

HID: pass the buffer size to hid_report_raw_event

This commit passes the buffer size along with the data size to
hid_report_raw_event() to make a better decision on whether to reject the
buffer or safely memset it to 0 and pass it to the rest of the stack.

> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> index 4fb573ee31b2c..a8d4673c7b8e1 100644
> --- a/drivers/hid/hid-core.c
> +++ b/drivers/hid/hid-core.c
> @@ -1775,8 +1775,8 @@ int __hid_request(struct hid_device *hid, struct hid_report *report,
>  }
>  EXPORT_SYMBOL_GPL(__hid_request);
>  
> -int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
> -		int interrupt)
> +int hid_report_raw_event(struct hid_device *hid, int type, u8 *data,
> +			 size_t bufsize, u32 size, int interrupt)
>  {
>  	struct hid_report_enum *report_enum = hid->report_enum + type;
>  	struct hid_report *report;
> @@ -1784,16 +1784,24 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
>  	int max_buffer_size = HID_MAX_BUFFER_SIZE;
>  	unsigned int a;
>  	u32 rsize, csize = size;
> +	size_t bsize = bufsize;
>  	u8 *cdata = data;
>  	int ret = 0;
>  
>  	report = hid_get_report(report_enum, data);
>  	if (!report)
> -		goto out;
> +		return 0;
> +
> +	if (unlikely(bsize < csize)) {
> +		hid_warn_ratelimited(hid, "Event data for report %d is incorrect (%d vs %ld)\n",
> +				     report->id, csize, bsize);

[Severity: Low]
Does this cause a compiler warning on 32-bit platforms? bsize is a size_t,
but is being printed with the %ld format specifier, which might trigger a
-Wformat warning since size_t is usually an unsigned int on those
architectures. Should this use %zu instead?

> +		return -EINVAL;
> +	}
>  
>  	if (report_enum->numbered) {
>  		cdata++;
>  		csize--;
> +		bsize--;
>  	}
>  
>  	rsize = hid_compute_report_size(report);
> @@ -1806,9 +1814,15 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
>  	else if (rsize > max_buffer_size)
>  		rsize = max_buffer_size;
>  
> +	if (bsize < rsize) {
> +		hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %ld)\n",
> +				     report->id, rsize, bsize);

[Severity: Low]
This isn't a bug, but there's another instance here where bsize is printed
with %ld instead of %zu.

> +		return -EINVAL;
> +	}
> +
>  	if (csize < rsize) {
>  		dbg_hid("report %d is too short, (%d < %d)\n", report->id,
> -				csize, rsize);
> +			csize, rsize);
>  		memset(cdata + csize, 0, rsize - csize);
>  	}

[ ... ]

> @@ -1851,6 +1865,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int i
>  	struct hid_report_enum *report_enum;
>  	struct hid_driver *hdrv;
>  	struct hid_report *report;
> +	size_t bufsize = size;
>  	int ret = 0;
>  
>  	if (!hid)
> @@ -1889,7 +1904,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int i
>  			goto unlock;
>  	}
>  
> -	ret = hid_report_raw_event(hid, type, data, size, interrupt);
> +	ret = hid_report_raw_event(hid, type, data, bufsize, size, interrupt);

[Severity: High]
Does this defeat the short report mitigation for most devices?

Since hid_input_report() is the primary entry point for HID transport
drivers and lacks a bufsize argument, it sets bufsize equal to size (the
payload length). When a short report is received, this guarantees that
bsize < rsize evaluates to true in hid_report_raw_event().

Will this incorrectly drop valid short reports for most HID devices by
triggering the -EINVAL rejection path?

>  
>  unlock:
>  	up(&hid->driver_input_lock);

[ ... ]

> diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
> index c8a8daedff3d0..1b130ac45acad 100644
> --- a/drivers/hid/wacom_sys.c
> +++ b/drivers/hid/wacom_sys.c
> @@ -79,7 +79,7 @@ static void wacom_wac_queue_flush(struct hid_device *hdev,
>  		int err;
>  
>  		size = kfifo_out(fifo, buf, sizeof(buf));
> -		err = hid_report_raw_event(hdev, HID_INPUT_REPORT, buf, size, false);
> +		err = hid_report_raw_event(hdev, HID_INPUT_REPORT, buf, size, size, false);

[Severity: High]
Should the bufsize argument here be sizeof(buf) instead of size?

Because bufsize is being passed as the short data length rather than the
true allocated buffer size, hid_report_raw_event() will evaluate
bsize < rsize as true and incorrectly reject valid short wacom reports
with -EINVAL.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260604092659.3953067-2-lee@kernel.org?part=1

^ permalink raw reply

* [linux-5.15.y 3/3] HID: core: Fix size_t specifier in hid_report_raw_event()
From: Lee Jones @ 2026-06-04  9:26 UTC (permalink / raw)
  To: lee, Jiri Kosina, Benjamin Tissoires, Viresh Kumar, Johan Hovold,
	Alex Elder, Greg Kroah-Hartman, linux-input, linux-kernel,
	greybus-dev, linux-staging
  Cc: stable, Nathan Chancellor, Miguel Ojeda, Linus Torvalds,
	Sasha Levin
In-Reply-To: <20260604092659.3953067-1-lee@kernel.org>

From: Nathan Chancellor <nathan@kernel.org>

[ Upstream commit 4d3a2a466b8d68d852a1f3bbf11204b718428dc4 ]

When building for 32-bit platforms, for which 'size_t' is
'unsigned int', there are warnings around using the incorrect format
specifier to print bsize in hid_report_raw_event():

  drivers/hid/hid-core.c:2054:29: error: format specifies type 'long' but the argument has type 'size_t' (aka 'unsigned int') [-Werror,-Wformat]
   2053 |                 hid_warn_ratelimited(hid, "Event data for report %d is incorrect (%d vs %ld)\n",
        |                                                                                         ~~~
        |                                                                                         %zu
   2054 |                                      report->id, csize, bsize);
        |                                                         ^~~~~
  drivers/hid/hid-core.c:2076:29: error: format specifies type 'long' but the argument has type 'size_t' (aka 'unsigned int') [-Werror,-Wformat]
   2075 |                 hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %ld)\n",
        |                                                                                          ~~~
        |                                                                                          %zu
   2076 |                                      report->id, rsize, bsize);
        |                                                         ^~~~~

Use the proper 'size_t' format specifier, '%zu', to clear up the
warnings.

Cc: stable@vger.kernel.org
Fixes: 2c85c61d1332 ("HID: pass the buffer size to hid_report_raw_event")
Reported-by: Miguel Ojeda <ojeda@kernel.org>
Closes: https://lore.kernel.org/20260516020430.110135-1-ojeda@kernel.org/
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
(cherry picked from commit 3ab135238832446399614e7a4bb796d620717806)
Signed-off-by: Lee Jones <lee@kernel.org>
(cherry picked from commit 0f77a993b5426cca1b046c9ab4b2f8355a4d45dc)
Signed-off-by: Lee Jones <lee@kernel.org>
---
 drivers/hid/hid-core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index a8d4673c7b8e..e106b59b55da 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1793,7 +1793,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data,
 		return 0;
 
 	if (unlikely(bsize < csize)) {
-		hid_warn_ratelimited(hid, "Event data for report %d is incorrect (%d vs %ld)\n",
+		hid_warn_ratelimited(hid, "Event data for report %d is incorrect (%d vs %zu)\n",
 				     report->id, csize, bsize);
 		return -EINVAL;
 	}
@@ -1815,7 +1815,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data,
 		rsize = max_buffer_size;
 
 	if (bsize < rsize) {
-		hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %ld)\n",
+		hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %zu)\n",
 				     report->id, rsize, bsize);
 		return -EINVAL;
 	}
-- 
2.54.0.1032.g2f8565e1d1-goog


^ permalink raw reply related

* [linux-5.15.y 2/3] HID: pass the buffer size to hid_report_raw_event
From: Lee Jones @ 2026-06-04  9:26 UTC (permalink / raw)
  To: lee, Jiri Kosina, Benjamin Tissoires, Viresh Kumar, Johan Hovold,
	Alex Elder, Greg Kroah-Hartman, linux-input, linux-kernel,
	greybus-dev, linux-staging
  Cc: stable, Benjamin Tissoires, Jiri Kosina, Sasha Levin
In-Reply-To: <20260604092659.3953067-1-lee@kernel.org>

From: Benjamin Tissoires <bentiss@kernel.org>

[ Upstream commit 2c85c61d1332e1e16f020d76951baf167dcb6f7a ]

commit 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing
bogus memset()") enforced the provided data to be at least the size of
the declared buffer in the report descriptor to prevent a buffer
overflow. However, we can try to be smarter by providing both the buffer
size and the data size, meaning that hid_report_raw_event() can make
better decision whether we should plaining reject the buffer (buffer
overflow attempt) or if we can safely memset it to 0 and pass it to the
rest of the stack.

Fixes: 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()")
Cc: stable@vger.kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Acked-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Stable-dep-of: 206342541fc8 ("HID: core: introduce hid_safe_input_report()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
(cherry picked from commit 509c2605065004fc4cd86ee50a9350d402785307)
[Lee: Backported to linux-6.12.y and beyond]
Signed-off-by: Lee Jones <lee@kernel.org>
---
 drivers/hid/hid-core.c           | 29 ++++++++++++++++++++++-------
 drivers/hid/hid-gfrm.c           |  4 ++--
 drivers/hid/hid-logitech-hidpp.c |  2 +-
 drivers/hid/hid-multitouch.c     |  2 +-
 drivers/hid/hid-primax.c         |  2 +-
 drivers/hid/hid-vivaldi.c        |  2 +-
 drivers/hid/wacom_sys.c          |  6 +++---
 drivers/staging/greybus/hid.c    |  2 +-
 include/linux/hid.h              |  4 ++--
 9 files changed, 34 insertions(+), 19 deletions(-)

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 4fb573ee31b2..a8d4673c7b8e 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1775,8 +1775,8 @@ int __hid_request(struct hid_device *hid, struct hid_report *report,
 }
 EXPORT_SYMBOL_GPL(__hid_request);
 
-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
-		int interrupt)
+int hid_report_raw_event(struct hid_device *hid, int type, u8 *data,
+			 size_t bufsize, u32 size, int interrupt)
 {
 	struct hid_report_enum *report_enum = hid->report_enum + type;
 	struct hid_report *report;
@@ -1784,16 +1784,24 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
 	int max_buffer_size = HID_MAX_BUFFER_SIZE;
 	unsigned int a;
 	u32 rsize, csize = size;
+	size_t bsize = bufsize;
 	u8 *cdata = data;
 	int ret = 0;
 
 	report = hid_get_report(report_enum, data);
 	if (!report)
-		goto out;
+		return 0;
+
+	if (unlikely(bsize < csize)) {
+		hid_warn_ratelimited(hid, "Event data for report %d is incorrect (%d vs %ld)\n",
+				     report->id, csize, bsize);
+		return -EINVAL;
+	}
 
 	if (report_enum->numbered) {
 		cdata++;
 		csize--;
+		bsize--;
 	}
 
 	rsize = hid_compute_report_size(report);
@@ -1806,9 +1814,15 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
 	else if (rsize > max_buffer_size)
 		rsize = max_buffer_size;
 
+	if (bsize < rsize) {
+		hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %ld)\n",
+				     report->id, rsize, bsize);
+		return -EINVAL;
+	}
+
 	if (csize < rsize) {
 		dbg_hid("report %d is too short, (%d < %d)\n", report->id,
-				csize, rsize);
+			csize, rsize);
 		memset(cdata + csize, 0, rsize - csize);
 	}
 
@@ -1817,7 +1831,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
 	if (hid->claimed & HID_CLAIMED_HIDRAW) {
 		ret = hidraw_report_event(hid, data, size);
 		if (ret)
-			goto out;
+			return ret;
 	}
 
 	if (hid->claimed != HID_CLAIMED_HIDRAW && report->maxfield) {
@@ -1830,7 +1844,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
 
 	if (hid->claimed & HID_CLAIMED_INPUT)
 		hidinput_report_event(hid, report);
-out:
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(hid_report_raw_event);
@@ -1851,6 +1865,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int i
 	struct hid_report_enum *report_enum;
 	struct hid_driver *hdrv;
 	struct hid_report *report;
+	size_t bufsize = size;
 	int ret = 0;
 
 	if (!hid)
@@ -1889,7 +1904,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int i
 			goto unlock;
 	}
 
-	ret = hid_report_raw_event(hid, type, data, size, interrupt);
+	ret = hid_report_raw_event(hid, type, data, bufsize, size, interrupt);
 
 unlock:
 	up(&hid->driver_input_lock);
diff --git a/drivers/hid/hid-gfrm.c b/drivers/hid/hid-gfrm.c
index 699186ff2349..d2a56bf92b41 100644
--- a/drivers/hid/hid-gfrm.c
+++ b/drivers/hid/hid-gfrm.c
@@ -66,7 +66,7 @@ static int gfrm_raw_event(struct hid_device *hdev, struct hid_report *report,
 	switch (data[1]) {
 	case GFRM100_SEARCH_KEY_DOWN:
 		ret = hid_report_raw_event(hdev, HID_INPUT_REPORT, search_key_dn,
-					   sizeof(search_key_dn), 1);
+					   sizeof(search_key_dn), sizeof(search_key_dn), 1);
 		break;
 
 	case GFRM100_SEARCH_KEY_AUDIO_DATA:
@@ -74,7 +74,7 @@ static int gfrm_raw_event(struct hid_device *hdev, struct hid_report *report,
 
 	case GFRM100_SEARCH_KEY_UP:
 		ret = hid_report_raw_event(hdev, HID_INPUT_REPORT, search_key_up,
-					   sizeof(search_key_up), 1);
+					   sizeof(search_key_up), sizeof(search_key_up), 1);
 		break;
 
 	default:
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 7ed851bf5bc8..812ed660c555 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -3440,7 +3440,7 @@ static int hidpp10_consumer_keys_raw_event(struct hidpp_device *hidpp,
 	memcpy(&consumer_report[1], &data[3], 4);
 	/* We are called from atomic context */
 	hid_report_raw_event(hidpp->hid_dev, HID_INPUT_REPORT,
-			     consumer_report, 5, 1);
+			     consumer_report, sizeof(consumer_report), 5, 1);
 
 	return 1;
 }
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 7a092a2a1bf0..df87d7ae94c4 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -479,7 +479,7 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
 		}
 
 		ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf,
-					   size, 0);
+					   size, size, 0);
 		if (ret)
 			dev_warn(&hdev->dev, "failed to report feature\n");
 	}
diff --git a/drivers/hid/hid-primax.c b/drivers/hid/hid-primax.c
index 1e6413d07cae..16e2a811eda9 100644
--- a/drivers/hid/hid-primax.c
+++ b/drivers/hid/hid-primax.c
@@ -44,7 +44,7 @@ static int px_raw_event(struct hid_device *hid, struct hid_report *report,
 			data[0] |= (1 << (data[idx] - 0xE0));
 			data[idx] = 0;
 		}
-		hid_report_raw_event(hid, HID_INPUT_REPORT, data, size, 0);
+		hid_report_raw_event(hid, HID_INPUT_REPORT, data, size, size, 0);
 		return 1;
 
 	default:	/* unknown report */
diff --git a/drivers/hid/hid-vivaldi.c b/drivers/hid/hid-vivaldi.c
index d57ec1767037..fdfea1355ee7 100644
--- a/drivers/hid/hid-vivaldi.c
+++ b/drivers/hid/hid-vivaldi.c
@@ -126,7 +126,7 @@ static void vivaldi_feature_mapping(struct hid_device *hdev,
 	}
 
 	ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, report_data,
-				   report_len, 0);
+				   report_len, report_len, 0);
 	if (ret) {
 		dev_warn(&hdev->dev, "failed to report feature %d\n",
 			 field->report->id);
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index c8a8daedff3d..1b130ac45aca 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -79,7 +79,7 @@ static void wacom_wac_queue_flush(struct hid_device *hdev,
 		int err;
 
 		size = kfifo_out(fifo, buf, sizeof(buf));
-		err = hid_report_raw_event(hdev, HID_INPUT_REPORT, buf, size, false);
+		err = hid_report_raw_event(hdev, HID_INPUT_REPORT, buf, size, size, false);
 		if (err) {
 			hid_warn(hdev, "%s: unable to flush event due to error %d\n",
 				 __func__, err);
@@ -324,7 +324,7 @@ static void wacom_feature_mapping(struct hid_device *hdev,
 					       data, n, WAC_CMD_RETRIES);
 			if (ret == n && features->type == HID_GENERIC) {
 				ret = hid_report_raw_event(hdev,
-					HID_FEATURE_REPORT, data, n, 0);
+					HID_FEATURE_REPORT, data, n, n, 0);
 			} else if (ret == 2 && features->type != HID_GENERIC) {
 				features->touch_max = data[1];
 			} else {
@@ -385,7 +385,7 @@ static void wacom_feature_mapping(struct hid_device *hdev,
 					data, n, WAC_CMD_RETRIES);
 		if (ret == n) {
 			ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT,
-						   data, n, 0);
+						   data, n, n, 0);
 		} else {
 			hid_warn(hdev, "%s: could not retrieve sensor offsets\n",
 				 __func__);
diff --git a/drivers/staging/greybus/hid.c b/drivers/staging/greybus/hid.c
index adb91286803a..49b42c0ab078 100644
--- a/drivers/staging/greybus/hid.c
+++ b/drivers/staging/greybus/hid.c
@@ -201,7 +201,7 @@ static void gb_hid_init_report(struct gb_hid *ghid, struct hid_report *report)
 	 * we just need to setup the input fields, so using
 	 * hid_report_raw_event is safe.
 	 */
-	hid_report_raw_event(ghid->hid, report->type, ghid->inbuf, size, 1);
+	hid_report_raw_event(ghid->hid, report->type, ghid->inbuf, ghid->bufsize, size, 1);
 }
 
 static void gb_hid_init_reports(struct gb_hid *ghid)
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 3968fa039c26..c92c5e2ae24f 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1206,8 +1206,8 @@ static inline u32 hid_report_len(struct hid_report *report)
 	return DIV_ROUND_UP(report->size, 8) + (report->id > 0);
 }
 
-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
-		int interrupt);
+int hid_report_raw_event(struct hid_device *hid, int type, u8 *data,
+			 size_t bufsize, u32 size, int interrupt);
 
 /* HID quirks API */
 unsigned long hid_lookup_quirk(const struct hid_device *hdev);
-- 
2.54.0.1032.g2f8565e1d1-goog


^ permalink raw reply related

* [linux-5.15.y 1/3] HID: core: Add printk_ratelimited variants to hid_warn() etc
From: Lee Jones @ 2026-06-04  9:26 UTC (permalink / raw)
  To: lee, Jiri Kosina, Benjamin Tissoires, Viresh Kumar, Johan Hovold,
	Alex Elder, Greg Kroah-Hartman, linux-input, linux-kernel,
	greybus-dev, linux-staging
  Cc: stable, Vicki Pfau, Jiri Kosina

From: Vicki Pfau <vi@endrift.com>

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

Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
(cherry picked from commit 1d64624243af8329b4b219d8c39e28ea448f9929)
Signed-off-by: Lee Jones <lee@kernel.org>
(cherry picked from commit 3dc96d0b81eae69bf71e129e3f331c982c5c70fd)
Signed-off-by: Lee Jones <lee@kernel.org>
---
 include/linux/hid.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/hid.h b/include/linux/hid.h
index 671403f208c9..3968fa039c26 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1248,4 +1248,15 @@ do {									\
 #define hid_dbg_once(hid, fmt, ...)			\
 	dev_dbg_once(&(hid)->dev, fmt, ##__VA_ARGS__)
 
+#define hid_err_ratelimited(hid, fmt, ...)			\
+	dev_err_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__)
+#define hid_notice_ratelimited(hid, fmt, ...)			\
+	dev_notice_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__)
+#define hid_warn_ratelimited(hid, fmt, ...)			\
+	dev_warn_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__)
+#define hid_info_ratelimited(hid, fmt, ...)			\
+	dev_info_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__)
+#define hid_dbg_ratelimited(hid, fmt, ...)			\
+	dev_dbg_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__)
+
 #endif
-- 
2.54.0.1032.g2f8565e1d1-goog


^ permalink raw reply related

* Re: [PATCH v2 4/4] Input: snvs_pwrkey - report press event in interrupt handler
From: sashiko-bot @ 2026-06-04  9:07 UTC (permalink / raw)
  To: Joy Zou; +Cc: imx, Frank.Li, linux-input, dmitry.torokhov
In-Reply-To: <20260604-pwrkey-cleanup-v2-4-59fa0ddf0d7c@nxp.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Data race between hardirq and timer softirq leads to desynchronized key state
--

commit 9a729213fc1cfc21c866a352fad1a978bfa80359
Author: Joy Zou <joy.zou@nxp.com>

Input: snvs_pwrkey - report press event in interrupt handler

This commit modifies the snvs_pwrkey driver to directly report key press
events from the interrupt handler during system suspend. This bypasses the
debounce timer to prevent event loss during the no_irq resume phase.

> diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c
> index 4a1d048984826..f212a6b26185d 100644
> --- a/drivers/input/keyboard/snvs_pwrkey.c
> +++ b/drivers/input/keyboard/snvs_pwrkey.c
[ ... ]
> @@ -92,6 +93,15 @@ static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void *dev_id)
>  			input_sync(input);
>  			pm_relax(input->dev.parent);
>  		} else {
> +			/*
> +			 * Report key press events directly in interrupt handler to prevent event
> +			 * loss during system suspend.
> +			 */
> +			if (pdata->suspended) {
> +				pdata->keystate = 1;
> +				input_report_key(input, pdata->keycode, 1);
> +				input_sync(input);
> +			}

[Severity: High]
Does this introduce a data race with the timer callback
imx_imx_snvs_check_for_events()?

The new hardirq logic writes to pdata->keystate locklessly here, but
imx_imx_snvs_check_for_events() also reads and writes it locklessly in
softirq context.

Could this sequence occur:

1. The timer callback reads state = 0 (key released) and evaluates
   (state ^ pdata->keystate) as true.
2. The timer sets pdata->keystate = 0.
3. Before the timer calls input_event(), a key press triggers the hardirq
   on the same CPU (preemption) or another CPU.
4. The hardirq sees pdata->suspended == true, sets pdata->keystate = 1,
   and reports a key press (1).
5. The timer resumes and reports the release (0) to the input core.

This would leave pdata->keystate as 1, while the input subsystem's last
reported state is 0. On the next physical key press, the timer would read
state = 1, evaluate 1 ^ 1 as 0, and ignore the event. This might cause the
power key to become logically stuck until physically released again.

>  			mod_timer(&pdata->check_timer,
>  			          jiffies + msecs_to_jiffies(DEBOUNCE_TIME));
>  		}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260604-pwrkey-cleanup-v2-0-59fa0ddf0d7c@nxp.com?part=4

^ permalink raw reply

* Re: [PATCH v2 1/4] Input: snvs_pwrkey - make use of dev_err_probe()
From: sashiko-bot @ 2026-06-04  7:04 UTC (permalink / raw)
  To: Joy Zou; +Cc: linux-input, imx, Frank.Li, dmitry.torokhov
In-Reply-To: <20260604-pwrkey-cleanup-v2-1-59fa0ddf0d7c@nxp.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] Incorrect pairing of pm_wakeup_event(dev, 0) and pm_relax(dev) fails to keep the system awake.
- [Medium] Missing cleanup for dev_pm_set_wake_irq() causes resource leak and -EEXIST on rebind.
--

commit c91200344c06e4226bdcadd16b77ac3688786f5d
Author: Joy Zou <joy.zou@nxp.com>

Input: snvs_pwrkey - make use of dev_err_probe()

This patch updates the imx_snvs_pwrkey_probe function to use dev_err_probe()
on its error paths. This provides more concise error logging and helps
identify issues more easily during probe.

> diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c
> index 954055aaf6e29..748196fcce75b 100644
> --- a/drivers/input/keyboard/snvs_pwrkey.c
> +++ b/drivers/input/keyboard/snvs_pwrkey.c

[ ... ]

> @@ -209,16 +203,12 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
>  	error = devm_request_irq(&pdev->dev, pdata->irq,
>  			       imx_snvs_pwrkey_interrupt,
>  			       0, pdev->name, pdev);
> -	if (error) {
> -		dev_err(&pdev->dev, "interrupt not available.\n");
> -		return error;
> -	}
> +	if (error)
> +		return dev_err_probe(&pdev->dev, error, "interrupt not available.\n");
>  
>  	error = input_register_device(input);
> -	if (error < 0) {
> -		dev_err(&pdev->dev, "failed to register input device\n");
> -		return error;
> -	}
> +	if (error < 0)
> +		return dev_err_probe(&pdev->dev, error, "failed to register input device\n");
>  
>  	device_init_wakeup(&pdev->dev, pdata->wakeup);
>  	error = dev_pm_set_wake_irq(&pdev->dev, pdata->irq);

[Severity: Medium]
This is a pre-existing issue, but since dev_pm_set_wake_irq() is called here
without a corresponding cleanup mechanism, does this cause a resource leak?

When the driver is unbound via sysfs, the allocated wake_irq structure is
leaked and the device remains marked with a wakeirq because there is no
.remove callback or devm action to call dev_pm_clear_wake_irq().

Will a subsequent rebind cause dev_pm_set_wake_irq() to fail with -EEXIST
because dev->power.wakeirq is still populated?

This is also a pre-existing issue, but I noticed something else regarding the
wake event handling.

drivers/input/keyboard/snvs_pwrkey.c:imx_snvs_pwrkey_interrupt() {
    ...
	pm_wakeup_event(input->dev.parent, 0);
    ...
}

And later in the driver:

drivers/input/keyboard/snvs_pwrkey.c:imx_imx_snvs_check_for_events() {
    ...
		pm_relax(pdata->input->dev.parent);
    ...
}

[Severity: High]
Does this incorrect pairing of pm_wakeup_event(dev, 0) and pm_relax(dev) fail
to keep the system awake?

Passing a 0 ms timeout to pm_wakeup_event() activates and immediately
deactivates the wakeup source. Because the wakeup source is already inactive,
the later call to pm_relax() acts as a no-op.

Does this mean the system is free to enter auto-sleep immediately after the
interrupt and before the timer executes, potentially delaying or dropping the
power key event delivery? Would it be better to use pm_stay_awake() here
instead?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260604-pwrkey-cleanup-v2-0-59fa0ddf0d7c@nxp.com?part=1

^ permalink raw reply

* [PATCH v2 4/4] Input: snvs_pwrkey - report press event in interrupt handler
From: Joy Zou @ 2026-06-04  6:56 UTC (permalink / raw)
  To: Dmitry Torokhov, Frank Li, Peng Fan, Jacky Bai, Ye Li
  Cc: imx, linux-input, linux-kernel, Joy Zou
In-Reply-To: <20260604-pwrkey-cleanup-v2-0-59fa0ddf0d7c@nxp.com>

The driver implements debounce protection using a timer-based mechanism:
when a key interrupt occurs, a timer is scheduled to verify the key state
after DEBOUNCE_TIME before reporting the event. This works well during
normal operation.

However, key press events can be lost during system resume on platforms
like i.MX8MQ-EVK because:
1. During the no_irq resume phase, PCIe driver restoration can take up to
200ms with IRQs disabled.
2. The power key interrupt remains pending during the no_irq phase.
3. If the key is released before IRQs are re-enabled, the timer eventually
runs but sees the key as released and skips reporting the event.

Report key press events directly in interrupt handler to prevent event
loss during system suspend. This is safe because:

1. Only one event is reported per suspend cycle.
2. Normal operation retains the existing timer-based debounce mechanism.

Signed-off-by: Joy Zou <joy.zou@nxp.com>
---
Changes for v2:
1. Add a boolean variable suspended and PM callback functions to replace
   the use of the is_suspended field per AI review comments.
2. Move event report handle to else branch in suspended state, since the
   pdata->minor_rev == 0 branch has no debounce detection per AI review
   comments.
3. Modify the commit message.
---
 drivers/input/keyboard/snvs_pwrkey.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c
index 4a1d04898482669894e9978014b62e4e9774b4e4..f212a6b26185d13e1af62728e7b2add5010adc5a 100644
--- a/drivers/input/keyboard/snvs_pwrkey.c
+++ b/drivers/input/keyboard/snvs_pwrkey.c
@@ -39,6 +39,7 @@ struct pwrkey_drv_data {
 	int keycode;
 	int keystate;  /* 1:pressed */
 	int wakeup;
+	bool suspended; /* Track suspend state */
 	struct timer_list check_timer;
 	struct input_dev *input;
 	u8 minor_rev;
@@ -92,6 +93,15 @@ static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void *dev_id)
 			input_sync(input);
 			pm_relax(input->dev.parent);
 		} else {
+			/*
+			 * Report key press events directly in interrupt handler to prevent event
+			 * loss during system suspend.
+			 */
+			if (pdata->suspended) {
+				pdata->keystate = 1;
+				input_report_key(input, pdata->keycode, 1);
+				input_sync(input);
+			}
 			mod_timer(&pdata->check_timer,
 			          jiffies + msecs_to_jiffies(DEBOUNCE_TIME));
 		}
@@ -219,6 +229,30 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int __maybe_unused imx_snvs_pwrkey_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
+
+	pdata->suspended = true;
+
+	return 0;
+}
+
+static int __maybe_unused imx_snvs_pwrkey_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
+
+	pdata->suspended = false;
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(imx_snvs_pwrkey_pm_ops,
+			 imx_snvs_pwrkey_suspend,
+			 imx_snvs_pwrkey_resume);
+
 static const struct of_device_id imx_snvs_pwrkey_ids[] = {
 	{ .compatible = "fsl,sec-v4.0-pwrkey" },
 	{ /* sentinel */ }
@@ -229,6 +263,7 @@ static struct platform_driver imx_snvs_pwrkey_driver = {
 	.driver = {
 		.name = "snvs_pwrkey",
 		.of_match_table = imx_snvs_pwrkey_ids,
+		.pm   = &imx_snvs_pwrkey_pm_ops,
 	},
 	.probe = imx_snvs_pwrkey_probe,
 };

-- 
2.50.1


^ permalink raw reply related

* [PATCH v2 3/4] Input: snvs_pwrkey - use local device pointer to simple code
From: Joy Zou @ 2026-06-04  6:56 UTC (permalink / raw)
  To: Dmitry Torokhov, Frank Li, Peng Fan, Jacky Bai, Ye Li
  Cc: imx, linux-input, linux-kernel, Joy Zou
In-Reply-To: <20260604-pwrkey-cleanup-v2-0-59fa0ddf0d7c@nxp.com>

Use local struct device pointer to avoid reference the platform_device
pointer every time.

No functional change.

Signed-off-by: Joy Zou <joy.zou@nxp.com>
---
Changes for v2:
1. Use dev instead of &pdev->dev for devm_input_allocate_device(),
   which was missed in patch v1 per AI review comments.
2. Modify commit message.
---
 drivers/input/keyboard/snvs_pwrkey.c | 41 ++++++++++++++++++------------------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c
index a291812e6d22ea963568cced5b889bad00658526..4a1d04898482669894e9978014b62e4e9774b4e4 100644
--- a/drivers/input/keyboard/snvs_pwrkey.c
+++ b/drivers/input/keyboard/snvs_pwrkey.c
@@ -112,6 +112,7 @@ static void imx_snvs_pwrkey_act(void *pdata)
 
 static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
 	struct pwrkey_drv_data *pdata;
 	struct input_dev *input;
 	struct device_node *np;
@@ -122,26 +123,26 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
 	u32 vid;
 
 	/* Get SNVS register Page */
-	np = pdev->dev.of_node;
+	np = dev->of_node;
 	if (!np)
-		return dev_err_probe(&pdev->dev, -ENODEV, "Device tree node not found\n");
+		return dev_err_probe(dev, -ENODEV, "Device tree node not found\n");
 
-	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return -ENOMEM;
 
 	pdata->snvs = syscon_regmap_lookup_by_phandle(np, "regmap");
 	if (IS_ERR(pdata->snvs))
-		return dev_err_probe(&pdev->dev, PTR_ERR(pdata->snvs), "Can't get snvs syscon\n");
+		return dev_err_probe(dev, PTR_ERR(pdata->snvs), "Can't get snvs syscon\n");
 
 	if (of_property_read_u32(np, "linux,keycode", &pdata->keycode)) {
 		pdata->keycode = KEY_POWER;
-		dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n");
+		dev_warn(dev, "KEY_POWER without setting in dts\n");
 	}
 
-	clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
+	clk = devm_clk_get_optional_enabled(dev, NULL);
 	if (IS_ERR(clk))
-		return dev_err_probe(&pdev->dev, PTR_ERR(clk),
+		return dev_err_probe(dev, PTR_ERR(clk),
 				     "Failed to get snvs clock (%pe)\n", clk);
 
 	pdata->wakeup = of_property_read_bool(np, "wakeup-source");
@@ -162,7 +163,7 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
 			bpt = (val / 5) - 1;
 			break;
 		default:
-			return dev_err_probe(&pdev->dev, -EINVAL,
+			return dev_err_probe(dev, -EINVAL,
 					     "power-off-time-sec %d out of range\n", val);
 		}
 
@@ -180,9 +181,9 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
 
 	timer_setup(&pdata->check_timer, imx_imx_snvs_check_for_events, 0);
 
-	input = devm_input_allocate_device(&pdev->dev);
+	input = devm_input_allocate_device(dev);
 	if (!input) {
-		dev_err(&pdev->dev, "failed to allocate the input device\n");
+		dev_err(dev, "failed to allocate the input device\n");
 		return -ENOMEM;
 	}
 
@@ -193,27 +194,27 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
 	input_set_capability(input, EV_KEY, pdata->keycode);
 
 	/* input customer action to cancel release timer */
-	error = devm_add_action(&pdev->dev, imx_snvs_pwrkey_act, pdata);
+	error = devm_add_action(dev, imx_snvs_pwrkey_act, pdata);
 	if (error)
-		return dev_err_probe(&pdev->dev, error, "failed to register remove action\n");
+		return dev_err_probe(dev, error, "failed to register remove action\n");
 
 	pdata->input = input;
 	platform_set_drvdata(pdev, pdata);
 
-	error = devm_request_irq(&pdev->dev, pdata->irq,
-			       imx_snvs_pwrkey_interrupt,
-			       0, pdev->name, pdev);
+	error = devm_request_irq(dev, pdata->irq,
+				 imx_snvs_pwrkey_interrupt,
+				 0, pdev->name, pdev);
 	if (error)
-		return dev_err_probe(&pdev->dev, error, "interrupt not available.\n");
+		return dev_err_probe(dev, error, "interrupt not available.\n");
 
 	error = input_register_device(input);
 	if (error < 0)
-		return dev_err_probe(&pdev->dev, error, "failed to register input device\n");
+		return dev_err_probe(dev, error, "failed to register input device\n");
 
-	device_init_wakeup(&pdev->dev, pdata->wakeup);
-	error = dev_pm_set_wake_irq(&pdev->dev, pdata->irq);
+	device_init_wakeup(dev, pdata->wakeup);
+	error = dev_pm_set_wake_irq(dev, pdata->irq);
 	if (error)
-		dev_err(&pdev->dev, "irq wake enable failed.\n");
+		dev_err(dev, "irq wake enable failed.\n");
 
 	return 0;
 }

-- 
2.50.1


^ permalink raw reply related

* [PATCH v2 2/4] Input: snvs_pwrkey - replace hardcoding -EINVAL with original error code
From: Joy Zou @ 2026-06-04  6:56 UTC (permalink / raw)
  To: Dmitry Torokhov, Frank Li, Peng Fan, Jacky Bai, Ye Li
  Cc: imx, linux-input, linux-kernel, Joy Zou
In-Reply-To: <20260604-pwrkey-cleanup-v2-0-59fa0ddf0d7c@nxp.com>

Hardcoding -EINVAL discards the actual error code, which breaks probe
deferral (-EPROBE_DEFER) and loses critical diagnostic information
needed for proper kernel error handling.

Signed-off-by: Joy Zou <joy.zou@nxp.com>
---
 drivers/input/keyboard/snvs_pwrkey.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c
index 748196fcce75ba7192b1ee5fc516bdf4a9ae074d..a291812e6d22ea963568cced5b889bad00658526 100644
--- a/drivers/input/keyboard/snvs_pwrkey.c
+++ b/drivers/input/keyboard/snvs_pwrkey.c
@@ -148,7 +148,7 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
 
 	pdata->irq = platform_get_irq(pdev, 0);
 	if (pdata->irq < 0)
-		return -EINVAL;
+		return pdata->irq;
 
 	error = of_property_read_u32(np, "power-off-time-sec", &val);
 	if (!error) {

-- 
2.50.1


^ permalink raw reply related

* [PATCH v2 1/4] Input: snvs_pwrkey - make use of dev_err_probe()
From: Joy Zou @ 2026-06-04  6:56 UTC (permalink / raw)
  To: Dmitry Torokhov, Frank Li, Peng Fan, Jacky Bai, Ye Li
  Cc: imx, linux-input, linux-kernel, Joy Zou
In-Reply-To: <20260604-pwrkey-cleanup-v2-0-59fa0ddf0d7c@nxp.com>

Add dev_err_probe() at return path of probe() to support users to
identify issues easier.

Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Joy Zou <joy.zou@nxp.com>
---
Changes in v2:
1. Drop dev_err_probe() change for platform_get_irq() per AI review comments.
2. Add Reviewed-by tag.
---
 drivers/input/keyboard/snvs_pwrkey.c | 38 +++++++++++++-----------------------
 1 file changed, 14 insertions(+), 24 deletions(-)

diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c
index 954055aaf6e29527f22f8129fd47ca17722e2bc9..748196fcce75ba7192b1ee5fc516bdf4a9ae074d 100644
--- a/drivers/input/keyboard/snvs_pwrkey.c
+++ b/drivers/input/keyboard/snvs_pwrkey.c
@@ -124,17 +124,15 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
 	/* Get SNVS register Page */
 	np = pdev->dev.of_node;
 	if (!np)
-		return -ENODEV;
+		return dev_err_probe(&pdev->dev, -ENODEV, "Device tree node not found\n");
 
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return -ENOMEM;
 
 	pdata->snvs = syscon_regmap_lookup_by_phandle(np, "regmap");
-	if (IS_ERR(pdata->snvs)) {
-		dev_err(&pdev->dev, "Can't get snvs syscon\n");
-		return PTR_ERR(pdata->snvs);
-	}
+	if (IS_ERR(pdata->snvs))
+		return dev_err_probe(&pdev->dev, PTR_ERR(pdata->snvs), "Can't get snvs syscon\n");
 
 	if (of_property_read_u32(np, "linux,keycode", &pdata->keycode)) {
 		pdata->keycode = KEY_POWER;
@@ -142,10 +140,9 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
 	}
 
 	clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
-	if (IS_ERR(clk)) {
-		dev_err(&pdev->dev, "Failed to get snvs clock (%pe)\n", clk);
-		return PTR_ERR(clk);
-	}
+	if (IS_ERR(clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(clk),
+				     "Failed to get snvs clock (%pe)\n", clk);
 
 	pdata->wakeup = of_property_read_bool(np, "wakeup-source");
 
@@ -165,9 +162,8 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
 			bpt = (val / 5) - 1;
 			break;
 		default:
-			dev_err(&pdev->dev,
-				"power-off-time-sec %d out of range\n", val);
-			return -EINVAL;
+			return dev_err_probe(&pdev->dev, -EINVAL,
+					     "power-off-time-sec %d out of range\n", val);
 		}
 
 		regmap_update_bits(pdata->snvs, SNVS_LPCR_REG, SNVS_LPCR_BPT_MASK,
@@ -198,10 +194,8 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
 
 	/* input customer action to cancel release timer */
 	error = devm_add_action(&pdev->dev, imx_snvs_pwrkey_act, pdata);
-	if (error) {
-		dev_err(&pdev->dev, "failed to register remove action\n");
-		return error;
-	}
+	if (error)
+		return dev_err_probe(&pdev->dev, error, "failed to register remove action\n");
 
 	pdata->input = input;
 	platform_set_drvdata(pdev, pdata);
@@ -209,16 +203,12 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
 	error = devm_request_irq(&pdev->dev, pdata->irq,
 			       imx_snvs_pwrkey_interrupt,
 			       0, pdev->name, pdev);
-	if (error) {
-		dev_err(&pdev->dev, "interrupt not available.\n");
-		return error;
-	}
+	if (error)
+		return dev_err_probe(&pdev->dev, error, "interrupt not available.\n");
 
 	error = input_register_device(input);
-	if (error < 0) {
-		dev_err(&pdev->dev, "failed to register input device\n");
-		return error;
-	}
+	if (error < 0)
+		return dev_err_probe(&pdev->dev, error, "failed to register input device\n");
 
 	device_init_wakeup(&pdev->dev, pdata->wakeup);
 	error = dev_pm_set_wake_irq(&pdev->dev, pdata->irq);

-- 
2.50.1


^ permalink raw reply related

* [PATCH v2 0/4] snvs_pwrkey - code improvements and add report event
From: Joy Zou @ 2026-06-04  6:56 UTC (permalink / raw)
  To: Dmitry Torokhov, Frank Li, Peng Fan, Jacky Bai, Ye Li
  Cc: imx, linux-input, linux-kernel, Joy Zou

This patch series improves the snvs_pwrkey driver with better code quality
and add report press event.

The main improvements include:
1. Clean up the code by using local device pointers and dev_err_probe() for
better readability and easier debugging.

2. Fix potential event loss during system suspend by reporting key press events
directly in the interrupt handler.

To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: Frank Li <Frank.Li@nxp.com>
To: Peng Fan <peng.fan@nxp.com>
To: Jacky Bai <ping.bai@nxp.com>
To: Ye Li <ye.li@nxp.com>
Cc: imx@lists.linux.dev
Cc: linux-input@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

Signed-off-by: Joy Zou <joy.zou@nxp.com>
---
Changes in v2:
- Drop dev_err_probe() change for platform_get_irq() per AI review comments.
- Add new patch #2 replace hardcoding -EINVAL with original error code per
  AI review comments.
- Use dev instead of &pdev->dev for devm_input_allocate_device(), which was
  missed in patch v1 per AI review comments.
- Add a boolean variable suspended and PM callback functions to replace
  the use of the is_suspended field per AI review comments.
- Move event report handle to else branch in suspended state, since the
  pdata->minor_rev == 0 branch has no debounce detection per AI review
  comments.
- Modify patch #3 and #4 commit message.
- Add Reviewed-by tag for patch #1.
- Link to v1: https://lore.kernel.org/r/20260326-pwrkey-cleanup-v1-0-d85d7c0bf275@nxp.com

---
Joy Zou (4):
      Input: snvs_pwrkey - make use of dev_err_probe()
      Input: snvs_pwrkey - replace hardcoding -EINVAL with original error code
      Input: snvs_pwrkey - use local device pointer to simple code
      Input: snvs_pwrkey - report press event in interrupt handler

 drivers/input/keyboard/snvs_pwrkey.c | 102 ++++++++++++++++++++++-------------
 1 file changed, 64 insertions(+), 38 deletions(-)
---
base-commit: f7af91adc230aa99e23330ecf85bc9badd9780ad
change-id: 20260326-pwrkey-cleanup-99d3de61ed6d

Best regards,
-- 
Joy Zou <joy.zou@nxp.com>


^ permalink raw reply

* Re: [PATCH v2] HID: wacom: stop hardware after post-start probe failures
From: sashiko-bot @ 2026-06-04  5:14 UTC (permalink / raw)
  To: Myeonghun Pak; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260604045710.25512-1-mhun512@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [High] Failing to cancel scheduled delayed works and timers on the probe error path leads to a Use-After-Free when the `wacom` structure is freed.
- [High] Nullifying input pointers in `wacom_register_inputs` before stopping the hardware leaves a race window where incoming interrupts can cause a NULL pointer dereference.
- [High] Hardware interrupts can arrive before `wacom->remote` is allocated, causing a NULL pointer dereference in the IRQ handlers.
--

commit 517a367ac93aa0d6c6470c3a21cdb477449345e3
Author: Myeonghun Pak <mhun512@gmail.com>
Subject: HID: wacom: stop hardware after post-start probe failures

This patch routes post-hid_hw_start() failures in wacom_parse_and_register()
through hid_hw_stop() before releasing driver resources. This ensures that the
HID hardware is properly stopped before the wacom resources are freed.

> diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
> index 2220168bf1164..252771dcfd8f8 100644
> --- a/drivers/hid/wacom_sys.c
> +++ b/drivers/hid/wacom_sys.c
> @@ -2462,16 +2462,16 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
>  
>  	error = wacom_register_inputs(wacom);
>  	if (error)
> -		goto fail;
> +		goto fail_hw_stop;

[Severity: High]
This is a pre-existing issue, but does this leave a small race window where
an interrupt could cause a NULL pointer dereference?

If wacom_register_inputs() fails, its error path sets the input pointers to
NULL:

    fail:
        wacom_wac->pad_input = NULL;
        wacom_wac->touch_input = NULL;
        wacom_wac->pen_input = NULL;
        return error;

The code then jumps to fail_hw_stop. Since hid_hw_start() has already been
called, the hardware is active. Could an interrupt arrive before hid_hw_stop()
completes, triggering an IRQ handler like wacom_intuos_irq() which
dereferences wacom->pen_input without checking for NULL?

>  
>  	if (wacom->wacom_wac.features.device_type & WACOM_DEVICETYPE_PAD) {
>  		error = wacom_initialize_leds(wacom);
>  		if (error)
> -			goto fail;
> +			goto fail_hw_stop;
>  
>  		error = wacom_initialize_remotes(wacom);
>  		if (error)
> -			goto fail;
> +			goto fail_hw_stop;

[Severity: High]
This is a pre-existing issue, but I have a question about how this handles
interrupts arriving before initialization is complete.

Since hid_hw_start() is called prior to wacom_initialize_remotes():

    error = hid_hw_start(hdev, connect_mask);
    ...
    error = wacom_initialize_remotes(wacom);

Could an early hardware event or a malicious USB report arrive and trigger
wacom_remote_irq() or wacom_remote_status_irq()? Those handlers appear to
dereference wacom->remote to acquire a spinlock:

    spin_lock_irqsave(&remote->remote_lock, flags);

If the interrupt arrives before wacom_initialize_remotes() has allocated
wacom->remote, would this lead to a NULL pointer dereference?

[ ... ]

> @@ -2501,7 +2501,7 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
>  
>  	return 0;
>  
> -fail_quirks:
> +fail_hw_stop:
>  	hid_hw_stop(hdev);
>  fail:
>  	wacom_release_resources(wacom);

[Severity: High]
This isn't a bug introduced by this patch, but it seems there might be a
pre-existing issue with pending works on the error path.

If wacom_query_tablet_data() is called earlier:

    wacom_query_tablet_data(struct wacom *wacom)
    {
        schedule_delayed_work(&wacom->init_work, msecs_to_jiffies(1000));
    }

And then a subsequent step like hid_hw_open() fails, we jump to fail_hw_stop
which stops the hardware and releases resources:

    fail_hw_stop:
        hid_hw_stop(hdev);
    fail:
        wacom_release_resources(wacom);
        return error;

Since the error is returned to wacom_probe() which can cause the devres core
to free the wacom structure, could the uncancelled wacom->init_work (or other
works/timers scheduled by interrupts) execute later and dereference the freed
wacom memory?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260604045710.25512-1-mhun512@gmail.com?part=1

^ permalink raw reply

* [PATCH v2] HID: wacom: stop hardware after post-start probe failures
From: Myeonghun Pak @ 2026-06-04  4:56 UTC (permalink / raw)
  To: Ping Cheng, Jason Gerecke
  Cc: Jiri Kosina, Benjamin Tissoires, linux-input, linux-kernel,
	Myeonghun Pak, stable, Ijae Kim, Dmitry Torokhov
In-Reply-To: <20260524175552.1973-1-mhun512@gmail.com>

wacom_parse_and_register() starts HID hardware before registering inputs
and initializing pad LEDs/remotes. Those later steps can fail, but their
error paths currently release Wacom resources without stopping the HID
hardware.

Route post-hid_hw_start() failures through hid_hw_stop() before
releasing driver resources.

This issue was identified during our ongoing static-analysis research while
reviewing kernel code.

Fixes: c1d6708bf0d3 ("HID: wacom: Do not register input devices until after hid_hw_start")
Cc: stable@vger.kernel.org
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
Changes in v2:
- Drop fail_quirks and use fail_hw_stop for every post-hid_hw_start()
  failure path, as suggested by Dmitry.

 drivers/hid/wacom_sys.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 0d1c6d90f..ee53186e0 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -2456,16 +2456,16 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
 
 	error = wacom_register_inputs(wacom);
 	if (error)
-		goto fail;
+		goto fail_hw_stop;
 
 	if (wacom->wacom_wac.features.device_type & WACOM_DEVICETYPE_PAD) {
 		error = wacom_initialize_leds(wacom);
 		if (error)
-			goto fail;
+			goto fail_hw_stop;
 
 		error = wacom_initialize_remotes(wacom);
 		if (error)
-			goto fail;
+			goto fail_hw_stop;
 	}
 
 	if (!wireless) {
@@ -2479,14 +2479,14 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
 		cancel_delayed_work_sync(&wacom->init_work);
 		_wacom_query_tablet_data(wacom);
 		error = -ENODEV;
-		goto fail_quirks;
+		goto fail_hw_stop;
 	}
 
 	if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) {
 		error = hid_hw_open(hdev);
 		if (error) {
 			hid_err(hdev, "hw open failed\n");
-			goto fail_quirks;
+			goto fail_hw_stop;
 		}
 	}
 
@@ -2495,7 +2495,7 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
 	return 0;
 
-fail_quirks:
+fail_hw_stop:
 	hid_hw_stop(hdev);
 fail:
 	wacom_release_resources(wacom);
 	return error;
-- 
2.47.1

^ permalink raw reply related

* Re: [PATCH] HID: wacom: stop hardware after post-start probe failures
From: Myeonghun Pak @ 2026-06-04  4:43 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Dmitry Torokhov, Ping Cheng, Jason Gerecke, Benjamin Tissoires,
	linux-input, linux-kernel, stable, Ijae Kim
In-Reply-To: <nr568s88-77o5-p5pn-5r1n-236371989rn0@xreary.bet>

Hi Jiri and Dmitry,

Thank you both for the review. I agree with Dmitry's suggestion to
remove 'fail_quirks' and use 'fail_hw_stop' throughout the probe path.
I will send out v2 with this change shortly.

Best regards,
Myeonghun Pak

2026년 6월 3일 (수) 오후 9:23, Jiri Kosina <jikos@kernel.org>님이 작성:
>
> On Wed, 27 May 2026, Dmitry Torokhov wrote:
>
> > > wacom_parse_and_register() starts HID hardware before registering inputs
> > > and initializing pad LEDs/remotes. Those later steps can fail, but their
> > > error paths currently release Wacom resources without stopping the HID
> > > hardware.
> > >
> > > Route post-hid_hw_start() failures through hid_hw_stop() before
> > > releasing driver resources.
> > >
> > > This issue was identified during our ongoing static-analysis research while
> > > reviewing kernel code.
> > >
> > > Fixes: c1d6708bf0d3 ("HID: wacom: Do not register input devices until after hid_hw_start")
> > > Cc: stable@vger.kernel.org
> > > Co-developed-by: Ijae Kim <ae878000@gmail.com>
> > > Signed-off-by: Ijae Kim <ae878000@gmail.com>
> > > Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
> > > ---
> > >  drivers/hid/wacom_sys.c | 7 ++++---
> > >  1 file changed, 4 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
> > > index 0d1c6d90fe..c824d9c224 100644
> > > --- a/drivers/hid/wacom_sys.c
> > > +++ b/drivers/hid/wacom_sys.c
> > > @@ -2456,16 +2456,16 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
> > >
> > >     error = wacom_register_inputs(wacom);
> > >     if (error)
> > > -           goto fail;
> > > +           goto fail_hw_stop;
> > >
> > >     if (wacom->wacom_wac.features.device_type & WACOM_DEVICETYPE_PAD) {
> > >             error = wacom_initialize_leds(wacom);
> > >             if (error)
> > > -                   goto fail;
> > > +                   goto fail_hw_stop;
> > >
> > >             error = wacom_initialize_remotes(wacom);
> > >             if (error)
> > > -                   goto fail;
> > > +                   goto fail_hw_stop;
> > >     }
> > >
> > >     if (!wireless) {
> > > @@ -2496,6 +2496,7 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
> > >     return 0;
> > >
> > >  fail_quirks:
> > > +fail_hw_stop:
> > >     hid_hw_stop(hdev);
> > >  fail:
> > >     wacom_release_resources(wacom);
> >
> > I'd get rid of 'fail_quirks' and use 'fail_hw_stop' everywhere,
>
> Agreed. Myeonghun, will you send v2 please?
>
> Thanks,
>
> --
> Jiri Kosina
> SUSE Labs
>

^ permalink raw reply

* Re: [PATCH v2 2/3] HID: i2c-hid: Move common ACPI _DSM helper into core
From: 谢致邦 (XIE Zhibang) @ 2026-06-04  4:23 UTC (permalink / raw)
  To: linux-input, hansg, dmitry.torokhov, bentiss
  Cc: Yeking, dianders, error27, jikos, kenkinming2002, linux-kernel,
	raoxu, superm1, treapking, 谢致邦 (XIE Zhibang),
	Uwe Kleine-König (The Capable Hub)
In-Reply-To: <aiApE2WoVitHetQv@beelink>

Hi Hans and Benjamin,

Thank you for the constructive discussion.

A correction on the origin of this firmware quirk:

This is not a Loongson platform issue. Loongson 3A5000 and
3A6000 laptops using the EA Excelsior ODM design do not have
this problem. The affected machines — Lenovo KaiTian N60d and
Inspur CP300L3 — use a different ODM.

The ODM is likely Baolongda (Bitland), based on CQC certification
records and a design patent filing. Firmware analysis shows the
N60d is codenamed NL296A and the CP300L3 is NL296B, and there
may be NL296C as well. The ODM's NL296 project team likely
lacked ACPI experience, resulting in the broken PRP0001 +
"hid-over-i2c" + no "hid-descr-addr" but has _DSM combination.

I will use the name i2c-hid-acpi-prp0001, without DMI matching.
The new driver will first check whether "hid-descr-addr" is
present and silently return -ENODEV if so, falling back to _DSM
only when the property is missing.

I am testing the new driver and will send it out once verified.

The TPD0 node is identical on the N60d and CP300L3:

    Device (TPD0)
    {
        Name (_HID, "PRP0001")
        Name (_DSD, Package (0x02)
        {
            ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package (0x01)
            {
                Package (0x02)
                {
                    "compatible",
                    "hid-over-i2c"
                }
            }
        })
        Name (_CRS, ResourceTemplate ()
        {
            I2cSerialBusV2 (0x002C, ControllerInitiated, 0x00061A80,
                AddressingMode7Bit, "\\_SB.I2C1",
                0x00, ResourceConsumer, , Exclusive,
                )
            Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
            {
                0x0000007F,
            }
        })
        Method (_DSM, 4, Serialized)
        {
            Switch (Arg0)
            {
                Case (ToUUID ("3cdff6f7-4267-4555-ad05-b30a3d8938de"))
                {
                    Switch (Arg1)
                    {
                        Case (One)
                        {
                            Switch (Arg2)
                            {
                                Case (One)
                                {
                                    Return (0x20)
                                }
                            }
                        }
                    }
                }
            }
        }
    }

Regards,
Zhibang


^ permalink raw reply

* [dtor-input:for-linus] BUILD SUCCESS ad0979fe053e9f2db82da82188256ef6eb41095a
From: kernel test robot @ 2026-06-04  3:37 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus
branch HEAD: ad0979fe053e9f2db82da82188256ef6eb41095a  Input: atkbd - add DMI quirk for Lenovo Yoga Air 14 (83QK)

elapsed time: 1665m

configs tested: 147
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig    gcc-15.2.0
alpha                            allyesconfig    gcc-15.2.0
arc                              allmodconfig    gcc-15.2.0
arc                               allnoconfig    gcc-15.2.0
arc                              allyesconfig    gcc-15.2.0
arc                   randconfig-001-20260604    clang-17
arc                   randconfig-002-20260604    clang-17
arm                               allnoconfig    clang-23
arm                               allnoconfig    gcc-15.2.0
arm                              allyesconfig    gcc-15.2.0
arm                   randconfig-001-20260604    clang-17
arm                   randconfig-002-20260604    clang-17
arm                   randconfig-003-20260604    clang-17
arm                   randconfig-004-20260604    clang-17
arm64                            allmodconfig    clang-19
arm64                             allnoconfig    gcc-15.2.0
csky                             allmodconfig    gcc-15.2.0
csky                             allmodconfig    gcc-16.1.0
csky                              allnoconfig    gcc-15.2.0
hexagon                          allmodconfig    clang-17
hexagon                          allmodconfig    gcc-15.2.0
hexagon                           allnoconfig    clang-23
hexagon                           allnoconfig    gcc-15.2.0
hexagon                        randconfig-001    gcc-11.5.0
hexagon               randconfig-001-20260604    gcc-11.5.0
hexagon                        randconfig-002    gcc-11.5.0
hexagon               randconfig-002-20260604    gcc-11.5.0
i386                              allnoconfig    gcc-14
i386                              allnoconfig    gcc-15.2.0
i386        buildonly-randconfig-001-20260604    clang-20
i386        buildonly-randconfig-002-20260604    clang-20
i386        buildonly-randconfig-003-20260604    clang-20
i386        buildonly-randconfig-004-20260604    clang-20
i386        buildonly-randconfig-005-20260604    clang-20
i386        buildonly-randconfig-006-20260604    clang-20
i386                  randconfig-011-20260604    gcc-14
i386                  randconfig-012-20260604    gcc-14
i386                  randconfig-013-20260604    gcc-14
i386                  randconfig-014-20260604    gcc-14
i386                  randconfig-015-20260604    gcc-14
i386                  randconfig-016-20260604    gcc-14
i386                  randconfig-017-20260604    gcc-14
loongarch                        allmodconfig    clang-19
loongarch                         allnoconfig    clang-23
loongarch                         allnoconfig    gcc-15.2.0
loongarch                           defconfig    clang-23
loongarch                      randconfig-001    gcc-11.5.0
loongarch             randconfig-001-20260604    gcc-11.5.0
loongarch                      randconfig-002    gcc-11.5.0
loongarch             randconfig-002-20260604    gcc-11.5.0
m68k                             allmodconfig    gcc-15.2.0
m68k                             allmodconfig    gcc-16.1.0
m68k                              allnoconfig    gcc-15.2.0
m68k                             allyesconfig    gcc-15.2.0
m68k                                defconfig    clang-23
microblaze                        allnoconfig    gcc-15.2.0
microblaze                       allyesconfig    gcc-15.2.0
microblaze                       allyesconfig    gcc-16.1.0
microblaze                          defconfig    clang-23
mips                             allmodconfig    gcc-16.1.0
mips                              allnoconfig    gcc-15.2.0
mips                             allyesconfig    gcc-15.2.0
mips                             allyesconfig    gcc-16.1.0
nios2                            allmodconfig    gcc-11.5.0
nios2                             allnoconfig    clang-17
nios2                             allnoconfig    gcc-11.5.0
nios2                               defconfig    clang-23
nios2                          randconfig-001    gcc-11.5.0
nios2                 randconfig-001-20260604    gcc-11.5.0
nios2                          randconfig-002    gcc-11.5.0
nios2                 randconfig-002-20260604    gcc-11.5.0
openrisc                         allmodconfig    gcc-15.2.0
openrisc                          allnoconfig    clang-17
openrisc                          allnoconfig    gcc-15.2.0
openrisc                            defconfig    gcc-16.1.0
parisc                           allmodconfig    gcc-16.1.0
parisc                            allnoconfig    clang-17
parisc                            allnoconfig    gcc-15.2.0
parisc                           allyesconfig    clang-19
parisc                           allyesconfig    gcc-15.2.0
parisc                              defconfig    gcc-16.1.0
parisc64                            defconfig    clang-23
powerpc                          allmodconfig    gcc-16.1.0
powerpc                           allnoconfig    clang-17
powerpc                           allnoconfig    gcc-15.2.0
riscv                            allmodconfig    clang-23
riscv                             allnoconfig    clang-17
riscv                             allnoconfig    gcc-15.2.0
riscv                            allyesconfig    clang-16
riscv                               defconfig    gcc-16.1.0
riscv                          randconfig-001    clang-17
riscv                 randconfig-001-20260604    clang-17
riscv                          randconfig-002    clang-17
riscv                 randconfig-002-20260604    clang-17
s390                             allmodconfig    clang-18
s390                             allmodconfig    clang-19
s390                              allnoconfig    clang-17
s390                              allnoconfig    clang-23
s390                             allyesconfig    gcc-16.1.0
s390                                defconfig    gcc-16.1.0
s390                           randconfig-001    clang-17
s390                  randconfig-001-20260604    clang-17
s390                           randconfig-002    clang-17
s390                  randconfig-002-20260604    clang-17
sh                               allmodconfig    gcc-15.2.0
sh                                allnoconfig    clang-17
sh                                allnoconfig    gcc-15.2.0
sh                               allyesconfig    clang-19
sh                               allyesconfig    gcc-15.2.0
sh                                  defconfig    gcc-14
sh                             randconfig-001    clang-17
sh                    randconfig-001-20260604    clang-17
sh                             randconfig-002    clang-17
sh                    randconfig-002-20260604    clang-17
sh                          urquell_defconfig    gcc-16.1.0
sparc                             allnoconfig    clang-17
sparc                             allnoconfig    gcc-15.2.0
sparc                               defconfig    gcc-16.1.0
sparc64                          allmodconfig    clang-23
sparc64                             defconfig    gcc-14
um                               allmodconfig    clang-19
um                                allnoconfig    clang-17
um                                allnoconfig    clang-23
um                               allyesconfig    gcc-14
um                               allyesconfig    gcc-15.2.0
um                                  defconfig    gcc-14
um                             i386_defconfig    gcc-14
um                           x86_64_defconfig    gcc-14
x86_64                            allnoconfig    clang-17
x86_64                            allnoconfig    clang-20
x86_64      buildonly-randconfig-001-20260604    gcc-14
x86_64      buildonly-randconfig-002-20260604    gcc-14
x86_64      buildonly-randconfig-003-20260604    gcc-14
x86_64      buildonly-randconfig-004-20260604    gcc-14
x86_64      buildonly-randconfig-005-20260604    gcc-14
x86_64      buildonly-randconfig-006-20260604    gcc-14
x86_64                              defconfig    gcc-14
x86_64                                  kexec    clang-22
x86_64                               rhel-9.4    clang-22
x86_64                           rhel-9.4-bpf    gcc-14
x86_64                          rhel-9.4-func    clang-22
x86_64                    rhel-9.4-kselftests    clang-22
x86_64                         rhel-9.4-kunit    gcc-14
x86_64                           rhel-9.4-ltp    gcc-14
x86_64                          rhel-9.4-rust    clang-22
xtensa                            allnoconfig    clang-17
xtensa                            allnoconfig    gcc-15.2.0

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH v2 4/4] dt-bindings: input: remove obsolete matrix-keymap.txt
From: Rob Herring (Arm) @ 2026-06-03 22:26 UTC (permalink / raw)
  To: Akash Sukhavasi
  Cc: Conor Dooley, David S. Miller, Andrew Lunn, linux-tegra,
	linux-input, Mauro Carvalho Chehab, Heiner Kallweit,
	Thierry Reding, linux-media, Krzysztof Kozlowski, Jakub Kicinski,
	Vladimir Oltean, linux-doc, linux-kernel, Eric Dumazet,
	Dmitry Torokhov, Jonathan Hunter, Simon Horman, devicetree,
	Paolo Abeni, Lee Jones, netdev, Shuah Khan, Russell King,
	Jonathan Corbet
In-Reply-To: <20260603-b4-remove-redirect-stubs-v2-4-c8c19876ab64@gmail.com>


On Wed, 03 Jun 2026 15:42:21 -0500, Akash Sukhavasi wrote:
> matrix-keymap.txt has been a single-line redirect to
> matrix-keymap.yaml since commit 639d6eda3b80 ("dt-bindings: input:
> Convert matrix-keymap to json-schema"), which introduced the .yaml
> schema and reduced the .txt to a stub in the same change. The .yaml
> has the same filename in the same directory, making this redirect
> unnecessary for discoverability.
> 
> Eight instances across six files still reference matrix-keymap.txt,
> forcing readers through an extra hop to reach the .yaml. The stub has
> not been touched since June 2020. Update all references across input
> and mfd binding documentation to point directly to matrix-keymap.yaml
> and remove the stub.
> 
> Signed-off-by: Akash Sukhavasi <akash.sukhavasi@gmail.com>
> ---
> v2:
> - Patch 4/4: corrected commit message (eight references in six files,
>   not eight files), Sashiko review.
>   https://sashiko.dev/#/patchset/20260529052246.4934-1-akash.sukhavasi@gmail.com?part=4
> 
> v1: https://lore.kernel.org/all/20260529052246.4934-5-akash.sukhavasi@gmail.com/
> ---
>  Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt    | 2 +-
>  Documentation/devicetree/bindings/input/clps711x-keypad.txt    | 2 +-
>  Documentation/devicetree/bindings/input/matrix-keymap.txt      | 1 -
>  Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt | 2 +-
>  Documentation/devicetree/bindings/input/pxa27x-keypad.txt      | 2 +-
>  Documentation/devicetree/bindings/input/st-keyscan.txt         | 2 +-
>  Documentation/devicetree/bindings/mfd/tc3589x.txt              | 6 +++---
>  7 files changed, 8 insertions(+), 9 deletions(-)
> 

Acked-by: Rob Herring (Arm) <robh@kernel.org>


^ permalink raw reply

* Re: [PATCH v2 0/4] dt-bindings: remove redundant .txt redirect stubs
From: Rob Herring @ 2026-06-03 22:21 UTC (permalink / raw)
  To: Akash Sukhavasi
  Cc: Andrew Lunn, Heiner Kallweit, Russell King, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Krzysztof Kozlowski,
	Conor Dooley, Mauro Carvalho Chehab, Vladimir Oltean,
	Simon Horman, Jonathan Corbet, Shuah Khan, Dmitry Torokhov,
	Thierry Reding, Jonathan Hunter, Lee Jones, netdev, devicetree,
	linux-kernel, linux-media, linux-doc, linux-input, linux-tegra
In-Reply-To: <20260603-b4-remove-redirect-stubs-v2-0-c8c19876ab64@gmail.com>

On Wed, Jun 03, 2026 at 03:42:17PM -0500, Akash Sukhavasi wrote:
> Several .txt files under Documentation/devicetree/bindings/ contain
> only a redirect notice pointing to a .yaml schema with the same base
> filename in the same directory. These stubs were useful during the
> .txt to .yaml transition but are now redundant, since the .yaml is
> discoverable by name. Meanwhile, other documentation still references
> some of these stubs, forcing readers through an unnecessary extra hop
> to reach the actual schema.
> 
> This series removes four such stubs and updates all remaining
> cross-references to point directly to the .yaml schemas.
> 
> Other redirect stubs in the tree were evaluated and intentionally
> kept:
> 
>  - Stubs pointing to .yaml files with different names (e.g.,
>    spi-bus.txt -> spi-controller.yaml) serve as breadcrumbs for
>    the renamed schema.
> 
>  - Stubs pointing to multiple .yaml files (e.g., nvmem.txt ->
>    nvmem.yaml and nvmem-consumer.yaml) convey that the content
>    was split.
> 
>  - Stubs pointing to .yaml files in a different directory (e.g.,
>    reset/st,stm32-rcc.txt -> clock/st,stm32-rcc.yaml) serve as
>    cross-directory pointers.
> 
> Two additional same-name, same-directory stubs (leds/common.txt,
> regulator/regulator.txt) have significantly more cross references
> and will be addressed in a follow-up series.
> 
> v2:
> - Patch 4/4: corrected commit message (eight references in six files, not
>   eight files), Sashiko review.
>   https://sashiko.dev/#/patchset/20260529052246.4934-1-akash.sukhavasi@gmail.com?part=4
> 
> v1: https://lore.kernel.org/all/20260529052246.4934-1-akash.sukhavasi@gmail.com/
> 
> Patch 1 supersedes my earlier standalone submission:
> https://lore.kernel.org/all/20260523004223.3045-1-akash.sukhavasi@gmail.com/
> 
> Signed-off-by: Akash Sukhavasi <akash.sukhavasi@gmail.com>
> ---
> Akash Sukhavasi (4):
>       dt-bindings: net: remove obsolete mdio.txt
>       dt-bindings: media: remove obsolete rc.txt
>       dt-bindings: net: dsa: remove obsolete dsa.txt
>       dt-bindings: input: remove obsolete matrix-keymap.txt

This goes to 3 different subsystems, so it should be 3 different series. 
No need to resend just for that.

Rob

^ permalink raw reply

* Re: [PATCH v2 3/4] dt-bindings: net: dsa: remove obsolete dsa.txt
From: Rob Herring (Arm) @ 2026-06-03 22:20 UTC (permalink / raw)
  To: Akash Sukhavasi
  Cc: Dmitry Torokhov, linux-media, Thierry Reding, linux-input,
	Eric Dumazet, linux-tegra, Shuah Khan, David S. Miller,
	Krzysztof Kozlowski, Conor Dooley, devicetree,
	Mauro Carvalho Chehab, Heiner Kallweit, Andrew Lunn, Simon Horman,
	Jakub Kicinski, netdev, linux-kernel, Jonathan Hunter, Lee Jones,
	Russell King, Paolo Abeni, Vladimir Oltean, Jonathan Corbet,
	linux-doc
In-Reply-To: <20260603-b4-remove-redirect-stubs-v2-3-c8c19876ab64@gmail.com>


On Wed, 03 Jun 2026 15:42:20 -0500, Akash Sukhavasi wrote:
> dsa.txt has been a redirect to dsa.yaml since commit bce58590d1bd
> ("dt-bindings: net: dsa: Add DSA yaml binding") introduced the .yaml
> schema. The .yaml has the same filename in the same directory, making
> this redirect unnecessary for discoverability.
> 
> Two files still reference dsa.txt, forcing readers through an extra
> hop to reach the .yaml. The stub has not been touched since August
> 2020. Update references in lan9303.txt and
> Documentation/networking/dsa/dsa.rst to point directly to dsa.yaml
> and remove the stub.
> 
> Signed-off-by: Akash Sukhavasi <akash.sukhavasi@gmail.com>
> ---
>  Documentation/devicetree/bindings/net/dsa/dsa.txt     | 4 ----
>  Documentation/devicetree/bindings/net/dsa/lan9303.txt | 2 +-
>  Documentation/networking/dsa/dsa.rst                  | 2 +-
>  3 files changed, 2 insertions(+), 6 deletions(-)
> 

Acked-by: Rob Herring (Arm) <robh@kernel.org>


^ permalink raw reply

* Re: [PATCH v2 2/4] dt-bindings: media: remove obsolete rc.txt
From: Rob Herring (Arm) @ 2026-06-03 22:20 UTC (permalink / raw)
  To: Akash Sukhavasi
  Cc: Jakub Kicinski, Jonathan Hunter, Paolo Abeni, linux-kernel,
	linux-input, Heiner Kallweit, Eric Dumazet, devicetree,
	Simon Horman, Mauro Carvalho Chehab, linux-media, linux-tegra,
	David S. Miller, Jonathan Corbet, Shuah Khan, Conor Dooley,
	Lee Jones, Andrew Lunn, Krzysztof Kozlowski, Russell King,
	linux-doc, netdev, Vladimir Oltean, Dmitry Torokhov,
	Thierry Reding
In-Reply-To: <20260603-b4-remove-redirect-stubs-v2-2-c8c19876ab64@gmail.com>


On Wed, 03 Jun 2026 15:42:19 -0500, Akash Sukhavasi wrote:
> rc.txt has been a single-line redirect to rc.yaml since
> commit 7c31b9d67342 ("media: dt-bindings: media: Add YAML schemas for
> the generic RC bindings"), which introduced the .yaml schema and
> reduced the .txt to a stub in the same change. The .yaml has the same
> filename in the same directory, making this redirect unnecessary
> for discoverability.
> 
> One file still references rc.txt, forcing readers through an extra
> hop to reach the .yaml. The stub has not been touched since August
> 2019. Update the reference in hix5hd2-ir.txt to point directly to
> rc.yaml and remove the stub.
> 
> Signed-off-by: Akash Sukhavasi <akash.sukhavasi@gmail.com>
> ---
>  Documentation/devicetree/bindings/media/hix5hd2-ir.txt | 2 +-
>  Documentation/devicetree/bindings/media/rc.txt         | 1 -
>  2 files changed, 1 insertion(+), 2 deletions(-)
> 

Acked-by: Rob Herring (Arm) <robh@kernel.org>


^ permalink raw reply

* Re: [PATCH v2 1/4] dt-bindings: net: remove obsolete mdio.txt
From: Rob Herring (Arm) @ 2026-06-03 22:19 UTC (permalink / raw)
  To: Akash Sukhavasi
  Cc: Heiner Kallweit, David S. Miller, Vladimir Oltean, linux-media,
	linux-tegra, Dmitry Torokhov, linux-doc, Conor Dooley,
	Jonathan Corbet, Shuah Khan, linux-kernel, Mauro Carvalho Chehab,
	devicetree, Simon Horman, Andrew Lunn, Paolo Abeni, Lee Jones,
	Krzysztof Kozlowski, netdev, Eric Dumazet, linux-input,
	Russell King, Thierry Reding, Jonathan Hunter, Jakub Kicinski
In-Reply-To: <20260603-b4-remove-redirect-stubs-v2-1-c8c19876ab64@gmail.com>


On Wed, 03 Jun 2026 15:42:18 -0500, Akash Sukhavasi wrote:
> mdio.txt has been a single-line redirect to mdio.yaml since
> commit 62d77ff7ecbf ("dt-bindings: net: Add a YAML schemas for the
> generic MDIO options"), which introduced the .yaml schema and reduced
> the .txt to a stub in the same change. The .yaml has the same filename
> in the same directory, making this redirect unnecessary for
> discoverability.
> 
> No files in the tree reference mdio.txt and it has not been touched
> since June 2019. Remove the obsolete stub.
> 
> Signed-off-by: Akash Sukhavasi <akash.sukhavasi@gmail.com>
> ---
>  Documentation/devicetree/bindings/net/mdio.txt | 1 -
>  1 file changed, 1 deletion(-)
> 

Acked-by: Rob Herring (Arm) <robh@kernel.org>


^ permalink raw reply


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