* [PATCH v2 02/10] m68k/coldfire: replace linux/gpio.h inclusions
From: Arnd Bergmann @ 2026-07-10 21:19 UTC (permalink / raw)
To: linux-gpio, Linus Walleij, Bartosz Golaszewski
Cc: Arnd Bergmann, 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, Dmitry Torokhov, Dominik Brodowski,
linux-kernel, linux-arm-kernel, linux-samsung-soc, patches,
linux-m68k, linux-mips, linux-sh, linux-input, linux-sunxi,
linux-phy, linux-rockchip, linux-sound, Bartosz Golaszewski
In-Reply-To: <20260710211954.1373336-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
linux/gpio.h should no longer be used, convert these instead to
linux/gpio/legacy.h for coldfire.
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
arch/m68k/coldfire/device.c | 2 +-
arch/m68k/include/asm/mcfgpio.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/m68k/coldfire/device.c b/arch/m68k/coldfire/device.c
index 1420bae0964f..9a0258acd998 100644
--- a/arch/m68k/coldfire/device.c
+++ b/arch/m68k/coldfire/device.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/spi/spi.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/fec.h>
#include <linux/dmaengine.h>
#include <asm/traps.h>
diff --git a/arch/m68k/include/asm/mcfgpio.h b/arch/m68k/include/asm/mcfgpio.h
index 7103cfa4edb6..29726aa40eb6 100644
--- a/arch/m68k/include/asm/mcfgpio.h
+++ b/arch/m68k/include/asm/mcfgpio.h
@@ -16,7 +16,7 @@ int __mcfgpio_request(unsigned gpio);
void __mcfgpio_free(unsigned gpio);
#ifdef CONFIG_GPIOLIB
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#else
/* our alternate 'gpiolib' functions */
--
2.39.5
^ permalink raw reply related
* [PATCH v2 01/10] ARM: replace linux/gpio.h inclusions
From: Arnd Bergmann @ 2026-07-10 21:19 UTC (permalink / raw)
To: linux-gpio, Linus Walleij, Bartosz Golaszewski
Cc: Arnd Bergmann, 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, Dmitry Torokhov, Dominik Brodowski,
linux-kernel, linux-arm-kernel, linux-samsung-soc, patches,
linux-m68k, linux-mips, linux-sh, linux-input, linux-sunxi,
linux-phy, linux-rockchip, linux-sound, Bartosz Golaszewski, soc
In-Reply-To: <20260710211954.1373336-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
linux/gpio.h should no longer be used, convert these instead to
either linux/gpio/consumer.h or linux/gpio/legacy.h as needed.
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Cc: soc@lists.linux.dev
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/mach-davinci/da850.c | 2 +-
arch/arm/mach-dove/mpp.c | 2 +-
arch/arm/mach-mv78xx0/buffalo-wxl-setup.c | 2 +-
arch/arm/mach-mv78xx0/irq.c | 2 +-
arch/arm/mach-mv78xx0/mpp.c | 2 +-
arch/arm/mach-mvebu/pm.c | 2 +-
arch/arm/mach-mxs/mach-mxs.c | 2 +-
arch/arm/mach-orion5x/board-d2net.c | 2 +-
arch/arm/mach-orion5x/board-rd88f5182.c | 2 +-
arch/arm/mach-orion5x/dns323-setup.c | 2 +-
arch/arm/mach-orion5x/irq.c | 2 +-
arch/arm/mach-orion5x/kurobox_pro-setup.c | 2 +-
arch/arm/mach-orion5x/mv2120-setup.c | 2 +-
arch/arm/mach-orion5x/net2big-setup.c | 2 +-
arch/arm/mach-orion5x/terastation_pro2-setup.c | 2 +-
arch/arm/mach-orion5x/ts209-setup.c | 2 +-
arch/arm/mach-orion5x/ts409-setup.c | 2 +-
arch/arm/mach-pxa/am200epd.c | 2 +-
arch/arm/mach-pxa/am300epd.c | 2 +-
arch/arm/mach-pxa/generic.c | 2 +-
arch/arm/mach-pxa/gumstix.c | 2 +-
arch/arm/mach-pxa/mfp-pxa2xx.c | 2 +-
arch/arm/mach-pxa/pxa25x.c | 2 +-
arch/arm/mach-pxa/pxa27x.c | 2 +-
arch/arm/mach-pxa/reset.c | 2 +-
arch/arm/mach-pxa/sharpsl_pm.c | 2 +-
arch/arm/mach-pxa/spitz.c | 2 +-
arch/arm/mach-pxa/spitz_pm.c | 2 +-
arch/arm/mach-s3c/dev-audio-s3c64xx.c | 2 +-
arch/arm/mach-s3c/devs.c | 2 +-
arch/arm/mach-s3c/mach-crag6410.c | 2 +-
arch/arm/mach-s3c/pm-gpio.c | 2 +-
arch/arm/mach-s3c/pm-s3c64xx.c | 2 +-
arch/arm/mach-s3c/setup-fb-24bpp-s3c64xx.c | 2 +-
arch/arm/mach-s3c/setup-i2c0-s3c64xx.c | 2 +-
arch/arm/mach-s3c/setup-i2c1-s3c64xx.c | 2 +-
arch/arm/mach-s3c/setup-keypad-s3c64xx.c | 2 +-
arch/arm/mach-s3c/setup-sdhci-gpio-s3c64xx.c | 2 +-
arch/arm/mach-s3c/setup-spi-s3c64xx.c | 2 +-
arch/arm/mach-sa1100/collie.c | 2 +-
arch/arm/mach-sa1100/generic.c | 2 +-
arch/arm/mach-sa1100/h3600.c | 2 +-
arch/arm/mach-sa1100/h3xxx.c | 2 +-
arch/arm/plat-orion/mpp.c | 2 +-
44 files changed, 44 insertions(+), 44 deletions(-)
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 706f8241b5e7..611cce70c5bb 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -9,7 +9,7 @@
* 2009 (c) MontaVista Software, Inc.
*/
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/mfd/da8xx-cfgchip.h>
diff --git a/arch/arm/mach-dove/mpp.c b/arch/arm/mach-dove/mpp.c
index 93cb137da5f8..e41bd473abe9 100644
--- a/arch/arm/mach-dove/mpp.c
+++ b/arch/arm/mach-dove/mpp.c
@@ -6,7 +6,7 @@
*/
#include <linux/kernel.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/io.h>
#include <plat/mpp.h>
#include <plat/orion-gpio.h>
diff --git a/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
index 62e982f74bc2..3b2e381b7383 100644
--- a/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
+++ b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
@@ -14,7 +14,7 @@
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <linux/i2c.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <asm/mach-types.h>
diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c
index a34b6855fb19..6e42f6446637 100644
--- a/arch/arm/mach-mv78xx0/irq.c
+++ b/arch/arm/mach-mv78xx0/irq.c
@@ -4,7 +4,7 @@
*
* MV78xx0 IRQ handling.
*/
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/io.h>
diff --git a/arch/arm/mach-mv78xx0/mpp.c b/arch/arm/mach-mv78xx0/mpp.c
index aff0e612cbba..32bf590d79fe 100644
--- a/arch/arm/mach-mv78xx0/mpp.c
+++ b/arch/arm/mach-mv78xx0/mpp.c
@@ -4,7 +4,7 @@
*
* MPP functions for Marvell MV78x00 SoCs
*/
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
diff --git a/arch/arm/mach-mvebu/pm.c b/arch/arm/mach-mvebu/pm.c
index b149d9b77505..616a7fb22d86 100644
--- a/arch/arm/mach-mvebu/pm.c
+++ b/arch/arm/mach-mvebu/pm.c
@@ -9,7 +9,7 @@
#include <linux/cpu_pm.h>
#include <linux/delay.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mbus.h>
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
index f639d5004351..c8231a480052 100644
--- a/arch/arm/mach-mxs/mach-mxs.c
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -9,7 +9,7 @@
#include <linux/clkdev.h>
#include <linux/delay.h>
#include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/reboot.h>
#include <linux/micrel_phy.h>
diff --git a/arch/arm/mach-orion5x/board-d2net.c b/arch/arm/mach-orion5x/board-d2net.c
index 09bf366d05ff..7cf09da9d9e7 100644
--- a/arch/arm/mach-orion5x/board-d2net.c
+++ b/arch/arm/mach-orion5x/board-d2net.c
@@ -13,7 +13,7 @@
#include <linux/pci.h>
#include <linux/irq.h>
#include <linux/leds.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/gpio/machine.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-orion5x/board-rd88f5182.c b/arch/arm/mach-orion5x/board-rd88f5182.c
index 1c14e49a90a6..9e2fe74ec68a 100644
--- a/arch/arm/mach-orion5x/board-rd88f5182.c
+++ b/arch/arm/mach-orion5x/board-rd88f5182.c
@@ -6,7 +6,7 @@
*
* Maintainer: Ronen Shitrit <rshitrit@marvell.com>
*/
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of.h>
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
index fcd38ff7ca45..7b81b08b0dda 100644
--- a/arch/arm/mach-orion5x/dns323-setup.c
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -13,7 +13,7 @@
* License, or (at your option) any later version.
*
*/
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/gpio/machine.h>
#include <linux/kernel.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c
index e17727e53cb4..689bec1ebe89 100644
--- a/arch/arm/mach-orion5x/irq.c
+++ b/arch/arm/mach-orion5x/irq.c
@@ -6,7 +6,7 @@
*
* Maintainer: Tzachi Perelstein <tzachi@marvell.com>
*/
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/io.h>
diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c
index 339b10891808..e61b9ab06943 100644
--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c
+++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c
@@ -4,7 +4,7 @@
*
* Maintainer: Ronen Shitrit <rshitrit@marvell.com>
*/
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
diff --git a/arch/arm/mach-orion5x/mv2120-setup.c b/arch/arm/mach-orion5x/mv2120-setup.c
index 5b0249f109cd..b15fe5b7a0f9 100644
--- a/arch/arm/mach-orion5x/mv2120-setup.c
+++ b/arch/arm/mach-orion5x/mv2120-setup.c
@@ -7,7 +7,7 @@
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*/
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/gpio/machine.h>
#include <linux/kernel.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-orion5x/net2big-setup.c b/arch/arm/mach-orion5x/net2big-setup.c
index 4afd9b4c71a9..f04571e79805 100644
--- a/arch/arm/mach-orion5x/net2big-setup.c
+++ b/arch/arm/mach-orion5x/net2big-setup.c
@@ -17,7 +17,7 @@
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/ata_platform.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/gpio/machine.h>
#include <linux/delay.h>
#include <asm/mach-types.h>
diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c
index a9f01859d101..c3db3376950a 100644
--- a/arch/arm/mach-orion5x/terastation_pro2-setup.c
+++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c
@@ -4,7 +4,7 @@
*
* Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com>
*/
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c
index de9092e992c5..25cd50306c65 100644
--- a/arch/arm/mach-orion5x/ts209-setup.c
+++ b/arch/arm/mach-orion5x/ts209-setup.c
@@ -4,7 +4,7 @@
*
* Maintainer: Byron Bradley <byron.bbradley@gmail.com>
*/
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
diff --git a/arch/arm/mach-orion5x/ts409-setup.c b/arch/arm/mach-orion5x/ts409-setup.c
index 725688aa5cba..f92acef0b45f 100644
--- a/arch/arm/mach-orion5x/ts409-setup.c
+++ b/arch/arm/mach-orion5x/ts409-setup.c
@@ -7,7 +7,7 @@
* Copyright (C) 2008 Sylver Bruneau <sylver.bruneau@gmail.com>
* Copyright (C) 2008 Martin Michlmayr <tbm@cyrius.com>
*/
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/gpio/machine.h>
#include <linux/kernel.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c
index cac0bb09db14..4814f3cfe775 100644
--- a/arch/arm/mach-pxa/am200epd.c
+++ b/arch/arm/mach-pxa/am200epd.c
@@ -28,7 +28,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include "pxa25x.h"
#include "gumstix.h"
diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c
index 4b55bc89db8f..435fb72da7de 100644
--- a/arch/arm/mach-pxa/am300epd.c
+++ b/arch/arm/mach-pxa/am300epd.c
@@ -26,7 +26,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include "gumstix.h"
#include "mfp-pxa25x.h"
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 02fdde7e3e34..f181e7b7c6be 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -13,7 +13,7 @@
* initialization stuff for PXA machines which can be overridden later if
* need be.
*/
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
index 6074815a4bca..7ab0cb015d1b 100644
--- a/arch/arm/mach-pxa/gumstix.c
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -22,7 +22,7 @@
#include <linux/mtd/partitions.h>
#include <linux/gpio/machine.h>
#include <linux/gpio/property.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/err.h>
#include <linux/clk.h>
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
index d1347055fbe4..566fb4e2adba 100644
--- a/arch/arm/mach-pxa/mfp-pxa2xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -9,7 +9,7 @@
* on PXA3xx, what's more important, the low power pin state and
* wakeup detection are also supported by the same framework.
*/
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/gpio-pxa.h>
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index a4e878be004a..a273f0af095e 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -15,7 +15,7 @@
*/
#include <linux/dmaengine.h>
#include <linux/dma/pxa-dma.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/gpio-pxa.h>
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 1d34de7e5fbe..814e0a12f38a 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -10,7 +10,7 @@
*/
#include <linux/dmaengine.h>
#include <linux/dma/pxa-dma.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/gpio-pxa.h>
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c
index 27293549f8ad..49d2e46a1fae 100644
--- a/arch/arm/mach-pxa/reset.c
+++ b/arch/arm/mach-pxa/reset.c
@@ -2,7 +2,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/io.h>
#include <asm/proc-fns.h>
#include <asm/system_misc.h>
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index 71b282b146d0..a611eea70e5a 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -19,7 +19,7 @@
#include <linux/delay.h>
#include <linux/leds.h>
#include <linux/suspend.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/io.h>
#include <asm/mach-types.h>
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 5091b601c4e1..5eaf38243b9e 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -12,7 +12,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/gpio_keys.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/gpio/machine.h>
#include <linux/gpio/property.h>
#include <linux/leds.h>
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 03b4b347f11a..806847c36549 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -10,7 +10,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/gpio-pxa.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
diff --git a/arch/arm/mach-s3c/dev-audio-s3c64xx.c b/arch/arm/mach-s3c/dev-audio-s3c64xx.c
index 7ce119dc3a72..8884374dbcdc 100644
--- a/arch/arm/mach-s3c/dev-audio-s3c64xx.c
+++ b/arch/arm/mach-s3c/dev-audio-s3c64xx.c
@@ -7,7 +7,7 @@
#include <linux/string.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/export.h>
#include "irqs.h"
diff --git a/arch/arm/mach-s3c/devs.c b/arch/arm/mach-s3c/devs.c
index bab2abd8a34a..572b156644bd 100644
--- a/arch/arm/mach-s3c/devs.c
+++ b/arch/arm/mach-s3c/devs.c
@@ -5,7 +5,7 @@
//
// Base Samsung platform device definitions
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
diff --git a/arch/arm/mach-s3c/mach-crag6410.c b/arch/arm/mach-s3c/mach-crag6410.c
index c4040aad1ed3..57176719d8a6 100644
--- a/arch/arm/mach-s3c/mach-crag6410.c
+++ b/arch/arm/mach-s3c/mach-crag6410.c
@@ -15,7 +15,7 @@
#include <linux/io.h>
#include <linux/init.h>
#include <linux/input-event-codes.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/gpio/machine.h>
#include <linux/leds.h>
#include <linux/delay.h>
diff --git a/arch/arm/mach-s3c/pm-gpio.c b/arch/arm/mach-s3c/pm-gpio.c
index cfdbc2337998..fd5897cc26c7 100644
--- a/arch/arm/mach-s3c/pm-gpio.c
+++ b/arch/arm/mach-s3c/pm-gpio.c
@@ -11,7 +11,7 @@
#include <linux/device.h>
#include <linux/init.h>
#include <linux/io.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include "gpio-samsung.h"
diff --git a/arch/arm/mach-s3c/pm-s3c64xx.c b/arch/arm/mach-s3c/pm-s3c64xx.c
index 284d5f462513..a73b8bd12949 100644
--- a/arch/arm/mach-s3c/pm-s3c64xx.c
+++ b/arch/arm/mach-s3c/pm-s3c64xx.c
@@ -11,7 +11,7 @@
#include <linux/suspend.h>
#include <linux/serial_core.h>
#include <linux/io.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/pm_domain.h>
#include "map.h"
diff --git a/arch/arm/mach-s3c/setup-fb-24bpp-s3c64xx.c b/arch/arm/mach-s3c/setup-fb-24bpp-s3c64xx.c
index c3269cd6a848..20ae926e12db 100644
--- a/arch/arm/mach-s3c/setup-fb-24bpp-s3c64xx.c
+++ b/arch/arm/mach-s3c/setup-fb-24bpp-s3c64xx.c
@@ -9,7 +9,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include "fb.h"
#include "gpio-cfg.h"
diff --git a/arch/arm/mach-s3c/setup-i2c0-s3c64xx.c b/arch/arm/mach-s3c/setup-i2c0-s3c64xx.c
index a6ef8d2bc995..520e97dc8754 100644
--- a/arch/arm/mach-s3c/setup-i2c0-s3c64xx.c
+++ b/arch/arm/mach-s3c/setup-i2c0-s3c64xx.c
@@ -9,7 +9,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
struct platform_device; /* don't need the contents */
diff --git a/arch/arm/mach-s3c/setup-i2c1-s3c64xx.c b/arch/arm/mach-s3c/setup-i2c1-s3c64xx.c
index 0fe37363d26e..26f7ae455328 100644
--- a/arch/arm/mach-s3c/setup-i2c1-s3c64xx.c
+++ b/arch/arm/mach-s3c/setup-i2c1-s3c64xx.c
@@ -9,7 +9,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
struct platform_device; /* don't need the contents */
diff --git a/arch/arm/mach-s3c/setup-keypad-s3c64xx.c b/arch/arm/mach-s3c/setup-keypad-s3c64xx.c
index 8463ad37c6ab..2e1367878fb1 100644
--- a/arch/arm/mach-s3c/setup-keypad-s3c64xx.c
+++ b/arch/arm/mach-s3c/setup-keypad-s3c64xx.c
@@ -5,7 +5,7 @@
//
// GPIO configuration for S3C64XX KeyPad device
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include "gpio-cfg.h"
#include "keypad.h"
#include "gpio-samsung.h"
diff --git a/arch/arm/mach-s3c/setup-sdhci-gpio-s3c64xx.c b/arch/arm/mach-s3c/setup-sdhci-gpio-s3c64xx.c
index 646ff949acd5..728b66f80493 100644
--- a/arch/arm/mach-s3c/setup-sdhci-gpio-s3c64xx.c
+++ b/arch/arm/mach-s3c/setup-sdhci-gpio-s3c64xx.c
@@ -11,7 +11,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include "gpio-cfg.h"
#include "sdhci.h"
diff --git a/arch/arm/mach-s3c/setup-spi-s3c64xx.c b/arch/arm/mach-s3c/setup-spi-s3c64xx.c
index 497aff71c29c..8d15b13ed7d5 100644
--- a/arch/arm/mach-s3c/setup-spi-s3c64xx.c
+++ b/arch/arm/mach-s3c/setup-spi-s3c64xx.c
@@ -3,7 +3,7 @@
// Copyright (C) 2011 Samsung Electronics Ltd.
// http://www.samsung.com/
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/platform_data/spi-s3c64xx.h>
#include "gpio-cfg.h"
#include "gpio-samsung.h"
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 466d755d5702..af9c68b2093e 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -29,7 +29,7 @@
#include <linux/timer.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/gpio/machine.h>
#include <linux/power/gpio-charger.h>
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 99ff55e8131d..a995625ab1a0 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -6,7 +6,7 @@
*
* Code common to all SA11x0 machines.
*/
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index 1cfc0b1fa41c..59e9251a138e 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -8,7 +8,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <video/sa1100fb.h>
diff --git a/arch/arm/mach-sa1100/h3xxx.c b/arch/arm/mach-sa1100/h3xxx.c
index d685f03f51f3..b8fc1953db9f 100644
--- a/arch/arm/mach-sa1100/h3xxx.c
+++ b/arch/arm/mach-sa1100/h3xxx.c
@@ -8,7 +8,7 @@
#include <linux/kernel.h>
#include <linux/gpio/machine.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/mtd/mtd.h>
diff --git a/arch/arm/plat-orion/mpp.c b/arch/arm/plat-orion/mpp.c
index 8a6880d528b6..673ecedc721d 100644
--- a/arch/arm/plat-orion/mpp.c
+++ b/arch/arm/plat-orion/mpp.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <plat/orion-gpio.h>
#include <plat/mpp.h>
--
2.39.5
^ permalink raw reply related
* [PATCH v2 00/10] treewide: replace linux/gpio.h
From: Arnd Bergmann @ 2026-07-10 21:19 UTC (permalink / raw)
To: linux-gpio, Linus Walleij, Bartosz Golaszewski
Cc: Arnd Bergmann, 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, Dmitry Torokhov, Dominik Brodowski,
linux-kernel, linux-arm-kernel, linux-samsung-soc, patches,
linux-m68k, linux-mips, linux-sh, linux-input, linux-sunxi,
linux-phy, linux-rockchip, linux-sound
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,
or linux/gpio/legacy.h for the few remaining users of the old number
based interface.
All patches in this series can get applied independently, so my
preference would be for each subsystem maintainer to apply these
directly, with the rest going into the gpio tree at some point.
I've uploaded this to
https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/ config-gpio-legacy-for-7.3
Arnd
v2: dropped two already applied patches,
removed duplicate includes,
dropped final patch to remove linux/gpio.h as it now depends
on patches in linux-next
arch/arm/mach-davinci/da850.c | 2 +-
arch/arm/mach-dove/mpp.c | 2 +-
arch/arm/mach-mv78xx0/buffalo-wxl-setup.c | 2 +-
arch/arm/mach-mv78xx0/irq.c | 2 +-
arch/arm/mach-mv78xx0/mpp.c | 2 +-
arch/arm/mach-mvebu/pm.c | 2 +-
arch/arm/mach-mxs/mach-mxs.c | 2 +-
arch/arm/mach-orion5x/board-d2net.c | 2 +-
arch/arm/mach-orion5x/board-rd88f5182.c | 2 +-
arch/arm/mach-orion5x/dns323-setup.c | 2 +-
arch/arm/mach-orion5x/irq.c | 2 +-
arch/arm/mach-orion5x/kurobox_pro-setup.c | 2 +-
arch/arm/mach-orion5x/mv2120-setup.c | 2 +-
arch/arm/mach-orion5x/net2big-setup.c | 2 +-
arch/arm/mach-orion5x/terastation_pro2-setup.c | 2 +-
arch/arm/mach-orion5x/ts209-setup.c | 2 +-
arch/arm/mach-orion5x/ts409-setup.c | 2 +-
arch/arm/mach-pxa/am200epd.c | 2 +-
arch/arm/mach-pxa/am300epd.c | 2 +-
arch/arm/mach-pxa/generic.c | 2 +-
arch/arm/mach-pxa/gumstix.c | 2 +-
arch/arm/mach-pxa/mfp-pxa2xx.c | 2 +-
arch/arm/mach-pxa/pxa25x.c | 2 +-
arch/arm/mach-pxa/pxa27x.c | 2 +-
arch/arm/mach-pxa/reset.c | 2 +-
arch/arm/mach-pxa/sharpsl_pm.c | 2 +-
arch/arm/mach-pxa/spitz.c | 2 +-
arch/arm/mach-pxa/spitz_pm.c | 2 +-
arch/arm/mach-s3c/dev-audio-s3c64xx.c | 2 +-
arch/arm/mach-s3c/devs.c | 2 +-
arch/arm/mach-s3c/mach-crag6410.c | 2 +-
arch/arm/mach-s3c/pm-gpio.c | 2 +-
arch/arm/mach-s3c/pm-s3c64xx.c | 2 +-
arch/arm/mach-s3c/setup-fb-24bpp-s3c64xx.c | 2 +-
arch/arm/mach-s3c/setup-i2c0-s3c64xx.c | 2 +-
arch/arm/mach-s3c/setup-i2c1-s3c64xx.c | 2 +-
arch/arm/mach-s3c/setup-keypad-s3c64xx.c | 2 +-
arch/arm/mach-s3c/setup-sdhci-gpio-s3c64xx.c | 2 +-
arch/arm/mach-s3c/setup-spi-s3c64xx.c | 2 +-
arch/arm/mach-sa1100/collie.c | 2 +-
arch/arm/mach-sa1100/generic.c | 2 +-
arch/arm/mach-sa1100/h3600.c | 2 +-
arch/arm/mach-sa1100/h3xxx.c | 2 +-
arch/arm/plat-orion/mpp.c | 2 +-
arch/m68k/coldfire/device.c | 2 +-
arch/m68k/include/asm/mcfgpio.h | 2 +-
arch/mips/alchemy/board-xxs1500.c | 2 +-
arch/mips/alchemy/devboards/db1000.c | 2 +-
arch/mips/alchemy/devboards/db1200.c | 2 +-
arch/mips/alchemy/devboards/db1550.c | 2 +-
arch/mips/bcm47xx/workarounds.c | 2 +-
arch/mips/bcm63xx/boards/board_bcm963xx.c | 1 +
arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 2 +-
arch/mips/txx9/rbtx4927/setup.c | 2 +-
arch/sh/boards/board-magicpanelr2.c | 2 +-
arch/sh/boards/board-sh7757lcr.c | 2 +-
arch/sh/boards/board-urquell.c | 2 +-
arch/sh/boards/mach-ap325rxa/setup.c | 2 +-
arch/sh/boards/mach-ecovec24/setup.c | 2 +-
arch/sh/boards/mach-highlander/pinmux-r7785rp.c | 2 +-
arch/sh/boards/mach-kfr2r09/lcd_wqvga.c | 2 +-
arch/sh/boards/mach-kfr2r09/setup.c | 2 +-
arch/sh/boards/mach-migor/lcd_qvga.c | 2 +-
arch/sh/boards/mach-migor/setup.c | 2 +-
arch/sh/boards/mach-rsk/devices-rsk7203.c | 2 +-
arch/sh/boards/mach-rsk/devices-rsk7269.c | 1 -
arch/sh/boards/mach-se/7724/setup.c | 2 +-
arch/sh/include/mach-common/mach/magicpanelr2.h | 2 --
arch/sh/kernel/cpu/sh4a/setup-shx3.c | 2 +-
drivers/gpib/gpio/gpib_bitbang.c | 1 -
drivers/input/keyboard/matrix_keypad.c | 1 -
drivers/mfd/aat2870-core.c | 2 +-
drivers/mfd/arizona-irq.c | 2 +-
drivers/mfd/lp3943.c | 2 +-
drivers/mfd/sm501.c | 2 +-
drivers/mfd/tps6105x.c | 2 +-
drivers/mfd/tps65911-comparator.c | 2 +-
drivers/mfd/wm8994-irq.c | 2 +-
drivers/pcmcia/bcm63xx_pcmcia.c | 2 +-
drivers/pcmcia/db1xxx_ss.c | 2 +-
drivers/pcmcia/sa1100_h3600.c | 2 +-
drivers/pcmcia/soc_common.c | 2 +-
drivers/pcmcia/xxs1500_ss.c | 2 +-
drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c | 1 -
drivers/phy/rockchip/phy-rockchip-usbdp.c | 2 +-
drivers/phy/ti/phy-j721e-wiz.c | 1 -
include/linux/mfd/lp3943.h | 2 +-
include/linux/mfd/ti-lmu.h | 1 -
include/linux/mfd/tps65910.h | 2 +-
include/linux/mfd/ucb1x00.h | 2 +-
sound/soc/codecs/cs42l84.c | 1 -
sound/soc/codecs/cx2072x.c | 2 +-
sound/soc/codecs/dmic.c | 1 -
93 files changed, 84 insertions(+), 93 deletions(-)
--
2.39.5
Cc: Bartosz Golaszewski <brgl@kernel.org>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Cc: Gregory Clement <gregory.clement@bootlin.com>
Cc: Frank Li <Frank.Li@nxp.com>
Cc: Robert Jarzmik <robert.jarzmik@free.fr>
Cc: Krzysztof Kozlowski <krzk@kernel.org>
Cc: Greg Ungerer <gerg@linux-m68k.org>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Hauke Mehrtens <hauke@hauke-m.de>
Cc: "Rafał Miłecki" <zajec5@gmail.com>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Cc: Linus Walleij <linusw@kernel.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-samsung-soc@vger.kernel.org
Cc: patches@opensource.cirrus.com
Cc: linux-m68k@lists.linux-m68k.org
Cc: linux-mips@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Cc: linux-gpio@vger.kernel.org
Cc: linux-input@vger.kernel.org
Cc: linux-sunxi@lists.linux.dev
Cc: linux-phy@lists.infradead.org
Cc: linux-rockchip@lists.infradead.org
Cc: linux-sound@vger.kernel.org
^ permalink raw reply
* [PATCH 6/6] [v6] gpiolib: turn off legacy interface by default
From: Arnd Bergmann @ 2026-07-10 21:18 UTC (permalink / raw)
To: linux-gpio, Linus Walleij, Bartosz Golaszewski
Cc: Arnd Bergmann, John Paul Adrian Glaubitz, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Dmitry Torokhov, Lee Jones, Pavel Machek, linux-sh, linux-kernel,
linux-input, linux-leds, Bartosz Golaszewski
In-Reply-To: <20260710211854.1371746-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
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.
Allow turning it on manually for compile testing, in order to keep
the build coverage of the legacy drivers in allmodconfig and
randconfig.
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> # for input
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v5: added patch, now that we are getting closer to completing
the series
---
drivers/gpio/Kconfig | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 28cf6d2e83c2..f063bdfd111b 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
+ 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.
config HAVE_SHARED_GPIOS
bool
--
2.39.5
^ permalink raw reply related
* [PATCH 5/6] [v6] x86/olpc: select GPIOLIB_LEGACY
From: Arnd Bergmann @ 2026-07-10 21:18 UTC (permalink / raw)
To: linux-gpio, Linus Walleij, Bartosz Golaszewski
Cc: Arnd Bergmann, John Paul Adrian Glaubitz, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Dmitry Torokhov, Lee Jones, Pavel Machek, linux-sh, linux-kernel,
linux-input, linux-leds, Takashi Iwai, Bartosz Golaszewski
In-Reply-To: <20260710211854.1371746-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
The OLPC GPIO controller sets up a fixed number space that is used
by at least two drivers:
arch/x86/platform/olpc/olpc-xo1-sci.c: In function 'setup_ec_sci':
arch/x86/platform/olpc/olpc-xo1-sci.c:358:13: error: implicit declaration of function 'gpio_request' [-Wimplicit-function-declaration]
358 | r = gpio_request(OLPC_GPIO_ECSCI, "OLPC-ECSCI");
| ^~~~~~~~~~~~
sound/pci/cs5535audio/cs5535audio_olpc.c: In function 'olpc_analog_input':
sound/pci/cs5535audio/cs5535audio_olpc.c:41:9: error: implicit declaration of function 'gpio_set_value'; did you mean 'gpiod_set_value'? [-Wimplicit-function-declaration]
41 | gpio_set_value(OLPC_GPIO_MIC_AC, on);
The AMD Geode platform that this is based on is now marked as
'Orphaned' in Kconfig, and it is likely that there are no XO1
users on modern kernels, but so far there is no consensus on
removing it entirely.
Select CONFIG_GPIOLIB_LEGACY for this platform and make sure the
sound driver portion cannot be compiled without this.
Acked-by: Borislav Petkov (AMD) <bp@alien8.de>
Acked-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> # for input
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v3..v5: no changes
v2: update changelog text
---
arch/x86/Kconfig | 1 +
arch/x86/platform/olpc/olpc-xo1-sci.c | 2 +-
sound/pci/Kconfig | 1 +
sound/pci/cs5535audio/cs5535audio_olpc.c | 2 +-
4 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bdad90f210e4..4ad8a7bbd93d 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2976,6 +2976,7 @@ config OLPC
bool "One Laptop Per Child support"
depends on !X86_PAE
select GPIOLIB
+ select GPIOLIB_LEGACY
select OF
select OF_PROMTREE
select IRQ_DOMAIN
diff --git a/arch/x86/platform/olpc/olpc-xo1-sci.c b/arch/x86/platform/olpc/olpc-xo1-sci.c
index 30751b42d54e..a5b47960ba32 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>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index e0996a9d90b0..6366f72b3667 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -300,6 +300,7 @@ config SND_CS5535AUDIO
tristate "CS5535/CS5536 Audio"
depends on X86_32 || MIPS || COMPILE_TEST
depends on HAS_IOPORT
+ depends on GPIOLIB_LEGACY || !OLPC
select SND_PCM
select SND_AC97_CODEC
help
diff --git a/sound/pci/cs5535audio/cs5535audio_olpc.c b/sound/pci/cs5535audio/cs5535audio_olpc.c
index 122170a410d9..cfdcc5bf4341 100644
--- a/sound/pci/cs5535audio/cs5535audio_olpc.c
+++ b/sound/pci/cs5535audio/cs5535audio_olpc.c
@@ -9,7 +9,7 @@
#include <sound/info.h>
#include <sound/control.h>
#include <sound/ac97_codec.h>
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include <asm/olpc.h>
#include "cs5535audio.h"
--
2.39.5
^ permalink raw reply related
* [PATCH 4/6] [v6] sh: select legacy gpiolib interface
From: Arnd Bergmann @ 2026-07-10 21:18 UTC (permalink / raw)
To: linux-gpio, Linus Walleij, Bartosz Golaszewski
Cc: Arnd Bergmann, John Paul Adrian Glaubitz, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Dmitry Torokhov, Lee Jones, Pavel Machek, linux-sh, linux-kernel,
linux-input, linux-leds, Bartosz Golaszewski
In-Reply-To: <20260710211854.1371746-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
Many board files on sh reference the legacy gpiolib interfaces that
are becoming optional. To ensure the boards can keep building, select
CONFIG_GPIOLIB_LEGACY on each of the boards that have one of the
hardcoded calls.
Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> # for input
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v2..v5: no changes. The patch did not make it into v7.2-rc1, so
I'm keeping it with the rest of the series
---
arch/sh/Kconfig | 1 +
arch/sh/boards/Kconfig | 8 ++++++++
arch/sh/boards/mach-highlander/Kconfig | 1 +
arch/sh/boards/mach-rsk/Kconfig | 3 +++
4 files changed, 13 insertions(+)
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index d5795067befa..d60f1d5a94c0 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -462,6 +462,7 @@ config CPU_SUBTYPE_SHX3
select CPU_SHX3
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
select GPIOLIB
+ select GPIOLIB_LEGACY
select PINCTRL
# SH4AL-DSP Processor Support
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 1af93be61b1f..d89b74177233 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -80,6 +80,7 @@ config SH_7724_SOLUTION_ENGINE
select SOLUTION_ENGINE
depends on CPU_SUBTYPE_SH7724
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
imply SND_SOC_AK4642 if SND_SIMPLE_CARD
help
@@ -199,6 +200,7 @@ config SH_SH7757LCR
bool "SH7757LCR"
depends on CPU_SUBTYPE_SH7757
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
config SH_SH7785LCR
@@ -226,6 +228,7 @@ config SH_URQUELL
bool "Urquell"
depends on CPU_SUBTYPE_SH7786
select GPIOLIB
+ select GPIOLIB_LEGACY
select HAVE_PCI
select NO_IOPORT_MAP if !PCI
@@ -233,6 +236,7 @@ config SH_MIGOR
bool "Migo-R"
depends on CPU_SUBTYPE_SH7722
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
help
Select Migo-R if configuring for the SH7722 Migo-R platform
@@ -242,6 +246,7 @@ config SH_AP325RXA
bool "AP-325RXA"
depends on CPU_SUBTYPE_SH7723
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
help
Renesas "AP-325RXA" support.
@@ -251,6 +256,7 @@ config SH_KFR2R09
bool "KFR2R09"
depends on CPU_SUBTYPE_SH7724
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
help
"Kit For R2R for 2009" support.
@@ -259,6 +265,7 @@ config SH_ECOVEC
bool "EcoVec"
depends on CPU_SUBTYPE_SH7724
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
imply SND_SOC_DA7210 if SND_SIMPLE_CARD
help
@@ -329,6 +336,7 @@ config SH_MAGIC_PANEL_R2
bool "Magic Panel R2"
depends on CPU_SUBTYPE_SH7720
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
help
Select Magic Panel R2 if configuring for Magic Panel R2.
diff --git a/arch/sh/boards/mach-highlander/Kconfig b/arch/sh/boards/mach-highlander/Kconfig
index b0abd03cac4e..cd3a553ce30c 100644
--- a/arch/sh/boards/mach-highlander/Kconfig
+++ b/arch/sh/boards/mach-highlander/Kconfig
@@ -20,6 +20,7 @@ config SH_R7785RP
bool "R7785RP board support"
depends on CPU_SUBTYPE_SH7785
select GPIOLIB
+ select GPIOLIB_LEGACY
endchoice
diff --git a/arch/sh/boards/mach-rsk/Kconfig b/arch/sh/boards/mach-rsk/Kconfig
index f0299bc4416f..3810937aa5d4 100644
--- a/arch/sh/boards/mach-rsk/Kconfig
+++ b/arch/sh/boards/mach-rsk/Kconfig
@@ -12,16 +12,19 @@ config SH_RSK7201
config SH_RSK7203
bool "RSK7203"
select GPIOLIB
+ select GPIOLIB_LEGACY
depends on CPU_SUBTYPE_SH7203
config SH_RSK7264
bool "RSK2+SH7264"
select GPIOLIB
+ select GPIOLIB_LEGACY
depends on CPU_SUBTYPE_SH7264
config SH_RSK7269
bool "RSK2+SH7269"
select GPIOLIB
+ select GPIOLIB_LEGACY
depends on CPU_SUBTYPE_SH7269
endchoice
--
2.39.5
^ permalink raw reply related
* [PATCH 3/6] [v6] leds: gpio: make legacy gpiolib interface optional
From: Arnd Bergmann @ 2026-07-10 21:18 UTC (permalink / raw)
To: linux-gpio, Linus Walleij, Bartosz Golaszewski
Cc: Arnd Bergmann, John Paul Adrian Glaubitz, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Dmitry Torokhov, Lee Jones, Pavel Machek, linux-sh, linux-kernel,
linux-input, linux-leds, Bartosz Golaszewski, Andy Shevchenko
In-Reply-To: <20260710211854.1371746-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
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.
Link: https://lore.kernel.org/all/e9252384-a55c-4a91-9c61-06e05a0b2ce4@app.fastmail.com/
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> # for input
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v5: no changes
v4: whitespace changes only
v3: simplify gpio_led_get_gpiod
v2: rework a little bit to keep the legacy code path more separate,
extend changelog description
---
drivers/leds/leds-gpio.c | 52 +++++++++++++++++++++++++++-------------
include/linux/leds.h | 2 ++
2 files changed, 37 insertions(+), 17 deletions(-)
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index a3428b22de3a..9cbcf7e40a15 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>
#include <linux/leds.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
@@ -212,7 +212,6 @@ static struct gpio_desc *gpio_led_get_gpiod(struct device *dev, int idx,
const struct gpio_led *template)
{
struct gpio_desc *gpiod;
- int ret;
/*
* This means the LED does not come from the device tree
@@ -223,16 +222,29 @@ static struct gpio_desc *gpio_led_get_gpiod(struct device *dev, int idx,
gpiod = devm_gpiod_get_index_optional(dev, NULL, idx, GPIOD_OUT_LOW);
if (IS_ERR(gpiod))
return gpiod;
- if (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.
- */
+ gpiod_set_consumer_name(gpiod, template->name);
+ return gpiod;
+}
+
+#ifdef CONFIG_GPIOLIB_LEGACY
+/*
+ * This is the legacy code path for platform code that still uses
+ * GPIO numbers, mainly MIPS and SuperH board files.
+ * Ultimately we would like to get rid of this block completely.
+ *
+ * ppc44x-warp sets the template->gpiod directly instead of
+ * adding a lookup table or device properties. This is not
+ * much better.
+ */
+static struct gpio_desc *gpio_led_get_legacy_gpiod(struct device *dev, int idx,
+ const struct gpio_led *template)
+{
+ struct gpio_desc *gpiod;
+ int ret;
+
+ if (template->gpiod)
+ return template->gpiod;
/* skip leds that aren't available */
if (!gpio_is_valid(template->gpio))
@@ -252,6 +264,13 @@ static struct gpio_desc *gpio_led_get_gpiod(struct device *dev, int idx,
return gpiod;
}
+#else
+static struct gpio_desc *gpio_led_get_legacy_gpiod(struct device *dev, int idx,
+ const struct gpio_led *template)
+{
+ return template->gpiod ?: ERR_PTR(-ENOENT);
+}
+#endif
static int gpio_led_probe(struct platform_device *pdev)
{
@@ -270,14 +289,13 @@ static int gpio_led_probe(struct platform_device *pdev)
const struct gpio_led *template = &pdata->leds[i];
struct gpio_led_data *led_dat = &priv->leds[i];
- if (template->gpiod)
- led_dat->gpiod = template->gpiod;
- else
+ led_dat->gpiod = gpio_led_get_gpiod(dev, i, template);
+ if (!led_dat->gpiod)
led_dat->gpiod =
- gpio_led_get_gpiod(dev, i, template);
+ gpio_led_get_legacy_gpiod(dev, i, template);
if (IS_ERR(led_dat->gpiod)) {
- dev_info(dev, "Skipping unavailable LED gpio %d (%s)\n",
- template->gpio, template->name);
+ dev_info(dev, "Skipping unavailable LED gpio %s\n",
+ template->name);
continue;
}
diff --git a/include/linux/leds.h b/include/linux/leds.h
index b16b803cc1ac..e646bffcd8e7 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -676,8 +676,10 @@ typedef int (*gpio_blink_set_t)(struct gpio_desc *desc, int state,
struct gpio_led {
const char *name;
const char *default_trigger;
+#ifdef CONFIG_GPIOLIB_LEGACY
unsigned gpio;
unsigned active_low : 1;
+#endif
unsigned retain_state_suspended : 1;
unsigned panic_indicator : 1;
unsigned default_state : 2;
--
2.39.5
^ permalink raw reply related
* [PATCH 2/6] [v6] Input: gpio-keys: make legacy gpiolib optional
From: Arnd Bergmann @ 2026-07-10 21:18 UTC (permalink / raw)
To: linux-gpio, Linus Walleij, Bartosz Golaszewski
Cc: Arnd Bergmann, John Paul Adrian Glaubitz, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Dmitry Torokhov, Lee Jones, Pavel Machek, linux-sh, linux-kernel,
linux-input, linux-leds, Bartosz Golaszewski
In-Reply-To: <20260710211854.1371746-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
Most users of gpio-keys and gpio-keys-polled use modern gpiolib
interfaces, but there are still number of ancient sh, arm32 and x86
machines that have never been converted.
Add an #ifdef block for the parts of the driver that are only used on
those legacy machines.
The two Rohm PMIC drivers use a gpio-keys device without an actual GPIO,
passing an IRQ number instead. In order to keep this working both with
and with CONFIG_GPIOLIB_LEGACY, change the gpio-keys driver to ignore
the gpio number if an IRQ is passed.
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/
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> # for input
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v3..v5: resend
v2: skip the fake GPIO number passing from mfd
This patch now has a small conflict with the rework of the rohm drivers
to use software nodes. That patch is the one we want, and then
the drivers/mfd changes here can get dropped, but the two need to
get merged in the correct order.
---
drivers/input/keyboard/gpio_keys.c | 9 +++++----
drivers/input/keyboard/gpio_keys_polled.c | 4 +++-
drivers/mfd/rohm-bd71828.c | 1 -
drivers/mfd/rohm-bd718x7.c | 1 -
include/linux/gpio_keys.h | 2 ++
5 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index e19617485679..e988657f97cb 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -23,8 +23,8 @@
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/workqueue.h>
-#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
+#include <linux/gpio/legacy.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/spinlock.h>
@@ -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)) {
/*
* Legacy GPIO number, so request the GPIO here and
* convert it to descriptor.
@@ -546,6 +547,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
if (button->active_low ^ gpiod_is_active_low(bdata->gpiod))
gpiod_toggle_active_low(bdata->gpiod);
+#endif
}
if (bdata->gpiod) {
@@ -583,8 +585,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
if (irq < 0) {
error = irq;
dev_err_probe(dev, error,
- "Unable to get irq number for GPIO %d\n",
- button->gpio);
+ "Unable to get irq number for GPIO\n");
return error;
}
bdata->irq = irq;
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c
index e6707d72210e..4e7a366ff05b 100644
--- a/drivers/input/keyboard/gpio_keys_polled.c
+++ b/drivers/input/keyboard/gpio_keys_polled.c
@@ -18,8 +18,8 @@
#include <linux/input.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
-#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
+#include <linux/gpio/legacy.h>
#include <linux/gpio_keys.h>
#include <linux/property.h>
@@ -301,6 +301,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(bdata->gpiod),
"failed to get gpio\n");
}
+#ifdef CONFIG_GPIOLIB_LEGACY
} else if (gpio_is_valid(button->gpio)) {
/*
* Legacy GPIO number so request the GPIO here and
@@ -323,6 +324,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
if (button->active_low ^ gpiod_is_active_low(bdata->gpiod))
gpiod_toggle_active_low(bdata->gpiod);
+#endif
}
bdata->last_state = -1;
diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
index a79f354bf5cb..df6dad762ec9 100644
--- a/drivers/mfd/rohm-bd71828.c
+++ b/drivers/mfd/rohm-bd71828.c
@@ -39,7 +39,6 @@
static struct gpio_keys_button button = {
.code = KEY_POWER,
- .gpio = -1,
.type = EV_KEY,
.wakeup = 1,
};
diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c
index ff714fd4f54d..dd774aa8828b 100644
--- a/drivers/mfd/rohm-bd718x7.c
+++ b/drivers/mfd/rohm-bd718x7.c
@@ -20,7 +20,6 @@
static struct gpio_keys_button button = {
.code = KEY_POWER,
- .gpio = -1,
.type = EV_KEY,
};
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h
index 80fa930b04c6..e8d6dc290efb 100644
--- a/include/linux/gpio_keys.h
+++ b/include/linux/gpio_keys.h
@@ -25,7 +25,9 @@ struct device;
*/
struct gpio_keys_button {
unsigned int code;
+#ifdef CONFIG_GPIOLIB_LEGACY
int gpio;
+#endif
int active_low;
const char *desc;
unsigned int type;
--
2.39.5
^ permalink raw reply related
* [PATCH 1/6] [v6] Input: soc_button_array - select CONFIG_GPIOLIB_LEGACY
From: Arnd Bergmann @ 2026-07-10 21:18 UTC (permalink / raw)
To: linux-gpio, Linus Walleij, Bartosz Golaszewski
Cc: Arnd Bergmann, John Paul Adrian Glaubitz, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Dmitry Torokhov, Lee Jones, Pavel Machek, linux-sh, linux-kernel,
linux-input, linux-leds, Bartosz Golaszewski
In-Reply-To: <20260710211854.1371746-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
This driver converts information from ACPI in x86 based tablets and
laptops into platform_data for the gpio_keys driver, using the obsolete
gpio number based interfaces.
This should really be converted to some other method, but since the
conversion is nontrivial, have this one select GPIOLIB_LEGACY for the
time being.
This enables turning GPIOLIB_LEGACY off by default on most kernel
builds. Since the driver is only used on x86 portables, add a CONFIG_X86
dependency, which means non-x86 allmodconfig builds usuallly build
without the legacy gpio support.
Link: https://lore.kernel.org/all/ah-1z9LhVG0wtfBw@google.com/
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> # for input
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v5: This was part of an earlier "x86/platform: select legacy
gpiolib interfaces where used" patch that covered several
drivers. This is the only one left as of linux-7.2-rc1
---
drivers/input/misc/Kconfig | 3 +++
drivers/input/misc/soc_button_array.c | 1 -
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 1f6c57dba030..9c66e3a67127 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -892,6 +892,9 @@ config INPUT_IDEAPAD_SLIDEBAR
config INPUT_SOC_BUTTON_ARRAY
tristate "Windows-compatible SoC Button Array"
depends on KEYBOARD_GPIO && ACPI
+ depends on X86
+ depends on GPIOLIB
+ select GPIOLIB_LEGACY
help
Say Y here if you have a SoC-based tablet that originally runs
Windows 8 or a Microsoft Surface Book 2, Pro 5, Laptop 1 or later.
diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
index b8cad415c62c..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.h>
#include <linux/platform_device.h>
static bool use_low_level_irq;
--
2.39.5
^ permalink raw reply related
* [PATCH v6 0/6] gpiolib: fence off legacy interfaces
From: Arnd Bergmann @ 2026-07-10 21:18 UTC (permalink / raw)
To: linux-gpio, Linus Walleij, Bartosz Golaszewski
Cc: Arnd Bergmann, John Paul Adrian Glaubitz, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Dmitry Torokhov, Lee Jones, Pavel Machek, linux-sh, linux-kernel,
linux-input, linux-leds
From: Arnd Bergmann <arnd@arndb.de>
This is the remainder of the series previously posted in [1] and [2].
I only made one trivial chance suggested by Andy Shevchenko and
reordered the series to have the input patches first.
Dmitry Torokhov asked about having an immutable branch, so I would
suggest sharing the two input patches between the mfd and gpio
trees, and everything else go through the gpio tree only.
Arnd
[1] https://lore.kernel.org/all/20260520183815.2510387-1-arnd@kernel.org/
[2] https://lore.kernel.org/all/20260629130329.1291953-1-arnd@kernel.org/
Arnd Bergmann (6):
[v6] Input: soc_button_array - select CONFIG_GPIOLIB_LEGACY
[v6] Input: gpio-keys: make legacy gpiolib optional
[v6] leds: gpio: make legacy gpiolib interface optional
[v6] sh: select legacy gpiolib interface
[v6] x86/olpc: select GPIOLIB_LEGACY
[v6] gpiolib: turn off legacy interface by default
arch/sh/Kconfig | 1 +
arch/sh/boards/Kconfig | 8 ++++
arch/sh/boards/mach-highlander/Kconfig | 1 +
arch/sh/boards/mach-rsk/Kconfig | 3 ++
arch/x86/Kconfig | 1 +
arch/x86/platform/olpc/olpc-xo1-sci.c | 2 +-
drivers/gpio/Kconfig | 9 +++-
drivers/input/keyboard/gpio_keys.c | 9 ++--
drivers/input/keyboard/gpio_keys_polled.c | 4 +-
drivers/input/misc/Kconfig | 3 ++
drivers/input/misc/soc_button_array.c | 1 -
drivers/leds/leds-gpio.c | 52 +++++++++++++++--------
drivers/mfd/rohm-bd71828.c | 1 -
drivers/mfd/rohm-bd718x7.c | 1 -
include/linux/gpio_keys.h | 2 +
include/linux/leds.h | 2 +
sound/pci/Kconfig | 1 +
sound/pci/cs5535audio/cs5535audio_olpc.c | 2 +-
18 files changed, 75 insertions(+), 28 deletions(-)
--
2.39.5
Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: x86@kernel.org
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Linus Walleij <linusw@kernel.org>
Cc: Bartosz Golaszewski <brgl@kernel.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Lee Jones <lee@kernel.org>
Cc: Pavel Machek <pavel@kernel.org>
Cc: linux-sh@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-gpio@vger.kernel.org
Cc: linux-input@vger.kernel.org
Cc: linux-leds@vger.kernel.org
^ permalink raw reply
* Re: [PATCH v2 00/11] Remove support for platform data from samsung keypad
From: Linus Walleij @ 2026-07-10 19:41 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
Alim Akhtar, Russell King, Mark Brown, Charles Keepax,
Sam Protsenko, Arnd Bergmann, Bartosz Golaszewski,
Krzysztof Kozlowski, linux-input, devicetree, linux-kernel,
linux-arm-kernel, linux-samsung-soc, patches
In-Reply-To: <20260708-samsung-kp-v2-0-3c6ed4c9b3b6@gmail.com>
On Thu, Jul 9, 2026 at 6:53 AM Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> This is a reworked and extended version of the series previously posted
> to convert the Samsung keypad driver and Cragganmore 6410 board to
> generic device properties. The first 8 patches of the original series
> (general cleanups) have been merged into mainline, and this version
> focuses on the remaining keypad rework and extends the board conversion.
Looks good to me!
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH 0/3] HID: wiimote: new LED behavior on connect, and scoped guards
From: Rafael Passos @ 2026-07-10 19:35 UTC (permalink / raw)
To: Rafael Passos, bentiss, david, jikos
Cc: Shuah Khan, Brigham Campbell, Jori Koolstra, linux-input
In-Reply-To: <20260710153456.2093889-1-rafael@rcpassos.me>
I checked sashiko reviews, and there are a few needed fixes.
I will delay sending the v2 by a few days, in case there are any other reviews.
Specially regarding these two questions:
On Fri Jul 10, 2026 at 12:32 PM -03, Rafael Passos wrote:
> [...]
> The hid_info log message prints out the controller id.
> I was considering adding this number to the controller name too,
> but was unsure if this could impact applications using it.
- device naming
> The wiimote_hid_probe call can also be changed in this way, but I
> left it because it uses the wiimote_destroy in one of the err cases (w/ kfree inside).
> But I can apply the change there too, to make this more complete.
- wiimote_hid_probe scope cleanup
Thanks,
Rafael
^ permalink raw reply
* Re: [PATCH v2 RESEND] HID: appletb-kbd: add option to switch default layer on double pressing fn key
From: Aditya Garg @ 2026-07-10 16:40 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires
Cc: Linux Input Mailing List, Linux Kernel Mailing List
In-Reply-To: <20260620112635.17246-1-gargaditya08@proton.me>
Hi Jiri
Can I have an update on this?
On Saturday, 20 June 2026 at 4:56 PM, Aditya Garg <gargaditya08@proton.me> wrote:
> From: Aditya Garg <gargaditya08@proton.me>
>
> This patch enables a user to switch the default layer from media to fn
> keys and vice-versa upon double pressing the fn key. This behaviour can
> be configured using the double_press_switch_time module parameter whose
> value depicts the time in milliseconds within which the fn key must be
> pressed again to switch the default layer. If set to 0, it simply
> disables this behaviour.
>
> Signed-off-by: Aditya Garg <gargaditya08@proton.me>
> ---
>
> v2: added a check to ensure negative fn switch times are ignored.
>
> drivers/hid/hid-appletb-kbd.c | 60 +++++++++++++++++++++++++++++++----
> 1 file changed, 53 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid/hid-appletb-kbd.c
> index 462010a75899..34bfc595949d 100644
> --- a/drivers/hid/hid-appletb-kbd.c
> +++ b/drivers/hid/hid-appletb-kbd.c
> @@ -56,6 +56,12 @@ static int appletb_tb_idle_timeout = 15;
> module_param_named(idle_timeout, appletb_tb_idle_timeout, int, 0644);
> MODULE_PARM_DESC(idle_timeout, "Idle timeout in sec");
>
> +static int appletb_tb_double_press_switch_layers;
> +module_param_named(double_press_switch_time,
> + appletb_tb_double_press_switch_layers, int, 0644);
> +MODULE_PARM_DESC(double_press_switch_time, "Time in ms within which if fn key is double "
> + "pressed will switch layers");
> +
> struct appletb_kbd {
> struct hid_field *mode_field;
> struct input_handler inp_handler;
> @@ -68,6 +74,7 @@ struct appletb_kbd {
> bool has_turned_off;
> u8 saved_mode;
> u8 current_mode;
> + unsigned long last_fn_press;
> };
>
> static const struct key_entry appletb_kbd_keymap[] = {
> @@ -243,6 +250,18 @@ static int appletb_kbd_hid_event(struct hid_device *hdev, struct hid_field *fiel
> return kbd->current_mode == APPLETB_KBD_MODE_OFF;
> }
>
> +static u8 appletb_switch_mode(u8 mode)
> +{
> + switch (mode) {
> + case APPLETB_KBD_MODE_SPCL:
> + return APPLETB_KBD_MODE_FN;
> + case APPLETB_KBD_MODE_FN:
> + return APPLETB_KBD_MODE_SPCL;
> + default:
> + return mode;
> + }
> +}
> +
> static void appletb_kbd_inp_event(struct input_handle *handle, unsigned int type,
> unsigned int code, int value)
> {
> @@ -250,15 +269,42 @@ static void appletb_kbd_inp_event(struct input_handle *handle, unsigned int type
>
> reset_inactivity_timer(kbd);
>
> - if (type == EV_KEY && code == KEY_FN && appletb_tb_fn_toggle &&
> - (kbd->current_mode == APPLETB_KBD_MODE_SPCL ||
> - kbd->current_mode == APPLETB_KBD_MODE_FN)) {
> + if (type == EV_KEY && code == KEY_FN &&
> + (kbd->current_mode == APPLETB_KBD_MODE_SPCL ||
> + kbd->current_mode == APPLETB_KBD_MODE_FN)) {
> +
> if (value == 1) {
> - kbd->saved_mode = kbd->current_mode;
> - appletb_kbd_set_mode(kbd, kbd->current_mode == APPLETB_KBD_MODE_SPCL
> - ? APPLETB_KBD_MODE_FN : APPLETB_KBD_MODE_SPCL);
> + if (appletb_tb_double_press_switch_layers > 0) {
> + unsigned long now = jiffies;
> +
> + if (time_before(now, kbd->last_fn_press +
> + msecs_to_jiffies(appletb_tb_double_press_switch_layers))) {
> +
> + appletb_tb_def_mode =
> + appletb_switch_mode(
> + appletb_tb_def_mode);
> +
> + appletb_kbd_set_mode(kbd,
> + appletb_tb_def_mode);
> +
> + kbd->saved_mode = appletb_tb_def_mode;
> + kbd->last_fn_press = 0;
> +
> + return;
> + }
> +
> + kbd->last_fn_press = now;
> + }
> + if (appletb_tb_fn_toggle) {
> + kbd->saved_mode = kbd->current_mode;
> +
> + appletb_kbd_set_mode(kbd,
> + appletb_switch_mode(kbd->current_mode));
> + }
> +
> } else if (value == 0) {
> - if (kbd->saved_mode != kbd->current_mode)
> + if (appletb_tb_fn_toggle &&
> + kbd->saved_mode != kbd->current_mode)
> appletb_kbd_set_mode(kbd, kbd->saved_mode);
> }
> }
>
> Range-diff against v1:
> 1: 5c9d8c8ba8c0 ! 1: 4f6a818b98b9 HID: appletb-kbd: add option to switch default layer on double pressing fn key
> @@ drivers/hid/hid-appletb-kbd.c: static void appletb_kbd_inp_event(struct input_ha
> - kbd->saved_mode = kbd->current_mode;
> - appletb_kbd_set_mode(kbd, kbd->current_mode == APPLETB_KBD_MODE_SPCL
> - ? APPLETB_KBD_MODE_FN : APPLETB_KBD_MODE_SPCL);
> -+ if (appletb_tb_double_press_switch_layers) {
> ++ if (appletb_tb_double_press_switch_layers > 0) {
> + unsigned long now = jiffies;
> +
> + if (time_before(now, kbd->last_fn_press +
> --
> 2.53.0
>
>
^ permalink raw reply
* Re: [PATCH 2/3] HID: wiimote: replace spinlock pairs with scoped_guard
From: sashiko-bot @ 2026-07-10 15:47 UTC (permalink / raw)
To: Rafael Passos; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260710153456.2093889-3-rafael@rcpassos.me>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Low] Functions wiimote_init_detect() and wiimote_init_check() mix goto-based cleanup labels with cleanup.h helpers (scoped_guard).
Pre-existing issues:
- [High] Race condition during device teardown allows `queue.worker` to be re-scheduled after cancellation, leading to a Use-After-Free on `wdata`.
--
--- Patch [2]: [PATCH 2/3] HID: wiimote: replace spinlock pairs with scoped_guard ---
commit b72167f4bfaf6c447e5bff82a564df82f7c2a54d
Author: Rafael Passos <rafael@rcpassos.me>
HID: wiimote: replace spinlock pairs with scoped_guard
Cleanup code replacing manual lock/unlock with scoped guards.
This does not change any behavior, but makes it safer to modify.
> diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
> --- a/drivers/hid/hid-wiimote-core.c
> +++ b/drivers/hid/hid-wiimote-core.c
> @@ -878,19 +867,19 @@ static void wiimote_init_detect(struct wiimote_data *wdata)
>
> wiimote_cmd_acquire_noint(wdata);
>
> - spin_lock_irq(&wdata->state.lock);
> - wdata->state.devtype = WIIMOTE_DEV_UNKNOWN;
> - wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0);
> - wiiproto_req_status(wdata);
> - spin_unlock_irq(&wdata->state.lock);
> + scoped_guard(spinlock_irq, &wdata->state.lock) {
> + wdata->state.devtype = WIIMOTE_DEV_UNKNOWN;
> + wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0);
> + wiiproto_req_status(wdata);
> + }
> +
>
> ret = wiimote_cmd_wait_noint(wdata);
> if (ret)
> goto out_release;
[Severity: Low]
Is it acceptable to mix goto-based error handling with scoped_guard() in the
same function?
According to the cleanup.h documentation, the expectation is that a function
either uses goto-based cleanup or scope-based cleanup exclusively. Since
this patch introduces scoped_guard() while leaving goto out_release, does
this violate the subsystem guidelines for mixing cleanup styles? This same
pattern also appears further down in wiimote_init_check().
[ ... ]
> @@ -1767,14 +1745,12 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
>
> static void wiimote_destroy(struct wiimote_data *wdata)
> {
> - unsigned long flags;
> -
> wiidebug_deinit(wdata);
>
> /* prevent init_worker from being scheduled again */
> - spin_lock_irqsave(&wdata->state.lock, flags);
> - wdata->state.flags |= WIIPROTO_FLAG_EXITING;
> - spin_unlock_irqrestore(&wdata->state.lock, flags);
> + scoped_guard(spinlock_irqsave, &wdata->state.lock) {
> + wdata->state.flags |= WIIPROTO_FLAG_EXITING;
> + }
>
> cancel_work_sync(&wdata->init_worker);
> timer_shutdown_sync(&wdata->timer);
[ ... ]
> wiimote_mp_unload(wdata);
> wiimote_ext_unload(wdata);
> wiimote_modules_unload(wdata);
> cancel_work_sync(&wdata->queue.worker);
> hid_hw_close(wdata->hdev);
> hid_hw_stop(wdata->hdev);
>
> kfree(wdata);
> }
[Severity: High]
This is a pre-existing issue, but could this teardown sequence result in a
use-after-free on wdata?
Currently, cancel_work_sync(&wdata->queue.worker) is called before
hid_hw_stop(wdata->hdev). If an incoming status report arrives after the work
is canceled but before the HID device is stopped, wiimote_hid_event() could
handle it and call handler_status_K() -> wiiproto_req_drm() ->
wiimote_queue(), which unconditionally re-arms the work queue via
schedule_work(&wdata->queue.worker).
If the queue worker executes after wdata is freed by kfree(wdata) here,
would it dereference freed memory?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260710153456.2093889-1-rafael@rcpassos.me?part=2
^ permalink raw reply
* Re: [PATCH 1/3] HID: wiimote: turn on the LEDs indicating the controller id
From: sashiko-bot @ 2026-07-10 15:46 UTC (permalink / raw)
To: Rafael Passos; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260710153456.2093889-2-rafael@rcpassos.me>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
New issues:
- [High] Incorrect error check for `ida_alloc_min()` fails to catch negative error codes, leading to an out-of-bounds array read on `player_leds`.
- [Medium] The fallback logic for IDA allocation failure incorrectly claims ID 1, leading to ID collisions and corruption of the IDA state upon removal.
- [Medium] Mixing of `goto`-based error handling and scope-based cleanup helpers (`scoped_guard`) in the same function.
- [Low] Defining a static array in a header file duplicates it across multiple translation units.
Pre-existing issues:
- [High] Missing `state.lock` when calling `wiimote_cmd_abort` in `wiimote_queue`.
--
--- Patch [1]: [PATCH 1/3] HID: wiimote: turn on the LEDs indicating the controller id ---
commit 48125f73deb74f22332d54c849af1f5b48042ab2
Author: Rafael Passos <rafael@rcpassos.me>
HID: wiimote: turn on the LEDs indicating the controller id
This commit introduces a new feature to assign an ID to each connected
Wiimote using an IDA struct. It also updates the module loading sequence
to cycle the LEDs from 1 to 4 to visually indicate the assigned player ID.
> diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
> index 63c4fa8fbb9b6..0d36a38bdcdad 100644
> --- a/drivers/hid/hid-wiimote-core.c
> +++ b/drivers/hid/hid-wiimote-core.c
[Severity: High]
This isn't a bug introduced by this patch, but does wiimote_queue() call
wiimote_cmd_abort() while holding queue.lock instead of state.lock?
drivers/hid/hid-wiimote-core.c:wiimote_queue() {
...
out_error:
wiimote_cmd_abort(wdata);
out_unlock:
spin_unlock_irqrestore(&wdata->queue.lock, flags);
}
The documentation for wiimote_cmd_abort() specifies that it requires
state.lock:
drivers/hid/hid-wiimote.h:
/* requires the state.lock spinlock to be held */
static inline void wiimote_cmd_abort(struct wiimote_data *wdata)
Could this cause a data race with other command state accesses?
[ ... ]
> @@ -671,6 +671,12 @@ static void wiimote_modules_load(struct wiimote_data *wdata,
> spin_lock_irq(&wdata->state.lock);
> wdata->state.devtype = devtype;
> spin_unlock_irq(&wdata->state.lock);
> +
> + /* after loading all modules, set the LED for the player ID cycling from 1 to 4*/
> + scoped_guard(spinlock_irqsave, &wdata->state.lock) {
> + wiiproto_req_leds(wdata, player_leds[(wdata->instance_id - 1) % 4]);
> + }
> +
> return;
>
> error:
[Severity: Medium]
Is it acceptable to mix scope-based cleanup helpers like scoped_guard()
with goto-based error handling in the same function?
The cleanup documentation states that goto-based cleanup and scope-based
cleanup should not be mixed within the same routine.
[ ... ]
> @@ -1834,7 +1844,15 @@ static int wiimote_hid_probe(struct hid_device *hdev,
> if (ret)
> goto err_free;
>
> - hid_info(hdev, "New device registered\n");
> + instance_id = ida_alloc_min(&wiimote_ida, 1, GFP_KERNEL);
> + if (!instance_id) {
> + hid_err(hdev, "cannot allocate controller id, defaulting to 1\n");
> + instance_id = 1;
> + }
[Severity: High]
Since ida_alloc_min() returns a negative error code on failure rather than 0,
does this check fail to catch allocation errors?
If ida_alloc_min() fails and returns a negative error code, the later
calculation in wiimote_modules_load():
player_leds[(wdata->instance_id - 1) % 4]
would result in a negative modulo and an out-of-bounds array read.
[Severity: Medium]
Additionally, if the IDA allocation fails and this fallback logic is reached,
does assigning instance_id = 1 without actually reserving it in the IDA
risk corrupting the state?
[ ... ]
> @@ -1862,6 +1880,8 @@ static void wiimote_hid_remove(struct hid_device *hdev)
> {
> struct wiimote_data *wdata = hid_get_drvdata(hdev);
>
> + ida_free(&wiimote_ida, wdata->instance_id);
> +
> hid_info(hdev, "Device removed\n");
> wiimote_destroy(wdata);
> }
[Severity: Medium]
If the fallback logic in wiimote_hid_probe() set instance_id to 1 without
reserving it, will this unconditional free corrupt the IDA state if another
device had legitimately claimed ID 1?
[ ... ]
> diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h
> index 9c12f63f6dd2d..639f67c24f15f 100644
> --- a/drivers/hid/hid-wiimote.h
> +++ b/drivers/hid/hid-wiimote.h
> @@ -50,6 +50,13 @@
> #define WIIPROTO_FLAGS_IR (WIIPROTO_FLAG_IR_BASIC | WIIPROTO_FLAG_IR_EXT | \
> WIIPROTO_FLAG_IR_FULL)
>
> +static const __u8 player_leds[] = {
> + WIIPROTO_FLAG_LED1,
> + WIIPROTO_FLAG_LED2,
> + WIIPROTO_FLAG_LED3,
> + WIIPROTO_FLAG_LED4
> +};
> +
[Severity: Low]
Does defining a static array in a header file cause it to be unnecessarily
duplicated in the .rodata section for every translation unit that includes
hid-wiimote.h?
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260710153456.2093889-1-rafael@rcpassos.me?part=1
^ permalink raw reply
* Re: [PATCH 3/3] HID: wiimote: use scoped cleanup in led creation
From: sashiko-bot @ 2026-07-10 15:44 UTC (permalink / raw)
To: Rafael Passos; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260710153456.2093889-4-rafael@rcpassos.me>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The check `if (!instance_id)` after `ida_alloc_min()` incorrectly assumes 0 on failure, missing negative error codes and leading to an out-of-bounds array access and kernel BUG.
--
--- Patch [3]: [PATCH 3/3] HID: wiimote: use scoped cleanup in led creation ---
commit 2a6971d40f61933b6a7890df0931f14066de90e7
Author: Rafael Passos <rafael@rcpassos.me>
HID: wiimote: use scoped cleanup in led creation
This commit updates the wiimod_led_probe function to use modern scoped
cleanup for led allocation. It ensures the led structure is safely freed
on error paths while transferring ownership appropriately on success.
> diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
> index f42f9aa7b2d49..7c305099c82d6 100644
> --- a/drivers/hid/hid-wiimote-modules.c
> +++ b/drivers/hid/hid-wiimote-modules.c
> @@ -340,11 +340,11 @@ static int wiimod_led_probe(const struct wiimod_ops *ops,
> {
> struct device *dev = &wdata->hdev->dev;
> size_t namesz = strlen(dev_name(dev)) + 9;
[ ... ]
[Severity: High]
Does this driver handle negative error codes from ida_alloc_min() correctly?
Looking at wiimote_hid_probe(), the return value is checked with a boolean
negation:
drivers/hid/hid-wiimote-core.c:wiimote_hid_probe() {
...
instance_id = ida_alloc_min(&wiimote_ida, 1, GFP_KERNEL);
if (!instance_id) {
hid_err(hdev, "cannot allocate controller id, defaulting to 1\n");
instance_id = 1;
}
...
}
If ida_alloc_min() fails due to memory pressure or IDA exhaustion, it
returns a negative error code like -ENOMEM. The check if (!instance_id)
evaluates to false, bypassing the fallback logic and allowing the
negative error code to be stored in wdata->instance_id.
This negative value is later used in an array index calculation:
drivers/hid/hid-wiimote-core.c:wiimote_modules_load() {
...
scoped_guard(spinlock_irqsave, &wdata->state.lock) {
wiiproto_req_leds(wdata, player_leds[(wdata->instance_id - 1) % 4]);
}
...
}
Can this cause an out-of-bounds array read, since the modulo operator
in C retains the sign of the dividend?
Additionally, when the device is removed or rolled back, this negative ID
is freed:
drivers/hid/hid-wiimote-core.c:wiimote_hid_remove() {
...
ida_free(&wiimote_ida, wdata->instance_id);
...
}
Could passing the negative ID to ida_free() explicitly trigger a BUG_ON
and crash the kernel during teardown?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260710153456.2093889-1-rafael@rcpassos.me?part=3
^ permalink raw reply
* [PATCH 3/3] HID: wiimote: use scoped cleanup in led creation
From: Rafael Passos @ 2026-07-10 15:32 UTC (permalink / raw)
To: david, jikos, bentiss
Cc: Shuah Khan, Brigham Campbell, Jori Koolstra, Rafael Passos,
linux-input
In-Reply-To: <20260710153456.2093889-1-rafael@rcpassos.me>
Cleanup code in led probe function, using the modern scoped cleanup.
This prevents mistakes in future changes to this function.
Signed-off-by: Rafael Passos <rafael@rcpassos.me>
---
drivers/hid/hid-wiimote-modules.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index f42f9aa7b2d4..7c305099c82d 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -340,11 +340,11 @@ static int wiimod_led_probe(const struct wiimod_ops *ops,
{
struct device *dev = &wdata->hdev->dev;
size_t namesz = strlen(dev_name(dev)) + 9;
- struct led_classdev *led;
char *name;
int ret;
- led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL);
+ struct led_classdev *led __free(kfree) =
+ kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL);
if (!led)
return -ENOMEM;
@@ -358,8 +358,13 @@ static int wiimod_led_probe(const struct wiimod_ops *ops,
wdata->leds[ops->arg] = led;
ret = led_classdev_register(dev, led);
- if (ret)
- goto err_free;
+ if (ret) {
+ wdata->leds[ops->arg] = NULL;
+ return ret;
+ }
+
+ /* Ownership transferred to wdata – prevent cleanup from freeing */
+ led = NULL;
/* enable LED1 to stop initial LED-blinking */
if (ops->arg == 0) {
@@ -368,11 +373,6 @@ static int wiimod_led_probe(const struct wiimod_ops *ops,
}
return 0;
-
-err_free:
- wdata->leds[ops->arg] = NULL;
- kfree(led);
- return ret;
}
static void wiimod_led_remove(const struct wiimod_ops *ops,
--
2.53.0
^ permalink raw reply related
* [PATCH 2/3] HID: wiimote: replace spinlock pairs with scoped_guard
From: Rafael Passos @ 2026-07-10 15:32 UTC (permalink / raw)
To: david, jikos, bentiss
Cc: Shuah Khan, Brigham Campbell, Jori Koolstra, Rafael Passos,
linux-input
In-Reply-To: <20260710153456.2093889-1-rafael@rcpassos.me>
Cleanup code replacing manual lock/unlock with scoped guards.
This does not change any behavior, but makes it safer to modify.
The multi line spinlock blocks were replaced by braced scoped_guard,
and one-liners by a scoped_guard without braces nor indentation.
There are two cases left in this driver using lock/unlock, because
guard would make the code more complex than current implementation.
Signed-off-by: Rafael Passos <rafael@rcpassos.me>
---
drivers/hid/hid-wiimote-core.c | 206 +++++++++++++-----------------
drivers/hid/hid-wiimote-debug.c | 41 +++---
drivers/hid/hid-wiimote-modules.c | 4 +-
3 files changed, 108 insertions(+), 143 deletions(-)
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index 0d36a38bdcda..b0403b750d6b 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -362,13 +362,12 @@ void wiiproto_req_rmem(struct wiimote_data *wdata, bool eeprom, __u32 offset,
int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
const __u8 *wmem, __u8 size)
{
- unsigned long flags;
int ret;
- spin_lock_irqsave(&wdata->state.lock, flags);
- wiimote_cmd_set(wdata, WIIPROTO_REQ_WMEM, 0);
- wiiproto_req_wreg(wdata, offset, wmem, size);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock) {
+ wiimote_cmd_set(wdata, WIIPROTO_REQ_WMEM, 0);
+ wiiproto_req_wreg(wdata, offset, wmem, size);
+ }
ret = wiimote_cmd_wait(wdata);
if (!ret && wdata->state.cmd_err)
@@ -381,21 +380,19 @@ int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset, __u8 *rmem,
__u8 size)
{
- unsigned long flags;
ssize_t ret;
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->state.cmd_read_size = size;
- wdata->state.cmd_read_buf = rmem;
- wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, offset & 0xffff);
- wiiproto_req_rreg(wdata, offset, size);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock) {
+ wdata->state.cmd_read_size = size;
+ wdata->state.cmd_read_buf = rmem;
+ wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, offset & 0xffff);
+ wiiproto_req_rreg(wdata, offset, size);
+ }
ret = wiimote_cmd_wait(wdata);
- spin_lock_irqsave(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock)
wdata->state.cmd_read_buf = NULL;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
if (!ret) {
if (wdata->state.cmd_read_size == 0)
@@ -696,13 +693,11 @@ static void wiimote_modules_unload(struct wiimote_data *wdata)
{
const __u8 *mods, *iter;
const struct wiimod_ops *ops;
- unsigned long flags;
mods = wiimote_devtype_mods[wdata->state.devtype];
- spin_lock_irqsave(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock)
wdata->state.devtype = WIIMOTE_DEV_UNKNOWN;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
/* find end of list */
for (iter = mods; *iter != WIIMOD_NULL; ++iter)
@@ -729,7 +724,6 @@ static void wiimote_modules_unload(struct wiimote_data *wdata)
static void wiimote_ext_load(struct wiimote_data *wdata, unsigned int ext)
{
- unsigned long flags;
const struct wiimod_ops *ops;
int ret;
@@ -741,22 +735,20 @@ static void wiimote_ext_load(struct wiimote_data *wdata, unsigned int ext)
ext = WIIMOTE_EXT_UNKNOWN;
}
- spin_lock_irqsave(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock)
wdata->state.exttype = ext;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
}
static void wiimote_ext_unload(struct wiimote_data *wdata)
{
- unsigned long flags;
const struct wiimod_ops *ops;
ops = wiimod_ext_table[wdata->state.exttype];
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->state.exttype = WIIMOTE_EXT_UNKNOWN;
- wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock) {
+ wdata->state.exttype = WIIMOTE_EXT_UNKNOWN;
+ wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED;
+ }
if (ops->remove)
ops->remove(ops, wdata);
@@ -764,7 +756,6 @@ static void wiimote_ext_unload(struct wiimote_data *wdata)
static void wiimote_mp_load(struct wiimote_data *wdata)
{
- unsigned long flags;
const struct wiimod_ops *ops;
int ret;
__u8 mode = 2;
@@ -776,14 +767,12 @@ static void wiimote_mp_load(struct wiimote_data *wdata)
mode = 1;
}
- spin_lock_irqsave(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock)
wdata->state.mp = mode;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
}
static void wiimote_mp_unload(struct wiimote_data *wdata)
{
- unsigned long flags;
const struct wiimod_ops *ops;
if (wdata->state.mp < 2)
@@ -791,10 +780,10 @@ static void wiimote_mp_unload(struct wiimote_data *wdata)
ops = &wiimod_mp;
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->state.mp = 0;
- wdata->state.flags &= ~WIIPROTO_FLAG_MP_USED;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock) {
+ wdata->state.mp = 0;
+ wdata->state.flags &= ~WIIPROTO_FLAG_MP_USED;
+ }
if (ops->remove)
ops->remove(ops, wdata);
@@ -878,19 +867,19 @@ static void wiimote_init_detect(struct wiimote_data *wdata)
wiimote_cmd_acquire_noint(wdata);
- spin_lock_irq(&wdata->state.lock);
- wdata->state.devtype = WIIMOTE_DEV_UNKNOWN;
- wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0);
- wiiproto_req_status(wdata);
- spin_unlock_irq(&wdata->state.lock);
+ scoped_guard(spinlock_irq, &wdata->state.lock) {
+ wdata->state.devtype = WIIMOTE_DEV_UNKNOWN;
+ wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0);
+ wiiproto_req_status(wdata);
+ }
+
ret = wiimote_cmd_wait_noint(wdata);
if (ret)
goto out_release;
- spin_lock_irq(&wdata->state.lock);
+ scoped_guard(spinlock_irq, &wdata->state.lock)
ext = wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED;
- spin_unlock_irq(&wdata->state.lock);
if (!ext)
goto out_release;
@@ -903,11 +892,11 @@ static void wiimote_init_detect(struct wiimote_data *wdata)
wiimote_init_set_type(wdata, exttype);
/* schedule MP timer */
- spin_lock_irq(&wdata->state.lock);
- if (!(wdata->state.flags & WIIPROTO_FLAG_BUILTIN_MP) &&
- !(wdata->state.flags & WIIPROTO_FLAG_NO_MP))
- mod_timer(&wdata->timer, jiffies + HZ * 4);
- spin_unlock_irq(&wdata->state.lock);
+ scoped_guard(spinlock_irq, &wdata->state.lock) {
+ if (!(wdata->state.flags & WIIPROTO_FLAG_BUILTIN_MP) &&
+ !(wdata->state.flags & WIIPROTO_FLAG_NO_MP))
+ mod_timer(&wdata->timer, jiffies + HZ * 4);
+ }
}
/*
@@ -955,9 +944,8 @@ static bool wiimote_init_check(struct wiimote_data *wdata)
__u8 type, data[6];
bool ret, poll_mp;
- spin_lock_irq(&wdata->state.lock);
+ scoped_guard(spinlock_irq, &wdata->state.lock)
flags = wdata->state.flags;
- spin_unlock_irq(&wdata->state.lock);
wiimote_cmd_acquire_noint(wdata);
@@ -973,11 +961,11 @@ static bool wiimote_init_check(struct wiimote_data *wdata)
type = wiimote_cmd_read_mp_mapped(wdata);
ret = type == WIIMOTE_MP_SINGLE;
- spin_lock_irq(&wdata->state.lock);
- ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE);
- ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_PLUGGED);
- ret = ret && (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE);
- spin_unlock_irq(&wdata->state.lock);
+ scoped_guard(spinlock_irq, &wdata->state.lock) {
+ ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE);
+ ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_PLUGGED);
+ ret = ret && (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE);
+ }
if (!ret)
hid_dbg(wdata->hdev, "state left: !EXT && MP\n");
@@ -998,10 +986,10 @@ static bool wiimote_init_check(struct wiimote_data *wdata)
type = wiimote_cmd_read_ext(wdata, data);
ret = type == wdata->state.exttype;
- spin_lock_irq(&wdata->state.lock);
- ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE);
- ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE);
- spin_unlock_irq(&wdata->state.lock);
+ scoped_guard(spinlock_irq, &wdata->state.lock) {
+ ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE);
+ ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE);
+ }
if (!ret)
hid_dbg(wdata->hdev, "state left: EXT && !MP\n");
@@ -1024,11 +1012,11 @@ static bool wiimote_init_check(struct wiimote_data *wdata)
type = wiimote_cmd_read_ext(wdata, data);
ret = type == wdata->state.exttype;
- spin_lock_irq(&wdata->state.lock);
- ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE);
- ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE);
- ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED);
- spin_unlock_irq(&wdata->state.lock);
+ scoped_guard(spinlock_irq, &wdata->state.lock) {
+ ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE);
+ ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE);
+ ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED);
+ }
if (!ret)
hid_dbg(wdata->hdev, "state left: !EXT && !MP\n");
@@ -1054,11 +1042,11 @@ static bool wiimote_init_check(struct wiimote_data *wdata)
ret = ret && type != WIIMOTE_MP_UNKNOWN;
ret = ret && type != WIIMOTE_MP_SINGLE;
- spin_lock_irq(&wdata->state.lock);
- ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED);
- ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE);
- ret = ret && (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE);
- spin_unlock_irq(&wdata->state.lock);
+ scoped_guard(spinlock_irq, &wdata->state.lock) {
+ ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED);
+ ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE);
+ ret = ret && (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE);
+ }
if (!ret)
hid_dbg(wdata->hdev, "state left: EXT && MP\n");
@@ -1113,16 +1101,15 @@ static void wiimote_init_hotplug(struct wiimote_data *wdata)
wiimote_cmd_acquire_noint(wdata);
- spin_lock_irq(&wdata->state.lock);
-
- /* get state snapshot that we will then work on */
- flags = wdata->state.flags;
+ scoped_guard(spinlock_irq, &wdata->state.lock) {
- /* disable event forwarding temporarily */
- wdata->state.flags &= ~WIIPROTO_FLAG_EXT_ACTIVE;
- wdata->state.flags &= ~WIIPROTO_FLAG_MP_ACTIVE;
+ /* get state snapshot that we will then work on */
+ flags = wdata->state.flags;
- spin_unlock_irq(&wdata->state.lock);
+ /* disable event forwarding temporarily */
+ wdata->state.flags &= ~WIIPROTO_FLAG_EXT_ACTIVE;
+ wdata->state.flags &= ~WIIPROTO_FLAG_MP_ACTIVE;
+ }
/* init extension and MP (deactivates current extension or MP) */
wiimote_cmd_init_ext(wdata);
@@ -1145,9 +1132,8 @@ static void wiimote_init_hotplug(struct wiimote_data *wdata)
hid_info(wdata->hdev, "cannot detect extension; %6phC\n",
extdata);
} else if (exttype == WIIMOTE_EXT_NONE) {
- spin_lock_irq(&wdata->state.lock);
+ scoped_guard(spinlock_irq, &wdata->state.lock)
wdata->state.exttype = WIIMOTE_EXT_NONE;
- spin_unlock_irq(&wdata->state.lock);
} else {
hid_info(wdata->hdev, "detected extension: %s\n",
wiimote_exttype_names[exttype]);
@@ -1185,27 +1171,25 @@ static void wiimote_init_hotplug(struct wiimote_data *wdata)
mod_timer(&wdata->timer, jiffies + HZ * 4);
}
- spin_lock_irq(&wdata->state.lock);
-
- /* enable data forwarding again and set expected hotplug state */
- if (mp) {
- wdata->state.flags |= WIIPROTO_FLAG_MP_ACTIVE;
- if (wdata->state.exttype == WIIMOTE_EXT_NONE) {
- wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED;
- wdata->state.flags &= ~WIIPROTO_FLAG_MP_PLUGGED;
- } else {
- wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED;
- wdata->state.flags |= WIIPROTO_FLAG_MP_PLUGGED;
+ scoped_guard(spinlock_irq, &wdata->state.lock) {
+ /* enable data forwarding again and set expected hotplug state */
+ if (mp) {
+ wdata->state.flags |= WIIPROTO_FLAG_MP_ACTIVE;
+ if (wdata->state.exttype == WIIMOTE_EXT_NONE) {
+ wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED;
+ wdata->state.flags &= ~WIIPROTO_FLAG_MP_PLUGGED;
+ } else {
+ wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED;
+ wdata->state.flags |= WIIPROTO_FLAG_MP_PLUGGED;
+ wdata->state.flags |= WIIPROTO_FLAG_EXT_ACTIVE;
+ }
+ } else if (wdata->state.exttype != WIIMOTE_EXT_NONE) {
wdata->state.flags |= WIIPROTO_FLAG_EXT_ACTIVE;
}
- } else if (wdata->state.exttype != WIIMOTE_EXT_NONE) {
- wdata->state.flags |= WIIPROTO_FLAG_EXT_ACTIVE;
- }
- /* request status report for hotplug state updates */
- wiiproto_req_status(wdata);
-
- spin_unlock_irq(&wdata->state.lock);
+ /* request status report for hotplug state updates */
+ wiiproto_req_status(wdata);
+ }
hid_dbg(wdata->hdev, "detected extensions: MP: %d EXT: %d\n",
wdata->state.mp, wdata->state.exttype);
@@ -1237,11 +1221,8 @@ void __wiimote_schedule(struct wiimote_data *wdata)
static void wiimote_schedule(struct wiimote_data *wdata)
{
- unsigned long flags;
-
- spin_lock_irqsave(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock)
__wiimote_schedule(wdata);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
}
static void wiimote_init_timeout(struct timer_list *t)
@@ -1631,7 +1612,6 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
struct wiimote_data *wdata = hid_get_drvdata(hdev);
const struct wiiproto_handler *h;
int i;
- unsigned long flags;
if (size < 1)
return -EINVAL;
@@ -1639,9 +1619,9 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
for (i = 0; handlers[i].id; ++i) {
h = &handlers[i];
if (h->id == raw_data[0] && h->size < size) {
- spin_lock_irqsave(&wdata->state.lock, flags);
- h->func(wdata, &raw_data[1]);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock) {
+ h->func(wdata, &raw_data[1]);
+ }
break;
}
}
@@ -1659,11 +1639,10 @@ static ssize_t wiimote_ext_show(struct device *dev,
{
struct wiimote_data *wdata = dev_to_wii(dev);
__u8 type;
- unsigned long flags;
- spin_lock_irqsave(&wdata->state.lock, flags);
- type = wdata->state.exttype;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock) {
+ type = wdata->state.exttype;
+ }
switch (type) {
case WIIMOTE_EXT_NONE:
@@ -1712,11 +1691,10 @@ static ssize_t wiimote_dev_show(struct device *dev,
{
struct wiimote_data *wdata = dev_to_wii(dev);
__u8 type;
- unsigned long flags;
- spin_lock_irqsave(&wdata->state.lock, flags);
- type = wdata->state.devtype;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock) {
+ type = wdata->state.devtype;
+ }
switch (type) {
case WIIMOTE_DEV_GENERIC:
@@ -1767,14 +1745,12 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
static void wiimote_destroy(struct wiimote_data *wdata)
{
- unsigned long flags;
-
wiidebug_deinit(wdata);
/* prevent init_worker from being scheduled again */
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->state.flags |= WIIPROTO_FLAG_EXITING;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock) {
+ wdata->state.flags |= WIIPROTO_FLAG_EXITING;
+ }
cancel_work_sync(&wdata->init_worker);
timer_shutdown_sync(&wdata->timer);
diff --git a/drivers/hid/hid-wiimote-debug.c b/drivers/hid/hid-wiimote-debug.c
index 5f74917781f2..b174fa030c71 100644
--- a/drivers/hid/hid-wiimote-debug.c
+++ b/drivers/hid/hid-wiimote-debug.c
@@ -25,7 +25,6 @@ static ssize_t wiidebug_eeprom_read(struct file *f, char __user *u, size_t s,
{
struct wiimote_debug *dbg = f->private_data;
struct wiimote_data *wdata = dbg->wdata;
- unsigned long flags;
ssize_t ret;
char buf[16];
__u16 size = 0;
@@ -41,20 +40,19 @@ static ssize_t wiidebug_eeprom_read(struct file *f, char __user *u, size_t s,
if (ret)
return ret;
- spin_lock_irqsave(&wdata->state.lock, flags);
- wdata->state.cmd_read_size = s;
- wdata->state.cmd_read_buf = buf;
- wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, *off & 0xffff);
- wiiproto_req_reeprom(wdata, *off, s);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock) {
+ wdata->state.cmd_read_size = s;
+ wdata->state.cmd_read_buf = buf;
+ wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, *off & 0xffff);
+ wiiproto_req_reeprom(wdata, *off, s);
+ }
ret = wiimote_cmd_wait(wdata);
if (!ret)
size = wdata->state.cmd_read_size;
- spin_lock_irqsave(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock)
wdata->state.cmd_read_buf = NULL;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
wiimote_cmd_release(wdata);
@@ -99,12 +97,10 @@ static int wiidebug_drm_show(struct seq_file *f, void *p)
{
struct wiimote_debug *dbg = f->private;
const char *str = NULL;
- unsigned long flags;
__u8 drm;
- spin_lock_irqsave(&dbg->wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &dbg->wdata->state.lock)
drm = dbg->wdata->state.drm;
- spin_unlock_irqrestore(&dbg->wdata->state.lock, flags);
if (drm < WIIPROTO_REQ_MAX)
str = wiidebug_drmmap[drm];
@@ -126,7 +122,6 @@ static ssize_t wiidebug_drm_write(struct file *f, const char __user *u,
{
struct seq_file *sf = f->private_data;
struct wiimote_debug *dbg = sf->private;
- unsigned long flags;
char buf[16];
ssize_t len;
int i;
@@ -150,12 +145,12 @@ static ssize_t wiidebug_drm_write(struct file *f, const char __user *u,
if (i == WIIPROTO_REQ_MAX)
i = simple_strtoul(buf, NULL, 16);
- spin_lock_irqsave(&dbg->wdata->state.lock, flags);
- dbg->wdata->state.flags &= ~WIIPROTO_FLAG_DRM_LOCKED;
- wiiproto_req_drm(dbg->wdata, (__u8) i);
- if (i != WIIPROTO_REQ_NULL)
- dbg->wdata->state.flags |= WIIPROTO_FLAG_DRM_LOCKED;
- spin_unlock_irqrestore(&dbg->wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &dbg->wdata->state.lock) {
+ dbg->wdata->state.flags &= ~WIIPROTO_FLAG_DRM_LOCKED;
+ wiiproto_req_drm(dbg->wdata, (__u8) i);
+ if (i != WIIPROTO_REQ_NULL)
+ dbg->wdata->state.flags |= WIIPROTO_FLAG_DRM_LOCKED;
+ }
return len;
}
@@ -172,7 +167,6 @@ static const struct file_operations wiidebug_drm_fops = {
int wiidebug_init(struct wiimote_data *wdata)
{
struct wiimote_debug *dbg;
- unsigned long flags;
dbg = kzalloc_obj(*dbg);
if (!dbg)
@@ -186,9 +180,8 @@ int wiidebug_init(struct wiimote_data *wdata)
dbg->drm = debugfs_create_file("drm", S_IRUSR,
dbg->wdata->hdev->debug_dir, dbg, &wiidebug_drm_fops);
- spin_lock_irqsave(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock)
wdata->debug = dbg;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
return 0;
@@ -197,14 +190,12 @@ int wiidebug_init(struct wiimote_data *wdata)
void wiidebug_deinit(struct wiimote_data *wdata)
{
struct wiimote_debug *dbg = wdata->debug;
- unsigned long flags;
if (!dbg)
return;
- spin_lock_irqsave(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock)
wdata->debug = NULL;
- spin_unlock_irqrestore(&wdata->state.lock, flags);
debugfs_remove(dbg->drm);
debugfs_remove(dbg->eeprom);
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index dccb78bb3afd..f42f9aa7b2d4 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -341,7 +341,6 @@ static int wiimod_led_probe(const struct wiimod_ops *ops,
struct device *dev = &wdata->hdev->dev;
size_t namesz = strlen(dev_name(dev)) + 9;
struct led_classdev *led;
- unsigned long flags;
char *name;
int ret;
@@ -364,9 +363,8 @@ static int wiimod_led_probe(const struct wiimod_ops *ops,
/* enable LED1 to stop initial LED-blinking */
if (ops->arg == 0) {
- spin_lock_irqsave(&wdata->state.lock, flags);
+ scoped_guard(spinlock_irqsave, &wdata->state.lock)
wiiproto_req_leds(wdata, WIIPROTO_FLAG_LED1);
- spin_unlock_irqrestore(&wdata->state.lock, flags);
}
return 0;
--
2.53.0
^ permalink raw reply related
* [PATCH 1/3] HID: wiimote: turn on the LEDs indicating the controller id
From: Rafael Passos @ 2026-07-10 15:32 UTC (permalink / raw)
To: david, jikos, bentiss
Cc: Shuah Khan, Brigham Campbell, Jori Koolstra, Rafael Passos,
linux-input
In-Reply-To: <20260710153456.2093889-1-rafael@rcpassos.me>
The behavior in a Wii/Wii U console is to have each controller turn on
a different LED indicating the controller id.
This commit implements the same behavior using the ida struct.
Unlike switch controllers, each ID only turns one LED (from 1 to 4).
Signed-off-by: Rafael Passos <rafael@rcpassos.me>
---
drivers/hid/hid-wiimote-core.c | 46 +++++++++++++++++++++++++++++-----
drivers/hid/hid-wiimote.h | 8 ++++++
2 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index 63c4fa8fbb9b..0d36a38bdcda 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -671,6 +671,12 @@ static void wiimote_modules_load(struct wiimote_data *wdata,
spin_lock_irq(&wdata->state.lock);
wdata->state.devtype = devtype;
spin_unlock_irq(&wdata->state.lock);
+
+ /* after loading all modules, set the LED for the player ID cycling from 1 to 4*/
+ scoped_guard(spinlock_irqsave, &wdata->state.lock) {
+ wiiproto_req_leds(wdata, player_leds[(wdata->instance_id - 1) % 4]);
+ }
+
return;
error:
@@ -855,11 +861,11 @@ static void wiimote_init_set_type(struct wiimote_data *wdata,
done:
if (devtype == WIIMOTE_DEV_GENERIC)
- hid_info(wdata->hdev, "cannot detect device; NAME: %s VID: %04x PID: %04x EXT: %04x\n",
- name, vendor, product, exttype);
+ hid_info(wdata->hdev, "cannot detect device; NAME: %s VID: %04x PID: %04x EXT: %04x (%d)\n",
+ name, vendor, product, exttype, wdata->instance_id);
else
- hid_info(wdata->hdev, "detected device: %s\n",
- wiimote_devtype_names[devtype]);
+ hid_info(wdata->hdev, "detected device: %s (%d)\n",
+ wiimote_devtype_names[devtype], wdata->instance_id);
wiimote_modules_load(wdata, devtype);
}
@@ -1786,11 +1792,15 @@ static void wiimote_destroy(struct wiimote_data *wdata)
kfree(wdata);
}
+/* Global id allocator for wii remotes */
+static DEFINE_IDA(wiimote_ida);
+
static int wiimote_hid_probe(struct hid_device *hdev,
const struct hid_device_id *id)
{
struct wiimote_data *wdata;
int ret;
+ int instance_id;
hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
@@ -1834,7 +1844,15 @@ static int wiimote_hid_probe(struct hid_device *hdev,
if (ret)
goto err_free;
- hid_info(hdev, "New device registered\n");
+ instance_id = ida_alloc_min(&wiimote_ida, 1, GFP_KERNEL);
+ if (!instance_id) {
+ hid_err(hdev, "cannot allocate controller id, defaulting to 1\n");
+ instance_id = 1;
+ }
+
+ wdata->instance_id = instance_id;
+
+ hid_info(hdev, "New device registered (Wiimote %d)\n", instance_id);
/* schedule device detection */
wiimote_schedule(wdata);
@@ -1862,6 +1880,8 @@ static void wiimote_hid_remove(struct hid_device *hdev)
{
struct wiimote_data *wdata = hid_get_drvdata(hdev);
+ ida_free(&wiimote_ida, wdata->instance_id);
+
hid_info(hdev, "Device removed\n");
wiimote_destroy(wdata);
}
@@ -1887,7 +1907,21 @@ static struct hid_driver wiimote_hid_driver = {
.remove = wiimote_hid_remove,
.raw_event = wiimote_hid_event,
};
-module_hid_driver(wiimote_hid_driver);
+
+
+static int __init wiimote_init(void)
+{
+ return hid_register_driver(&wiimote_hid_driver);
+}
+
+static void __exit wiimote_exit(void)
+{
+ hid_unregister_driver(&wiimote_hid_driver);
+ ida_destroy(&wiimote_ida);
+}
+
+module_init(wiimote_init);
+module_exit(wiimote_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h
index 9c12f63f6dd2..639f67c24f15 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
@@ -50,6 +50,13 @@
#define WIIPROTO_FLAGS_IR (WIIPROTO_FLAG_IR_BASIC | WIIPROTO_FLAG_IR_EXT | \
WIIPROTO_FLAG_IR_FULL)
+static const __u8 player_leds[] = {
+ WIIPROTO_FLAG_LED1,
+ WIIPROTO_FLAG_LED2,
+ WIIPROTO_FLAG_LED3,
+ WIIPROTO_FLAG_LED4
+};
+
/* return flag for led \num */
#define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1))
@@ -153,6 +160,7 @@ struct wiimote_data {
struct input_dev *mp;
struct timer_list timer;
struct wiimote_debug *debug;
+ int instance_id;
union {
struct input_dev *input;
--
2.53.0
^ permalink raw reply related
* [PATCH 0/3] HID: wiimote: new LED behavior on connect, and scoped guards
From: Rafael Passos @ 2026-07-10 15:32 UTC (permalink / raw)
To: bentiss, david, jikos
Cc: Shuah Khan, Brigham Campbell, Jori Koolstra, Rafael Passos,
linux-input
Hi,
This patchset contains one feature change, and two cleanup patches.
The feature is turning different LEDs for each of the first 4 wiimotes connected.
From id 5 forward, the LED will cycle back to 1, and so on.
This uses the ida struct, so its quite simple and lightweight.
The hid_info log message prints out the controller id.
I was considering adding this number to the controller name too,
but was unsure if this could impact applications using it.
While implementing this feature, I decided to cleanup the code using
scoped_guard for the many spinlocks in the driver. There are two places
where the original lock/unlock version fits best, and I left them
untouched.
Lastly, I used the __free scope cleanup in the LED probe function.
The wiimote_hid_probe call can also be changed in this way, but I
left it because it uses the wiimote_destroy in one of the err cases (w/ kfree inside).
But I can apply the change there too, to make this more complete.
It was really fun working with this driver.
I tested it with 4 Wii Motion Plus remotes (gen2).
Video recording of my tests (48s video).
https://rcpassos.me/video/wiimote-led-linux-driver
Thanks,
Rafael Passos
Rafael Passos (3):
HID: wiimote: turn on the LEDs indicating the controller id
HID: wiimote: replace spinlock pairs with scoped_guard
HID: wiimote: use scoped cleanup in led creation
drivers/hid/hid-wiimote-core.c | 252 ++++++++++++++++--------------
drivers/hid/hid-wiimote-debug.c | 41 ++---
drivers/hid/hid-wiimote-modules.c | 22 ++-
drivers/hid/hid-wiimote.h | 8 +
4 files changed, 165 insertions(+), 158 deletions(-)
--
2.53.0
^ permalink raw reply
* i2c-hid: Goodix GXTP5100 (27c6:01e9) touch engine latches off when probed early at boot
From: djedi @ 2026-07-10 13:56 UTC (permalink / raw)
To: linux-input; +Cc: Jiri Kosina, Benjamin Tissoires
Hello,
I'm hitting a reproducible boot-time race on a laptop touchpad and I'd
like input on whether the existing i2c-hid quirk mechanism is the right
place to fix it, or whether I'm looking in the wrong layer. I have a
speculative sketch patch but I'm not confident enough in it to send as a
real submission -- details on why below, and I'd rather ask than send a
patch I can't stand behind.
Hardware
--------
Lenovo ThinkBook 16 G7+ IAH (type 21TL), DMI pvrThinkBook16G7+IAH.
Touchpad: Goodix GXTP5100 haptic pressure pad, i2c-hid over ACPI
(i2c_hid_acpi), USB/i2c ID 27c6:01e9, i2c-1, bound to hid-multitouch.
Kernel: 7.0.12 (also reproduced identically on 6.12.95 -- this is not a
kernel-version regression, both exhibit it).
Symptom
-------
When i2c_hid_acpi probes this device during early boot, the touch
ENGINE latches off permanently: the i2c front end keeps ACKing and the
device enumerates completely normally (identical kernel probe trace
whether the pad ends up dead or alive -- see below), but no touch input
ever arrives. It survives an EC reset. The only way to clear it is a
full power loss to the pad (cold boot; a warm/soft reboot is not
sufficient).
Evidence
--------
1. Identical probe trace regardless of outcome. From journalctl across
both a "dead" boot and a "revived" one (same day, same kernel):
kernel: hid-generic 0018:27C6:01E9.0001: item 0 1 0 11 parsing failed
kernel: hid-generic 0018:27C6:01E9.0001: probe with driver hid-generic failed with error -22
kernel: hid-multitouch 0018:27C6:01E9.0001: GT7868Q report descriptor fixup is applied.
kernel: input: GXTP5100:00 27C6:01E9 as .../input/input3
kernel: input: GXTP5100:00 27C6:01E9 as .../input/input4
kernel: hid-multitouch 0018:27C6:01E9.0001: input,hidraw0: I2C HID v1.00 Mouse [GXTP5100:00 27C6:01E9] on i2c-GXTP5100:00
These lines are byte-for-byte identical on a boot where the pad ends
up completely unresponsive and on a boot where it works fine. The
kernel-visible probe/bind sequence gives no signal that anything is
wrong -- whatever differs is happening inside the Goodix firmware's
touch engine, below what i2c-hid observes.
2. IRQ evidence. On a dead pad, the shared i2c controller line still
flows (protocol/ACK traffic keeps working) but the touch controller's
dedicated GPIO IRQ line stays at 0 forever. On a working pad, both
flow, e.g. currently on this machine:
32: ... 41998 IR-IO-APIC 32-fasteoi idma64.0, i2c_designware.0 (i2c bus IRQ)
235: ... 1031 intel-gpio 182 GXTP5100:00 (touch IRQ, climbing with use)
3. Recovery is 100% correlated with power-cycling the pad, not with any
driver-level reset, EC reset, or software reload -- only removing and
restoring power to the Goodix chip itself clears the latch.
4. Empirical fix: blacklisting i2c_hid_acpi at early boot and loading it
~15s later via a oneshot systemd unit (after multi-user.target) makes
the pad come up working consistently. Delaying the probe, not
retrying it, resolves it -- consistent with a firmware-internal
power-on/wakeup race that needs time to settle before anything
touches the device.
Precedent I found, and why I'm not just sending that patch
------------------------------------------------------------
drivers/hid/i2c-hid/i2c-hid-core.c already has a quirk for a sibling
Goodix device, 27c6:0d42:
{ I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_0D42,
I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME },
with the comment:
"On Goodix 27c6:0d42 wait extra time before device wakeup. It's not
clear why but if we send wakeup too early, the device will never
trigger input interrupts."
That is a striking match for our symptom description. I went and read
where I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME is actually consumed,
though, and it's only checked inside i2c_hid_core_resume() -- it never
fires during __i2c_hid_core_probe()/i2c_hid_core_probe() at all. Our
repro is a cold-boot/first-probe symptom; this machine never exercises
suspend/resume in any of this investigation (sleep targets are masked
system-wide here because s2idle hard-freezes the box, unrelated issue).
So simply adding 27c6:01e9 to that same quirk table entry would compile
fine and do nothing for us, since the code path that applies it is never
reached on a cold boot. I don't want to send a one-line patch I already
know wouldn't fix anything.
I also noticed I2C_DEVICE_ID_GOODIX_01E9 (0x01e9) is already defined in
drivers/hid/hid-ids.h and used in hid-multitouch.c for the GT7868Q
report-descriptor fixup and device-ID table -- so this exact ID is known
to the HID subsystem already, just not wired into the i2c-hid-core quirk
table or anything probe-time-delay-related.
What I'm asking
----------------
Is there an existing, preferred way to delay the *first* wakeup/reset
handshake after a fresh probe (as opposed to after a resume) for a
device like this? Candidates I can see, roughly in order of how
surgical they'd be, but I'd defer entirely to your judgment:
a) A new quirk flag applied inside __i2c_hid_core_probe() /
i2c_hid_core_probe(), analogous in shape to
I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME but for the probe path.
b) Something at the ACPI power-resource layer -- i2c_hid_acpi_probe()
in i2c-hid-acpi.c calls acpi_device_fix_up_power() right before
i2c_hid_core_probe(); if the race is really about the ACPI power
resource turning on the rail and the chip's internal boot sequence
not being done yet, that might be a better layer than i2c-hid-core.
c) Something Goodix-firmware-specific that doesn't belong in i2c-hid
at all.
I have a rough, deliberately-labeled-speculative sketch of option (a)
that I'm attaching inline below for discussion only -- it is untested,
unbuilt, and not something I'm asking you to merge. If (a) or (b) sounds
right to you I'm glad to build a test kernel, reproduce on this exact
hardware (I have a reliable dead-boot repro and a known-working
late-modprobe workaround to compare against), capture before/after
/proc/interrupts, and send a real patch with a proper commit message and
sign-off.
Current workaround, for reference (not something I'm proposing upstream,
just so the symptom description is fully reproducible by others):
/etc/modprobe.d/goodix-tpad-lateload.conf:
blacklist i2c_hid_acpi
/etc/systemd/system/tpad-lateload.service:
[Unit]
Description=Late-load Goodix GXTP5100 touchpad driver (boot-time wakeup race workaround)
[Service]
Type=oneshot
ExecStartPre=/bin/sleep 15
ExecStart=/sbin/modprobe i2c_hid_acpi
[Install]
WantedBy=multi-user.target
Speculative sketch (RFC only, not a submission -- see caveats above)
---------------------------------------------------------------------
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -52,6 +52,7 @@
#define I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND BIT(5)
#define I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME BIT(6)
#define I2C_HID_QUIRK_RE_POWER_ON BIT(7)
+#define I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_PROBE BIT(8) /* RFC, see this thread */
/* Command opcodes */
#define I2C_HID_OPCODE_RESET 0x01
@@ -149,6 +150,16 @@
I2C_HID_QUIRK_BOGUS_IRQ },
{ I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_0D42,
I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME },
+ /*
+ * RFC: 27c6:01e9 (GXTP5100, e.g. Lenovo ThinkBook 16 G7+ IAH)
+ * appears to latch its touch engine off if probed too early
+ * after a cold boot; untested guess at the same class of fix
+ * as the 0d42 resume quirk above, applied at first probe.
+ */
+ { I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_01E9,
+ I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_PROBE },
{ I2C_VENDOR_ID_BLTP, I2C_PRODUCT_ID_BLTP7853,
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
{ 0, 0 }
@@ -1292,6 +1303,12 @@
ret = __i2c_hid_core_probe(ihid);
if (ret < 0)
goto err_power_down;
+
+ /* RFC: see I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_PROBE comment
+ * above -- untested, guessing at parity with the
+ * resume-path quirk.
+ */
+ if (ihid->quirks & I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_PROBE)
+ msleep(1500);
}
ret = i2c_hid_init_irq(client);
Thanks for reading this far, and happy to provide any more detail,
dmesg, or i2cdump output you'd like.
djedi
edwardsr99@gmail.com
^ permalink raw reply
* Re: [PATCH] dt-bindings: input: fix bracket
From: Hugo Villeneuve @ 2026-07-10 12:11 UTC (permalink / raw)
To: Manuel Ebner
Cc: Hugo Villeneuve, Dmitry Torokhov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-input, devicetree,
linux-kernel
In-Reply-To: <20260710090153.431170-2-manuelebner@mailbox.org>
On Fri, 10 Jul 2026 11:01:53 +0200
Manuel Ebner <manuelebner@mailbox.org> wrote:
> [You don't often get email from manuelebner@mailbox.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> Add missing '('.
>
> Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
Acked-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
> ---
> .../devicetree/bindings/input/gpio-charlieplex-keypad.yaml | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml b/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
> index c085de6dab85..c6842c017934 100644
> --- a/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
> +++ b/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
> @@ -11,7 +11,7 @@ maintainers:
> - Hugo Villeneuve <hvilleneuve@dimonoff.com>
>
> description: |
> - The charlieplex keypad supports N^2)-N different key combinations (where N is
> + The charlieplex keypad supports (N^2)-N different key combinations (where N is
> the number of I/O lines). Key presses and releases are detected by configuring
> only one line as output at a time, and reading other line states. This process
> is repeated for each line. Diodes are required to ensure current flows in only
> --
> 2.54.0
>
--
Hugo Villeneuve
^ permalink raw reply
* Re: [PATCH v6 0/9] HID: steelseries: split out Arctis driver and add Nova 5X/Nova 7 support
From: Bastien Nocera @ 2026-07-10 12:02 UTC (permalink / raw)
To: Sriman Achanta, Jiri Kosina, Benjamin Tissoires
Cc: linux-input, linux-kernel, Simon Wood, Christian Mayer
In-Reply-To: <20260709032316.1908460-1-68172138+srimanachanta@users.noreply.github.com>
Hey Sriman,
I won't have time to review the patchset this week, but I've created a
test kernel for Fedora 44 users, which should stay available for about
a week (IIRC).
https://koji.fedoraproject.org/koji/taskinfo?taskID=147618251
I'll try to send my review next week.
Regards
On Wed, 2026-07-08 at 23:23 -0400, Sriman Achanta wrote:
> From: Sriman Achanta <srimanachanta@gmail.com>
>
> This series moves the SteelSeries Arctis headset support out of
> hid-steelseries.c into its own module, reworks it around a per-model
> device_info table, hardens the battery power-supply lifetime, adds an
> asynchronous status interface, and finally adds support for the
> Arctis
> Nova 5X and Nova 7 families. After the split, hid-steelseries.c is
> left
> handling only the SRW-S1 racing wheel.
>
> Changes since v5:
> - Nova: rename the Gen2-only parse function and device_info to
> steelseries_arctis_nova_{parse_status,info} now that they are also
> used by the Nova 5X and the 2026 refresh, not just Gen2.
> - Nova: add device IDs and a device_info for the original (pre-Gen2)
> Arctis Nova 7 family. It answers the same 0xb0/0xb7/0xb9/0xbb
> status
> opcodes on the same interfaces as Gen2, but reports battery
> capacity
> as a discrete 0-4 level rather than a raw percentage, so it gets
> its
> own parse function that maps the level through
> steelseries_map_capacity() instead of using it directly.
> - Nova: add the Arctis Nova 5X, which shares the Gen2/2026 protocol.
> - hid-ids.h: fix a whitespace-only bug where the new Nova 5X macro
> was
> space-aligned instead of tab-aligned.
> - Rebased on current master.
>
> The Nova 5X protocol was verified against hardware by
> sp4m.an.joker@gmail.com, and the original Nova 7 protocol was
> verified
> against hardware by colin@1101b.com. Thanks to both for testing. I
> previously ommited other devices in the v4 patch series due to being
> unable to verify.
>
> Sriman Achanta (9):
> HID: steelseries: Fix ARCTIS_1_X device mislabeling
> HID: steelseries: Split Arctis headset driver into separate module
> HID: steelseries: Inline and simplify SRWS1 wheel driver
> HID: steelseries: Refactor Arctis driver to use device_info
> framework
> HID: steelseries: Report POWER_SUPPLY_STATUS_FULL when full
> HID: steelseries: Correct Arctis 9 battery calibration range
> HID: steelseries: Manage battery lifetime with refcounting
> HID: steelseries: Add async status interface support
> HID: steelseries: Add support for Arctis Nova 5X and Nova 7
> families
>
> drivers/hid/Makefile | 2 +-
> drivers/hid/hid-ids.h | 18 +-
> drivers/hid/hid-quirks.c | 16 +-
> drivers/hid/hid-steelseries-arctis.c | 718
> +++++++++++++++++++++++++++
> drivers/hid/hid-steelseries.c | 406 +--------------
> 5 files changed, 759 insertions(+), 401 deletions(-)
> create mode 100644 drivers/hid/hid-steelseries-arctis.c
>
>
> base-commit: 7404ce51637231382873d0b55edabc2f3b841a9d
^ permalink raw reply
* Re: [PATCH] HID: tmff: Use 64-bit arithmetic for force feedback scaling
From: sashiko-bot @ 2026-07-10 10:35 UTC (permalink / raw)
To: Linmao Li; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260710102314.190094-1-lilinmao@kylinos.cn>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Structural race condition leading to NULL pointer dereference in Force Feedback initialization.
--
--- Patch [1]: [PATCH] HID: tmff: Use 64-bit arithmetic for force feedback scaling ---
commit b7654294b005de01aa2d8e34c8846bfff883d73f
Author: Linmao Li <lilinmao@kylinos.cn>
HID: tmff: Use 64-bit arithmetic for force feedback scaling
This commit fixes an integer overflow in force feedback scaling calculations
by using 64-bit intermediate variables. It updates both tmff_scale_u16() and
tmff_scale_s8() helpers to use div_s64() to prevent incorrect values when
processing logical minimum and maximums from HID report descriptors.
> diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
> index 423f395d01ac5..319e7b6703846 100644
> --- a/drivers/hid/hid-tmff.c
> +++ b/drivers/hid/hid-tmff.c
> @@ -17,6 +17,7 @@
>
> #include <linux/hid.h>
> #include <linux/input.h>
> +#include <linux/math64.h>
[Severity: High]
This isn't a bug introduced by this patch, but does the force feedback
initialization in this driver have a structural race condition?
Looking at tm_probe(), hid_hw_start() fully registers the input device and
exposes the event node to userspace before tmff_init() configures force
feedback:
drivers/hid/hid-tmff.c:tm_probe() {
...
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
if (ret) {
hid_err(hdev, "hw start failed\n");
goto err;
}
tmff_init(hdev, (void *)id->driver_data);
...
}
Inside tmff_init(), capability bits are set and the FF structures are
initialized:
drivers/hid/hid-tmff.c:tmff_init() {
...
for (i = 0; ff_bits[i] >= 0; i++)
set_bit(ff_bits[i], input_dev->ffbit);
break;
...
error = input_ff_create_memless(input_dev, tmff, tmff_play);
...
}
If a local user monitors for device creation, they might immediately open the
event node and issue an EVIOCSFF ioctl.
This would execute input_ff_upload(), which checks that EV_FF and the effect
bits are set. Since tmff_init() has already set the capabilities, could this
unconditionally call an uninitialized ff->upload pointer before
input_ff_create_memless() finishes setting it up?
Would it be possible to encounter a NULL pointer dereference here?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260710102314.190094-1-lilinmao@kylinos.cn?part=1
^ permalink raw reply
* [PATCH] HID: tmff: Use 64-bit arithmetic for force feedback scaling
From: Linmao Li @ 2026-07-10 10:23 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires
Cc: Dmitry Torokhov, Anssi Hannula, linux-input, linux-kernel,
Linmao Li
The logical minimum and maximum values come from the HID report
descriptor and cover the full signed 32-bit range. Subtracting them in
an int can overflow before the force feedback value is scaled. The
subsequent multiplication can overflow as well, producing an incorrect
value despite the final range checks.
Use 64-bit intermediates for both scaling helpers, as done by commit
48d1677779ad ("HID: pidff: Fix integer overflow in pidff_rescale") for
the same arithmetic in the PID driver. This keeps the arithmetic
defined for the complete descriptor range before the result is clamped.
Fixes: dc76c912145f ("Input: use new FF interface in the HID force feedback drivers")
Fixes: b27c9590ca0f ("HID: add support for Thrustmaster FGT Force Feedback wheel")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
---
drivers/hid/hid-tmff.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index 423f395d01ac..319e7b670384 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -17,6 +17,7 @@
#include <linux/hid.h>
#include <linux/input.h>
+#include <linux/math64.h>
#include <linux/slab.h>
#include <linux/module.h>
@@ -47,9 +48,9 @@ struct tmff_device {
/* Changes values from 0 to 0xffff into values from minimum to maximum */
static inline int tmff_scale_u16(unsigned int in, int minimum, int maximum)
{
- int ret;
+ s64 ret;
- ret = (in * (maximum - minimum) / 0xffff) + minimum;
+ ret = div_s64((s64)in * ((s64)maximum - minimum), 0xffff) + minimum;
if (ret < minimum)
return minimum;
if (ret > maximum)
@@ -60,9 +61,9 @@ static inline int tmff_scale_u16(unsigned int in, int minimum, int maximum)
/* Changes values from -0x80 to 0x7f into values from minimum to maximum */
static inline int tmff_scale_s8(int in, int minimum, int maximum)
{
- int ret;
+ s64 ret;
- ret = (((in + 0x80) * (maximum - minimum)) / 0xff) + minimum;
+ ret = div_s64((s64)(in + 0x80) * ((s64)maximum - minimum), 0xff) + minimum;
if (ret < minimum)
return minimum;
if (ret > maximum)
--
2.25.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox