[PATCH v2 1/4] platform/x86: x86-android-tablets: Fix GPIO software node matching

From: Maurizio Casciano

Date: Thu Aug 27 2026 - 14:18:14 EST


gpio_secondary_fwnode_init() attaches each provider software node to the
ACPI device. The registered gpio_device has a different primary fwnode,
so gpio_device_find_by_fwnode() never sees that secondary node and
software-node GPIO consumers defer indefinitely.

Find the gpio_device by its matching label and attach the secondary node
directly to that device. Keep the returned reference until the managed
cleanup action unsets the node.

Fixes: 1448c2d2ca5c ("platform/x86: x86-android-tablets: enable fwnode matching of GPIO chips")
Signed-off-by: Maurizio Casciano <mauriziocasciano7@xxxxxxxxx>
Assisted-by: Codex:gpt-5.6-sol sparse
---
.../platform/x86/x86-android-tablets/core.c | 21 ++++++++++++-------
1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c
index 5db794d65eb5..8dfd15afdca2 100644
--- a/drivers/platform/x86/x86-android-tablets/core.c
+++ b/drivers/platform/x86/x86-android-tablets/core.c
@@ -16,6 +16,7 @@
#include <linux/dmi.h>
#include <linux/fwnode.h>
#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
#include <linux/gpio/machine.h>
#include <linux/irq.h>
#include <linux/module.h>
@@ -364,9 +365,10 @@ static const struct software_node *cherryview_gpiochip_node_group[] = {

static void gpio_secondary_unset(void *data)
{
- struct device *dev = data;
+ struct gpio_device *gdev = data;

- set_secondary_fwnode(dev, NULL);
+ set_secondary_fwnode(gpio_device_to_device(gdev), NULL);
+ gpio_device_put(gdev);
}

static void gpio_secondary_unregister_node_group(void *data)
@@ -396,20 +398,23 @@ static int gpio_secondary_fwnode_init(struct device *parent)
return ret;

for (swnode = gpiochip_node_group; *swnode; swnode++) {
- struct device *dev __free(put_device) =
- acpi_bus_find_device_by_name((*swnode)->name);
- if (!dev)
+ struct gpio_device *gdev;
+
+ gdev = gpio_device_find_by_label((*swnode)->name);
+ if (!gdev)
return dev_err_probe(parent,
-ENODEV, "Failed to find the required GPIO controller: %s\n",
(*swnode)->name);

fwnode = software_node_fwnode(*swnode);
- if (WARN_ON(!fwnode))
+ if (WARN_ON(!fwnode)) {
+ gpio_device_put(gdev);
return -ENOENT;
+ }

- set_secondary_fwnode(dev, fwnode);
+ set_secondary_fwnode(gpio_device_to_device(gdev), fwnode);

- ret = devm_add_action_or_reset(parent, gpio_secondary_unset, dev);
+ ret = devm_add_action_or_reset(parent, gpio_secondary_unset, gdev);
if (ret)
return ret;
}
--
2.53.0