Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH 13/13] gpiolib: remove linux/gpio.h
From: Arnd Bergmann @ 2026-06-29 13:26 UTC (permalink / raw)
  To: linux-gpio
  Cc: Arnd Bergmann, Bartosz Golaszewski, Andrew Lunn,
	Sebastian Hesselbarth, Gregory Clement, Frank Li, Robert Jarzmik,
	Krzysztof Kozlowski, Greg Ungerer, Thomas Bogendoerfer,
	Hauke Mehrtens, Rafał Miłecki, Yoshinori Sato,
	John Paul Adrian Glaubitz, Linus Walleij, Dmitry Torokhov,
	Jakub Kicinski, Paolo Abeni, Dominik Brodowski, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, patches, linux-m68k,
	linux-mips, linux-sh, linux-input, linux-media, netdev,
	linux-sunxi, linux-phy, linux-rockchip, linux-sound
In-Reply-To: <20260629132633.1300009-1-arnd@kernel.org>

From: Arnd Bergmann <arnd@arndb.de>

After all other drivers have converted to linux/gpio/consumer.h
or linux/gpio/legacy.h, remove the final leftover bits here.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 MAINTAINERS                   |  1 -
 drivers/gpio/TODO             |  4 +---
 drivers/gpio/gpiolib-cdev.c   |  2 +-
 drivers/gpio/gpiolib-legacy.c |  3 +--
 drivers/gpio/gpiolib.c        |  2 +-
 include/linux/gpio.h          | 22 ----------------------
 6 files changed, 4 insertions(+), 30 deletions(-)
 delete mode 100644 include/linux/gpio.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 15011f5752a9..7f3f386b1d8c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11175,7 +11175,6 @@ F:	Documentation/devicetree/bindings/gpio/
 F:	Documentation/driver-api/gpio/
 F:	drivers/gpio/
 F:	include/dt-bindings/gpio/
-F:	include/linux/gpio.h
 F:	include/linux/gpio/
 K:	(devm_)?gpio_(request|free|direction|get|set)
 K:	GPIOD_FLAGS_BIT_NONEXCLUSIVE
diff --git a/drivers/gpio/TODO b/drivers/gpio/TODO
index 7ce80fde1f17..894c7e1af252 100644
--- a/drivers/gpio/TODO
+++ b/drivers/gpio/TODO
@@ -52,9 +52,7 @@ Work items:
   base can be made dynamic (set to -1) if CONFIG_GPIO_SYSFS is disabled.
 
 - When this work is complete (will require some of the items in the
-  following ongoing work as well) we can delete the old global
-  numberspace accessors from <linux/gpio.h> and eventually delete
-  <linux/gpio.h> altogether.
+  following ongoing work as well) we can delete <linux/gpio/lagacy.h>.
 
 -------------------------------------------------------------------------------
 
diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index 82f27db0b230..9b6a28819371 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -11,7 +11,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/file.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/gpio/driver.h>
 #include <linux/hte.h>
 #include <linux/interrupt.h>
diff --git a/drivers/gpio/gpiolib-legacy.c b/drivers/gpio/gpiolib-legacy.c
index ef3f2ef30cf2..33e5a45e720b 100644
--- a/drivers/gpio/gpiolib-legacy.c
+++ b/drivers/gpio/gpiolib-legacy.c
@@ -7,8 +7,7 @@
 
 #include <linux/gpio/consumer.h>
 #include <linux/gpio/driver.h>
-
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
 
 #include "gpiolib.h"
 
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index e5fb60111151..1f498d6c8c68 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -29,7 +29,7 @@
 #include <linux/string.h>
 #include <linux/string_choices.h>
 
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/gpio/driver.h>
 #include <linux/gpio/machine.h>
 
diff --git a/include/linux/gpio.h b/include/linux/gpio.h
deleted file mode 100644
index b0d4942a65de..000000000000
--- a/include/linux/gpio.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * NOTE: This header *must not* be included.
- *
- * If you're implementing a GPIO driver, only include <linux/gpio/driver.h>
- * If you're implementing a GPIO consumer, only include <linux/gpio/consumer.h>
- * If you're using the legacy interfaces, include <linux/gpio/legacy.h>
- */
-
-#ifndef __LINUX_GPIO_H
-#define __LINUX_GPIO_H
-
-#include <linux/types.h>
-#ifdef CONFIG_GPIOLIB
-#include <linux/gpio/consumer.h>
-#endif
-
-#ifdef CONFIG_GPIOLIB_LEGACY
-#include <linux/gpio/legacy.h>
-#endif /* CONFIG_GPIOLIB_LEGACY */
-
-#endif /* __LINUX_GPIO_H */
-- 
2.39.5


^ permalink raw reply related

* Re: [PATCH 4/6] [v5] Input: gpio-keys: make legacy gpiolib optional
From: sashiko-bot @ 2026-06-29 13:32 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linux-leds, lee, linux-input, dmitry.torokhov
In-Reply-To: <20260629130329.1291953-5-arnd@kernel.org>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The target patch breaks button hold and debounce functionality for legacy boards that specify both a GPIO and an IRQ in their platform data.
--

commit 7c2e3c482d0d5858bfbdee73da72e2a7bcba0509
Author: Arnd Bergmann <arnd@arndb.de>

Input: gpio-keys: make legacy gpiolib optional

This commit makes the legacy gpiolib interfaces optional in the gpio-keys
and gpio-keys-polled drivers by enclosing them in an #ifdef block. It also
modifies the gpio-keys driver to ignore the GPIO number if an IRQ is passed
to keep the Rohm PMIC drivers working.

Link: https://lore.kernel.org/all/b3c94552-c104-42e3-be15-7e8362e8039e@gmail.com/
Link: https://lore.kernel.org/all/afJXG4_rtaj3l2Dk@google.com/
Link: https://lore.kernel.org/all/ajQ-CtU131FAJ9ES@google.com/

> diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
> --- a/drivers/input/keyboard/gpio_keys.c
> +++ b/drivers/input/keyboard/gpio_keys.c

[ ... ]

> @@ -528,7 +528,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
>  			 */
>  			bdata->gpiod = NULL;
>  		}
> -	} else if (gpio_is_valid(button->gpio)) {
> +#ifdef CONFIG_GPIOLIB_LEGACY
> +	} else if (!button->irq && gpio_is_valid(button->gpio)) {

[Severity: High]
Does this skip requesting the legacy GPIO descriptor if an IRQ is provided,
breaking platforms that explicitly provide both?

Legacy boards (like assabet, collie, or h3xxx) use both a GPIO and an IRQ
to allow reading the button state alongside a custom IRQ trigger.

By skipping the GPIO setup when an IRQ is provided, bdata->gpiod remains
NULL. The driver then falls back to its IRQ-only mode where it can no
longer read the physical state of the GPIO, instead simulating an immediate
key press and release via a timer.

Could this break button hold and debounce functionality for these legacy
machines?

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260629130329.1291953-1-arnd@kernel.org?part=4

^ permalink raw reply

* Re: [PATCH 4/4] Input: sur40 - fix V4L2 video device lifetime
From: Hans Verkuil @ 2026-06-29 13:33 UTC (permalink / raw)
  To: Dmitry Torokhov, Hans Verkuil, linux-input
  Cc: linux-kernel, sashiko-bot, stable
In-Reply-To: <20260616051235.1549517-4-dmitry.torokhov@gmail.com>

On 16/06/2026 07:12, Dmitry Torokhov wrote:
> sur40_disconnect() synchronously frees the sur40_state structure (kfree(sur40))
> while userspace might still hold an open file descriptor to the V4L2 video
> device node. When userspace later accesses or closes the lingering file
> descriptor, the V4L2 core invokes file operations (such as vb2_fop_release)
> that dereference the already freed sur40 memory, resulting in a use-after-free
> vulnerability.
> 
> Fix this by implementing a V4L2 release callback (sur40_video_release) in
> sur40_video_device to clean up V4L2 components and free the sur40 structure
> only when the last video file descriptor is closed.
> 
> Additionally, update the sur40_probe() error path to call video_unregister_device()
> and return inline if input initialization fails after video device registration
> succeeded, allowing the V4L2 release callback to manage cleanup.
> 
> Also, call v4l2_device_disconnect() in sur40_disconnect() to safely dissociate
> the V4L2 device from the parent USB device during unplug.
> 
> Reported-by: sashiko-bot@kernel.org
> Cc: stable@vger.kernel.org
> Assisted-by: Antigravity:gemini-3.5-flash
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
>  drivers/input/touchscreen/sur40.c | 27 ++++++++++++++++-----------
>  1 file changed, 16 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
> index 1ad68131e3a6..2f0efee23d1e 100644
> --- a/drivers/input/touchscreen/sur40.c
> +++ b/drivers/input/touchscreen/sur40.c
> @@ -806,8 +806,10 @@ static int sur40_probe(struct usb_interface *interface,
>  	}
>  
>  	error = sur40_init_input(sur40);
> -	if (error)
> -		goto err_unreg_video;
> +	if (error) {
> +		video_unregister_device(&sur40->vdev);
> +		return error;
> +	}
>  
>  	/* we can register the device now, as it is ready */
>  	usb_set_intfdata(interface, sur40);
> @@ -815,8 +817,6 @@ static int sur40_probe(struct usb_interface *interface,
>  
>  	return 0;
>  
> -err_unreg_video:
> -	video_unregister_device(&sur40->vdev);
>  err_free_ctrl:
>  	v4l2_ctrl_handler_free(&sur40->hdl);
>  err_unreg_v4l2:
> @@ -835,13 +835,8 @@ static void sur40_disconnect(struct usb_interface *interface)
>  	struct sur40_state *sur40 = usb_get_intfdata(interface);
>  
>  	input_unregister_device(sur40->input);
> -
> -	v4l2_ctrl_handler_free(&sur40->hdl);
>  	video_unregister_device(&sur40->vdev);

This call can free sur40,

> -	v4l2_device_unregister(&sur40->v4l2);
> -
> -	kfree(sur40->bulk_in_buffer);
> -	kfree(sur40);
> +	v4l2_device_disconnect(&sur40->v4l2);

but this call still uses it.

The easiest fix is just to swap the two lines.

Regards,

	Hans

>  
>  	usb_set_intfdata(interface, NULL);
>  	dev_dbg(&interface->dev, "%s is now disconnected\n", DRIVER_DESC);
> @@ -1176,11 +1171,21 @@ static const struct v4l2_ioctl_ops sur40_video_ioctl_ops = {
>  	.vidioc_streamoff	= vb2_ioctl_streamoff,
>  };
>  
> +static void sur40_video_release(struct video_device *vdev)
> +{
> +	struct sur40_state *sur40 = video_get_drvdata(vdev);
> +
> +	v4l2_device_unregister(&sur40->v4l2);
> +	v4l2_ctrl_handler_free(&sur40->hdl);
> +	kfree(sur40->bulk_in_buffer);
> +	kfree(sur40);
> +}
> +
>  static const struct video_device sur40_video_device = {
>  	.name = DRIVER_LONG,
>  	.fops = &sur40_video_fops,
>  	.ioctl_ops = &sur40_video_ioctl_ops,
> -	.release = video_device_release_empty,
> +	.release = sur40_video_release,
>  	.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TOUCH |
>  		       V4L2_CAP_READWRITE | V4L2_CAP_STREAMING,
>  };


^ permalink raw reply

* Re: [PATCH 5/6] [v5] leds: gpio: make legacy gpiolib interface optional
From: sashiko-bot @ 2026-06-29 13:38 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: dmitry.torokhov, linux-input, linux-leds, lee
In-Reply-To: <20260629130329.1291953-6-arnd@kernel.org>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Fatal build error due to missing header file `linux/gpio/legacy.h`.
--

commit 2f558c72edeac39e19dec733e556e60219934526
Author: Arnd Bergmann <arnd@arndb.de>

leds: gpio: make legacy gpiolib interface optional

This commit splits out the legacy portion of the platform_data handling into
a custom helper function guarded by CONFIG_GPIOLIB_LEGACY. The goal is to
allow the leds-gpio driver to compile cleanly when the legacy configuration
gets turned off for modern platforms.

Link: https://lore.kernel.org/all/e9252384-a55c-4a91-9c61-06e05a0b2ce4@app.fastmail.com/

> diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
> index a3428b22de3a1..740772c2504a1 100644
> --- a/drivers/leds/leds-gpio.c
> +++ b/drivers/leds/leds-gpio.c
> @@ -9,8 +9,8 @@
>  #include <linux/container_of.h>
>  #include <linux/device.h>
>  #include <linux/err.h>
> -#include <linux/gpio.h>
>  #include <linux/gpio/consumer.h>
> +#include <linux/gpio/legacy.h>

[Severity: Low]
Does this cause a build failure? It looks like linux/gpio/legacy.h doesn't
exist in the kernel source tree, and the legacy GPIO APIs remain conditionally
available within include/linux/gpio.h itself.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260629130329.1291953-1-arnd@kernel.org?part=5

^ permalink raw reply

* Re: [PATCH 05/10] Input: synaptics-rmi4 - block s_input when F54 queue is busy
From: Hans Verkuil @ 2026-06-29 13:38 UTC (permalink / raw)
  To: Dmitry Torokhov, Bryam Vargas, Hans Verkuil
  Cc: linux-input, linux-kernel, stable
In-Reply-To: <20260626051802.4033172-5-dmitry.torokhov@gmail.com>

On 26/06/2026 07:17, Dmitry Torokhov wrote:
> Changing the input (diagnostic report type) mid-stream changes the
> report size. Since V4L2 buffers are allocated based on the size at
> stream start, changing the input while streaming could lead to a
> heap buffer overflow if the new size is larger than the allocated
> buffers.
> 
> Prevent this by blocking VIDIOC_S_INPUT with -EBUSY if the V4L2 queue
> is busy (streaming).
> 
> Fixes: 3a762dbd5347 ("[media] Input: synaptics-rmi4 - add support for F54 diagnostics")
> Cc: stable@vger.kernel.org
> Assisted-by: Antigravity:gemini-3.5-flash
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

Reviewed-by: Hans Verkuil <hverkuil+cisco@kernel.org>

Regards,

	Hans

> ---
>  drivers/input/rmi4/rmi_f54.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
> index aebe74d2032c..e86dfc9ce7d9 100644
> --- a/drivers/input/rmi4/rmi_f54.c
> +++ b/drivers/input/rmi4/rmi_f54.c
> @@ -445,7 +445,12 @@ static int rmi_f54_set_input(struct f54_data *f54, unsigned int i)
>  
>  static int rmi_f54_vidioc_s_input(struct file *file, void *priv, unsigned int i)
>  {
> -	return rmi_f54_set_input(video_drvdata(file), i);
> +	struct f54_data *f54 = video_drvdata(file);
> +
> +	if (vb2_is_busy(&f54->queue))
> +		return -EBUSY;
> +
> +	return rmi_f54_set_input(f54, i);
>  }
>  
>  static int rmi_f54_vidioc_g_input(struct file *file, void *priv,


^ permalink raw reply

* Re: [PATCH 2/6] [v5] x86/olpc: select GPIOLIB_LEGACY
From: Arnd Bergmann @ 2026-06-29 13:40 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: linux-input, Lee Jones, Dmitry Torokhov, linux-leds
In-Reply-To: <20260629132505.A53EB1F000E9@smtp.kernel.org>

On Mon, Jun 29, 2026, at 15:25, sashiko-bot@kernel.org wrote:
>> diff --git a/arch/x86/platform/olpc/olpc-xo1-sci.c b/arch/x86/platform/olpc/olpc-xo1-sci.c
>> index 30751b42d54ef..a5b47960ba32e 100644
>> --- a/arch/x86/platform/olpc/olpc-xo1-sci.c
>> +++ b/arch/x86/platform/olpc/olpc-xo1-sci.c
>> @@ -9,7 +9,7 @@
>>  
>>  #include <linux/cs5535.h>
>>  #include <linux/device.h>
>> -#include <linux/gpio.h>
>> +#include <linux/gpio/legacy.h>
>
> [Severity: Low]
> Does this cause a build failure when setup_ec_sci() and other functions in
> this file are compiled? It appears include/linux/gpio/legacy.h does not exist
> in the tree, and the legacy GPIO APIs might still be declared directly in
> include/linux/gpio.h.

The header was added in 7.2-rc1.

     Arnd

^ permalink raw reply

* Re: [PATCH 07/10] Input: synaptics-rmi4 - check V4L2 buffer size in F54 queue
From: Hans Verkuil @ 2026-06-29 13:42 UTC (permalink / raw)
  To: Dmitry Torokhov, Bryam Vargas, Hans Verkuil
  Cc: linux-input, linux-kernel, stable
In-Reply-To: <20260626051802.4033172-7-dmitry.torokhov@gmail.com>

On 26/06/2026 07:17, Dmitry Torokhov wrote:
> Add a safety check in rmi_f54_buffer_queue() to ensure that the
> requested report size (f54->report_size) does not exceed the actual
> allocated size of the V4L2 buffer (vb2_plane_size()).
> 
> This provides a defense-in-depth measure against any potential size
> mismatches between the V4L2 queue and the driver's internal state.
> 
> Fixes: 3a762dbd5347 ("[media] Input: synaptics-rmi4 - add support for F54 diagnostics")
> Cc: stable@vger.kernel.org
> Assisted-by: Antigravity:gemini-3.5-flash
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
>  drivers/input/rmi4/rmi_f54.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
> index c86bc81845bb..93526feea563 100644
> --- a/drivers/input/rmi4/rmi_f54.c
> +++ b/drivers/input/rmi4/rmi_f54.c
> @@ -354,6 +354,13 @@ static void rmi_f54_buffer_queue(struct vb2_buffer *vb)
>  		goto data_done;
>  	}
>  
> +	if (f54->report_size > vb2_plane_size(vb, 0)) {
> +		dev_err(&f54->fn->dev, "Buffer too small (%lu < %d)\n",
> +			vb2_plane_size(vb, 0), f54->report_size);
> +		state = VB2_BUF_STATE_ERROR;
> +		goto data_done;
> +	}
> +

That's the wrong place, it's too late for that check.

This should be checked in the buf_prepare callback. See e.g.
drivers/media/test-drivers/vivid/vivid-touch-cap.c.

Regards,

	Hans

>  	memcpy(ptr, f54->report_data, f54->report_size);
>  	vb2_set_plane_payload(vb, 0, rmi_f54_get_report_size(f54));
>  	state = VB2_BUF_STATE_DONE;


^ permalink raw reply

* Re: [PATCH 6/6] [v5] gpiolib: turn off legacy interface by default
From: sashiko-bot @ 2026-06-29 13:46 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linux-input, linux-leds, dmitry.torokhov, lee
In-Reply-To: <20260629130329.1291953-7-arnd@kernel.org>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Drivers depending on `GPIOLIB_LEGACY` rather than selecting it are rendered unselectable and silently disabled on normal builds.
- [Low] Disabling CONFIG_GPIOLIB_LEGACY by default causes widespread build failures for platforms and drivers still relying on legacy GPIO functions.
--

commit bad1a2df68babe59200c7570528e8b8606464b68
Author: Arnd Bergmann <arnd@arndb.de>

gpiolib: turn off legacy interface by default

This commit changes the GPIOLIB_LEGACY configuration to default to 'n' instead
of 'y'. It restricts manual selection to builds where COMPILE_TEST is enabled,
intending to only build the legacy interface on platforms that require it.

> All users of the legacy interface now select CONFIG_GPIOLIB_LEGACY,
> so it can be turned off by default and only get built on platforms
> that still have one unconverted driver.

[Severity: High]
Is this description entirely accurate?

There appear to be drivers that use 'depends on GPIOLIB_LEGACY' rather than
selecting it, such as MFD_AAT2870_CORE, MFD_SI476X_CORE, and
SND_SOC_TLV320DAC33.

If GPIOLIB_LEGACY defaults to 'n' without COMPILE_TEST enabled, will these
drivers be rendered unselectable and silently disabled on normal builds?

> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 020e51e30317a..543de15a12f63 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -4,7 +4,14 @@
>  #
>  
>  config GPIOLIB_LEGACY
> -	def_bool y
> +	bool "Legacy GPIO interfaces" if COMPILE_TEST

[Severity: Low]
Could disabling this by default cause build failures on legacy platforms that
still call GPIO functions but do not explicitly select GPIOLIB_LEGACY?

For instance, arch/arm/mach-pxa/am200epd.c still uses gpio_request():

arch/arm/mach-pxa/am200epd.c:am200_init_gpio_regs() {
        ...
        err = gpio_request(gpios[i], gpio_names[i]);
        ...
}

Because include/linux/gpio.h excludes the legacy prototypes when
CONFIG_GPIOLIB_LEGACY is disabled, will this cause implicit declaration
compiler errors during standard builds for architectures like PXA?

> +	help
> +	  There are a few legacy platforms that use the traditional GPIO
> +	  number based interfaces instead of GPIO descriptors.
> +	  Say Y here to enable build testing drivers that are specific
> +	  to those platforms.
> +
> +	  If unsure, say N.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260629130329.1291953-1-arnd@kernel.org?part=6

^ permalink raw reply

* Re: [PATCH] HID: hiddev: keep state alive through disconnect unlock
From: Yousef Alhouseen @ 2026-06-29 13:57 UTC (permalink / raw)
  To: Hillf Danton
  Cc: Jiri Kosina, Benjamin Tissoires, linux-input, linux-usb,
	linux-kernel, syzbot+563191a4939ddbfe73d4
In-Reply-To: <20260628222617.226-1-hdanton@sina.com>

The missing interleaving is that mutex_unlock() clears the owner
before taking wait_lock. A contender already spinning on existancelock
can acquire it after that owner clear, reach the final-release path,
and free hiddev before the disconnecting task reaches
raw_spin_lock_irqsave(&lock->wait_lock, ...). It does not need to be
woken by the disconnecting task.

That is also why mutex_unlock() explicitly requires the containing
object to remain alive until the call returns. I will make this
interleaving explicit in v2.

Thanks,
Yousef

On Mon, 29 Jun 2026 06:26:15 +0800, Hillf Danton <hdanton@sina.com> wrote:
> On Sun, 28 Jun 2026 11:32:45 +0200 Yousef Alhouseen wrote:
> > hiddev_disconnect() drops existancelock before freeing the hiddev state,
> > but a waiting final file release can run as soon as the mutex becomes
> > available. On PREEMPT_RT, that waiter may free hiddev while the disconnect
> > thread is still executing the mutex slow-unlock path, causing a
> > use-after-free in the mutex implementation.
> >
> The root cause is not specified as clearly as expected.
>
> hiddev_disconnect() hiddev_release()
> --- ---
> mutex_lock(&hiddev->existancelock);
> hiddev->exist = 0;
>
> if (hiddev->open) {
> hid_hw_close(hiddev->hid);
> wake_up_interruptible(&hiddev->wait);
> mutex_unlock(&hiddev->existancelock);
> __mutex_unlock_slowpath()
> raw_spin_lock_irqsave() //UAF
>
> mutex_lock(&list->hiddev->existancelock);
> if (!--list->hiddev->open) {
> if (list->hiddev->exist) {
> hid_hw_close(list->hiddev->hid);
> hid_hw_power(list->hiddev->hid, PM_HINT_NORMAL);
> } else {
> mutex_unlock(&list->hiddev->existancelock);
> kfree(list->hiddev); // free mem
> vfree(list);
> return 0;
> }
> }
> mutex_unlock(&list->hiddev->existancelock);
>
> Given the syzbot report, uaf occured upon acquiring the raw spinlock in
> __mutex_unlock_slowpath(), but no mutex waiter could be waken up without
> the raw spinlock held, thus the report sounds false positive.
>
> > Give the connection and each open file an explicit reference. Drop each
> > reference only after its existancelock critical section has completed, so
> > the state cannot be freed from the other unlock path.
> >
> > Fixes: 079034073faf ("HID: hiddev cleanup -- handle all error conditions properly")
> > Reported-by: syzbot+563191a4939ddbfe73d4@syzkaller.appspotmail.com
> > Closes: https://syzkaller.appspot.com/bug?extid=563191a4939ddbfe73d4
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
> > ---
> > drivers/hid/usbhid/hiddev.c | 37 +++++++++++++++++++------------------
> > include/linux/hiddev.h | 2 ++
> > 2 files changed, 21 insertions(+), 18 deletions(-)
> >
> > diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
> > index 6378801b22c6..21396481995b 100644
> > --- a/drivers/hid/usbhid/hiddev.c
> > +++ b/drivers/hid/usbhid/hiddev.c
> > @@ -46,6 +46,12 @@ struct hiddev_list {
> > struct mutex thread_lock;
> > };
> >
> > +static void hiddev_put(struct hiddev *hiddev)
> > +{
> > + if (refcount_dec_and_test(&hiddev->refcount))
> > + kfree(hiddev);
> > +}
> > +
> > /*
> > * Find a report, given the report's type and ID. The ID can be specified
> > * indirectly by REPORT_ID_FIRST (which returns the first report of the given
> > @@ -216,26 +222,21 @@ static int hiddev_fasync(int fd, struct file *file, int on)
> > static int hiddev_release(struct inode * inode, struct file * file)
> > {
> > struct hiddev_list *list = file->private_data;
> > + struct hiddev *hiddev = list->hiddev;
> > unsigned long flags;
> >
> > - spin_lock_irqsave(&list->hiddev->list_lock, flags);
> > + spin_lock_irqsave(&hiddev->list_lock, flags);
> > list_del(&list->node);
> > - spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
> > + spin_unlock_irqrestore(&hiddev->list_lock, flags);
> >
> > - mutex_lock(&list->hiddev->existancelock);
> > - if (!--list->hiddev->open) {
> > - if (list->hiddev->exist) {
> > - hid_hw_close(list->hiddev->hid);
> > - hid_hw_power(list->hiddev->hid, PM_HINT_NORMAL);
> > - } else {
> > - mutex_unlock(&list->hiddev->existancelock);
> > - kfree(list->hiddev);
> > - vfree(list);
> > - return 0;
> > - }
> > + mutex_lock(&hiddev->existancelock);
> > + if (!--hiddev->open && hiddev->exist) {
> > + hid_hw_close(hiddev->hid);
> > + hid_hw_power(hiddev->hid, PM_HINT_NORMAL);
> > }
> >
> > - mutex_unlock(&list->hiddev->existancelock);
> > + mutex_unlock(&hiddev->existancelock);
> > + hiddev_put(hiddev);
> > vfree(list);
> >
> > return 0;
> > @@ -270,6 +271,7 @@ static int __hiddev_open(struct hiddev *hiddev, struct file *file)
> > spin_unlock_irq(&hiddev->list_lock);
> >
> > file->private_data = list;
> > + refcount_inc(&hiddev->refcount);
> >
> > return 0;
> >
> > @@ -897,6 +899,7 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
> > INIT_LIST_HEAD(&hiddev->list);
> > spin_lock_init(&hiddev->list_lock);
> > mutex_init(&hiddev->existancelock);
> > + refcount_set(&hiddev->refcount, 1);
> > hid->hiddev = hiddev;
> > hiddev->hid = hid;
> > hiddev->exist = 1;
> > @@ -937,9 +940,7 @@ void hiddev_disconnect(struct hid_device *hid)
> > if (hiddev->open) {
> > hid_hw_close(hiddev->hid);
> > wake_up_interruptible(&hiddev->wait);
> > - mutex_unlock(&hiddev->existancelock);
> > - } else {
> > - mutex_unlock(&hiddev->existancelock);
> > - kfree(hiddev);
> > }
> > + mutex_unlock(&hiddev->existancelock);
> > + hiddev_put(hiddev);
> > }
> > diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h
> > index 2164c03d2c72..8e9f8a33e359 100644
> > --- a/include/linux/hiddev.h
> > +++ b/include/linux/hiddev.h
> > @@ -13,6 +13,7 @@
> > #ifndef _HIDDEV_H
> > #define _HIDDEV_H
> >
> > +#include <linux/refcount.h>
> > #include <uapi/linux/hiddev.h>
> >
> >
> > @@ -24,6 +25,7 @@ struct hiddev {
> > int minor;
> > int exist;
> > int open;
> > + refcount_t refcount;
> > struct mutex existancelock;
> > wait_queue_head_t wait;
> > struct hid_device *hid;
> > --
> > 2.54.0

^ permalink raw reply

* [PATCH] [RFC] gpiolib: introduce gpio_name() helper
From: Arnd Bergmann @ 2026-06-29 13:56 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski
  Cc: Arnd Bergmann, Marcel Holtmann, MyungJoo Ham, Chanwoo Choi,
	Geert Uytterhoeven, Andy Shevchenko, Dmitry Torokhov, Ulf Hansson,
	linux-bluetooth, linux-kernel, linux-gpio, dri-devel, linux-i2c,
	linux-iio, linux-input, linux-mmc, linux-arm-kernel, linux-pm,
	linux-usb

From: Arnd Bergmann <arnd@arndb.de>

Most remaining users of desc_to_gpio() only call it for printing debug
information.

Replace this with a new gpiod_name() helper that returns the
gpio_desc->name string after checking the gpio_desc pointer.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---

Not sure if this the way we want to take this, or if the gpio name is
an appropriate replacement in debug printk.

Since most of the callers of desc_to_gpio() and gpio_to_desc() are
otherwise in drivers that already depend on CONFIG_GPIOLIB_LEGACY and
include linux/gpio/legacy.h, only a handful of instances remain that
are otherwise in files that otherwise only use the descriptor interfaces:

arch/arm/mach-pxa/pxa27x.c:	reset_gpio = desc_to_gpio(gpiod);
arch/arm/plat-orion/gpio.c:	unsigned gpio = desc_to_gpio(desc);
drivers/gpio/gpio-nomadik.c:		mode = nmk_prcm_gpiocr_get_mode(pctldev, desc_to_gpio(desc));
drivers/gpio/gpiolib-acpi-core.c:			desc = gpio_to_desc(agpio->pin_table[pin_index]);
drivers/gpio/gpiolib-cdev.c:	hte_init_line_attr(hdesc, desc_to_gpio(line->desc), flags, NULL,
drivers/gpio/gpiolib-sysfs.c:	desc = gpio_to_desc(gpio);
drivers/gpio/gpiolib-sysfs.c:						   desc_to_gpio(desc));
drivers/gpio/gpiolib.c:	trace_gpio_direction(desc_to_gpio(desc), 1, ret);
drivers/input/misc/soc_button_array.c:	*gpio_ret = desc_to_gpio(desc);
drivers/pinctrl/core.c:			gdev = gpiod_to_gpio_device(gpio_to_desc(gpio_num));
drivers/platform/x86/x86-android-tablets/core.c: * 2. Calling desc_to_gpio() to get an old style GPIO number for gpio-keys
drivers/soc/fsl/qe/gpio.c:	gpio_num = desc_to_gpio(gpiod);
---
 drivers/bluetooth/hci_intel.c             |  4 ++--
 drivers/extcon/extcon-rtk-type-c.c        |  4 ++--
 drivers/gpio/gpio-aggregator.c            |  4 ++--
 drivers/gpio/gpiolib.c                    | 13 +++++++++++++
 drivers/gpu/drm/bridge/analogix/anx7625.c |  6 +++---
 drivers/i2c/busses/i2c-gpio.c             |  4 ++--
 drivers/iio/accel/mma9551.c               |  4 ++--
 drivers/iio/humidity/dht11.c              |  2 +-
 drivers/input/touchscreen/edt-ft5x06.c    |  6 +++---
 drivers/input/touchscreen/hycon-hy46xx.c  |  5 ++---
 drivers/mmc/host/atmel-mci.c              |  8 ++++----
 drivers/power/supply/bq24257_charger.c    |  2 +-
 drivers/usb/gadget/udc/at91_udc.c         |  4 ++--
 include/linux/gpio/consumer.h             |  8 ++++++++
 14 files changed, 47 insertions(+), 27 deletions(-)

diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c
index c31105b91e47..2e6ebc152bcb 100644
--- a/drivers/bluetooth/hci_intel.c
+++ b/drivers/bluetooth/hci_intel.c
@@ -1176,8 +1176,8 @@ static int intel_probe(struct platform_device *pdev)
 	list_add_tail(&idev->list, &intel_device_list);
 	mutex_unlock(&intel_device_list_lock);
 
-	dev_info(&pdev->dev, "registered, gpio(%d)/irq(%d).\n",
-		 desc_to_gpio(idev->reset), idev->irq);
+	dev_info(&pdev->dev, "registered, gpio(%s)/irq(%d).\n",
+		 gpiod_name(idev->reset), idev->irq);
 
 	return 0;
 }
diff --git a/drivers/extcon/extcon-rtk-type-c.c b/drivers/extcon/extcon-rtk-type-c.c
index 82b60b927e41..fb57e9d7ddb6 100644
--- a/drivers/extcon/extcon-rtk-type-c.c
+++ b/drivers/extcon/extcon-rtk-type-c.c
@@ -1356,8 +1356,8 @@ static int extcon_rtk_type_c_probe(struct platform_device *pdev)
 				(int)PTR_ERR(gpio));
 		} else {
 			type_c->rd_ctrl_gpio_desc = gpio;
-			dev_dbg(dev, "%s get rd-ctrl-gpios (id=%d) OK\n",
-				__func__, desc_to_gpio(gpio));
+			dev_dbg(dev, "%s get rd-ctrl-gpios (id=%s) OK\n",
+				__func__, gpiod_name(gpio));
 		}
 	}
 
diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c
index bc6699a821ee..27df680fbdbb 100644
--- a/drivers/gpio/gpio-aggregator.c
+++ b/drivers/gpio/gpio-aggregator.c
@@ -758,8 +758,8 @@ int gpiochip_fwd_desc_add(struct gpiochip_fwd *fwd, struct gpio_desc *desc,
 
 	fwd->descs[offset] = desc;
 
-	dev_dbg(chip->parent, "%u => gpio %d irq %d\n", offset,
-		desc_to_gpio(desc), gpiod_to_irq(desc));
+	dev_dbg(chip->parent, "%u => gpio %s irq %d\n", offset,
+		gpiod_name(desc), gpiod_to_irq(desc));
 
 	return 0;
 }
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 1f498d6c8c68..00de24db74a5 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -4122,6 +4122,19 @@ int gpiod_set_consumer_name(struct gpio_desc *desc, const char *name)
 }
 EXPORT_SYMBOL_GPL(gpiod_set_consumer_name);
 
+/**
+ * gpiod_name() - get a name to print for a gpio descriptor
+ * @desc: gpio or NULL pointer to query
+ *
+ * Returns:
+ * The desc->name field or a dummy string for unknown GPIOs.
+ */
+const char *gpiod_name(const struct gpio_desc *desc)
+{
+	return desc ? desc->name : "(no gpio)";
+}
+EXPORT_SYMBOL_GPL(gpiod_name);
+
 /**
  * gpiod_is_shared() - check if this GPIO can be shared by multiple consumers
  * @desc: GPIO to inspect
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index fffcd6154c71..5dce097d4045 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -1448,9 +1448,9 @@ static void anx7625_init_gpio(struct anx7625_data *platform)
 
 	if (platform->pdata.gpio_p_on && platform->pdata.gpio_reset) {
 		platform->pdata.low_power_mode = 1;
-		DRM_DEV_DEBUG_DRIVER(dev, "low power mode, pon %d, reset %d.\n",
-				     desc_to_gpio(platform->pdata.gpio_p_on),
-				     desc_to_gpio(platform->pdata.gpio_reset));
+		DRM_DEV_DEBUG_DRIVER(dev, "low power mode, pon %s, reset %s.\n",
+				     gpiod_name(platform->pdata.gpio_p_on),
+				     gpiod_name(platform->pdata.gpio_reset));
 	} else {
 		platform->pdata.low_power_mode = 0;
 		DRM_DEV_DEBUG_DRIVER(dev, "not low power mode.\n");
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index f4355b17bfbf..4c320a833d9e 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -440,8 +440,8 @@ static int i2c_gpio_probe(struct platform_device *pdev)
 	 * get accessors to get the actual name of the GPIO line,
 	 * from the descriptor, then provide that instead.
 	 */
-	dev_info(dev, "using lines %u (SDA) and %u (SCL%s)\n",
-		 desc_to_gpio(priv->sda), desc_to_gpio(priv->scl),
+	dev_info(dev, "using lines %s (SDA) and %s (SCL%s)\n",
+		 gpiod_name(priv->sda), gpiod_name(priv->scl),
 		 pdata->scl_is_output_only
 		 ? ", no clock stretching" : "");
 
diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c
index 020370b0ec07..b9d1fc3caf83 100644
--- a/drivers/iio/accel/mma9551.c
+++ b/drivers/iio/accel/mma9551.c
@@ -426,8 +426,8 @@ static int mma9551_gpio_probe(struct iio_dev *indio_dev)
 			return ret;
 		}
 
-		dev_dbg(dev, "gpio resource, no:%d irq:%d\n",
-			desc_to_gpio(gpio), data->irqs[i]);
+		dev_dbg(dev, "gpio resource, no:%s irq:%d\n",
+			gpiod_name(gpio), data->irqs[i]);
 	}
 
 	return 0;
diff --git a/drivers/iio/humidity/dht11.c b/drivers/iio/humidity/dht11.c
index 980cb946bbf7..ca6b8c53e462 100644
--- a/drivers/iio/humidity/dht11.c
+++ b/drivers/iio/humidity/dht11.c
@@ -305,7 +305,7 @@ static int dht11_probe(struct platform_device *pdev)
 
 	dht11->irq = gpiod_to_irq(dht11->gpiod);
 	if (dht11->irq < 0) {
-		dev_err(dev, "GPIO %d has no interrupt\n", desc_to_gpio(dht11->gpiod));
+		dev_err(dev, "GPIO %s has no interrupt\n", gpiod_name(dht11->gpiod));
 		return -EINVAL;
 	}
 
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index d3b1177185a3..2d31c77614b0 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -1326,10 +1326,10 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
 	edt_ft5x06_ts_prepare_debugfs(tsdata);
 
 	dev_dbg(&client->dev,
-		"EDT FT5x06 initialized: IRQ %d, WAKE pin %d, Reset pin %d.\n",
+		"EDT FT5x06 initialized: IRQ %d, WAKE pin %s, Reset pin %s.\n",
 		client->irq,
-		tsdata->wake_gpio ? desc_to_gpio(tsdata->wake_gpio) : -1,
-		tsdata->reset_gpio ? desc_to_gpio(tsdata->reset_gpio) : -1);
+		gpiod_name(tsdata->wake_gpio),
+		gpiod_name(tsdata->reset_gpio));
 
 	return 0;
 }
diff --git a/drivers/input/touchscreen/hycon-hy46xx.c b/drivers/input/touchscreen/hycon-hy46xx.c
index 1513f20cbf51..797667c5dd99 100644
--- a/drivers/input/touchscreen/hycon-hy46xx.c
+++ b/drivers/input/touchscreen/hycon-hy46xx.c
@@ -528,9 +528,8 @@ static int hycon_hy46xx_probe(struct i2c_client *client)
 		return error;
 
 	dev_dbg(&client->dev,
-		"HYCON HY46XX initialized: IRQ %d, Reset pin %d.\n",
-		client->irq,
-		tsdata->reset_gpio ? desc_to_gpio(tsdata->reset_gpio) : -1);
+		"HYCON HY46XX initialized: IRQ %d, Reset pin %s.\n",
+		client->irq, gpiod_name(tsdata->reset_gpio));
 
 	return 0;
 }
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 3b4928f5b9b2..b21820564315 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -2255,11 +2255,11 @@ static int atmci_init_slot(struct atmel_mci *host,
 	slot->sdio_irq = sdio_irq;
 
 	dev_dbg(&mmc->class_dev,
-	        "slot[%u]: bus_width=%u, detect_pin=%d, "
-		"detect_is_active_high=%s, wp_pin=%d\n",
-		id, slot_data->bus_width, desc_to_gpio(slot_data->detect_pin),
+	        "slot[%u]: bus_width=%u, detect_pin=%s, "
+		"detect_is_active_high=%s, wp_pin=%s\n",
+		id, slot_data->bus_width, gpiod_name(slot_data->detect_pin),
 		str_true_false(!gpiod_is_active_low(slot_data->detect_pin)),
-		desc_to_gpio(slot_data->wp_pin));
+		gpiod_name(slot_data->wp_pin));
 
 	mmc->ops = &atmci_ops;
 	mmc->f_min = DIV_ROUND_UP(host->bus_hz, 512);
diff --git a/drivers/power/supply/bq24257_charger.c b/drivers/power/supply/bq24257_charger.c
index 72f1bfea8d54..b756bab74eec 100644
--- a/drivers/power/supply/bq24257_charger.c
+++ b/drivers/power/supply/bq24257_charger.c
@@ -868,7 +868,7 @@ static void bq24257_pg_gpio_probe(struct bq24257_device *bq)
 	}
 
 	if (bq->pg)
-		dev_dbg(bq->dev, "probed PG pin = %d\n", desc_to_gpio(bq->pg));
+		dev_dbg(bq->dev, "probed PG pin = %s\n", gpiod_name(bq->pg));
 }
 
 static int bq24257_fw_probe(struct bq24257_device *bq)
diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c
index 5aa360ba4f03..099313604387 100644
--- a/drivers/usb/gadget/udc/at91_udc.c
+++ b/drivers/usb/gadget/udc/at91_udc.c
@@ -1896,8 +1896,8 @@ static int at91udc_probe(struct platform_device *pdev)
 					gpiod_to_irq(udc->board.vbus_pin),
 					at91_vbus_irq, 0, driver_name, udc);
 			if (retval) {
-				DBG("request vbus irq %d failed\n",
-				    desc_to_gpio(udc->board.vbus_pin));
+				DBG("request vbus irq %s failed\n",
+				    gpiod_name(udc->board.vbus_pin));
 				goto err_unprepare_iclk;
 			}
 		}
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index fceeefd5f893..9c91fae62f8c 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -172,6 +172,8 @@ int gpiod_set_consumer_name(struct gpio_desc *desc, const char *name);
 
 bool gpiod_is_shared(const struct gpio_desc *desc);
 
+const char *gpiod_name(const struct gpio_desc *desc);
+
 /* Convert between the old gpio_ and new gpiod_ interfaces */
 struct gpio_desc *gpio_to_desc(unsigned gpio);
 int desc_to_gpio(const struct gpio_desc *desc);
@@ -538,6 +540,12 @@ static inline bool gpiod_is_shared(const struct gpio_desc *desc)
 	return false;
 }
 
+static inline const char *gpiod_name(const struct gpio_desc *desc)
+{
+	WARN_ON(desc);
+	return "(no gpio)";
+}
+
 static inline struct gpio_desc *gpio_to_desc(unsigned gpio)
 {
 	return NULL;
-- 
2.39.5


^ permalink raw reply related

* Re: [PATCH 00/13] treewide: replace linux/gpio.h
From: Andreas Schwab @ 2026-06-29 14:01 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-gpio, Arnd Bergmann, Bartosz Golaszewski, Andrew Lunn,
	Sebastian Hesselbarth, Gregory Clement, Frank Li, Robert Jarzmik,
	Krzysztof Kozlowski, Greg Ungerer, Thomas Bogendoerfer,
	Hauke Mehrtens, Rafał Miłecki, Yoshinori Sato,
	John Paul Adrian Glaubitz, Linus Walleij, Dmitry Torokhov,
	Jakub Kicinski, Paolo Abeni, Dominik Brodowski, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, patches, linux-m68k,
	linux-mips, linux-sh, linux-input, linux-media, netdev,
	linux-sunxi, linux-phy, linux-rockchip, linux-sound
In-Reply-To: <20260629132633.1300009-1-arnd@kernel.org>

On Jun 29 2026, Arnd Bergmann wrote:

> From: Arnd Bergmann <arnd@arndb.de>
>
> The linux/gpio.h header used to be the global definition for the gpio
> interfaces, with 1100 users back in linux-3.17. In linux-7.2, only about
> 130 of those remain, so this series cleans out the rest.
>
> In each subsystem, we can replace the header either with
> linux/gpio/consumer.h for users of the modern gpio descriptor interface,

A few of them already used <linux/gpio/consumer.h>, and is duplicated
now.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply

* Re: [PATCH] [RFC] gpiolib: introduce gpio_name() helper
From: sashiko-bot @ 2026-06-29 14:10 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: dmitry.torokhov, linux-input, dri-devel
In-Reply-To: <20260629135917.1308621-1-arnd@kernel.org>

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

Pre-existing issues:
- [High] Uncanceled timer in the probe error path leads to a Use-After-Free when the timer fires.
- [High] Uncanceled delayed work in the probe error path and early IRQ request lead to Use-After-Free.
- [High] The return value of extcon_rtk_type_c_edev_register() is assigned but never checked, leading to silent failures.
--

commit fd9fdd473dd5d54a8f94bae5e74133accbec590a
Author: Arnd Bergmann <arnd@arndb.de>

gpiolib: introduce gpio_name() helper

Most remaining users of desc_to_gpio() only call it for printing debug
information.

Replace this with a new gpiod_name() helper that returns the
gpio_desc->name string after checking the gpio_desc pointer.

> diff --git a/drivers/extcon/extcon-rtk-type-c.c b/drivers/extcon/extcon-rtk-type-c.c
> index 82b60b927e41a..fb57e9d7ddb63 100644
> --- a/drivers/extcon/extcon-rtk-type-c.c
> +++ b/drivers/extcon/extcon-rtk-type-c.c
> @@ -1356,8 +1356,8 @@ static int extcon_rtk_type_c_probe(struct platform_device *pdev)
>  				(int)PTR_ERR(gpio));
>  		} else {
>  			type_c->rd_ctrl_gpio_desc = gpio;
> -			dev_dbg(dev, "%s get rd-ctrl-gpios (id=%d) OK\n",
> -				__func__, desc_to_gpio(gpio));
> +			dev_dbg(dev, "%s get rd-ctrl-gpios (id=%s) OK\n",
> +				__func__, gpiod_name(gpio));
>  		}
>  	}

[Severity: High]
This is a pre-existing issue, but I noticed a potential use-after-free if
extcon_rtk_type_c_init() fails.

In extcon_rtk_type_c_probe(), the code requests an IRQ before the delayed
work is initialized:

	ret = devm_request_irq(dev, type_c->irq, type_c_detect_irq, ...);
	...
	INIT_DELAYED_WORK(&type_c->delayed_work, host_device_switch);

	ret = extcon_rtk_type_c_init(type_c);
	if (ret) {
		dev_err(dev, "%s failed to init type_c\n", __func__);
		goto err;
	}

Could an early interrupt schedule the uninitialized work?

Also, if extcon_rtk_type_c_init() fails, the code jumps to the err label
and returns without canceling the delayed work. Since the structure is
freed by devres, will this cause a use-after-free when the work executes?

[Severity: High]
This is also a pre-existing issue, but further down in the same function,
the return value of extcon_rtk_type_c_edev_register() is assigned to ret
but is not checked:

	ret = extcon_rtk_type_c_edev_register(type_c);

	create_debug_files(type_c);

	return 0;

Could this mask a registration failure, since the function unconditionally
returns 0?

[ ... ]

> diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c
> index 5aa360ba4f039..0993136043870 100644
> --- a/drivers/usb/gadget/udc/at91_udc.c
> +++ b/drivers/usb/gadget/udc/at91_udc.c
> @@ -1896,8 +1896,8 @@ static int at91udc_probe(struct platform_device *pdev)
>  					gpiod_to_irq(udc->board.vbus_pin),
>  					at91_vbus_irq, 0, driver_name, udc);
>  			if (retval) {
> -				DBG("request vbus irq %d failed\n",
> -				    desc_to_gpio(udc->board.vbus_pin));
> +				DBG("request vbus irq %s failed\n",
> +				    gpiod_name(udc->board.vbus_pin));
>  				goto err_unprepare_iclk;
>  			}
>  		}

[Severity: High]
This is a pre-existing issue, but there appears to be a missing timer cleanup
in the probe error path.

In at91udc_probe(), when vbus_polled is true, a timer is armed:

		if (udc->board.vbus_polled) {
			INIT_WORK(&udc->vbus_timer_work, at91_vbus_timer_work);
			timer_setup(&udc->vbus_timer, at91_vbus_timer, 0);
			mod_timer(&udc->vbus_timer,
				  jiffies + VBUS_POLL_TIMEOUT);
		}

If usb_add_gadget_udc() fails later, the code jumps to err_unprepare_iclk
and returns without deleting the timer:

	retval = usb_add_gadget_udc(dev, &udc->gadget);
	if (retval)
		goto err_unprepare_iclk;
	...
err_unprepare_iclk:
	clk_unprepare(udc->iclk);
err_unprepare_fclk:
	clk_unprepare(udc->fclk);

	return retval;

If the probe fails, devres will free the udc structure. Does this mean the
timer can still fire and access the freed udc memory, causing a
use-after-free?

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

^ permalink raw reply

* Re: [PATCH 6/6] [v5] gpiolib: turn off legacy interface by default
From: Arnd Bergmann @ 2026-06-29 14:13 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: linux-input, linux-leds, Dmitry Torokhov, Lee Jones
In-Reply-To: <20260629134613.F154B1F000E9@smtp.kernel.org>

On Mon, Jun 29, 2026, at 15:46, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential 
> issue(s) to consider:
> - [High] Drivers depending on `GPIOLIB_LEGACY` rather than selecting it 
> are rendered unselectable and silently disabled on normal builds.
> - [Low] Disabling CONFIG_GPIOLIB_LEGACY by default causes widespread 
> build failures for platforms and drivers still relying on legacy GPIO 
> functions.

That is the idea, yes: If someone adds back a new legacy user, they
will get a build failure after this patch.

>> All users of the legacy interface now select CONFIG_GPIOLIB_LEGACY,
>> so it can be turned off by default and only get built on platforms
>> that still have one unconverted driver.
>
> [Severity: High]
> Is this description entirely accurate?
>
> There appear to be drivers that use 'depends on GPIOLIB_LEGACY' rather than
> selecting it, such as MFD_AAT2870_CORE, MFD_SI476X_CORE, and
> SND_SOC_TLV320DAC33.
>
> If GPIOLIB_LEGACY defaults to 'n' without COMPILE_TEST enabled, will these
> drivers be rendered unselectable and silently disabled on normal builds?

Yes, correct. I made sure that all platforms that do use GPIO
numbers select those symbols. The three drivers listed above
can only work if a platform has a board file with the corresponding
platform data, but nothing provides si476x_platform_data or
aat2870_platform_data, and SND_SOC_TLV320DAC33 is already
a hidden Kconfig symbol and disabled for all platforms.

      Arnd

^ permalink raw reply

* [BUG] I2C HID touchpad BLTP7853:00 347D:7853 enumerates but reports no events on MECHREVO XINGYAO Series-P916F-PTL
From: Steve Yang @ 2026-06-29 14:15 UTC (permalink / raw)
  To: linux-input, linux-acpi, linux-i2c, linux-gpio

Hello,

Resending as plain text; sorry if this is a duplicate. My previous
message was rejected by linux-acpi because Gmail sent a HTML part.

I am seeing a non-working internal I2C HID touchpad on a new MECHREVO
laptop. The device enumerates, binds to i2c_hid_acpi + hid-multitouch,
and userspace sees it as a touchpad, but touching/clicking it produces
no input events. The GPIO interrupt counter also does not increase
while touching the pad.

I am new to kernel debugging, but I have the machine here and can test
patches, ACPI overrides, debug kernels, etc.

Hardware
========

DMI, with serial/UUID intentionally omitted:

  BIOS Vendor: MECHREVO
  BIOS Version: 1.00
  BIOS Release Date: 03/14/2026
  Firmware Revision: 1.48
  EC Firmware Revision: 1.0
  System Manufacturer: MECHREVO
  Product Name: XINGYAO Series
  Family: Panther Lake
  Base Board Product Name: XINGYAO Series-P916F-PTL

Software
========

  Linux archbook 7.0.14-arch1-1 #1 SMP PREEMPT_DYNAMIC Sat, 27 Jun
2026 16:15:10 +0000 x86_64 GNU/Linux
  linux-firmware 20260622-1
  libinput 1.31.3
  hid-tools 0.12
  acpica 20251212

Kernel command line at initial capture time:

  BOOT_IMAGE=/vmlinuz-linux root=UUID=<omitted> rw rootflags=subvol=@
loglevel=3 quiet

Device identification
=====================

/sys/bus/i2c/devices/i2c-BLTP7853:00/uevent:

  DRIVER=i2c_hid_acpi
  MODALIAS=acpi:BLTP7853:PNP0C50:

/sys/bus/hid/devices/0018:347D:7853.0001/uevent:

  DRIVER=hid-multitouch
  HID_ID=0018:0000347D:00007853
  HID_NAME=BLTP7853:00 347D:7853
  HID_PHYS=i2c-BLTP7853:00
  MODALIAS=hid:b0018g0004v0000347Dp00007853

udev for /dev/input/event5:

  DEVNAME=/dev/input/event5
  ID_INPUT=1
  ID_INPUT_TOUCHPAD=1
  ID_INPUT_WIDTH_MM=115
  ID_INPUT_HEIGHT_MM=72
  ID_BUS=i2c
  ID_INTEGRATION=internal
  ID_INPUT_TOUCHPAD_INTEGRATION=internal
  LIBINPUT_DEVICE_GROUP=18/347d/7853:i2c-BLTP7853:00

Symptoms / tests
================

1. dmesg shows the device binding successfully:

  input: BLTP7853:00 347D:7853 Mouse ...
  input: BLTP7853:00 347D:7853 Touchpad ...
  hid-generic 0018:347D:7853.0001: input,hidraw0: I2C HID v1.00 Mouse
[BLTP7853:00 347D:7853] on i2c-BLTP7853:00
  input: BLTP7853:00 347D:7853 Touchpad ...
  hid-multitouch 0018:347D:7853.0001: input,hidraw0: I2C HID v1.00
Mouse [BLTP7853:00 347D:7853] on i2c-BLTP7853:00

2. evtest on /dev/input/event5 shows normal-looking touchpad
capabilities, for example
ABS_X/ABS_Y/ABS_MT_POSITION_X/ABS_MT_POSITION_Y/ABS_MT_SLOT/ABS_MT_TRACKING_ID
and BTN_TOUCH/BTN_LEFT. However, during physical touch/click tests it
prints no events after:

  Testing ... (interrupt to exit)

3. /proc/interrupts has an IRQ for the touchpad in the original ACPI
configuration:

  intel-gpio 18 BLTP7853:00

While physically touching/clicking the touchpad, the counter did not increase.

4. debugfs gpio shows this line as claimed by the touchpad and high:

  gpiochip1: 51 GPIOs, parent: platform/INTC10BC:01, INTC10BC:01:
   gpio-18 ( |TPD0 GpioInt(0) ) in hi IRQ

5. KDE/libinput sees a touchpad-class input device, but the pointer
does not move and clicks do not work.

Things already tried
====================

None of these changed the behavior:

  - acpi_osi=Windows 2021
  - BIOS option named "Enable Windows OSI"
  - unbind/bind i2c-BLTP7853:00 from i2c_hid_acpi
  - echo on > /sys/bus/i2c/devices/i2c-BLTP7853:00/power/control
  - unloading huawei_wmi
  - setting HID feature Inputmode=3 with hid-feature
  - setting HID feature Surface Switch=1 and Button Switch=1

ACPI override experiments
=========================

The kernel supports ACPI table upgrade, and I confirmed the modified
SSDT was loaded each time via dmesg, for example:

  ACPI: Table Upgrade: override [SSDT-XXXXXX-I2C_DEVT]

I tried these changes to the touchpad GpioInt resource:

  original: GpioInt(Level, ActiveLow, ...)
  test 1: GpioInt(Level, ActiveHigh, ...)
  test 2: GpioInt(Edge, ActiveLow, ...)
  test 3: GpioInt(Edge, ActiveHigh, ...)

All three GpioInt variants still resulted in an intel-gpio IRQ for
BLTP7853:00, but the IRQ counter did not increase while
touching/clicking the touchpad.

I also forced _CRS to return the SBFI Interrupt() resource instead of
the SBFG GpioInt() resource. That changed the interrupt to:

  IR-IO-APIC 84-fasteoi BLTP7853:00

but it caused an apparent interrupt storm, with the counter increasing
by thousands over a few seconds, and still no evtest events. So the
Interrupt() path does not look correct either.

ACPI notes
==========

The touchpad ACPI device appears in SSDT under:

  \_SB.PC00.I2C5.TPD0

Relevant decompiled pieces from ssdt18.dsl:

  Scope (\_SB.PC00.I2C5)
  {
      Device (TPD0)
      {
          Name (HID2, Zero)
          ...
          Name (SBFG, ResourceTemplate ()
          {
              GpioInt (Level, ActiveLow, ExclusiveAndWake, PullDefault, 0x0000,
                  "\\_SB.GPI1", 0x00, ResourceConsumer, ,)
                  { 0x0000 }
          })
          Name (SBFI, ResourceTemplate ()
          {
              Interrupt (ResourceConsumer, Level, ActiveLow,
ExclusiveAndWake, ,, _Y08)
              {
                  0x00000000,
              }
          })
          CreateWordField (SBFB, \_SB.PC00.I2C5.TPD0._Y07._ADR, BADR)
          CreateDWordField (SBFB, \_SB.PC00.I2C5.TPD0._Y07._SPE, SPED)
          CreateWordField (SBFG, 0x17, INT1)
          CreateDWordField (SBFI, \_SB.PC00.I2C5.TPD0._Y08._INT, INT2)

          Method (_INI, 0, NotSerialized)
          {
              INT1 = GNUM (\TPIT)
              INT2 = INUM (\TPIT)
              If ((TPDM == Zero))
              {
                  SHPO (\TPIT, One)
              }
              SGRA (\TPIT, TPDM)
              If ((TPDM == One))
              {
                  SGII (\TPIT, Zero)
                  GRXE (\TPIT, Zero)
              }
              If ((\TPTY == One))
              {
                  _HID = "BLTP7853"
                  HID2 = One
                  BADR = 0x2C
                  SPED = 0x00061A80
                  Return (Zero)
              }
          }

          Name (_HID, "XXXX0000")
          Name (_CID, "PNP0C50")

          Method (_CRS, 0, NotSerialized)
          {
              If ((TPDM == Zero))
              {
                  Return (ConcatenateResTemplate (I2CM (I2CX, BADR,
SPED), SBFG))
              }
              Return (ConcatenateResTemplate (I2CM (I2CX, BADR, SPED), SBFI))
          }
      }
  }

ssdt13.dsl defines the NVS fields used by that code:

  OperationRegion (LCNV, SystemMemory, 0x6FDE4000, 0x0300)
  Field (LCNV, AnyAcc, Lock, Preserve)
  {
      EDID, 4096,
      TPTY, 8,
      TPST, 8,
      TPIT, 32,
      ...
  }

A possibly relevant observation from the same SSDT: under
\_SB.PC00.I2C5, TPD0 seems to use the PXTC power resource, and the
Arg0==0 path in PON() appears to only route/configure IRQ. The Arg0==1
path, apparently for the touch panel PTPL resource, is the one that
toggles TPWR/TRST GPIOs. I have not tested overriding TPD0 to use that
power resource yet.

Question
========

Does this still look like an ACPI GPIO/resource issue, or should I now
focus on an i2c-hid/hid-multitouch quirk or a missing vendor-specific
reset/init sequence for HID 347D:7853?

I have a full debug bundle available, including acpidump, decompiled
SSDTs, dmesg, udev info, evtest output, hid-recorder output,
dmidecode, and /proc/interrupts snapshots. I can provide any specific
files or test patches you want.

Thanks,
Steve

^ permalink raw reply

* Re: [PATCH 00/13] treewide: replace linux/gpio.h
From: Arnd Bergmann @ 2026-06-29 14:24 UTC (permalink / raw)
  To: Andreas Schwab, Arnd Bergmann
  Cc: open list:GPIO SUBSYSTEM, Bartosz Golaszewski, Andrew Lunn,
	Sebastian Hesselbarth, Gregory Clement, Frank Li, Robert Jarzmik,
	Krzysztof Kozlowski, Greg Ungerer, Thomas Bogendoerfer,
	Hauke Mehrtens, Rafał Miłecki, Yoshinori Sato,
	John Paul Adrian Glaubitz, Linus Walleij, Dmitry Torokhov,
	Jakub Kicinski, Paolo Abeni, Dominik Brodowski, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, patches, linux-m68k,
	linux-mips, linux-sh, linux-input, linux-media, Netdev,
	linux-sunxi, linux-phy, linux-rockchip, linux-sound
In-Reply-To: <mvmik71win7.fsf@suse.de>

On Mon, Jun 29, 2026, at 16:01, Andreas Schwab wrote:
> On Jun 29 2026, Arnd Bergmann wrote:
>
>> From: Arnd Bergmann <arnd@arndb.de>
>>
>> The linux/gpio.h header used to be the global definition for the gpio
>> interfaces, with 1100 users back in linux-3.17. In linux-7.2, only about
>> 130 of those remain, so this series cleans out the rest.
>>
>> In each subsystem, we can replace the header either with
>> linux/gpio/consumer.h for users of the modern gpio descriptor interface,
>
> A few of them already used <linux/gpio/consumer.h>, and is duplicated
> now.

Indeed, I have removed the extra ones now and folded those into
the patches.

     Arnd

diff --git a/drivers/gpib/gpio/gpib_bitbang.c b/drivers/gpib/gpio/gpib_bitbang.c
index 2e8d895db06a..34d14b94a0b8 100644
--- a/drivers/gpib/gpio/gpib_bitbang.c
+++ b/drivers/gpib/gpio/gpib_bitbang.c
@@ -64,7 +64,6 @@
 #include <linux/gpio/consumer.h>
 #include <linux/gpio/driver.h>
 #include <linux/gpio/machine.h>
-#include <linux/gpio/consumer.h>
 #include <linux/irq.h>
 
 static int sn7516x_used = 1, sn7516x;
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 98d0269a978f..8863b741d1a3 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -16,7 +16,6 @@
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
 #include <linux/module.h>
-#include <linux/gpio/consumer.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/slab.h>
 #include <linux/of.h>
diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
index eb11bf2e9436..a6c984205123 100644
--- a/drivers/input/misc/soc_button_array.c
+++ b/drivers/input/misc/soc_button_array.c
@@ -15,7 +15,6 @@
 #include <linux/dmi.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio_keys.h>
-#include <linux/gpio/consumer.h>
 #include <linux/platform_device.h>
 
 static bool use_low_level_irq;
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 88c5c52e0e38..5f5adc9c9e83 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -16,7 +16,6 @@
 #include <linux/net_tstamp.h>
 #include <linux/ptp_classify.h>
 #include <linux/ptp_pch.h>
-#include <linux/gpio/consumer.h>
 
 #define PCH_GBE_MAR_ENTRIES		16
 #define PCH_GBE_SHORT_PKT		64
diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c
index a18263d5bb02..06151f207134 100644
--- a/drivers/net/phy/mdio_device.c
+++ b/drivers/net/phy/mdio_device.c
@@ -9,7 +9,6 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/gpio/consumer.h>
-#include <linux/gpio/consumer.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
diff --git a/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c b/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
index d9c06129ed23..171bf097a8b8 100644
--- a/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
+++ b/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
@@ -4,7 +4,6 @@
 #include <linux/delay.h>
 #include <linux/extcon-provider.h>
 #include <linux/gpio/consumer.h>
-#include <linux/gpio/consumer.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index 2233babc0078..1f5dba49ace4 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -12,7 +12,6 @@
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/gpio/consumer.h>
-#include <linux/gpio/consumer.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/mfd/syscon.h>
diff --git a/include/linux/mfd/ti-lmu.h b/include/linux/mfd/ti-lmu.h
index 5040c7d1e1b9..2089ec5124e8 100644
--- a/include/linux/mfd/ti-lmu.h
+++ b/include/linux/mfd/ti-lmu.h
@@ -10,7 +10,6 @@
 #ifndef __MFD_TI_LMU_H__
 #define __MFD_TI_LMU_H__
 
-#include <linux/gpio/consumer.h>
 #include <linux/notifier.h>
 #include <linux/regmap.h>
 #include <linux/gpio/consumer.h>
diff --git a/sound/soc/codecs/cs42l84.c b/sound/soc/codecs/cs42l84.c
index 36c3abc21fed..f2448b4c11fc 100644
--- a/sound/soc/codecs/cs42l84.c
+++ b/sound/soc/codecs/cs42l84.c
@@ -16,7 +16,6 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
-#include <linux/gpio/consumer.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index 8b05d6f9b429..cbed11136935 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -7,7 +7,6 @@
 
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
-#include <linux/gpio/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>

^ permalink raw reply related

* Re: [PATCH 5/6] [v5] leds: gpio: make legacy gpiolib interface optional
From: Andy Shevchenko @ 2026-06-29 15:09 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-gpio, Arnd Bergmann, John Paul Adrian Glaubitz,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
	Dmitry Torokhov, Lee Jones, Pavel Machek, linux-sh, linux-kernel,
	linux-input, linux-leds, Bartosz Golaszewski
In-Reply-To: <20260629130329.1291953-6-arnd@kernel.org>

On Mon, Jun 29, 2026 at 03:03:28PM +0200, Arnd Bergmann wrote:

> There are still a handful of ancient mips/armv5/sh boards that use the
> gpio_led:gpio member to pass an old-style gpio number, but all modern
> users have been converted to gpio descriptors.
> 
> While the CONFIG_GPIOLIB_LEGACY option that guards devm_gpio_request_one()
> and related helpers is currently turned on in all kernel builds,
> the plan is to only enable it on the few platforms that actually
> pass gpio numbers in any platform_data.
> 
> Split out the legacy portion of the platform_data handling into a custom
> helper function that is guarded with in #ifdef block, to allow the
> the leds-gpio driver to compile cleanly when CONFIG_GPIOLIB_LEGACY
> gets turned off. Once the last user is converted, this function can
> be removed.

...

>  	gpiod = devm_gpiod_get_index_optional(dev, NULL, idx, GPIOD_OUT_LOW);
> -	if (IS_ERR(gpiod))
> -		return gpiod;

We can leave these and rather have

	gpiod_set_consumer_name(gpiod, template->name);
	return gpiod;

than introduce irregular pattern.

> -	if (gpiod) {
> +	if (!IS_ERR(gpiod))
>  		gpiod_set_consumer_name(gpiod, template->name);
> -		return gpiod;
> -	}
>  
> -	/*
> -	 * This is the legacy code path for platform code that
> -	 * still uses GPIO numbers. Ultimately we would like to get
> -	 * rid of this block completely.
> -	 */
> +	return gpiod;
> +}

I haven't insisted on this previously as I thought that this was on track to be
applied. Since it's not (yet), please, amend the change.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Re: [PATCH] [RFC] gpiolib: introduce gpio_name() helper
From: Andy Shevchenko @ 2026-06-29 15:23 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Linus Walleij, Bartosz Golaszewski, Arnd Bergmann,
	Marcel Holtmann, MyungJoo Ham, Chanwoo Choi, Geert Uytterhoeven,
	Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, linux-bluetooth,
	linux-kernel, linux-gpio, dri-devel, linux-i2c, linux-iio,
	linux-input, linux-mmc, linux-arm-kernel, linux-pm, linux-usb
In-Reply-To: <20260629135917.1308621-1-arnd@kernel.org>

On Mon, Jun 29, 2026 at 03:56:29PM +0200, Arnd Bergmann wrote:

> Most remaining users of desc_to_gpio() only call it for printing debug
> information.
> 
> Replace this with a new gpiod_name() helper that returns the
> gpio_desc->name string after checking the gpio_desc pointer.

Oh, that's nice!

...

> +/**
> + * gpiod_name() - get a name to print for a gpio descriptor
> + * @desc: gpio or NULL pointer to query
> + *
> + * Returns:
> + * The desc->name field or a dummy string for unknown GPIOs.
> + */
> +const char *gpiod_name(const struct gpio_desc *desc)
> +{
> +	return desc ? desc->name : "(no gpio)";

Can we get into here with wrong (error pointer descriptor)? Shouldn't you call
one of validate_desc() / VALIDATE_DESC()?

Also not sure if "(no gpio)" is a good choice. "not requested"? "not provided"?

> +}

...

> +static inline const char *gpiod_name(const struct gpio_desc *desc)
> +{
> +	WARN_ON(desc);
> +	return "(no gpio)";

Hmm... This will be a second copy with a slight potential of going apart from
the other case. Perhaps a #define? (Yes, yes, I understand that there are pros
and cons, in particular readability with define is questionable.)

> +}

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* [PATCH v2] HID: hiddev: keep state alive through disconnect unlock
From: Yousef Alhouseen @ 2026-06-29 15:29 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires
  Cc: linux-input, linux-usb, linux-kernel, stable,
	syzbot+563191a4939ddbfe73d4, Yousef Alhouseen

mutex_unlock() clears the mutex owner before taking its wait lock. A
thread spinning in the final hiddev file release can acquire
existancelock after hiddev_disconnect() clears the owner, then free
hiddev before the disconnecting thread reaches the mutex wait lock. This
causes a use-after-free in the mutex slow unlock path.

Give the connection and each open file an explicit reference. Drop each
reference only after its existancelock critical section has completed,
so neither unlock path can free the mutex while the other is still using
it.

Fixes: 079034073faf ("HID: hiddev cleanup -- handle all error conditions properly")
Reported-by: syzbot+563191a4939ddbfe73d4@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=563191a4939ddbfe73d4
Cc: stable@vger.kernel.org
Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
---
Changes in v2:
- Explain the mutex owner-clear/spinning-contender race in the commit log.
- No code changes.

 drivers/hid/usbhid/hiddev.c | 37 +++++++++++++++++++------------------
 include/linux/hiddev.h      |  2 ++
 2 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 6378801b22c6..21396481995b 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -46,6 +46,12 @@ struct hiddev_list {
 	struct mutex thread_lock;
 };
 
+static void hiddev_put(struct hiddev *hiddev)
+{
+	if (refcount_dec_and_test(&hiddev->refcount))
+		kfree(hiddev);
+}
+
 /*
  * Find a report, given the report's type and ID.  The ID can be specified
  * indirectly by REPORT_ID_FIRST (which returns the first report of the given
@@ -216,26 +222,21 @@ static int hiddev_fasync(int fd, struct file *file, int on)
 static int hiddev_release(struct inode * inode, struct file * file)
 {
 	struct hiddev_list *list = file->private_data;
+	struct hiddev *hiddev = list->hiddev;
 	unsigned long flags;
 
-	spin_lock_irqsave(&list->hiddev->list_lock, flags);
+	spin_lock_irqsave(&hiddev->list_lock, flags);
 	list_del(&list->node);
-	spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
+	spin_unlock_irqrestore(&hiddev->list_lock, flags);
 
-	mutex_lock(&list->hiddev->existancelock);
-	if (!--list->hiddev->open) {
-		if (list->hiddev->exist) {
-			hid_hw_close(list->hiddev->hid);
-			hid_hw_power(list->hiddev->hid, PM_HINT_NORMAL);
-		} else {
-			mutex_unlock(&list->hiddev->existancelock);
-			kfree(list->hiddev);
-			vfree(list);
-			return 0;
-		}
+	mutex_lock(&hiddev->existancelock);
+	if (!--hiddev->open && hiddev->exist) {
+		hid_hw_close(hiddev->hid);
+		hid_hw_power(hiddev->hid, PM_HINT_NORMAL);
 	}
 
-	mutex_unlock(&list->hiddev->existancelock);
+	mutex_unlock(&hiddev->existancelock);
+	hiddev_put(hiddev);
 	vfree(list);
 
 	return 0;
@@ -270,6 +271,7 @@ static int __hiddev_open(struct hiddev *hiddev, struct file *file)
 	spin_unlock_irq(&hiddev->list_lock);
 
 	file->private_data = list;
+	refcount_inc(&hiddev->refcount);
 
 	return 0;
 
@@ -897,6 +899,7 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
 	INIT_LIST_HEAD(&hiddev->list);
 	spin_lock_init(&hiddev->list_lock);
 	mutex_init(&hiddev->existancelock);
+	refcount_set(&hiddev->refcount, 1);
 	hid->hiddev = hiddev;
 	hiddev->hid = hid;
 	hiddev->exist = 1;
@@ -937,9 +940,7 @@ void hiddev_disconnect(struct hid_device *hid)
 	if (hiddev->open) {
 		hid_hw_close(hiddev->hid);
 		wake_up_interruptible(&hiddev->wait);
-		mutex_unlock(&hiddev->existancelock);
-	} else {
-		mutex_unlock(&hiddev->existancelock);
-		kfree(hiddev);
 	}
+	mutex_unlock(&hiddev->existancelock);
+	hiddev_put(hiddev);
 }
diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h
index 2164c03d2c72..8e9f8a33e359 100644
--- a/include/linux/hiddev.h
+++ b/include/linux/hiddev.h
@@ -13,6 +13,7 @@
 #ifndef _HIDDEV_H
 #define _HIDDEV_H
 
+#include <linux/refcount.h>
 #include <uapi/linux/hiddev.h>
 
 
@@ -24,6 +25,7 @@ struct hiddev {
 	int minor;
 	int exist;
 	int open;
+	refcount_t refcount;
 	struct mutex existancelock;
 	wait_queue_head_t wait;
 	struct hid_device *hid;
-- 
2.54.0

^ permalink raw reply related

* Re: [PATCH] [RFC] gpiolib: introduce gpio_name() helper
From: Geert Uytterhoeven @ 2026-06-29 15:29 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Linus Walleij, Bartosz Golaszewski, Arnd Bergmann,
	Marcel Holtmann, MyungJoo Ham, Chanwoo Choi, Geert Uytterhoeven,
	Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, linux-bluetooth,
	linux-kernel, linux-gpio, dri-devel, linux-i2c, linux-iio,
	linux-input, linux-mmc, linux-arm-kernel, linux-pm, linux-usb
In-Reply-To: <20260629135917.1308621-1-arnd@kernel.org>

Hi Arnd,

On Mon, 29 Jun 2026 at 15:59, Arnd Bergmann <arnd@kernel.org> wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> Most remaining users of desc_to_gpio() only call it for printing debug
> information.
>
> Replace this with a new gpiod_name() helper that returns the
> gpio_desc->name string after checking the gpio_desc pointer.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>

Thanks for your patch!

> Not sure if this the way we want to take this, or if the gpio name is
> an appropriate replacement in debug printk.
>
> Since most of the callers of desc_to_gpio() and gpio_to_desc() are
> otherwise in drivers that already depend on CONFIG_GPIOLIB_LEGACY and
> include linux/gpio/legacy.h, only a handful of instances remain that
> are otherwise in files that otherwise only use the descriptor interfaces:

> --- a/drivers/gpio/gpio-aggregator.c
> +++ b/drivers/gpio/gpio-aggregator.c
> @@ -758,8 +758,8 @@ int gpiochip_fwd_desc_add(struct gpiochip_fwd *fwd, struct gpio_desc *desc,
>
>         fwd->descs[offset] = desc;
>
> -       dev_dbg(chip->parent, "%u => gpio %d irq %d\n", offset,
> -               desc_to_gpio(desc), gpiod_to_irq(desc));
> +       dev_dbg(chip->parent, "%u => gpio %s irq %d\n", offset,
> +               gpiod_name(desc), gpiod_to_irq(desc));
>
>         return 0;
>  }

Before, this printed:

    gpio-aggregator gpio-aggregator.1: 0 => gpio 589 irq 188
    gpio-aggregator gpio-aggregator.1: 1 => gpio 590 irq 189

After, this prints:

    gpio-aggregator gpio-aggregator.1: 0 => gpio (null) irq 188
    gpio-aggregator gpio-aggregator.1: 1 => gpio (null) irq 189

Same results for instantiation using sysfs or configfs[1], although
the latter does have optional support for specifying the name.

[1] Documentation/admin-guide/gpio/gpio-aggregator.rst

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH] [RFC] gpiolib: introduce gpio_name() helper
From: Arnd Bergmann @ 2026-06-29 15:45 UTC (permalink / raw)
  To: Andy Shevchenko, Arnd Bergmann
  Cc: Linus Walleij, Bartosz Golaszewski, Marcel Holtmann, MyungJoo Ham,
	Chanwoo Choi, Geert Uytterhoeven, Andy Shevchenko,
	Dmitry Torokhov, Ulf Hansson, linux-bluetooth, linux-kernel,
	open list:GPIO SUBSYSTEM, dri-devel, linux-i2c, linux-iio,
	linux-input, linux-mmc @ vger . kernel . org, linux-arm-kernel,
	linux-pm, linux-usb
In-Reply-To: <akKN59lv55CXS3HU@ashevche-desk.local>

On Mon, Jun 29, 2026, at 17:23, Andy Shevchenko wrote:
> On Mon, Jun 29, 2026 at 03:56:29PM +0200, Arnd Bergmann wrote:
>> +const char *gpiod_name(const struct gpio_desc *desc)
>> +{
>> +	return desc ? desc->name : "(no gpio)";
>
> Can we get into here with wrong (error pointer descriptor)? Shouldn't you call
> one of validate_desc() / VALIDATE_DESC()?

Since all the callers previously call desc_to_gpio and that does
not even check desc at all, it would be a preexisting bug if
any caller passed an error pointer.

I added the NULL pointer check since many callers had that
part originally, like

      tsdata->wake_gpio ? desc_to_gpio(tsdata->wake_gpio) : -1,

> Also not sure if "(no gpio)" is a good choice. "not requested"? "not provided"?

Any of those seem fine to me, not sure.

>> +static inline const char *gpiod_name(const struct gpio_desc *desc)
>> +{
>> +	WARN_ON(desc);
>> +	return "(no gpio)";
>
> Hmm... This will be a second copy with a slight potential of going apart from
> the other case. Perhaps a #define? (Yes, yes, I understand that there are pros
> and cons, in particular readability with define is questionable.)

I was mostly trying to optimize for consistency with the other
stub functions here. Since it should not actually be used at all
without gpiolib, returning NULL or an empty string here would
also work.

     Arnd

^ permalink raw reply

* Re: [PATCH] [RFC] gpiolib: introduce gpio_name() helper
From: Arnd Bergmann @ 2026-06-29 15:48 UTC (permalink / raw)
  To: Geert Uytterhoeven, Arnd Bergmann
  Cc: Linus Walleij, Bartosz Golaszewski, Marcel Holtmann, MyungJoo Ham,
	Chanwoo Choi, Geert Uytterhoeven, Andy Shevchenko,
	Dmitry Torokhov, Ulf Hansson, linux-bluetooth, linux-kernel,
	open list:GPIO SUBSYSTEM, dri-devel, linux-i2c, linux-iio,
	linux-input, linux-mmc @ vger . kernel . org, linux-arm-kernel,
	linux-pm, linux-usb
In-Reply-To: <CAMuHMdXhsM4JzArRuB=A46N-Ogbn2Fans+PVJVA-hEytFq=DeQ@mail.gmail.com>

On Mon, Jun 29, 2026, at 17:29, Geert Uytterhoeven wrote:
> On Mon, 29 Jun 2026 at 15:59, Arnd Bergmann <arnd@kernel.org> wrote:
>> From: Arnd Bergmann <arnd@arndb.de>
>>
>> Most remaining users of desc_to_gpio() only call it for printing debug
>> information.
>>
>> Replace this with a new gpiod_name() helper that returns the
>> gpio_desc->name string after checking the gpio_desc pointer.
>>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>
> Thanks for your patch!

Thanks for testing!

>> --- a/drivers/gpio/gpio-aggregator.c
>> +++ b/drivers/gpio/gpio-aggregator.c
>> @@ -758,8 +758,8 @@ int gpiochip_fwd_desc_add(struct gpiochip_fwd *fwd, struct gpio_desc *desc,
>>
>>         fwd->descs[offset] = desc;
>>
>> -       dev_dbg(chip->parent, "%u => gpio %d irq %d\n", offset,
>> -               desc_to_gpio(desc), gpiod_to_irq(desc));
>> +       dev_dbg(chip->parent, "%u => gpio %s irq %d\n", offset,
>> +               gpiod_name(desc), gpiod_to_irq(desc));
>>
>>         return 0;
>>  }
>
> Before, this printed:
>
>     gpio-aggregator gpio-aggregator.1: 0 => gpio 589 irq 188
>     gpio-aggregator gpio-aggregator.1: 1 => gpio 590 irq 189
>
> After, this prints:
>
>     gpio-aggregator gpio-aggregator.1: 0 => gpio (null) irq 188
>     gpio-aggregator gpio-aggregator.1: 1 => gpio (null) irq 189
>
> Same results for instantiation using sysfs or configfs[1], although
> the latter does have optional support for specifying the name.

I wonder how many of the other instances have the same problem
then. Would it be appropriate for gpiochip_fwd_desc_add() to set
a name itself to address this one?

       Arnd

^ permalink raw reply

* Re: (subset) [PATCH v5 0/6] Add support for Baijie Helper A133 board
From: Chen-Yu Tsai @ 2026-06-29 15:51 UTC (permalink / raw)
  To: linux-arm-kernel, linux-sunxi, Alexander Sverdlin
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jernej Skrabec,
	Samuel Holland, Hans de Goede, Dmitry Torokhov, Andre Przywara,
	Jun Yan, Lukas Schmid, J. Neuschäfer, Eric Biggers,
	Michal Simek, Luca Weiss, Sven Peter, Maxime Ripard, devicetree,
	linux-kernel, linux-input
In-Reply-To: <20260623204824.691832-1-alexander.sverdlin@gmail.com>

On Tue, 23 Jun 2026 22:48:12 +0200, Alexander Sverdlin wrote:
> Baijie Helper A133 board is a development board around Baijie A133 Core
> SBC. Features:
> 
> - 1/2/4GiB LPDDR4 DRAM
> - 8/16/32GiB eMMC
> - AXP707 PMIC
> - USB-C OTG port in peripheral mode (via onboard hub)
> - 2 USB 2.0 ports
> - MicroSD slot and on-board eMMC module
> - Gigabit Ethernet
> - Bluetooth
> - WiFi
> 
> [...]

Applied to sunxi/config-for-7.3 in local tree, thanks!

[1/6] arm64: defconfig: Enable Allwinner LRADC input driver
      commit: b4158103c45386ab30ba7624bee17ebf33940baa

Best regards,
-- 
Chen-Yu Tsai <wens@kernel.org>


^ permalink raw reply

* Re: [PATCH v2] HID: hiddev: keep state alive through disconnect unlock
From: sashiko-bot @ 2026-06-29 15:54 UTC (permalink / raw)
  To: Yousef Alhouseen; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260629152947.13821-1-alhouseenyousef@gmail.com>

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

Pre-existing issues:
- [High] A race condition in `hiddev_connect()` exposes the character device before initialization is complete, allowing bypass of `HID_QUIRK_NO_INIT_REPORTS`.
- [Medium] Runtime PM reference on the USB interface is leaked when the device is unbound while a hiddev file is open.
- [Low] An off-by-one error in the `array_index_nospec()` clamping logic prevents reading the last valid usage index during `HIDIOCGUSAGES`.
--

commit afdbfd4c2b634bf186c79d8a144039cac66bc1c8
Author: Yousef Alhouseen <alhouseenyousef@gmail.com>

HID: hiddev: keep state alive through disconnect unlock

This commit fixes a use-after-free issue in the hiddev mutex slow unlock
path. It gives the connection and each open file an explicit reference,
dropping the reference only after the existancelock critical section
completes.

Link: https://syzkaller.appspot.com/bug?extid=563191a4939ddbfe73d4

> diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
> index 6378801b22c6d..21396481995b2 100644
> --- a/drivers/hid/usbhid/hiddev.c
> +++ b/drivers/hid/usbhid/hiddev.c
[ ... ]
> @@ -216,26 +222,21 @@ static int hiddev_fasync(int fd, struct file *file, int on)
>  static int hiddev_release(struct inode * inode, struct file * file)
>  {
>  	struct hiddev_list *list = file->private_data;
> +	struct hiddev *hiddev = list->hiddev;
>  	unsigned long flags;
>  
> -	spin_lock_irqsave(&list->hiddev->list_lock, flags);
> +	spin_lock_irqsave(&hiddev->list_lock, flags);
>  	list_del(&list->node);
> -	spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
> +	spin_unlock_irqrestore(&hiddev->list_lock, flags);
>  
> -	mutex_lock(&list->hiddev->existancelock);
> -	if (!--list->hiddev->open) {
> -		if (list->hiddev->exist) {
> -			hid_hw_close(list->hiddev->hid);
> -			hid_hw_power(list->hiddev->hid, PM_HINT_NORMAL);
> -		} else {
> -			mutex_unlock(&list->hiddev->existancelock);
> -			kfree(list->hiddev);
> -			vfree(list);
> -			return 0;
> -		}
> +	mutex_lock(&hiddev->existancelock);
> +	if (!--hiddev->open && hiddev->exist) {
> +		hid_hw_close(hiddev->hid);
> +		hid_hw_power(hiddev->hid, PM_HINT_NORMAL);
>  	}

[Severity: Medium]
This is a pre-existing issue, but does this create a runtime PM reference leak
when the device is unbound while a hiddev file is open?

If a device unbind occurs while the file remains open, hiddev_disconnect()
clears hiddev->exist. When hiddev_release() is subsequently called, the
code avoids the hid_hw_power() call because hiddev->exist is 0.

Since the disconnect path does not call hid_hw_power() with PM_HINT_NORMAL,
could this leave the power domain permanently active and defeat USB autosuspend
until physical unplug?

>  
> -	mutex_unlock(&list->hiddev->existancelock);
> +	mutex_unlock(&hiddev->existancelock);
> +	hiddev_put(hiddev);
>  	vfree(list);
>  
>  	return 0;
[ ... ]
> @@ -897,6 +899,7 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
>  	INIT_LIST_HEAD(&hiddev->list);
>  	spin_lock_init(&hiddev->list_lock);
>  	mutex_init(&hiddev->existancelock);
> +	refcount_set(&hiddev->refcount, 1);
>  	hid->hiddev = hiddev;
>  	hiddev->hid = hid;
>  	hiddev->exist = 1;

[Severity: High]
This is a pre-existing issue, but does this create a race condition exposing
the character device before initialization is complete?

Shortly after this block, hiddev_connect() calls usb_register_dev() which
makes the device available to userspace. However, hiddev->initialized is set
later based on HID_QUIRK_NO_INIT_REPORTS.

If a userspace process immediately opens the newly registered device and
issues a HIDIOCGUSAGE ioctl before hiddev->initialized is set, could it
bypass the quirk and improperly trigger usbhid_init_reports() in
hiddev_ioctl()?

[ ... ]
> @@ -937,9 +940,7 @@ void hiddev_disconnect(struct hid_device *hid)
>  	if (hiddev->open) {
>  		hid_hw_close(hiddev->hid);
>  		wake_up_interruptible(&hiddev->wait);
> -		mutex_unlock(&hiddev->existancelock);
> -	} else {
> -		mutex_unlock(&hiddev->existancelock);
> -		kfree(hiddev);
>  	}
> +	mutex_unlock(&hiddev->existancelock);
> +	hiddev_put(hiddev);
>  }

[Severity: Low]
This is a pre-existing issue, but is there an off-by-one error in the clamping
logic within hiddev_ioctl_usage() that prevents reading the last valid usage
index?

When a user issues HIDIOCGUSAGES or HIDIOCSUSAGES, the code does:

	uref->usage_index =
		array_index_nospec(uref->usage_index,
				   field->report_count -
				   uref_multi->num_values);

Because array_index_nospec() strictly requires the index to be less than the
size, does an index exactly equal to the size (which is valid here) get
incorrectly clamped to 0?

Would this silently return the first block of usages instead of the last
valid block?

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

^ permalink raw reply

* Re: [PATCH 5/6] [v5] leds: gpio: make legacy gpiolib interface optional
From: Arnd Bergmann @ 2026-06-29 15:58 UTC (permalink / raw)
  To: Andy Shevchenko, Arnd Bergmann
  Cc: open list:GPIO SUBSYSTEM, John Paul Adrian Glaubitz,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
	Dmitry Torokhov, Lee Jones, Pavel Machek, linux-sh, linux-kernel,
	linux-input, linux-leds, Bartosz Golaszewski
In-Reply-To: <akKKxHB6RMymG70Z@ashevche-desk.local>

On Mon, Jun 29, 2026, at 17:09, Andy Shevchenko wrote:
> On Mon, Jun 29, 2026 at 03:03:28PM +0200, Arnd Bergmann wrote:
>
>>  	gpiod = devm_gpiod_get_index_optional(dev, NULL, idx, GPIOD_OUT_LOW);
>> -	if (IS_ERR(gpiod))
>> -		return gpiod;
>
> We can leave these and rather have
>
> 	gpiod_set_consumer_name(gpiod, template->name);
> 	return gpiod;
>
> than introduce irregular pattern.
>

Ok, changed now.

      Arnd

^ permalink raw reply

* Re: (subset) [PATCH v5 0/6] Add support for Baijie Helper A133 board
From: Chen-Yu Tsai @ 2026-06-29 16:08 UTC (permalink / raw)
  To: linux-arm-kernel, linux-sunxi, Alexander Sverdlin
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jernej Skrabec,
	Samuel Holland, Hans de Goede, Dmitry Torokhov, Andre Przywara,
	Jun Yan, Lukas Schmid, J. Neuschäfer, Eric Biggers,
	Michal Simek, Luca Weiss, Sven Peter, Maxime Ripard, devicetree,
	linux-kernel, linux-input
In-Reply-To: <20260623204824.691832-1-alexander.sverdlin@gmail.com>

On Tue, 23 Jun 2026 22:48:12 +0200, Alexander Sverdlin wrote:
> Baijie Helper A133 board is a development board around Baijie A133 Core
> SBC. Features:
> 
> - 1/2/4GiB LPDDR4 DRAM
> - 8/16/32GiB eMMC
> - AXP707 PMIC
> - USB-C OTG port in peripheral mode (via onboard hub)
> - 2 USB 2.0 ports
> - MicroSD slot and on-board eMMC module
> - Gigabit Ethernet
> - Bluetooth
> - WiFi
> 
> [...]

Applied to sunxi/dt-for-7.3 in local tree, thanks!

[2/6] dt-bindings: vendor-prefixes: Add Shenzhen Baijie Technology Co., Ltd.
      commit: c3600c97eb9c1a20a933a7fba08272955f7a7ccc
[3/6] dt-bindings: arm: sunxi: Add Baijie HelperBoard A133 compatible
      commit: 1d81cb06c30746448deb73b6ce9ceccc9fb6ca37
[4/6] dt-bindings: input: sun4i-lradc-keys: Add A100/A133 compatible
      commit: 5e5e8a2e5a5e31fbe8858f08ef7ac44dff9ee351
[5/6] arm64: dts: allwinner: a100: Add LRADC node
      commit: 8fa3a2bf77f0adb5440f25c3e2951543691e1536
[6/6] arm64: dts: allwinner: A133: add support for Baijie Helper A133 board
      commit: 7204944dcb8f1131b6303a5e9ca11128eb20ac21

Best regards,
-- 
Chen-Yu Tsai <wens@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