* [PATCH 6.12.y 2/3] gpiolib: Remove redundant assignment of return variable
From: Quentin Schulz @ 2026-06-18 16:02 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman
Cc: linux-gpio, linux-kernel, Bartosz Golaszewski, Quentin Schulz,
Andy Shevchenko
In-Reply-To: <20260618-6-12-cve-2026-31732-v1-0-7ca0d0b906b0@cherry.de>
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 550300b9a295a591e0721a31f8c964a4bc08d51c ]
In some functions the returned variable is assigned to 0 and then
reassigned to the actual value. Remove redundant assignments.
In one case make it more clear that the assignment is not needed.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20250416095645.2027695-9-andriy.shevchenko@linux.intel.com
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
Stable-dep-of: 16fdabe143fc ("gpio: Fix resource leaks on errors in gpiochip_add_data_with_key()")
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
---
drivers/gpio/gpiolib.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index d48a57b899f79..97a32e6f901fc 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -939,7 +939,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
struct gpio_device *gdev;
unsigned int desc_index;
int base = 0;
- int ret = 0;
+ int ret;
/*
* First: allocate and populate the internal stat container, and
@@ -959,11 +959,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
device_set_node(&gdev->dev, gpiochip_choose_fwnode(gc));
- gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL);
- if (gdev->id < 0) {
- ret = gdev->id;
+ ret = ida_alloc(&gpio_ida, GFP_KERNEL);
+ if (ret < 0)
goto err_free_gdev;
- }
+ gdev->id = ret;
ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
if (ret)
@@ -2882,7 +2881,7 @@ EXPORT_SYMBOL_GPL(gpiod_direction_output);
*/
int gpiod_enable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags)
{
- int ret = 0;
+ int ret;
VALIDATE_DESC(desc);
@@ -2915,7 +2914,7 @@ EXPORT_SYMBOL_GPL(gpiod_enable_hw_timestamp_ns);
*/
int gpiod_disable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags)
{
- int ret = 0;
+ int ret;
VALIDATE_DESC(desc);
--
2.54.0
^ permalink raw reply related
* [PATCH 6.12.y 1/3] gpiolib: Extract gpiochip_choose_fwnode() for wider use
From: Quentin Schulz @ 2026-06-18 16:02 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman
Cc: linux-gpio, linux-kernel, Bartosz Golaszewski, Quentin Schulz,
Andy Shevchenko, Mathieu Dubois-Briand
In-Reply-To: <20260618-6-12-cve-2026-31732-v1-0-7ca0d0b906b0@cherry.de>
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 375790f18396b2ba706e031b150c58cd37b45a11 ]
Extract gpiochip_choose_fwnode() for the future use in another function.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Reviewed-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Link: https://lore.kernel.org/r/20250213195621.3133406-2-andriy.shevchenko@linux.intel.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Stable-dep-of: 16fdabe143fc ("gpio: Fix resource leaks on errors in gpiochip_add_data_with_key()")
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
---
drivers/gpio/gpiolib.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 5c8cd81656963..d48a57b899f79 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -883,6 +883,21 @@ void *gpiochip_get_data(struct gpio_chip *gc)
}
EXPORT_SYMBOL_GPL(gpiochip_get_data);
+/*
+ * If the calling driver provides the specific firmware node,
+ * use it. Otherwise use the one from the parent device, if any.
+ */
+static struct fwnode_handle *gpiochip_choose_fwnode(struct gpio_chip *gc)
+{
+ if (gc->fwnode)
+ return gc->fwnode;
+
+ if (gc->parent)
+ return dev_fwnode(gc->parent);
+
+ return NULL;
+}
+
int gpiochip_get_ngpios(struct gpio_chip *gc, struct device *dev)
{
u32 ngpios = gc->ngpio;
@@ -942,14 +957,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
gc->gpiodev = gdev;
gpiochip_set_data(gc, data);
- /*
- * If the calling driver did not initialize firmware node,
- * do it here using the parent device, if any.
- */
- if (gc->fwnode)
- device_set_node(&gdev->dev, gc->fwnode);
- else if (gc->parent)
- device_set_node(&gdev->dev, dev_fwnode(gc->parent));
+ device_set_node(&gdev->dev, gpiochip_choose_fwnode(gc));
gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL);
if (gdev->id < 0) {
--
2.54.0
^ permalink raw reply related
* [PATCH 6.12.y 3/3] gpio: Fix resource leaks on errors in gpiochip_add_data_with_key()
From: Quentin Schulz @ 2026-06-18 16:02 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman
Cc: linux-gpio, linux-kernel, Bartosz Golaszewski, Quentin Schulz,
Tzung-Bi Shih, stable, Linus Walleij, Bartosz Golaszewski
In-Reply-To: <20260618-6-12-cve-2026-31732-v1-0-7ca0d0b906b0@cherry.de>
From: Tzung-Bi Shih <tzungbi@kernel.org>
[ Upstream commit 16fdabe143fce2cbf89139677728e17e21b46c28 ]
Since commit aab5c6f20023 ("gpio: set device type for GPIO chips"),
`gdev->dev.release` is unset. As a result, the reference count to
`gdev->dev` isn't dropped on the error handling paths.
Drop the reference on errors.
Also reorder the instructions to make the error handling simpler.
Now gpiochip_add_data_with_key() roughly looks like:
>>> Some memory allocation. Go to ERR ZONE 1 on errors.
>>> device_initialize().
gpiodev_release() takes over the responsibility for freeing the
resources of `gdev->dev`. The subsequent error handling paths
shouldn't go through ERR ZONE 1 again which leads to double free.
>>> Some initialization mainly on `gdev`.
>>> The rest of initialization. Go to ERR ZONE 2 on errors.
>>> Chip registration success and exit.
>>> ERR ZONE 2. gpio_device_put() and exit.
>>> ERR ZONE 1.
Cc: stable@vger.kernel.org
Fixes: aab5c6f20023 ("gpio: set device type for GPIO chips")
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260205092840.2574840-1-tzungbi@kernel.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
[missing commit fcc8b637c542 ("gpiolib: switch the line state notifier
to atomic"), commit dcb73cbaaeb3 ("gpio: cdev: use raw notifier for
line state events") and commit d4f335b410dd ("gpiolib: rename GPIO chip
printk macros") in 6.12.y.
s/gpiochip_err/chip_err/ as well as replaced
rwlock_init+RAW_INIT_NOTIFIER_HEAD with BLOCKING_INIT_NOTIFIER_HEAD
based on missing commits, following same logic as in 16fdabe143fc.]
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
---
drivers/gpio/gpiolib.c | 121 ++++++++++++++++++++++++-------------------------
1 file changed, 58 insertions(+), 63 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 97a32e6f901fc..878f9ab4a0982 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -785,13 +785,15 @@ static const struct device_type gpio_dev_type = {
#define gcdev_unregister(gdev) device_del(&(gdev)->dev)
#endif
+/*
+ * An initial reference count has been held in gpiochip_add_data_with_key().
+ * The caller should drop the reference via gpio_device_put() on errors.
+ */
static int gpiochip_setup_dev(struct gpio_device *gdev)
{
struct fwnode_handle *fwnode = dev_fwnode(&gdev->dev);
int ret;
- device_initialize(&gdev->dev);
-
/*
* If fwnode doesn't belong to another device, it's safe to clear its
* initialized flag.
@@ -859,9 +861,11 @@ static void gpiochip_setup_devs(void)
list_for_each_entry_srcu(gdev, &gpio_devices, list,
srcu_read_lock_held(&gpio_devices_srcu)) {
ret = gpiochip_setup_dev(gdev);
- if (ret)
+ if (ret) {
+ gpio_device_put(gdev);
dev_err(&gdev->dev,
"Failed to initialize gpio device (%d)\n", ret);
+ }
}
}
@@ -941,33 +945,64 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
int base = 0;
int ret;
- /*
- * First: allocate and populate the internal stat container, and
- * set up the struct device.
- */
gdev = kzalloc(sizeof(*gdev), GFP_KERNEL);
if (!gdev)
return -ENOMEM;
-
- gdev->dev.type = &gpio_dev_type;
- gdev->dev.bus = &gpio_bus_type;
- gdev->dev.parent = gc->parent;
- rcu_assign_pointer(gdev->chip, gc);
-
gc->gpiodev = gdev;
gpiochip_set_data(gc, data);
- device_set_node(&gdev->dev, gpiochip_choose_fwnode(gc));
-
ret = ida_alloc(&gpio_ida, GFP_KERNEL);
if (ret < 0)
goto err_free_gdev;
gdev->id = ret;
- ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
+ ret = init_srcu_struct(&gdev->srcu);
if (ret)
goto err_free_ida;
+ rcu_assign_pointer(gdev->chip, gc);
+ ret = init_srcu_struct(&gdev->desc_srcu);
+ if (ret)
+ goto err_cleanup_gdev_srcu;
+
+ ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
+ if (ret)
+ goto err_cleanup_desc_srcu;
+
+ device_initialize(&gdev->dev);
+ /*
+ * After this point any allocated resources to `gdev` will be
+ * free():ed by gpiodev_release(). If you add new resources
+ * then make sure they get free():ed there.
+ */
+ gdev->dev.type = &gpio_dev_type;
+ gdev->dev.bus = &gpio_bus_type;
+ gdev->dev.parent = gc->parent;
+ device_set_node(&gdev->dev, gpiochip_choose_fwnode(gc));
+
+ ret = gpiochip_get_ngpios(gc, &gdev->dev);
+ if (ret)
+ goto err_put_device;
+ gdev->ngpio = gc->ngpio;
+
+ gdev->descs = kcalloc(gc->ngpio, sizeof(*gdev->descs), GFP_KERNEL);
+ if (!gdev->descs) {
+ ret = -ENOMEM;
+ goto err_put_device;
+ }
+
+ gdev->label = kstrdup_const(gc->label ?: "unknown", GFP_KERNEL);
+ if (!gdev->label) {
+ ret = -ENOMEM;
+ goto err_put_device;
+ }
+
+ gdev->can_sleep = gc->can_sleep;
+ BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
+ BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier);
+#ifdef CONFIG_PINCTRL
+ INIT_LIST_HEAD(&gdev->pin_ranges);
+#endif
if (gc->parent && gc->parent->driver)
gdev->owner = gc->parent->driver->owner;
else if (gc->owner)
@@ -976,36 +1011,6 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
else
gdev->owner = THIS_MODULE;
- ret = gpiochip_get_ngpios(gc, &gdev->dev);
- if (ret)
- goto err_free_dev_name;
-
- gdev->descs = kcalloc(gc->ngpio, sizeof(*gdev->descs), GFP_KERNEL);
- if (!gdev->descs) {
- ret = -ENOMEM;
- goto err_free_dev_name;
- }
-
- gdev->label = kstrdup_const(gc->label ?: "unknown", GFP_KERNEL);
- if (!gdev->label) {
- ret = -ENOMEM;
- goto err_free_descs;
- }
-
- gdev->ngpio = gc->ngpio;
- gdev->can_sleep = gc->can_sleep;
-
- BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
- BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier);
-
- ret = init_srcu_struct(&gdev->srcu);
- if (ret)
- goto err_free_label;
-
- ret = init_srcu_struct(&gdev->desc_srcu);
- if (ret)
- goto err_cleanup_gdev_srcu;
-
scoped_guard(mutex, &gpio_devices_lock) {
/*
* TODO: this allocates a Linux GPIO number base in the global
@@ -1020,7 +1025,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
if (base < 0) {
ret = base;
base = 0;
- goto err_cleanup_desc_srcu;
+ goto err_put_device;
}
/*
@@ -1040,14 +1045,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
ret = gpiodev_add_to_list_unlocked(gdev);
if (ret) {
chip_err(gc, "GPIO integer space overlap, cannot add chip\n");
- goto err_cleanup_desc_srcu;
+ goto err_put_device;
}
}
-#ifdef CONFIG_PINCTRL
- INIT_LIST_HEAD(&gdev->pin_ranges);
-#endif
-
if (gc->names)
gpiochip_set_desc_names(gc);
@@ -1128,25 +1129,19 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
scoped_guard(mutex, &gpio_devices_lock)
list_del_rcu(&gdev->list);
synchronize_srcu(&gpio_devices_srcu);
- if (gdev->dev.release) {
- /* release() has been registered by gpiochip_setup_dev() */
- gpio_device_put(gdev);
- goto err_print_message;
- }
+err_put_device:
+ gpio_device_put(gdev);
+ goto err_print_message;
+
err_cleanup_desc_srcu:
cleanup_srcu_struct(&gdev->desc_srcu);
err_cleanup_gdev_srcu:
cleanup_srcu_struct(&gdev->srcu);
-err_free_label:
- kfree_const(gdev->label);
-err_free_descs:
- kfree(gdev->descs);
-err_free_dev_name:
- kfree(dev_name(&gdev->dev));
err_free_ida:
ida_free(&gpio_ida, gdev->id);
err_free_gdev:
kfree(gdev);
+
err_print_message:
/* failures here can mean systems won't boot... */
if (ret != -EPROBE_DEFER) {
--
2.54.0
^ permalink raw reply related
* [PATCH 6.12.y v2 0/3] gpiolib: backport 16fdabe143fc
From: Quentin Schulz @ 2026-06-18 16:34 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman
Cc: linux-gpio, linux-kernel, Bartosz Golaszewski, stable,
Quentin Schulz, Andy Shevchenko, Mathieu Dubois-Briand,
Tzung-Bi Shih, Linus Walleij, Bartosz Golaszewski
Backport 16fdabe143fc ("gpio: Fix resource leaks on errors in
gpiochip_add_data_with_key()") to 6.12.y. To make the git diff more
similar with the upstream commit, also backport 375790f18396 ("gpiolib:
Extract gpiochip_choose_fwnode() for wider use") and 550300b9a295
("gpiolib: Remove redundant assignment of return variable").
The changes between 16fdabe143fc and the third patch of this series is
(according to git-range-diff):
"""
## drivers/gpio/gpiolib.c ##
@@ drivers/gpio/gpiolib.c: static const struct device_type gpio_dev_type = {
@@ drivers/gpio/gpiolib.c: int gpiochip_add_data_with_key(struct gpio_chip *gc, voi
+ }
+
+ gdev->can_sleep = gc->can_sleep;
-+ rwlock_init(&gdev->line_state_lock);
-+ RAW_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
++ BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
+ BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier);
+#ifdef CONFIG_PINCTRL
+ INIT_LIST_HEAD(&gdev->pin_ranges);
@@ drivers/gpio/gpiolib.c: int gpiochip_add_data_with_key(struct gpio_chip *gc, voi
- gdev->ngpio = gc->ngpio;
- gdev->can_sleep = gc->can_sleep;
-
-- rwlock_init(&gdev->line_state_lock);
-- RAW_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
+- BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
- BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier);
-
- ret = init_srcu_struct(&gdev->srcu);
@@ drivers/gpio/gpiolib.c: int gpiochip_add_data_with_key(struct gpio_chip *gc, voi
@@ drivers/gpio/gpiolib.c: int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
ret = gpiodev_add_to_list_unlocked(gdev);
if (ret) {
- gpiochip_err(gc, "GPIO integer space overlap, cannot add chip\n");
+ chip_err(gc, "GPIO integer space overlap, cannot add chip\n");
- goto err_cleanup_desc_srcu;
+ goto err_put_device;
}
"""
s/gpiochip_err/chip_err/ aside, the rest of the diff comes from feature
commits which do not fit the rules for backporting to stable.
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
---
Changes in v2:
- added stable@vger.kernel.org in Cc, apologies for the noise.
- Link to v1: https://patch.msgid.link/20260618-6-12-cve-2026-31732-v1-0-7ca0d0b906b0@cherry.de
---
Andy Shevchenko (2):
gpiolib: Extract gpiochip_choose_fwnode() for wider use
gpiolib: Remove redundant assignment of return variable
Tzung-Bi Shih (1):
gpio: Fix resource leaks on errors in gpiochip_add_data_with_key()
drivers/gpio/gpiolib.c | 156 +++++++++++++++++++++++++------------------------
1 file changed, 79 insertions(+), 77 deletions(-)
---
base-commit: 1d3a00d3bacff25652c96e1527610c69e91f7c38
change-id: 20260618-6-12-cve-2026-31732-63076d516720
Best regards,
--
Quentin Schulz <quentin.schulz@cherry.de>
^ permalink raw reply
* [PATCH 6.12.y v2 2/3] gpiolib: Remove redundant assignment of return variable
From: Quentin Schulz @ 2026-06-18 16:34 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman
Cc: linux-gpio, linux-kernel, Bartosz Golaszewski, stable,
Quentin Schulz, Andy Shevchenko
In-Reply-To: <20260618-6-12-cve-2026-31732-v2-0-42cc54b7bf04@cherry.de>
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 550300b9a295a591e0721a31f8c964a4bc08d51c ]
In some functions the returned variable is assigned to 0 and then
reassigned to the actual value. Remove redundant assignments.
In one case make it more clear that the assignment is not needed.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20250416095645.2027695-9-andriy.shevchenko@linux.intel.com
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
Stable-dep-of: 16fdabe143fc ("gpio: Fix resource leaks on errors in gpiochip_add_data_with_key()")
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
---
drivers/gpio/gpiolib.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index d48a57b899f79..97a32e6f901fc 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -939,7 +939,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
struct gpio_device *gdev;
unsigned int desc_index;
int base = 0;
- int ret = 0;
+ int ret;
/*
* First: allocate and populate the internal stat container, and
@@ -959,11 +959,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
device_set_node(&gdev->dev, gpiochip_choose_fwnode(gc));
- gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL);
- if (gdev->id < 0) {
- ret = gdev->id;
+ ret = ida_alloc(&gpio_ida, GFP_KERNEL);
+ if (ret < 0)
goto err_free_gdev;
- }
+ gdev->id = ret;
ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
if (ret)
@@ -2882,7 +2881,7 @@ EXPORT_SYMBOL_GPL(gpiod_direction_output);
*/
int gpiod_enable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags)
{
- int ret = 0;
+ int ret;
VALIDATE_DESC(desc);
@@ -2915,7 +2914,7 @@ EXPORT_SYMBOL_GPL(gpiod_enable_hw_timestamp_ns);
*/
int gpiod_disable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags)
{
- int ret = 0;
+ int ret;
VALIDATE_DESC(desc);
--
2.54.0
^ permalink raw reply related
* [PATCH 6.12.y v2 3/3] gpio: Fix resource leaks on errors in gpiochip_add_data_with_key()
From: Quentin Schulz @ 2026-06-18 16:34 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman
Cc: linux-gpio, linux-kernel, Bartosz Golaszewski, stable,
Quentin Schulz, Tzung-Bi Shih, Linus Walleij, Bartosz Golaszewski
In-Reply-To: <20260618-6-12-cve-2026-31732-v2-0-42cc54b7bf04@cherry.de>
From: Tzung-Bi Shih <tzungbi@kernel.org>
[ Upstream commit 16fdabe143fce2cbf89139677728e17e21b46c28 ]
Since commit aab5c6f20023 ("gpio: set device type for GPIO chips"),
`gdev->dev.release` is unset. As a result, the reference count to
`gdev->dev` isn't dropped on the error handling paths.
Drop the reference on errors.
Also reorder the instructions to make the error handling simpler.
Now gpiochip_add_data_with_key() roughly looks like:
>>> Some memory allocation. Go to ERR ZONE 1 on errors.
>>> device_initialize().
gpiodev_release() takes over the responsibility for freeing the
resources of `gdev->dev`. The subsequent error handling paths
shouldn't go through ERR ZONE 1 again which leads to double free.
>>> Some initialization mainly on `gdev`.
>>> The rest of initialization. Go to ERR ZONE 2 on errors.
>>> Chip registration success and exit.
>>> ERR ZONE 2. gpio_device_put() and exit.
>>> ERR ZONE 1.
Cc: stable@vger.kernel.org
Fixes: aab5c6f20023 ("gpio: set device type for GPIO chips")
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260205092840.2574840-1-tzungbi@kernel.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
[missing commit fcc8b637c542 ("gpiolib: switch the line state notifier
to atomic"), commit dcb73cbaaeb3 ("gpio: cdev: use raw notifier for
line state events") and commit d4f335b410dd ("gpiolib: rename GPIO chip
printk macros") in 6.12.y.
s/gpiochip_err/chip_err/ as well as replaced
rwlock_init+RAW_INIT_NOTIFIER_HEAD with BLOCKING_INIT_NOTIFIER_HEAD
based on missing commits, following same logic as in 16fdabe143fc.]
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
---
drivers/gpio/gpiolib.c | 121 ++++++++++++++++++++++++-------------------------
1 file changed, 58 insertions(+), 63 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 97a32e6f901fc..878f9ab4a0982 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -785,13 +785,15 @@ static const struct device_type gpio_dev_type = {
#define gcdev_unregister(gdev) device_del(&(gdev)->dev)
#endif
+/*
+ * An initial reference count has been held in gpiochip_add_data_with_key().
+ * The caller should drop the reference via gpio_device_put() on errors.
+ */
static int gpiochip_setup_dev(struct gpio_device *gdev)
{
struct fwnode_handle *fwnode = dev_fwnode(&gdev->dev);
int ret;
- device_initialize(&gdev->dev);
-
/*
* If fwnode doesn't belong to another device, it's safe to clear its
* initialized flag.
@@ -859,9 +861,11 @@ static void gpiochip_setup_devs(void)
list_for_each_entry_srcu(gdev, &gpio_devices, list,
srcu_read_lock_held(&gpio_devices_srcu)) {
ret = gpiochip_setup_dev(gdev);
- if (ret)
+ if (ret) {
+ gpio_device_put(gdev);
dev_err(&gdev->dev,
"Failed to initialize gpio device (%d)\n", ret);
+ }
}
}
@@ -941,33 +945,64 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
int base = 0;
int ret;
- /*
- * First: allocate and populate the internal stat container, and
- * set up the struct device.
- */
gdev = kzalloc(sizeof(*gdev), GFP_KERNEL);
if (!gdev)
return -ENOMEM;
-
- gdev->dev.type = &gpio_dev_type;
- gdev->dev.bus = &gpio_bus_type;
- gdev->dev.parent = gc->parent;
- rcu_assign_pointer(gdev->chip, gc);
-
gc->gpiodev = gdev;
gpiochip_set_data(gc, data);
- device_set_node(&gdev->dev, gpiochip_choose_fwnode(gc));
-
ret = ida_alloc(&gpio_ida, GFP_KERNEL);
if (ret < 0)
goto err_free_gdev;
gdev->id = ret;
- ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
+ ret = init_srcu_struct(&gdev->srcu);
if (ret)
goto err_free_ida;
+ rcu_assign_pointer(gdev->chip, gc);
+ ret = init_srcu_struct(&gdev->desc_srcu);
+ if (ret)
+ goto err_cleanup_gdev_srcu;
+
+ ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
+ if (ret)
+ goto err_cleanup_desc_srcu;
+
+ device_initialize(&gdev->dev);
+ /*
+ * After this point any allocated resources to `gdev` will be
+ * free():ed by gpiodev_release(). If you add new resources
+ * then make sure they get free():ed there.
+ */
+ gdev->dev.type = &gpio_dev_type;
+ gdev->dev.bus = &gpio_bus_type;
+ gdev->dev.parent = gc->parent;
+ device_set_node(&gdev->dev, gpiochip_choose_fwnode(gc));
+
+ ret = gpiochip_get_ngpios(gc, &gdev->dev);
+ if (ret)
+ goto err_put_device;
+ gdev->ngpio = gc->ngpio;
+
+ gdev->descs = kcalloc(gc->ngpio, sizeof(*gdev->descs), GFP_KERNEL);
+ if (!gdev->descs) {
+ ret = -ENOMEM;
+ goto err_put_device;
+ }
+
+ gdev->label = kstrdup_const(gc->label ?: "unknown", GFP_KERNEL);
+ if (!gdev->label) {
+ ret = -ENOMEM;
+ goto err_put_device;
+ }
+
+ gdev->can_sleep = gc->can_sleep;
+ BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
+ BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier);
+#ifdef CONFIG_PINCTRL
+ INIT_LIST_HEAD(&gdev->pin_ranges);
+#endif
if (gc->parent && gc->parent->driver)
gdev->owner = gc->parent->driver->owner;
else if (gc->owner)
@@ -976,36 +1011,6 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
else
gdev->owner = THIS_MODULE;
- ret = gpiochip_get_ngpios(gc, &gdev->dev);
- if (ret)
- goto err_free_dev_name;
-
- gdev->descs = kcalloc(gc->ngpio, sizeof(*gdev->descs), GFP_KERNEL);
- if (!gdev->descs) {
- ret = -ENOMEM;
- goto err_free_dev_name;
- }
-
- gdev->label = kstrdup_const(gc->label ?: "unknown", GFP_KERNEL);
- if (!gdev->label) {
- ret = -ENOMEM;
- goto err_free_descs;
- }
-
- gdev->ngpio = gc->ngpio;
- gdev->can_sleep = gc->can_sleep;
-
- BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
- BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier);
-
- ret = init_srcu_struct(&gdev->srcu);
- if (ret)
- goto err_free_label;
-
- ret = init_srcu_struct(&gdev->desc_srcu);
- if (ret)
- goto err_cleanup_gdev_srcu;
-
scoped_guard(mutex, &gpio_devices_lock) {
/*
* TODO: this allocates a Linux GPIO number base in the global
@@ -1020,7 +1025,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
if (base < 0) {
ret = base;
base = 0;
- goto err_cleanup_desc_srcu;
+ goto err_put_device;
}
/*
@@ -1040,14 +1045,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
ret = gpiodev_add_to_list_unlocked(gdev);
if (ret) {
chip_err(gc, "GPIO integer space overlap, cannot add chip\n");
- goto err_cleanup_desc_srcu;
+ goto err_put_device;
}
}
-#ifdef CONFIG_PINCTRL
- INIT_LIST_HEAD(&gdev->pin_ranges);
-#endif
-
if (gc->names)
gpiochip_set_desc_names(gc);
@@ -1128,25 +1129,19 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
scoped_guard(mutex, &gpio_devices_lock)
list_del_rcu(&gdev->list);
synchronize_srcu(&gpio_devices_srcu);
- if (gdev->dev.release) {
- /* release() has been registered by gpiochip_setup_dev() */
- gpio_device_put(gdev);
- goto err_print_message;
- }
+err_put_device:
+ gpio_device_put(gdev);
+ goto err_print_message;
+
err_cleanup_desc_srcu:
cleanup_srcu_struct(&gdev->desc_srcu);
err_cleanup_gdev_srcu:
cleanup_srcu_struct(&gdev->srcu);
-err_free_label:
- kfree_const(gdev->label);
-err_free_descs:
- kfree(gdev->descs);
-err_free_dev_name:
- kfree(dev_name(&gdev->dev));
err_free_ida:
ida_free(&gpio_ida, gdev->id);
err_free_gdev:
kfree(gdev);
+
err_print_message:
/* failures here can mean systems won't boot... */
if (ret != -EPROBE_DEFER) {
--
2.54.0
^ permalink raw reply related
* [PATCH 6.12.y v2 1/3] gpiolib: Extract gpiochip_choose_fwnode() for wider use
From: Quentin Schulz @ 2026-06-18 16:34 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman
Cc: linux-gpio, linux-kernel, Bartosz Golaszewski, stable,
Quentin Schulz, Andy Shevchenko, Mathieu Dubois-Briand
In-Reply-To: <20260618-6-12-cve-2026-31732-v2-0-42cc54b7bf04@cherry.de>
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 375790f18396b2ba706e031b150c58cd37b45a11 ]
Extract gpiochip_choose_fwnode() for the future use in another function.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Reviewed-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Link: https://lore.kernel.org/r/20250213195621.3133406-2-andriy.shevchenko@linux.intel.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Stable-dep-of: 16fdabe143fc ("gpio: Fix resource leaks on errors in gpiochip_add_data_with_key()")
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
---
drivers/gpio/gpiolib.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 5c8cd81656963..d48a57b899f79 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -883,6 +883,21 @@ void *gpiochip_get_data(struct gpio_chip *gc)
}
EXPORT_SYMBOL_GPL(gpiochip_get_data);
+/*
+ * If the calling driver provides the specific firmware node,
+ * use it. Otherwise use the one from the parent device, if any.
+ */
+static struct fwnode_handle *gpiochip_choose_fwnode(struct gpio_chip *gc)
+{
+ if (gc->fwnode)
+ return gc->fwnode;
+
+ if (gc->parent)
+ return dev_fwnode(gc->parent);
+
+ return NULL;
+}
+
int gpiochip_get_ngpios(struct gpio_chip *gc, struct device *dev)
{
u32 ngpios = gc->ngpio;
@@ -942,14 +957,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
gc->gpiodev = gdev;
gpiochip_set_data(gc, data);
- /*
- * If the calling driver did not initialize firmware node,
- * do it here using the parent device, if any.
- */
- if (gc->fwnode)
- device_set_node(&gdev->dev, gc->fwnode);
- else if (gc->parent)
- device_set_node(&gdev->dev, dev_fwnode(gc->parent));
+ device_set_node(&gdev->dev, gpiochip_choose_fwnode(gc));
gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL);
if (gdev->id < 0) {
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v2 0/1] gpiolib: acpi: Add quirk for ASUS ROG Strix G16 G614 series
From: Marco Scardovi @ 2026-06-18 16:59 UTC (permalink / raw)
To: Basavaraj Natikar, Andy Shevchenko
Cc: w_armin, brgl, linusw, linux-acpi, linux-gpio, linux-kernel,
mario.limonciello, westeri
In-Reply-To: <ajQCOQzWEmNkzCVc@ashevche-desk.local>
On Thu, Jun 18, 2026 at 16:35:37 CEST, Andy Shevchenko wrote:
> On Thu, Jun 18, 2026 at 06:46:28PM +0530, Basavaraj Natikar wrote:
> > On 6/18/2026 4:44 AM, Marco Scardovi wrote:
> > > On Wed, Jun 17, 2026 at 10:33 PM, Armin Wolf wrote:
> ...
>
> > > I have extracted and decompiled the ACPI tables (DSDT and SSDTs) from
> > > acpidump. You can find the raw acpidump.out and the decompiled ASL
> > > tables in the following Google Drive folder:
> > > https://drive.google.com/drive/folders/1aTqLAnUhrTsPdpA8tfOFyRopG3P3DGnc
> > > ?usp=drive_link
> > >
> > > As far as I can see/understand there is no _DSM method defined under the
> > > GPIO controller device (AMDI0030) or the \_SB.GPIO scope.
> > >
> > > Under the _AEI method (defined in SSDT9 line 188-193), pin 21 (0x15) and
> > > pin 24 (0x18) are defined as:
> > >
> > > GpioInt (Edge, ActiveBoth, ExclusiveAndWake, PullNone, 0x0000,
> > >
> > > "\\_SB.GPIO", 0x00, ResourceConsumer, ,
> > > )
> > > {
> > >
> > > 0x0015 // Pin 21 (Touchpad attention line)
> > >
> > > }
> > >
> > > When triggered, they evaluate the _EVT method which calls:
> > > Case (0x15)
> > > {
> > >
> > > \_SB.PCI0.SBRG.HNC0 (0x15, Zero)
> > >
> > > }
> > >
> > > Since Arg1 is Zero, HNC0 executes the Else branch, invoking M009 and
> > > ATKM/ADTM, which stalls synchronously for ~36 seconds when executed
> > > during the probe path at boot time.
> >
> > I traced the _EVT for pin 21 through the dumps:
> >
> > _EVT(0x15) → \_SB.PCI0.SBRG.HNC0(0x15, Zero). With Arg1==0 it takes the
> > Else branch: M009(), then Notify(^^GPP0.PEGP, 0x81) "Information Change"
> > to the dGPU, then ATKM(0xC0)/ADTM().
It seems I have much more to study about ACPI Tables. Sorry for the confusion
and thank you for checking it out.
> >
> > So this _AEI event is dGPU/graphics‑related (it notifies PEGP), not the
> > touchpad — the earlier "touchpad" characterization is incorrect. The
> > touchpad (TPD0, _HID "ASUE1416", _CID "PNP0C50") has its own GpioInt() in
> > its _CRS on a different line (pin 0x08, Level/ActiveLow).
> >
> > The ~36 s stall is consistent with these synchronous MMIO reads + dGPU
> > notify \running in the boot probe path while the GPU isn't ready
> > (no explicit Sleep in the path; a trace_method_name on HNC0/M049 would
> > confirm the exact blocking access).
> > Either way, running this AML synchronously at boot is the firmware issue
> > the no_edge_events_on_boot quirk works around.
> >
> > Could you update the commit message accordingly — in particular, drop the
> > "touchpad" wording, since pin 21's _AEI event is the dGPU notify path, not
> > the touchpad?
I'll do it. Let also me know for @Andy request below.
> Thanks for the details! The crucial and most important question here, is AMD
> going to push OEM(s) to fix firmware accordingly?
It seems ASUS released a new BIOS update 2 days ago specifically for my device.
You can find the new acpidump here:
https://drive.google.com/drive/folders/1PYmF1R9n-6vHJVSH8bzEPZhRgdmBBJlT?usp=sharing
^ permalink raw reply
* Re: [PATCH v2 0/1] gpiolib: acpi: Add quirk for ASUS ROG Strix G16 G614 series
From: Andy Shevchenko @ 2026-06-18 18:01 UTC (permalink / raw)
To: Marco Scardovi
Cc: Basavaraj Natikar, w_armin, brgl, linusw, linux-acpi, linux-gpio,
linux-kernel, mario.limonciello, westeri
In-Reply-To: <AeA8zl9ySbqIYxvm7aBj4Q@disroot.org>
On Thu, Jun 18, 2026 at 06:59:15PM +0200, Marco Scardovi wrote:
> On Thu, Jun 18, 2026 at 16:35:37 CEST, Andy Shevchenko wrote:
> > On Thu, Jun 18, 2026 at 06:46:28PM +0530, Basavaraj Natikar wrote:
> > > On 6/18/2026 4:44 AM, Marco Scardovi wrote:
> > > > On Wed, Jun 17, 2026 at 10:33 PM, Armin Wolf wrote:
...
> > > > I have extracted and decompiled the ACPI tables (DSDT and SSDTs) from
> > > > acpidump. You can find the raw acpidump.out and the decompiled ASL
> > > > tables in the following Google Drive folder:
> > > > https://drive.google.com/drive/folders/1aTqLAnUhrTsPdpA8tfOFyRopG3P3DGnc
> > > > ?usp=drive_link
> > > >
> > > > As far as I can see/understand there is no _DSM method defined under the
> > > > GPIO controller device (AMDI0030) or the \_SB.GPIO scope.
> > > >
> > > > Under the _AEI method (defined in SSDT9 line 188-193), pin 21 (0x15) and
> > > > pin 24 (0x18) are defined as:
> > > >
> > > > GpioInt (Edge, ActiveBoth, ExclusiveAndWake, PullNone, 0x0000,
> > > >
> > > > "\\_SB.GPIO", 0x00, ResourceConsumer, ,
> > > > )
> > > > {
> > > >
> > > > 0x0015 // Pin 21 (Touchpad attention line)
> > > >
> > > > }
> > > >
> > > > When triggered, they evaluate the _EVT method which calls:
> > > > Case (0x15)
> > > > {
> > > >
> > > > \_SB.PCI0.SBRG.HNC0 (0x15, Zero)
> > > >
> > > > }
> > > >
> > > > Since Arg1 is Zero, HNC0 executes the Else branch, invoking M009 and
> > > > ATKM/ADTM, which stalls synchronously for ~36 seconds when executed
> > > > during the probe path at boot time.
> > >
> > > I traced the _EVT for pin 21 through the dumps:
> > >
> > > _EVT(0x15) → \_SB.PCI0.SBRG.HNC0(0x15, Zero). With Arg1==0 it takes the
> > > Else branch: M009(), then Notify(^^GPP0.PEGP, 0x81) "Information Change"
> > > to the dGPU, then ATKM(0xC0)/ADTM().
>
> It seems I have much more to study about ACPI Tables. Sorry for the confusion
> and thank you for checking it out.
>
> > > So this _AEI event is dGPU/graphics‑related (it notifies PEGP), not the
> > > touchpad — the earlier "touchpad" characterization is incorrect. The
> > > touchpad (TPD0, _HID "ASUE1416", _CID "PNP0C50") has its own GpioInt() in
> > > its _CRS on a different line (pin 0x08, Level/ActiveLow).
> > >
> > > The ~36 s stall is consistent with these synchronous MMIO reads + dGPU
> > > notify \running in the boot probe path while the GPU isn't ready
> > > (no explicit Sleep in the path; a trace_method_name on HNC0/M049 would
> > > confirm the exact blocking access).
> > > Either way, running this AML synchronously at boot is the firmware issue
> > > the no_edge_events_on_boot quirk works around.
> > >
> > > Could you update the commit message accordingly — in particular, drop the
> > > "touchpad" wording, since pin 21's _AEI event is the dGPU notify path, not
> > > the touchpad?
>
> I'll do it. Let also me know for @Andy request below.
>
> > Thanks for the details! The crucial and most important question here, is AMD
> > going to push OEM(s) to fix firmware accordingly?
>
> It seems ASUS released a new BIOS update 2 days ago specifically for my device.
> You can find the new acpidump here:
> https://drive.google.com/drive/folders/1PYmF1R9n-6vHJVSH8bzEPZhRgdmBBJlT?usp=sharing
Have you tried it already?
At least the DSDT has neither _AEI, nor ActiveBoth for anything (except speaker
device). Looks promising to me as a fixed version.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v2 0/1] gpiolib: acpi: Add quirk for ASUS ROG Strix G16 G614 series
From: Marco Scardovi @ 2026-06-18 18:07 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Basavaraj Natikar, w_armin, brgl, linusw, linux-acpi, linux-gpio,
linux-kernel, mario.limonciello, westeri
In-Reply-To: <ajQyhOuvripaiXEq@ashevche-desk.local>
In data giovedì 18 giugno 2026 20:01:40 Ora legale dell’Europa centrale, Andy Shevchenko ha scritto:
> On Thu, Jun 18, 2026 at 06:59:15PM +0200, Marco Scardovi wrote:
> > On Thu, Jun 18, 2026 at 16:35:37 CEST, Andy Shevchenko wrote:
> > > On Thu, Jun 18, 2026 at 06:46:28PM +0530, Basavaraj Natikar wrote:
> > > > On 6/18/2026 4:44 AM, Marco Scardovi wrote:
> > > > > On Wed, Jun 17, 2026 at 10:33 PM, Armin Wolf wrote:
>
> ...
>
> > > > > I have extracted and decompiled the ACPI tables (DSDT and SSDTs) from
> > > > > acpidump. You can find the raw acpidump.out and the decompiled ASL
> > > > > tables in the following Google Drive folder:
> > > > > https://drive.google.com/drive/folders/1aTqLAnUhrTsPdpA8tfOFyRopG3P3DGnc
> > > > > ?usp=drive_link
> > > > >
> > > > > As far as I can see/understand there is no _DSM method defined under the
> > > > > GPIO controller device (AMDI0030) or the \_SB.GPIO scope.
> > > > >
> > > > > Under the _AEI method (defined in SSDT9 line 188-193), pin 21 (0x15) and
> > > > > pin 24 (0x18) are defined as:
> > > > >
> > > > > GpioInt (Edge, ActiveBoth, ExclusiveAndWake, PullNone, 0x0000,
> > > > >
> > > > > "\\_SB.GPIO", 0x00, ResourceConsumer, ,
> > > > > )
> > > > > {
> > > > >
> > > > > 0x0015 // Pin 21 (Touchpad attention line)
> > > > >
> > > > > }
> > > > >
> > > > > When triggered, they evaluate the _EVT method which calls:
> > > > > Case (0x15)
> > > > > {
> > > > >
> > > > > \_SB.PCI0.SBRG.HNC0 (0x15, Zero)
> > > > >
> > > > > }
> > > > >
> > > > > Since Arg1 is Zero, HNC0 executes the Else branch, invoking M009 and
> > > > > ATKM/ADTM, which stalls synchronously for ~36 seconds when executed
> > > > > during the probe path at boot time.
> > > >
> > > > I traced the _EVT for pin 21 through the dumps:
> > > >
> > > > _EVT(0x15) → \_SB.PCI0.SBRG.HNC0(0x15, Zero). With Arg1==0 it takes the
> > > > Else branch: M009(), then Notify(^^GPP0.PEGP, 0x81) "Information Change"
> > > > to the dGPU, then ATKM(0xC0)/ADTM().
> >
> > It seems I have much more to study about ACPI Tables. Sorry for the confusion
> > and thank you for checking it out.
> >
> > > > So this _AEI event is dGPU/graphics‑related (it notifies PEGP), not the
> > > > touchpad — the earlier "touchpad" characterization is incorrect. The
> > > > touchpad (TPD0, _HID "ASUE1416", _CID "PNP0C50") has its own GpioInt() in
> > > > its _CRS on a different line (pin 0x08, Level/ActiveLow).
> > > >
> > > > The ~36 s stall is consistent with these synchronous MMIO reads + dGPU
> > > > notify \running in the boot probe path while the GPU isn't ready
> > > > (no explicit Sleep in the path; a trace_method_name on HNC0/M049 would
> > > > confirm the exact blocking access).
> > > > Either way, running this AML synchronously at boot is the firmware issue
> > > > the no_edge_events_on_boot quirk works around.
> > > >
> > > > Could you update the commit message accordingly — in particular, drop the
> > > > "touchpad" wording, since pin 21's _AEI event is the dGPU notify path, not
> > > > the touchpad?
> >
> > I'll do it. Let also me know for @Andy request below.
> >
> > > Thanks for the details! The crucial and most important question here, is AMD
> > > going to push OEM(s) to fix firmware accordingly?
> >
> > It seems ASUS released a new BIOS update 2 days ago specifically for my device.
> > You can find the new acpidump here:
> > https://drive.google.com/drive/folders/1PYmF1R9n-6vHJVSH8bzEPZhRgdmBBJlT?usp=sharing
>
> Have you tried it already?
>
> At least the DSDT has neither _AEI, nor ActiveBoth for anything (except speaker
> device). Looks promising to me as a fixed version.
>
Yes, it didn't solve the boot time problem
^ permalink raw reply
* Re: [GIT PULL] pin control changes for the v7.2 kernel cycle
From: pr-tracker-bot @ 2026-06-18 23:16 UTC (permalink / raw)
To: Linus Walleij
Cc: Linus Torvalds, Linux pin control, LKML, Bartosz Golaszewski,
Conor Dooley
In-Reply-To: <CAD++jLnqGA6eYwbuds+cC0uWvGd-dEX7TPU39ghattp-tETXSA@mail.gmail.com>
The pull request you sent on Thu, 18 Jun 2026 15:00:07 +0200:
> git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git tags/pinctrl-v7.2-1
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/53c7db5c1916afcecc8683ae01ff8415c708a883
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* Re: [PATCH 6.12.y 0/3] gpiolib: backport 16fdabe143fc
From: Sasha Levin @ 2026-06-19 4:07 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman
Cc: Sasha Levin, linux-gpio, linux-kernel, Bartosz Golaszewski,
Quentin Schulz, Andy Shevchenko, Mathieu Dubois-Briand,
Tzung-Bi Shih, stable, Linus Walleij, Bartosz Golaszewski,
Quentin Schulz
In-Reply-To: <20260618-6-12-cve-2026-31732-v1-0-7ca0d0b906b0@cherry.de>
> [PATCH 6.12.y 0/3] gpiolib: backport 16fdabe143fc (gpio: Fix resource
> leaks on errors in gpiochip_add_data_with_key()) - CVE-2026-31732
Queued the series for 6.12, thanks.
--
Thanks,
Sasha
^ permalink raw reply
* Re: Question: pinctrl-backed GPIO set_config and gpio_chip::can_sleep
From: Linus Walleij @ 2026-06-19 7:43 UTC (permalink / raw)
To: Runyu Xiao
Cc: Linus Walleij, Bartosz Golaszewski, Ludovic Desroches,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea, Antonio Borneo,
Maxime Coquelin, Alexandre Torgue, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, linux-arm-kernel, linux-gpio, linux-stm32,
linux-sunxi, linux-kernel, jianhao.xu
In-Reply-To: <20260618151052.3984665-1-runyu.xiao@seu.edu.cn>
Hi Runyu,
On Thu, Jun 18, 2026 at 5:11 PM Runyu Xiao <runyu.xiao@seu.edu.cn> wrote:
> I agree that marking these memory-mapped controllers as can_sleep is too
> broad if the only sleepable part is the pinctrl range lookup. That would
> make consumers treat otherwise MMIO-backed get/set paths as sleepable,
> which is not the contract I want to change.
>
> I will hold back the at91-pio4/stm32/sunxi can_sleep series and look at
> the pinctrl core direction instead, specifically whether
> pinctrldev_list_mutex can be replaced by a non-sleeping lock for
> pinctrl_get_device_gpio_range(). That should also line up with the GPIO
> direction callback case discussed in the other thread.
Your replies look like those one would get from an AI agent,
because they are repeating information (context) that I have just
provided, just with other words.
If this is the case you need to instruct your agent to be terse in
mailing list replies: it needs to quote what I just said with >
markers in the margin and just add the word "Agreed" after
it.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH libgpiod] build: gate subdirectories on the *_enabled variables
From: Bartosz Golaszewski @ 2026-06-19 8:32 UTC (permalink / raw)
To: Linus Walleij, Vincent Fazio, Kent Gibson, Bartosz Golaszewski
Cc: brgl, linux-gpio
In-Reply-To: <20260617-meson-enabled-checks-v1-1-2ff45c7691fe@oss.qualcomm.com>
On Wed, 17 Jun 2026 15:46:28 +0200, Bartosz Golaszewski wrote:
> The top-level meson.build descends into tests/ and dbus/ only when the
> computed tests_enabled and dbus_enabled gates are true, so the test
> helper libraries and D-Bus executables are only defined in those cases.
> The per-component subdirectories instead re-checked opt_*.allowed(),
> which is true under the default 'auto' even when the dependencies are
> missing, and then referenced those undefined variables - failing the
> configuration outright instead of quietly disabling the component.
>
> [...]
Applied, thanks!
[1/1] build: gate subdirectories on the *_enabled variables
https://git.kernel.org/brgl/c/40538a7b48c9a6bd50d6253f86fdcb354b45073b
Best regards,
--
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v3 04/21] pinctrl: starfive: Add StarFive JHB100 sys0 controller driver
From: Changhuang Liang @ 2026-06-19 8:41 UTC (permalink / raw)
To: Linus Walleij
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Emil Renner Berthing, Paul Walmsley, Albert Ou, Palmer Dabbelt,
Alexandre Ghiti, Philipp Zabel, Bartosz Golaszewski,
linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, linux-riscv@lists.infradead.org,
Lianfeng Ouyang
In-Reply-To: <CAD++jL=Qd8ADR_kX2Q7msM4Dd0xFayPGM4ZzB3uv2ufvkuybtQ@mail.gmail.com>
Hi, Linus
Thanks for the review.
I will first try making revisions according to your suggestions below. It may take some time for
the next version. If I run into any issues during the subsequent revisions, I may bother you then.
Best Regards,
Changhuang
> Hi Changhuang,
>
> thanks for your patch!
>
> On Wed, Jun 3, 2026 at 7:54 AM Changhuang Liang
> <changhuang.liang@starfivetech.com> wrote:
>
> > Add pinctrl driver for StarFive JHB100 SoC System-0(sys0) pinctrl
> > controller.
> >
> > Co-developed-by: Lianfeng Ouyang <lianfeng.ouyang@starfivetech.com>
> > Signed-off-by: Lianfeng Ouyang <lianfeng.ouyang@starfivetech.com>
> > Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
>
> This patch adds generic infrastructure "JHB100" that is then used by several
> drivers does it not?
>
> Write something about that and some about the design in the commit
> message.
>
> > +++ b/drivers/pinctrl/starfive/pinctrl-starfive-jhb100-sys0.c
> > @@ -0,0 +1,123 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Pinctrl / GPIO driver for StarFive JHB100 SoC System-0 domain
> > + *
> > + * Copyright (C) 2024 StarFive Technology Co., Ltd.
> > + * Author: Alex Soo <yuklin.soo@starfivetech.com>
>
> Shouldn't this person be in the Signed-off-by?
>
> I guess it's not legally necessary but feels appropriate.
>
> > +static struct config_reg_layout_desc jhb100_sys0_pinctrl_crl_desc[] = {
> > + {
> > + .pin_start = 0,
> > + .pin_cnt = 4,
> > + .drive_strength_2bit = { .shift = 0, .width
> = 2 },
> > + .input_enable = { .shift =
> 2, .width = 1 },
> > + .pull_down = { .shift =
> 3, .width = 1 },
> > + .pull_up = { .shift =
> 4, .width = 1 },
> > + .slew_rate = { .shift =
> 5, .width = 1 },
> > + .schmitt_trigger_select = { .shift = 6, .width =
> 1 },
> > + .reserved = { .shift =
> 7, .width = 8 },
> > + .debounce_width = { .shift =
> 15, .width = 17 },
> > + },
> > + {
> > + .pin_start = 4,
> > + .pin_cnt = 5,
> > + .schmitt_trigger_select = { .shift = 0, .width =
> 1 },
> > + .reserved = { .shift =
> 1, .width = 31 },
> > + },
> > + {
> > + .pin_start = 9,
> > + .pin_cnt = 1,
> > + .drive_strength_2bit = { .shift = 0, .width
> = 2 },
> > + .slew_rate = { .shift =
> 2, .width = 1 },
> > + .reserved = { .shift =
> 3, .width = 29 },
> > + },
> > + {
> > + .pin_start = 10,
> > + .pin_cnt = 1,
> > + .drive_strength_2bit = { .shift = 0, .width
> = 2 },
> > + .input_enable = { .shift =
> 2, .width = 1 },
> > + .pull_down = { .shift =
> 3, .width = 1 },
> > + .pull_up = { .shift =
> 4, .width = 1 },
> > + .slew_rate = { .shift =
> 5, .width = 1 },
> > + .schmitt_trigger_select = { .shift = 6, .width =
> 1 },
> > + .reserved = { .shift =
> 7, .width = 25 },
> > + },
> > + { 0xff },
> > +};
>
> Would it be appropriate to index the different register variants with a enum
> with a good name so it is easy to understand which variant each entry in the
> array is?
>
> > +#include <linux/string.h>
> > +#include <linux/sort.h>
>
> Hm why... I guess I will see.
>
> > +#define JHB100_DEBOUNCE_WIDTH_STAGES_MAX 0x1FFFFU
>
> Is that a GENMASK(16,0)?
>
> Since it seems to have something to do with bitfield widths.
>
> > +/* i2c open-drain pull-up select */
> > +#define JHB100_I2C_OPEN_DRAIN_PU_600_OHMS 0
> > +#define JHB100_I2C_OPEN_DRAIN_PU_900_OHMS 1
> > +#define JHB100_I2C_OPEN_DRAIN_PU_1200_OHMS 2
> > +#define JHB100_I2C_OPEN_DRAIN_PU_2000_OHMS 3
>
> Very nice and to the point! It's easy to read and understand drivers that are
> writing things out explicitly like this!
>
> > +#define JHB100_NR_GPIOS_PER_BANK 32
> (...)
> > +static inline struct jhb100_gpio_bank *jhb100_gc_to_bank(struct
> > +gpio_chip *gc) {
> > + return container_of(gc, struct jhb100_gpio_bank, gc); }
> > +
> > +static unsigned int jhb100_gpio_to_pin(struct gpio_chip *gc, unsigned
> > +int gpio) {
> > + struct jhb100_gpio_bank *bank = jhb100_gc_to_bank(gc);
> > +
> > + return bank->id * JHB100_NR_GPIOS_PER_BANK + gpio; }
>
> This usually tells me that GPIO_GENERIC can be used but maybe this has been
> discussed before...
>
> > +static const struct pinctrl_ops jhb100_pinctrl_ops = {
> > + .get_groups_count = pinctrl_generic_get_group_count,
> > + .get_group_name = pinctrl_generic_get_group_name,
> > + .get_group_pins = pinctrl_generic_get_group_pins,
> > + .dt_node_to_map =
> pinctrl_generic_pins_function_dt_node_to_map,
> > + .dt_free_map = pinctrl_utils_free_map,
> > +};
>
> Nice use of the generic helpers!
>
> > +static void jhb100_set_gpioval(struct jhb100_pinctrl *sfp, unsigned int pin,
> > + unsigned int val) {
> > + const struct jhb100_pinctrl_domain_info *info = sfp->info;
> > + unsigned int offset = 4 * (pin / 32);
> > + unsigned int shift = 1 * (pin % 32);
> > + unsigned int fs_offset = 4 * (pin / 16);
> > + unsigned int fs_shift = 2 * (pin % 16);
> > + u32 func_sel_mask;
> > + u32 dout, doen, fs;
> > + void __iomem *reg_gpio_o;
> > + void __iomem *reg_gpio_oen;
> > + void __iomem *reg_gpio_func_sel;
> > + unsigned long flags;
> > +
> > + reg_gpio_o = sfp->base + info->regs->output + offset;
> > + reg_gpio_oen = sfp->base + info->regs->output_en + offset;
> > + reg_gpio_func_sel = sfp->base + info->regs->func_sel.reg +
> > + fs_offset;
>
> The part from here:
>
> > + func_sel_mask = GENMASK(info->regs->func_sel.width_per_pin -
> > + 1, 0) << fs_shift;
> (...)
> > +
> > + raw_spin_lock_irqsave(&sfp->lock, flags);
> > + fs = readl_relaxed(reg_gpio_func_sel);
> > + if (fs & func_sel_mask) {
> > + fs &= ~func_sel_mask;
> > + writel_relaxed(fs, reg_gpio_func_sel);
> > + }
>
> ..to here seems to reimplement the shortcut
> .gpio_request_enable() in struct pinmux_ops.
>
> Then this:
>
> > + dout = val << shift;
> > + doen = 0;
>
> > + dout |= readl_relaxed(reg_gpio_o) & ~BIT(shift);
> > + writel_relaxed(dout, reg_gpio_o);
> > + doen |= readl_relaxed(reg_gpio_oen) & ~BIT(shift);
> > + writel_relaxed(doen, reg_gpio_oen);
>
> Seems more like the actual code that should be here.
>
> > + raw_spin_unlock_irqrestore(&sfp->lock, flags);
>
> Please use guards for these spinlocks. They make for less bugs.
>
> guard(raw_spinlock_irqsave)(&sfp->lock);
>
> > +static const struct pinmux_ops jhb100_pinmux_ops = {
> > + .get_functions_count = pinmux_generic_get_function_count,
> > + .get_function_name = pinmux_generic_get_function_name,
> > + .get_function_groups = pinmux_generic_get_function_groups,
> > + .set_mux = jhb100_set_mux,
> > +};
>
> Implement .gpio_request_enable() (see above) and
> .gpio_set_direction() see below.
>
> Maybe also .gpio_disable_free() if you need to deconfigure stuff when a pin is
> release from GPIO.
>
> > +static const struct pinconf_ops jhb100_pinconf_ops = {
> > + .pin_config_get = jhb100_pinconf_get,
> > + .pin_config_set = jhb100_pinconf_set,
> > + .pin_config_group_get = jhb100_pinconf_group_get,
> > + .pin_config_group_set = jhb100_pinconf_group_set,
> > + .is_generic = true,
> > +};
>
> Overall this looks nice, good use of the group config!
>
> > +static int jhb100_gpio_get_direction(struct gpio_chip *gc,
> > + unsigned int gpio) {
> > + struct jhb100_gpio_bank *bank = jhb100_gc_to_bank(gc);
> > + struct jhb100_pinctrl *sfp = gpiochip_get_data(gc);
> > + const struct jhb100_pinctrl_domain_info *info = sfp->info;
> > + unsigned int offset = 4 * bank->id;
> > + u32 doen;
> > + void __iomem *reg_gpio_oen;
> > +
> > + reg_gpio_oen = sfp->base + info->regs->output_en + offset;
> > +
> > + doen = (readl_relaxed(reg_gpio_oen) & BIT(gpio)) >> gpio;
> > +
> > + return doen == GPOEN_ENABLE ? GPIO_LINE_DIRECTION_OUT :
> > +GPIO_LINE_DIRECTION_IN; }
> > +
> > +static int jhb100_gpio_direction_input(struct gpio_chip *gc,
> > + unsigned int gpio) {
> > + struct jhb100_pinctrl *sfp = gpiochip_get_data(gc);
> > + struct device *dev = sfp->dev;
> > + struct config_reg_layout_desc *crl_desc;
> > + unsigned int pin = jhb100_gpio_to_pin(gc, gpio);
> > +
> > + crl_desc = get_crl_desc_by_pin(sfp, pin);
> > + if (!crl_desc) {
> > + dev_err(dev, "pin %d can't not found reg layout
> descriptor\n",
> > + pin);
> > + return -EINVAL;
> > + }
> > +
> > + jhb100_padcfg_rmw(sfp, pin,
> > + RL_DESC_GENMASK(crl_desc,
> input_enable) |
> > + RL_DESC_GENMASK(crl_desc,
> schmitt_trigger_select),
> > + RL_DESC_GENMASK(crl_desc,
> input_enable) |
> > + RL_DESC_GENMASK(crl_desc,
> > + schmitt_trigger_select));
>
> Instead of doing these writes directly into the config registers, implement
> .gpio_set_direction() in struct pinmux_ops and call the pinmux generic
> back-end.
>
> > +static int jhb100_gpio_direction_output(struct gpio_chip *gc,
> > + unsigned int gpio, int
> value)
> > +{
> > + struct jhb100_pinctrl *sfp = gpiochip_get_data(gc);
> > + struct device *dev = sfp->dev;
> > + struct config_reg_layout_desc *crl_desc;
> > + unsigned int pin = jhb100_gpio_to_pin(gc, gpio);
> > +
> > + jhb100_set_one_pin_mux(sfp, pin, 0,
> > + value ? GPOUT_HIGH :
> GPOUT_LOW);
> > +
> > + crl_desc = get_crl_desc_by_pin(sfp, pin);
> > + if (!crl_desc) {
> > + dev_err(dev, "pin %d can't not found reg layout
> descriptor\n",
> > + pin);
> > + return -EINVAL;
> > + }
> > +
> > + jhb100_padcfg_rmw(sfp, pin,
> > + RL_DESC_GENMASK(crl_desc,
> input_enable) |
> > + RL_DESC_GENMASK(crl_desc,
> schmitt_trigger_select) |
> > + RL_DESC_GENMASK(crl_desc, pull_down) |
> > + RL_DESC_GENMASK(crl_desc, pull_up),
> > + 0);
>
> Dito.
>
> > +static int jhb100_gpio_get(struct gpio_chip *gc, unsigned int gpio) {
> > + struct jhb100_gpio_bank *bank = jhb100_gc_to_bank(gc);
> > + struct jhb100_pinctrl *sfp = gpiochip_get_data(gc);
> > + const struct jhb100_pinctrl_domain_info *info = sfp->info;
> > + unsigned int offset = 4 * bank->id;
> > + u32 doen = 0;
> > + void __iomem *reg_gpio_oen;
> > + void __iomem *reg;
> > + unsigned long flags;
> > +
> > + reg_gpio_oen = sfp->base + info->regs->output_en + offset;
> > + reg = sfp->base + info->regs->gpio_status + offset;
> > +
> > + raw_spin_lock_irqsave(&sfp->lock, flags);
> > + doen = readl_relaxed(reg_gpio_oen) | BIT(gpio);
> > + writel_relaxed(doen, reg_gpio_oen);
> > + raw_spin_unlock_irqrestore(&sfp->lock, flags);
>
> Why *on* *earth* are you read-modify-writing the output enable register in
> the *get* function? Is this a copy-on-paste error??
>
> > + return !!(readl_relaxed(reg) & BIT(gpio % 32));
>
> Also you never actuall read reg .... ehhhh this is a glaring bug.
>
> > +static int jhb100_gpio_set(struct gpio_chip *gc, unsigned int gpio,
> > +int value) {
> > + struct jhb100_gpio_bank *bank = jhb100_gc_to_bank(gc);
> > + struct jhb100_pinctrl *sfp = gpiochip_get_data(gc);
> > + const struct jhb100_pinctrl_domain_info *info = sfp->info;
> > + unsigned int offset = 4 * bank->id;
> > + void __iomem *reg_dout;
> > + u32 dout;
> > + unsigned long flags;
> > +
> > + reg_dout = sfp->base + info->regs->output + offset;
> > + dout = (value ? GPOUT_HIGH : GPOUT_LOW) << gpio;
> > +
> > + raw_spin_lock_irqsave(&sfp->lock, flags);
> > + dout |= readl_relaxed(reg_dout) & ~BIT(gpio);
> > + writel_relaxed(dout, reg_dout);
> > + raw_spin_unlock_irqrestore(&sfp->lock, flags);
> > +
> > + return 0;
> > +}
>
> This looks right, did you only test output and not input..?
>
> > +static const struct irq_chip jhb100_irq_chip = {
> > + .irq_ack = jhb100_irq_ack,
> > + .irq_mask = jhb100_irq_mask,
> > + .irq_mask_ack = jhb100_irq_mask_ack,
> > + .irq_unmask = jhb100_irq_unmask,
> > + .irq_set_type = jhb100_irq_set_type,
> > + .irq_set_wake = jhb100_irq_set_wake,
> > + .irq_print_chip = jhb100_irq_print_chip,
> > + .flags = IRQCHIP_SET_TYPE_MASKED |
> > + IRQCHIP_IMMUTABLE |
> > + IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND
> |
> > + IRQCHIP_MASK_ON_SUSPEND |
> > + IRQCHIP_SKIP_SET_WAKE,
> > + GPIOCHIP_IRQ_RESOURCE_HELPERS, };
>
> The irqchip looks good!
>
> > +static int field_compare(const void *a, const void *b) {
> > + const struct field_info *fa = (const struct field_info *)a;
> > + const struct field_info *fb = (const struct field_info *)b;
> > +
> > + if (fa->shift < fb->shift)
> > + return -1;
> > +
> > + if (fa->shift > fb->shift)
> > + return 1;
> > +
> > + return 0;
> > +}
>
> Are you sure the kernel doesn't already have a helper like this...
>
> > + sfp->num_banks = DIV_ROUND_UP(sfp->ngpios,
> > + JHB100_NR_GPIOS_PER_BANK);
> > +
> > + for (unsigned int i = 0; i < sfp->num_banks; i++) {
> > + if (sfp->ngpios > (i + 1) *
> JHB100_NR_GPIOS_PER_BANK)
> > + sfp->banks[i].gc.ngpio = (i + 1) *
> JHB100_NR_GPIOS_PER_BANK;
> > + else
> > + sfp->banks[i].gc.ngpio = sfp->ngpios - i *
> > + JHB100_NR_GPIOS_PER_BANK;
>
> This looks completely bananas, shouldn't this be simply:
>
> sfp->banks[i].gc.ngpio = JHB100_NR_GPIOS_PER_BANK;
>
> ???
>
> What is getting assigned to ngpios looks like a gpiochip base, and have all the
> signs of a real bad AI hallucination.
>
> > +
> > + sfp->banks[i].id = i;
> > +
> > + sfp->banks[i].gc.parent = dev;
> > + sfp->banks[i].gc.label = dev_name(dev);
> > + sfp->banks[i].gc.owner = THIS_MODULE;
> > + sfp->banks[i].gc.request = pinctrl_gpio_request;
>
> Use
> gpiochip_generic_request
>
> > + sfp->banks[i].gc.free = pinctrl_gpio_free;
>
> Use
> gpiochip_generic_free
>
> These calls will do what you want, and also check that the right gpio ranges
> are available.
>
> Make sure you add GPIO ranges (the mapping between pin control pins and
> corresponding GPIO offsets) for this to work properly.
>
> I'm pretty sure you can have a generic pin config backend as well.
>
> sfp->banks[i].gc.set_config = gpiochip_generic_config;
>
> This will make config calls to the gpiochip call into the pinctrl backend = what
> you want.
>
> > + sfp->banks[i].gc.get_direction =
> jhb100_gpio_get_direction;
> > + sfp->banks[i].gc.direction_input =
> jhb100_gpio_direction_input;
> > + sfp->banks[i].gc.direction_output =
> jhb100_gpio_direction_output;
> > + sfp->banks[i].gc.get = jhb100_gpio_get;
> > + sfp->banks[i].gc.set = jhb100_gpio_set;
> > + sfp->banks[i].gc.set_config = gpiochip_generic_config;
> > + sfp->banks[i].gc.base = -1;
> > + sfp->banks[i].gc.of_gpio_n_cells = 3;
> > + sfp->banks[i].gc.of_node_instance_match =
> > + starfive_of_node_instance_match;
>
> Since you have a threecell scheme with 32 gpios
> (JHB100_NR_GPIOS_PER_BANK) per instance (right? the ngpios code above
> made me really confused....) you should be able so select GPIO_GENERIC,
> #include <linux/gpio/generic.h> and use the generic GPIO pretty much the
> same way drivers/gpio/gpio-spacemit-k1.c does it, check that driver out
> (especially spacemit_gpio_add_bank()).
>
> Yours,
> Linus Walleij
^ permalink raw reply
* [PATCH] gpio: make gpio_chip_guard accept const gpio_desc
From: Archit More @ 2026-06-19 8:50 UTC (permalink / raw)
To: linux-gpio; +Cc: linux-kernel, linus.walleij, brgl, Archit More
Make gpio_chip_guard accept a const struct gpio_desc pointer,
allowing gpiod_get_raw_value_commit() and gpiod_to_irq() to use
the helper instead of open-coding SRCU-protected chip lookups.
This removes duplicated code and eliminates the FIXME comments
about gpio_chip_guard being unusable with const descriptors.
Signed-off-by: Archit More <architmore303@gmail.com>
---
drivers/gpio/gpiolib.c | 28 ++++++++--------------------
drivers/gpio/gpiolib.h | 2 +-
2 files changed, 9 insertions(+), 21 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 1e6dce430dca..3ee924b2ab94 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -3406,20 +3406,13 @@ static int gpio_chip_get_value(struct gpio_chip *gc, const struct gpio_desc *des
static int gpiod_get_raw_value_commit(const struct gpio_desc *desc)
{
- struct gpio_device *gdev;
- struct gpio_chip *gc;
int value;
- /* FIXME Unable to use gpio_chip_guard due to const desc. */
- gdev = desc->gdev;
-
- guard(srcu)(&gdev->srcu);
-
- gc = srcu_dereference(gdev->chip, &gdev->srcu);
- if (!gc)
+ CLASS(gpio_chip_guard, guard)(desc);
+ if (!guard.gc)
return -ENODEV;
- value = gpio_chip_get_value(gc, desc);
+ value = gpio_chip_get_value(guard.gc, desc);
value = value < 0 ? value : !!value;
trace_gpio_value(desc_to_gpio(desc), 1, value);
return value;
@@ -4126,8 +4119,6 @@ EXPORT_SYMBOL_GPL(gpiod_is_shared);
*/
int gpiod_to_irq(const struct gpio_desc *desc)
{
- struct gpio_device *gdev;
- struct gpio_chip *gc;
int offset;
int ret;
@@ -4135,16 +4126,13 @@ int gpiod_to_irq(const struct gpio_desc *desc)
if (ret <= 0)
return -EINVAL;
- gdev = desc->gdev;
- /* FIXME Cannot use gpio_chip_guard due to const desc. */
- guard(srcu)(&gdev->srcu);
- gc = srcu_dereference(gdev->chip, &gdev->srcu);
- if (!gc)
+ CLASS(gpio_chip_guard, guard)(desc);
+ if (!guard.gc)
return -ENODEV;
offset = gpiod_hwgpio(desc);
- if (gc->to_irq) {
- ret = gc->to_irq(gc, offset);
+ if (guard.gc->to_irq) {
+ ret = guard.gc->to_irq(guard.gc, offset);
if (ret)
return ret;
@@ -4152,7 +4140,7 @@ int gpiod_to_irq(const struct gpio_desc *desc)
return -ENXIO;
}
#ifdef CONFIG_GPIOLIB_IRQCHIP
- if (gc->irq.chip) {
+ if (guard.gc->irq.chip) {
/*
* Avoid race condition with other code, which tries to lookup
* an IRQ before the irqchip has been properly registered,
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index dc4cb61a9318..841b7f8dba6c 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -244,7 +244,7 @@ DEFINE_CLASS(gpio_chip_guard,
_guard;
}),
- struct gpio_desc *desc)
+ const struct gpio_desc *desc)
int gpiod_request(struct gpio_desc *desc, const char *label);
int gpiod_request_commit(struct gpio_desc *desc, const char *label);
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] gpio: make gpio_chip_guard accept const gpio_desc
From: Bartosz Golaszewski @ 2026-06-19 8:57 UTC (permalink / raw)
To: Archit More; +Cc: linux-kernel, linus.walleij, brgl, linux-gpio
In-Reply-To: <20260619085036.85242-1-architmore303@gmail.com>
On Fri, 19 Jun 2026 10:50:36 +0200, Archit More <architmore303@gmail.com> said:
> Make gpio_chip_guard accept a const struct gpio_desc pointer,
> allowing gpiod_get_raw_value_commit() and gpiod_to_irq() to use
> the helper instead of open-coding SRCU-protected chip lookups.
>
> This removes duplicated code and eliminates the FIXME comments
> about gpio_chip_guard being unusable with const descriptors.
>
> Signed-off-by: Archit More <architmore303@gmail.com>
> ---
This was already done in commit aa7e8b7ef031 ("gpio: core: fix const-correctness
of gpio_chip_guard"). Please always base your work on top of current linux-next.
Bart
^ permalink raw reply
* Re: Question: pinctrl-backed GPIO set_config and gpio_chip::can_sleep
From: Bartosz Golaszewski @ 2026-06-19 9:01 UTC (permalink / raw)
To: Linus Walleij
Cc: Linus Walleij, Bartosz Golaszewski, Ludovic Desroches,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea, Antonio Borneo,
Maxime Coquelin, Alexandre Torgue, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, linux-arm-kernel, linux-gpio, linux-stm32,
linux-sunxi, linux-kernel, jianhao.xu, Runyu Xiao
In-Reply-To: <CAD++jLmW3vgTFryRAL24x2TbgbR1tbhjw-nFFH3askoZfSibaQ@mail.gmail.com>
On Thu, 18 Jun 2026 15:15:30 +0200, Linus Walleij <linusw@kernel.org> said:
> Hi Runyu,
>
> thanks for your analysis!
>
> On Thu, Jun 18, 2026 at 7:42 AM Runyu Xiao <runyu.xiao@seu.edu.cn> wrote:
>
>> The path we are concerned about is:
>>
>> gpiod_set_config()
>> -> gpio_do_set_config()
>> -> gpiochip_generic_config()
>> -> pinctrl_gpio_set_config()
>> -> pinctrl_get_device_gpio_range()
>> -> mutex_lock(&pctldev->mutex)
>
> That would be mutex_lock(&pinctrldev_list_mutex); would it not?
>
>> If gpiod_cansleep() returns false, a GPIO forwarder or another consumer
>> can choose an atomic carrier and call gpiod_set_config() while holding a
>> spinlock.
>
> I see the problem.
>
>> The local draft I am considering marks only these controllers as
>> sleeping:
>>
>> pinctrl: at91-pio4: mark the GPIO controller as sleeping
>> pinctrl: stm32: mark the GPIO controller as sleeping
>> pinctrl: sunxi: mark the GPIO controller as sleeping
>>
>> The reason is that all three expose gpiochip_generic_config() and can
>> therefore reach the pinctrl mutex from the GPIO set_config path, while
>> their current gpio_chip registration does not set can_sleep.
>
> But that's not the right solution is it? These controllers can probably
> just write a register and be done with it, they all look like they are
> memory-mapped? That means we introduce sleep where not needed.
>
> Can we simply replace pinctrldev_list_mutex with a spinlock?
Oh I've tried, I've give it a few attempts in the past. It's not a "simply"
case this one! :)
> The list isn't gonna be huge and all in-memory anyway.
> If it takes too much time we need to think about putting the
> ranges in a better data structure such as the maple tree.
>
FWIW radix tree provides some RCU synchronization IIRC.
> mutex_lock(&pinctrldev_list_mutex); could then be turned
> into spinlock_irqsave() or even better
> guard(spinlock_irqsave)(&pinctrldev_list_lock) in
> pinctrl_get_device_gpio_range().
>
I recall running into places where a mutex would be taken in atomic context
in that case.
Bart
> This would mean we just take two different spinlocks in seqence
> and save state in each so it should work just fine.
>
> Yours,
> Linus Walleij
>
^ permalink raw reply
* Re: [PATCH v2 0/1] gpiolib: acpi: Add quirk for ASUS ROG Strix G16 G614 series
From: Basavaraj Natikar @ 2026-06-19 10:17 UTC (permalink / raw)
To: Marco Scardovi, Andy Shevchenko
Cc: w_armin, brgl, linusw, linux-acpi, linux-gpio, linux-kernel,
mario.limonciello, westeri
In-Reply-To: <_tDfR2zvSRyshOH99j8NCA@disroot.org>
On 6/18/2026 11:37 PM, Marco Scardovi wrote:
> In data giovedì 18 giugno 2026 20:01:40 Ora legale dell’Europa centrale, Andy Shevchenko ha scritto:
>> On Thu, Jun 18, 2026 at 06:59:15PM +0200, Marco Scardovi wrote:
>>> On Thu, Jun 18, 2026 at 16:35:37 CEST, Andy Shevchenko wrote:
>>>> On Thu, Jun 18, 2026 at 06:46:28PM +0530, Basavaraj Natikar wrote:
>>>>> On 6/18/2026 4:44 AM, Marco Scardovi wrote:
>>>>>> On Wed, Jun 17, 2026 at 10:33 PM, Armin Wolf wrote:
>> ...
>>
>>>>>> I have extracted and decompiled the ACPI tables (DSDT and SSDTs) from
>>>>>> acpidump. You can find the raw acpidump.out and the decompiled ASL
>>>>>> tables in the following Google Drive folder:
>>>>>> https://drive.google.com/drive/folders/1aTqLAnUhrTsPdpA8tfOFyRopG3P3DGnc
>>>>>> ?usp=drive_link
>>>>>>
>>>>>> As far as I can see/understand there is no _DSM method defined under the
>>>>>> GPIO controller device (AMDI0030) or the \_SB.GPIO scope.
>>>>>>
>>>>>> Under the _AEI method (defined in SSDT9 line 188-193), pin 21 (0x15) and
>>>>>> pin 24 (0x18) are defined as:
>>>>>>
>>>>>> GpioInt (Edge, ActiveBoth, ExclusiveAndWake, PullNone, 0x0000,
>>>>>>
>>>>>> "\\_SB.GPIO", 0x00, ResourceConsumer, ,
>>>>>> )
>>>>>> {
>>>>>>
>>>>>> 0x0015 // Pin 21 (Touchpad attention line)
>>>>>>
>>>>>> }
>>>>>>
>>>>>> When triggered, they evaluate the _EVT method which calls:
>>>>>> Case (0x15)
>>>>>> {
>>>>>>
>>>>>> \_SB.PCI0.SBRG.HNC0 (0x15, Zero)
>>>>>>
>>>>>> }
>>>>>>
>>>>>> Since Arg1 is Zero, HNC0 executes the Else branch, invoking M009 and
>>>>>> ATKM/ADTM, which stalls synchronously for ~36 seconds when executed
>>>>>> during the probe path at boot time.
>>>>> I traced the _EVT for pin 21 through the dumps:
>>>>>
>>>>> _EVT(0x15) → \_SB.PCI0.SBRG.HNC0(0x15, Zero). With Arg1==0 it takes the
>>>>> Else branch: M009(), then Notify(^^GPP0.PEGP, 0x81) "Information Change"
>>>>> to the dGPU, then ATKM(0xC0)/ADTM().
>>> It seems I have much more to study about ACPI Tables. Sorry for the confusion
>>> and thank you for checking it out.
>>>
>>>>> So this _AEI event is dGPU/graphics‑related (it notifies PEGP), not the
>>>>> touchpad — the earlier "touchpad" characterization is incorrect. The
>>>>> touchpad (TPD0, _HID "ASUE1416", _CID "PNP0C50") has its own GpioInt() in
>>>>> its _CRS on a different line (pin 0x08, Level/ActiveLow).
>>>>>
>>>>> The ~36 s stall is consistent with these synchronous MMIO reads + dGPU
>>>>> notify \running in the boot probe path while the GPU isn't ready
>>>>> (no explicit Sleep in the path; a trace_method_name on HNC0/M049 would
>>>>> confirm the exact blocking access).
>>>>> Either way, running this AML synchronously at boot is the firmware issue
>>>>> the no_edge_events_on_boot quirk works around.
>>>>>
>>>>> Could you update the commit message accordingly — in particular, drop the
>>>>> "touchpad" wording, since pin 21's _AEI event is the dGPU notify path, not
>>>>> the touchpad?
>>> I'll do it. Let also me know for @Andy request below.
>>>
>>>> Thanks for the details! The crucial and most important question here, is AMD
>>>> going to push OEM(s) to fix firmware accordingly?
>>> It seems ASUS released a new BIOS update 2 days ago specifically for my device.
>>> You can find the new acpidump here:
>>> https://drive.google.com/drive/folders/1PYmF1R9n-6vHJVSH8bzEPZhRgdmBBJlT?usp=sharing
>> Have you tried it already?
>>
>> At least the DSDT has neither _AEI, nor ActiveBoth for anything (except speaker
>> device). Looks promising to me as a fixed version.
>>
> Yes, it didn't solve the boot time problem
>
>
I also checked the BIOS 316 ACPI dump — the stalling path is byte‑for‑byte identical
to 315, so the AML is unchanged and it'll still stall if pin 21 boots low.
On the OEM side, I'm connecting internally with our AMD contact for ASUS to report
this behavior and follow up on a firmware fix.
Thanks,
--
Basavaraj
>
^ permalink raw reply
* Re: [PATCH v2 0/1] gpiolib: acpi: Add quirk for ASUS ROG Strix G16 G614 series
From: Marco Scardovi @ 2026-06-19 10:28 UTC (permalink / raw)
To: Andy Shevchenko, Basavaraj Natikar
Cc: w_armin, brgl, linusw, linux-acpi, linux-gpio, linux-kernel,
mario.limonciello, westeri
In-Reply-To: <9643455e-f4ce-4496-bcdf-1122420c18eb@amd.com>
In data venerdì 19 giugno 2026 12:17:17 Ora legale dell’Europa centrale, Basavaraj Natikar ha scritto:
> On 6/18/2026 11:37 PM, Marco Scardovi wrote:
> > In data giovedì 18 giugno 2026 20:01:40 Ora legale dell’Europa centrale, Andy Shevchenko ha scritto:
> >> On Thu, Jun 18, 2026 at 06:59:15PM +0200, Marco Scardovi wrote:
> >>> On Thu, Jun 18, 2026 at 16:35:37 CEST, Andy Shevchenko wrote:
> >>>> On Thu, Jun 18, 2026 at 06:46:28PM +0530, Basavaraj Natikar wrote:
> >>>>> On 6/18/2026 4:44 AM, Marco Scardovi wrote:
> >>>>>> On Wed, Jun 17, 2026 at 10:33 PM, Armin Wolf wrote:
...
>
> I also checked the BIOS 316 ACPI dump — the stalling path is byte‑for‑byte identical
> to 315, so the AML is unchanged and it'll still stall if pin 21 boots low.
>
> On the OEM side, I'm connecting internally with our AMD contact for ASUS to report
> this behavior and follow up on a firmware fix.
>
> Thanks,
> --
> Basavaraj
>
Hi Basavaraj,
Thank you. Does that mean that my patch will not be required anymore?
If that's the case you can consider it as null. I don't mind having the boot
flag added until it's completely fixed on ASUS' side. BTW I have the suspect
that my model is not the only one with the long boot bug on ASUS [1] [2]
but actually the only one who came up with an actual patch on the kernel.
[1] https://bbs.archlinux.org/viewtopic.php?id=307251
[2] https://rog-forum.asus.com/t5/rog-strix-series/linux-boot-is-very-slow-at-this-moment/td-p/1138746
^ permalink raw reply
* [PATCH] gpio: tegra: do not call pinctrl for GPIO direction
From: Runyu Xiao @ 2026-06-19 15:24 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski
Cc: Thierry Reding, Jonathan Hunter, linux-gpio, linux-tegra,
linux-kernel, Runyu Xiao, stable
tegra_gpio_direction_input() and tegra_gpio_direction_output() already
program the GPIO controller direction registers directly. The additional
pinctrl_gpio_direction_input/output() calls do not add a Tegra pinctrl
operation, because the Tegra pinmux ops provide GPIO request/free
handling but no gpio_set_direction hook.
The extra call still enters the pinctrl core and takes pctldev->mutex.
Shared GPIO users can call the direction path while holding their
per-line spinlock, so this otherwise redundant pinctrl direction call can
sleep in an atomic context.
This was found by our static analysis tool and then confirmed by manual
review of tegra_gpio_probe(), the Tegra GPIO direction callbacks and the
Tegra pinctrl ops. The reviewed path has a default non-sleeping
struct gpio_chip while the direction callback still enters the pinctrl
mutex path.
A directed runtime validation kept the same non-sleeping chip registration
and drove:
gpio_shared_proxy_direction_output()
gpiod_direction_output_raw_commit()
tegra_gpio_direction_output()
pinctrl_gpio_direction_output()
Lockdep reported a sleep-in-atomic warning with the shared GPIO spinlock
held and pinctrl_get_device_gpio_range() plus tegra_gpio_direction_output()
on the stack.
Do not mark the whole chip as can_sleep to paper over this: can_sleep
describes whether get()/set() may sleep, and Tegra value access is MMIO.
Remove the redundant pinctrl direction calls and keep pinctrl involvement
in the existing request/free path.
Fixes: 11da90541283 ("gpio: tegra: Fix offset of pinctrl calls")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
---
drivers/gpio/gpio-tegra.c | 18 ++----------------
1 file changed, 2 insertions(+), 16 deletions(-)
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 15a5762a82c2..590e81c1e4d1 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -172,18 +172,11 @@ static int tegra_gpio_direction_input(struct gpio_chip *chip,
unsigned int offset)
{
struct tegra_gpio_info *tgi = gpiochip_get_data(chip);
- int ret;
tegra_gpio_mask_write(tgi, GPIO_MSK_OE(tgi, offset), offset, 0);
tegra_gpio_enable(tgi, offset);
- ret = pinctrl_gpio_direction_input(chip, offset);
- if (ret < 0)
- dev_err(tgi->dev,
- "Failed to set pinctrl input direction of GPIO %d: %d",
- chip->base + offset, ret);
-
- return ret;
+ return 0;
}
static int tegra_gpio_direction_output(struct gpio_chip *chip,
@@ -191,19 +184,12 @@ static int tegra_gpio_direction_output(struct gpio_chip *chip,
int value)
{
struct tegra_gpio_info *tgi = gpiochip_get_data(chip);
- int ret;
tegra_gpio_set(chip, offset, value);
tegra_gpio_mask_write(tgi, GPIO_MSK_OE(tgi, offset), offset, 1);
tegra_gpio_enable(tgi, offset);
- ret = pinctrl_gpio_direction_output(chip, offset);
- if (ret < 0)
- dev_err(tgi->dev,
- "Failed to set pinctrl output direction of GPIO %d: %d",
- chip->base + offset, ret);
-
- return ret;
+ return 0;
}
static int tegra_gpio_get_direction(struct gpio_chip *chip,
--
2.34.1
^ permalink raw reply related
* Question: pxa GPIO direction callbacks and pinctrl_gpio_direction_*()
From: Runyu Xiao @ 2026-06-19 15:32 UTC (permalink / raw)
To: Robert Jarzmik, Linus Walleij, Bartosz Golaszewski
Cc: Runyu Xiao, Jianhao Xu, linux-gpio, linux-kernel
Hi,
I found a possible sleep-in-atomic problem in the PXA GPIO direction
callbacks and would like to check the intended driver contract before
sending a patch.
The driver registers a normal MMIO gpio_chip without setting can_sleep.
On PXA variants where pxa_gpio_has_pinctrl() is true,
pxa_gpio_direction_input() and pxa_gpio_direction_output() first call
pinctrl_gpio_direction_input/output(). That path can reach the pinctrl
core and take pctldev->mutex.
This was found by our static analysis tool and then confirmed by manual
review of pxa_init_gpio_chip(), pxa_gpio_has_pinctrl(), and the direction
callbacks. I also used a directed runtime validation that preserves the
non-sleeping gpio_chip registration and drives the direction callback
through the pinctrl direction helper. Lockdep reports a sleep-in-atomic
warning with pxa_gpio_direction_output(), pinctrl_gpio_direction_output()
and pinctrl_get_device_gpio_range() on the stack.
The part I would like to confirm is the intended fix. Commit a770d946371e
("gpio: pxa: add pin control gpio direction and request") says that when a
pinctrl driver is available, pinctrl should control the GPIO direction so
that only one driver controls the direction. Because of that, simply
removing the pinctrl_gpio_direction_*() calls from the GPIO direction
callbacks may be too broad even though the GPIO driver also updates GPDR
itself.
Would the preferred fix be to keep the pinctrl direction path and mark the
chip as sleeping, or is it acceptable to keep direction changes on the
existing GPDR path and remove the pinctrl direction round-trip? If there is
another preferred way to preserve the PXA pinctrl contract without
advertising the direction callbacks as atomic-safe, I can prepare a patch
in that direction.
Thanks,
Runyu
^ permalink raw reply
* Question: mvebu GPIO can_sleep and pinctrl direction helpers
From: Runyu Xiao @ 2026-06-19 15:33 UTC (permalink / raw)
To: Uwe Kleine-Konig, Linus Walleij, Bartosz Golaszewski
Cc: Runyu Xiao, Jianhao Xu, Arnd Bergmann, Thomas Petazzoni,
Jason Cooper, linux-pwm, linux-gpio, linux-kernel
Hi,
I found a possible sleep-in-atomic problem in the MVEBU GPIO direction
callbacks and would like to check the intended gpio_chip contract before
sending a patch.
mvebu_gpio_probe() currently registers the GPIO controller with
mvchip->chip.can_sleep = false. At the same time,
mvebu_gpio_direction_input() and mvebu_gpio_direction_output() call
pinctrl_gpio_direction_input/output(), and that helper path can reach the
pinctrl core and take pctldev->mutex.
This was found by our static analysis tool and then confirmed by manual
review of mvebu_gpio_probe() and the direction callbacks. I also used a
directed runtime validation that preserves the non-sleeping gpio_chip
registration and drives the direction callback through the pinctrl
direction helper. Lockdep reports a sleep-in-atomic warning with
mvebu_gpio_direction_output(), pinctrl_gpio_direction_output() and
pinctrl_get_device_gpio_range() on the stack.
Before sending a fix, I would like to confirm which contract is preferred
for this driver. Should the controller be marked can_sleep because its
direction callbacks may sleep, or would that be too broad for an otherwise
MMIO-backed GPIO controller whose get/set paths are fast register accesses?
If marking the whole chip as sleeping is too broad, would it be preferable
to avoid or restructure the pinctrl direction round-trip instead?
Thanks,
Runyu
^ permalink raw reply
* [PATCH 00/11] ARM: NXP: Drop NOMMU platform support
From: Frank.Li @ 2026-06-19 15:40 UTC (permalink / raw)
To: Arnd Bergmann, Sascha Hauer, Pengutronix Kernel Team,
Stefan Agner, Fabio Estevam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Russell King, Abel Vesa, Peng Fan,
Michael Turquette, Stephen Boyd, Brian Masney, Dong Aisheng,
Jacky Bai, NXP S32 Linux Team, Linus Walleij, Vladimir Zapolskiy,
Piotr Wojtaszczyk, Kees Cook, Gustavo A. R. Silva
Cc: linux-arm-kernel, imx, devicetree, linux-kernel, linux-clk,
linux-gpio, linux-hardening, Frank Li
Commercial users and hardware vendors migrated to Zephyr or other RTOS
solutions years ago, leaving the NOMMU platform support effectively
unused and unmaintained.
Remove the obsolete support to reduce maintenance burden and simplify the
Freescale/nxp platform code.
Some driver code still be kept and may clean up later since it is possible
reused by other SoC.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
Frank Li (11):
ARM: dts: vf610m4: Remove NOMMU platform support
ARM: dts: imxrt1050: Remove NOMMU platform support
ARM: imx: Remove NOMMU platform support
clk: imx: imxrt1050: Remove NOMMU platform support
pinctrl: freescale: IMXRT: Remove NOMMU platform support
ARM: imxrt_defconfig: Remove NOMMU platform support
ARM: dts: lpc: Remove NOMMU platform support
ARM: mach-lpc: Remove NOMMU platform support
ARM: configs: lpc*: Remove NOMMU platform support
clk: nxp: lpc: Remove NOMMU platform support
pinctrl: nxp: lpc: Remove NOMMU platform support
.../devicetree/bindings/pinctrl/fsl,imxrt1050.yaml | 79 -
.../devicetree/bindings/pinctrl/fsl,imxrt1170.yaml | 77 -
arch/arm/Kconfig | 12 -
arch/arm/Makefile | 2 -
arch/arm/boot/dts/nxp/Makefile | 1 -
arch/arm/boot/dts/nxp/imx/Makefile | 2 -
arch/arm/boot/dts/nxp/imx/imxrt1050-evk.dts | 72 -
arch/arm/boot/dts/nxp/imx/imxrt1050-pinfunc.h | 993 ------------
arch/arm/boot/dts/nxp/imx/imxrt1050.dtsi | 160 --
arch/arm/boot/dts/nxp/imx/imxrt1170-pinfunc.h | 1561 -------------------
arch/arm/boot/dts/nxp/lpc/Makefile | 9 -
arch/arm/boot/dts/nxp/lpc/lpc18xx.dtsi | 543 -------
arch/arm/boot/dts/nxp/lpc/lpc3250-ea3250.dts | 273 ----
arch/arm/boot/dts/nxp/lpc/lpc3250-phy3250.dts | 236 ---
arch/arm/boot/dts/nxp/lpc/lpc32xx.dtsi | 540 -------
arch/arm/boot/dts/nxp/lpc/lpc4337-ciaa.dts | 221 ---
arch/arm/boot/dts/nxp/lpc/lpc4350-hitex-eval.dts | 485 ------
arch/arm/boot/dts/nxp/lpc/lpc4350.dtsi | 48 -
.../arm/boot/dts/nxp/lpc/lpc4357-ea4357-devkit.dts | 624 --------
arch/arm/boot/dts/nxp/lpc/lpc4357-myd-lpc4357.dts | 621 --------
arch/arm/boot/dts/nxp/lpc/lpc4357.dtsi | 52 -
arch/arm/boot/dts/nxp/vf/Makefile | 2 -
arch/arm/boot/dts/nxp/vf/vf610m4-colibri.dts | 61 -
arch/arm/boot/dts/nxp/vf/vf610m4-cosmic.dts | 88 --
arch/arm/boot/dts/nxp/vf/vf610m4.dtsi | 61 -
arch/arm/configs/imxrt_defconfig | 35 -
arch/arm/configs/lpc18xx_defconfig | 158 --
arch/arm/configs/lpc32xx_defconfig | 192 ---
arch/arm/mach-imx/Kconfig | 7 -
arch/arm/mach-imx/Makefile | 2 -
arch/arm/mach-imx/mach-imxrt.c | 19 -
arch/arm/mach-lpc18xx/Makefile | 2 -
arch/arm/mach-lpc18xx/board-dt.c | 19 -
arch/arm/mach-lpc32xx/Kconfig | 13 -
arch/arm/mach-lpc32xx/Makefile | 8 -
arch/arm/mach-lpc32xx/common.c | 125 --
arch/arm/mach-lpc32xx/common.h | 32 -
arch/arm/mach-lpc32xx/lpc32xx.h | 717 ---------
arch/arm/mach-lpc32xx/phy3250.c | 92 --
arch/arm/mach-lpc32xx/pm.c | 135 --
arch/arm/mach-lpc32xx/serial.c | 148 --
arch/arm/mach-lpc32xx/suspend.S | 148 --
drivers/clk/Kconfig | 7 -
drivers/clk/Makefile | 1 -
drivers/clk/imx/Kconfig | 6 -
drivers/clk/imx/Makefile | 1 -
drivers/clk/imx/clk-imxrt1050.c | 182 ---
drivers/clk/nxp/Makefile | 5 -
drivers/clk/nxp/clk-lpc18xx-ccu.c | 301 ----
drivers/clk/nxp/clk-lpc18xx-cgu.c | 668 --------
drivers/clk/nxp/clk-lpc18xx-creg.c | 225 ---
drivers/clk/nxp/clk-lpc32xx.c | 1591 --------------------
drivers/pinctrl/Kconfig | 9 -
drivers/pinctrl/Makefile | 1 -
drivers/pinctrl/freescale/Kconfig | 16 -
drivers/pinctrl/freescale/Makefile | 2 -
drivers/pinctrl/freescale/pinctrl-imxrt1050.c | 309 ----
drivers/pinctrl/freescale/pinctrl-imxrt1170.c | 349 -----
drivers/pinctrl/pinctrl-lpc18xx.c | 1382 -----------------
include/dt-bindings/clock/imxrt1050-clock.h | 72 -
60 files changed, 13802 deletions(-)
---
base-commit: 598c7067dd8b65b93f3ccada47e9014a13137f1b
change-id: 20260618-dts_cleanup_arm_mcore-e7e933da798a
Best regards,
--
Frank Li <Frank.Li@nxp.com>
^ permalink raw reply
* [PATCH 01/11] ARM: dts: vf610m4: Remove NOMMU platform support
From: Frank.Li @ 2026-06-19 15:40 UTC (permalink / raw)
To: Arnd Bergmann, Sascha Hauer, Pengutronix Kernel Team,
Stefan Agner, Fabio Estevam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Russell King, Abel Vesa, Peng Fan,
Michael Turquette, Stephen Boyd, Brian Masney, Dong Aisheng,
Jacky Bai, NXP S32 Linux Team, Linus Walleij, Vladimir Zapolskiy,
Piotr Wojtaszczyk, Kees Cook, Gustavo A. R. Silva
Cc: linux-arm-kernel, imx, devicetree, linux-kernel, linux-clk,
linux-gpio, linux-hardening, Frank Li
In-Reply-To: <20260619-dts_cleanup_arm_mcore-v1-0-0101795a2662@nxp.com>
From: Frank Li <Frank.Li@nxp.com>
The Vybrid M4 NOMMU platform support was added as a proof-of-concept and
has not seen practical use in production systems.
Commercial users and hardware vendors migrated to Zephyr or other RTOS
solutions years ago, leaving the NOMMU platform support effectively
unused and unmaintained.
Remove the obsolete support to reduce maintenance burden and simplify the
code.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
Cc: Stefan Agner <stefan@agner.ch>
---
arch/arm/boot/dts/nxp/vf/Makefile | 2 -
arch/arm/boot/dts/nxp/vf/vf610m4-colibri.dts | 61 -------------------
arch/arm/boot/dts/nxp/vf/vf610m4-cosmic.dts | 88 ----------------------------
arch/arm/boot/dts/nxp/vf/vf610m4.dtsi | 61 -------------------
4 files changed, 212 deletions(-)
diff --git a/arch/arm/boot/dts/nxp/vf/Makefile b/arch/arm/boot/dts/nxp/vf/Makefile
index 0a4a7f9dd43e4..1733506c0c725 100644
--- a/arch/arm/boot/dts/nxp/vf/Makefile
+++ b/arch/arm/boot/dts/nxp/vf/Makefile
@@ -3,9 +3,7 @@ dtb-$(CONFIG_SOC_VF610) += \
vf500-colibri-eval-v3.dtb \
vf610-bk4.dtb \
vf610-colibri-eval-v3.dtb \
- vf610m4-colibri.dtb \
vf610-cosmic.dtb \
- vf610m4-cosmic.dtb \
vf610-twr.dtb \
vf610-zii-cfu1.dtb \
vf610-zii-dev-rev-b.dtb \
diff --git a/arch/arm/boot/dts/nxp/vf/vf610m4-colibri.dts b/arch/arm/boot/dts/nxp/vf/vf610m4-colibri.dts
deleted file mode 100644
index 86d32f54c250f..0000000000000
--- a/arch/arm/boot/dts/nxp/vf/vf610m4-colibri.dts
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+ OR MIT
-/*
- * Device tree for Colibri VF61 Cortex-M4 support
- *
- * Copyright (C) 2015 Stefan Agner
- */
-
-/dts-v1/;
-#include "vf610m4.dtsi"
-
-/ {
- model = "VF610 Cortex-M4";
- compatible = "fsl,vf610m4";
-
- chosen {
- bootargs = "clk_ignore_unused init=/linuxrc rw";
- stdout-path = "serial2:115200";
- };
-
- memory@8c000000 {
- device_type = "memory";
- reg = <0x8c000000 0x3000000>;
- };
-};
-
-&gpio0 {
- status = "disabled";
-};
-
-&gpio1 {
- status = "disabled";
-};
-
-&gpio2 {
- status = "disabled";
-};
-
-&gpio3 {
- status = "disabled";
-};
-
-&gpio4 {
- status = "disabled";
-};
-
-&uart2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2>;
- status = "okay";
-};
-
-&iomuxc {
- pinctrl_uart2: uart2grp {
- fsl,pins = <
- VF610_PAD_PTD0__UART2_TX 0x21a2
- VF610_PAD_PTD1__UART2_RX 0x21a1
- VF610_PAD_PTD2__UART2_RTS 0x21a2
- VF610_PAD_PTD3__UART2_CTS 0x21a1
- >;
- };
-};
diff --git a/arch/arm/boot/dts/nxp/vf/vf610m4-cosmic.dts b/arch/arm/boot/dts/nxp/vf/vf610m4-cosmic.dts
deleted file mode 100644
index 454b484368cb7..0000000000000
--- a/arch/arm/boot/dts/nxp/vf/vf610m4-cosmic.dts
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Device tree for Cosmic+ VF6xx Cortex-M4 support
- *
- * Copyright (C) 2015
- *
- * Based on vf610m4 Colibri
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- * a) This file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- * b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/dts-v1/;
-#include "vf610m4.dtsi"
-
-/ {
- model = "VF610 Cortex-M4";
- compatible = "fsl,vf610m4";
-};
-
-&gpio0 {
- status = "disabled";
-};
-
-&gpio1 {
- status = "disabled";
-};
-
-&gpio2 {
- status = "disabled";
-};
-
-&gpio3 {
- status = "disabled";
-};
-
-&gpio4 {
- status = "disabled";
-};
-
-&uart3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart3>;
- status = "okay";
-};
-
-&iomuxc {
- pinctrl_uart3: uart3grp {
- fsl,pins = <
- VF610_PAD_PTA20__UART3_TX 0x21a2
- VF610_PAD_PTA21__UART3_RX 0x21a1
- >;
- };
-};
diff --git a/arch/arm/boot/dts/nxp/vf/vf610m4.dtsi b/arch/arm/boot/dts/nxp/vf/vf610m4.dtsi
deleted file mode 100644
index 648d219e1d0ed..0000000000000
--- a/arch/arm/boot/dts/nxp/vf/vf610m4.dtsi
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Device tree for VF6xx Cortex-M4 support
- *
- * Copyright (C) 2015 Stefan Agner
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- * a) This file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- * b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "../../armv7-m.dtsi"
-#include "vfxxx.dtsi"
-
-/ {
- #address-cells = <1>;
- #size-cells = <1>;
- chosen { };
- aliases { };
-};
-
-&mscm_ir {
- interrupt-parent = <&nvic>;
-};
-
-&nvic {
- arm,num-irq-priority-bits = <4>;
-};
--
2.43.0
^ 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