From: Hans de Goede <hansg@kernel.org>
To: "Bartosz Golaszewski" <bartosz.golaszewski@oss.qualcomm.com>,
"Andy Shevchenko" <andriy.shevchenko@linux.intel.com>,
"Daniel Scally" <djrscally@gmail.com>,
"Heikki Krogerus" <heikki.krogerus@linux.intel.com>,
"Sakari Ailus" <sakari.ailus@linux.intel.com>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"Danilo Krummrich" <dakr@kernel.org>,
"Mika Westerberg" <mika.westerberg@linux.intel.com>,
"Andy Shevchenko" <andy@kernel.org>,
"Linus Walleij" <linusw@kernel.org>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
"Dmitry Torokhov" <dmitry.torokhov@gmail.com>,
"Len Brown" <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org, driver-core@lists.linux.dev,
linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
platform-driver-x86@vger.kernel.org, brgl@kernel.org
Subject: Re: [PATCH v3 2/2] platform/x86: x86-android-tablets: enable fwnode matching of GPIO chips
Date: Tue, 28 Apr 2026 11:16:06 +0200 [thread overview]
Message-ID: <f100e787-f45a-4d72-9664-a75b1181763e@kernel.org> (raw)
In-Reply-To: <20260427-baytrail-real-swnode-v3-2-0003e4c1708c@oss.qualcomm.com>
Hi Bartosz,
On 27-Apr-26 14:19, Bartosz Golaszewski wrote:
> In order to allow GPIOLIB to match cherryview and baytrail GPIO
> controllers by their firmware nodes instead of their names, we need to
> attach the - currently "dangling" - existing software nodes to their
> target devices dynamically.
>
> We deal with devices described in ACPI so set up a bus notifier waiting
> for the ADD events. We know the name of the device we're waiting for so
> match against it and - on match - assign the appropriate software node
> as the secondary firmware node of the underlying ACPI node. In case the
> event was emitted earlier than this driver's probe: also make sure the
> device was not added before.
>
> Scheduling fine-grained devres actions allows for proper teardown and
> unsetting of the secondary firmware nodes.
Thank you for your work on this.
The x86-android-tablets.ko kernel module uses platform_create_bundle()
so its probe() cannot return -EPROBE_DEFER. IOW it expects all the GPIO
pins which it needs to already be there when it loads (which so far in
practice holds, since these x86 GPIO controllers are always builtin
for various reasons).
This means that there is no need all the notifier stuff. Only adding
an acpi_bus_find_device_by_name() helper as suggested by Rafael and
then finding the GPIO controllers and attaching the swnodes is
necessary.
And if the acpi_bus_find_device_by_name() fails it is ok to fail
the probe() just like it currently fails when gpiod_get() returns
-EPROBE_DEFER (or fails for other reasons).
This should nicely simplify this patch.
Regards,
Hans
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> ---
> drivers/platform/x86/x86-android-tablets/core.c | 127 +++++++++++++++++++++++-
> 1 file changed, 124 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c
> index 021009e9085bec3db9c4daa1f6235600210a6099..9e6e8f272dfe16cda421b569802045c3d94fc0ab 100644
> --- a/drivers/platform/x86/x86-android-tablets/core.c
> +++ b/drivers/platform/x86/x86-android-tablets/core.c
> @@ -13,10 +13,12 @@
> #include <linux/acpi.h>
> #include <linux/device.h>
> #include <linux/dmi.h>
> +#include <linux/fwnode.h>
> #include <linux/gpio/consumer.h>
> #include <linux/gpio/machine.h>
> #include <linux/irq.h>
> #include <linux/module.h>
> +#include <linux/notifier.h>
> #include <linux/pci.h>
> #include <linux/platform_device.h>
> #include <linux/serdev.h>
> @@ -360,6 +362,124 @@ static const struct software_node *cherryview_gpiochip_node_group[] = {
> NULL
> };
>
> +struct auto_secondary_data {
> + struct notifier_block nb;
> + struct device *parent;
> +};
> +
> +static void auto_secondary_unset(void *data)
> +{
> + struct fwnode_handle *fwnode = data;
> +
> + fwnode->secondary = NULL;
> +}
> +
> +static int acpi_set_secondary_fwnode(struct device *parent, struct device *dev,
> + const struct software_node *const swnode)
> +{
> + struct acpi_device *device = to_acpi_device(dev);
> + struct fwnode_handle *fwnode;
> + int ret;
> +
> + fwnode = software_node_fwnode(swnode);
> + if (WARN_ON(!fwnode))
> + return -ENOENT;
> +
> + fwnode->secondary = ERR_PTR(-ENODEV);
> + device->fwnode.secondary = fwnode;
> +
> + ret = devm_add_action_or_reset(parent, auto_secondary_unset, &device->fwnode);
> + if (ret)
> + dev_err(parent, "Failed to schedule the unset action for secondary fwnode\n");
> +
> + return ret;
> +}
> +
> +static int acpi_auto_secondary_notifier(struct notifier_block *nb,
> + unsigned long action, void *data)
> +{
> + struct auto_secondary_data *auto_sec = container_of(nb, struct auto_secondary_data, nb);
> + const struct software_node *const *swnode;
> + struct device *dev = data;
> + int ret;
> +
> + switch (action) {
> + case BUS_NOTIFY_ADD_DEVICE:
> + for (swnode = gpiochip_node_group; *swnode; swnode++) {
> + if (strcmp((*swnode)->name, dev_name(dev)) == 0) {
> + ret = acpi_set_secondary_fwnode(auto_sec->parent, dev, *swnode);
> + return ret ? NOTIFY_BAD : NOTIFY_OK;
> + }
> + }
> + break;
> + default:
> + break;
> + }
> +
> + return NOTIFY_DONE;
> +}
> +
> +static void auto_secondary_unregister_node_group(void *data)
> +{
> + const struct software_node **nodes = data;
> +
> + software_node_unregister_node_group(nodes);
> +}
> +
> +static void auto_secondary_unregister_notifier(void *data)
> +{
> + struct notifier_block *nb = data;
> +
> + bus_unregister_notifier(&acpi_bus_type, nb);
> +}
> +
> +static int auto_secondary_fwnode_init(struct device *parent)
> +{
> + const struct software_node *const *swnode;
> + struct auto_secondary_data *data;
> + int ret;
> +
> + ret = software_node_register_node_group(gpiochip_node_group);
> + if (ret)
> + return ret;
> +
> + ret = devm_add_action_or_reset(parent,
> + auto_secondary_unregister_node_group,
> + gpiochip_node_group);
> + if (ret)
> + return ret;
> +
> + data = devm_kzalloc(parent, sizeof(*data), GFP_KERNEL);
> + if (!data)
> + return -ENOMEM;
> +
> + data->nb.notifier_call = acpi_auto_secondary_notifier;
> + data->parent = parent;
> +
> + ret = bus_register_notifier(&acpi_bus_type, &data->nb);
> + if (ret)
> + return ret;
> +
> + ret = devm_add_action_or_reset(parent,
> + auto_secondary_unregister_notifier,
> + &data->nb);
> + if (ret)
> + return ret;
> +
> + /* Device may have been already added. */
> + for (swnode = gpiochip_node_group; *swnode; swnode++) {
> + struct device *dev __free(put_device) =
> + bus_find_device_by_name(&acpi_bus_type, NULL, (*swnode)->name);
> + if (dev) {
> + ret = acpi_set_secondary_fwnode(parent, dev, *swnode);
> + if (ret)
> + return ret;
> + }
> + }
> +
> + return 0;
> +}
> +
> static void x86_android_tablet_remove(struct platform_device *pdev)
> {
> int i;
> @@ -391,7 +511,6 @@ static void x86_android_tablet_remove(struct platform_device *pdev)
>
> software_node_unregister_node_group(gpio_button_swnodes);
> software_node_unregister_node_group(swnode_group);
> - software_node_unregister_node_group(gpiochip_node_group);
> }
>
> static __init int x86_android_tablet_probe(struct platform_device *pdev)
> @@ -427,9 +546,11 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev)
> break;
> }
>
> - ret = software_node_register_node_group(gpiochip_node_group);
> - if (ret)
> + ret = auto_secondary_fwnode_init(&pdev->dev);
> + if (ret) {
> + x86_android_tablet_remove(pdev);
> return ret;
> + }
>
> ret = software_node_register_node_group(dev_info->swnode_group);
> if (ret) {
>
next prev parent reply other threads:[~2026-04-28 9:16 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-27 12:19 [PATCH v3 0/2] platform/x86: x86-android-tablets: use real firmware node references with intel drivers Bartosz Golaszewski
2026-04-27 12:19 ` [PATCH v3 1/2] ACPI: bus: export the acpi_bus_type symbol Bartosz Golaszewski
2026-04-27 19:27 ` Rafael J. Wysocki
2026-04-27 12:19 ` [PATCH v3 2/2] platform/x86: x86-android-tablets: enable fwnode matching of GPIO chips Bartosz Golaszewski
2026-04-27 19:32 ` Rafael J. Wysocki
2026-04-28 9:16 ` Hans de Goede [this message]
2026-04-28 9:19 ` Bartosz Golaszewski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f100e787-f45a-4d72-9664-a75b1181763e@kernel.org \
--to=hansg@kernel.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=andy@kernel.org \
--cc=bartosz.golaszewski@oss.qualcomm.com \
--cc=brgl@kernel.org \
--cc=dakr@kernel.org \
--cc=djrscally@gmail.com \
--cc=dmitry.torokhov@gmail.com \
--cc=driver-core@lists.linux.dev \
--cc=gregkh@linuxfoundation.org \
--cc=heikki.krogerus@linux.intel.com \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=lenb@kernel.org \
--cc=linusw@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mika.westerberg@linux.intel.com \
--cc=platform-driver-x86@vger.kernel.org \
--cc=rafael@kernel.org \
--cc=sakari.ailus@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®