[{"id":3673493,"web_url":"http://patchwork.ozlabs.org/comment/3673493/","msgid":"<CAJZ5v0iwfZPcFtM7Jv29bXFmh3zN0OaG9UfNY5iC5RpzRzp07w@mail.gmail.com>","list_archive_url":null,"date":"2026-04-04T18:25:43","subject":"Re: [PATCH v2 4/4] platform/x86: x86-android-tablets: enable fwnode\n matching of GPIO chips","submitter":{"id":64267,"url":"http://patchwork.ozlabs.org/api/people/64267/","name":"Rafael J. Wysocki","email":"rafael@kernel.org"},"content":"On Thu, Apr 2, 2026 at 2:54 PM Bartosz Golaszewski\n<bartosz.golaszewski@oss.qualcomm.com> wrote:\n>\n> In order to allow GPIOLIB to match cherryview and baytrail GPIO\n> controllers by their firmware nodes instead of their names, we need to\n> attach the - currently \"dangling\" - existing software nodes to their\n> target devices dynamically.\n>\n> We deal with devices described in ACPI so set up a bus notifier waiting\n> for the ADD events. We know the name of the device we're waiting for so\n> match against it and - on match - assign the appropriate software node\n> as the secondary firmware node of the underlying ACPI node. In case the\n> event was emitted earlier than this driver's probe: also make sure the\n> device was not added before.\n>\n> Scheduling fine-grained devres actions allows for proper teardown and\n> unsetting of the secondary firmware nodes.\n>\n> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>\n> ---\n>  drivers/platform/x86/x86-android-tablets/core.c | 127 +++++++++++++++++++++++-\n>  1 file changed, 124 insertions(+), 3 deletions(-)\n>\n> diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c\n> index 021009e9085bec3db9c4daa1f6235600210a6099..9e6e8f272dfe16cda421b569802045c3d94fc0ab 100644\n> --- a/drivers/platform/x86/x86-android-tablets/core.c\n> +++ b/drivers/platform/x86/x86-android-tablets/core.c\n> @@ -13,10 +13,12 @@\n>  #include <linux/acpi.h>\n>  #include <linux/device.h>\n>  #include <linux/dmi.h>\n> +#include <linux/fwnode.h>\n>  #include <linux/gpio/consumer.h>\n>  #include <linux/gpio/machine.h>\n>  #include <linux/irq.h>\n>  #include <linux/module.h>\n> +#include <linux/notifier.h>\n>  #include <linux/pci.h>\n>  #include <linux/platform_device.h>\n>  #include <linux/serdev.h>\n> @@ -360,6 +362,124 @@ static const struct software_node *cherryview_gpiochip_node_group[] = {\n>         NULL\n>  };\n>\n> +struct auto_secondary_data {\n> +       struct notifier_block nb;\n> +       struct device *parent;\n> +};\n> +\n> +static void auto_secondary_unset(void *data)\n> +{\n> +       struct fwnode_handle *fwnode = data;\n> +\n> +       fwnode->secondary = NULL;\n> +}\n> +\n> +static int acpi_set_secondary_fwnode(struct device *parent, struct device *dev,\n> +                                    const struct software_node *const swnode)\n> +{\n> +       struct acpi_device *device = to_acpi_device(dev);\n> +       struct fwnode_handle *fwnode;\n> +       int ret;\n> +\n> +       fwnode = software_node_fwnode(swnode);\n> +       if (WARN_ON(!fwnode))\n> +               return -ENOENT;\n> +\n> +       fwnode->secondary = ERR_PTR(-ENODEV);\n> +       device->fwnode.secondary = fwnode;\n> +\n> +       ret = devm_add_action_or_reset(parent, auto_secondary_unset, &device->fwnode);\n> +       if (ret)\n> +               dev_err(parent, \"Failed to schedule the unset action for secondary fwnode\\n\");\n> +\n> +       return ret;\n> +}\n> +\n> +static int acpi_auto_secondary_notifier(struct notifier_block *nb,\n> +                                       unsigned long action, void *data)\n> +{\n> +       struct auto_secondary_data *auto_sec = container_of(nb, struct auto_secondary_data, nb);\n> +       const struct software_node *const *swnode;\n> +       struct device *dev = data;\n> +       int ret;\n> +\n> +       switch (action) {\n> +       case BUS_NOTIFY_ADD_DEVICE:\n> +               for (swnode = gpiochip_node_group; *swnode; swnode++) {\n> +                       if (strcmp((*swnode)->name, dev_name(dev)) == 0) {\n> +                               ret = acpi_set_secondary_fwnode(auto_sec->parent, dev, *swnode);\n> +                               return ret ? NOTIFY_BAD : NOTIFY_OK;\n> +                       }\n> +               }\n> +               break;\n> +       default:\n> +               break;\n> +       }\n> +\n> +       return NOTIFY_DONE;\n> +}\n> +\n> +static void auto_secondary_unregister_node_group(void *data)\n> +{\n> +       const struct software_node **nodes = data;\n> +\n> +       software_node_unregister_node_group(nodes);\n> +}\n> +\n> +static void auto_secondary_unregister_notifier(void *data)\n> +{\n> +       struct notifier_block *nb = data;\n> +\n> +       bus_unregister_notifier(&acpi_bus_type, nb);\n> +}\n\nInstead of exporting acpi_bus_type in the previous patch and defining\nthis function here, can you define\n\nvoid acpi_bus_unregister_notifier(void *data)\n{\n       struct notifier_block *nb = data;\n\n       bus_unregister_notifier(&acpi_bus_type, nb);\n}\n\nin the previous patch and use it here?\n\n> +\n> +static int auto_secondary_fwnode_init(struct device *parent)\n> +{\n> +       const struct software_node *const *swnode;\n> +       struct auto_secondary_data *data;\n> +       int ret;\n> +\n> +       ret = software_node_register_node_group(gpiochip_node_group);\n> +       if (ret)\n> +               return ret;\n> +\n> +       ret = devm_add_action_or_reset(parent,\n> +                                      auto_secondary_unregister_node_group,\n> +                                      gpiochip_node_group);\n> +       if (ret)\n> +               return ret;\n> +\n> +       data = devm_kzalloc(parent, sizeof(*data), GFP_KERNEL);\n> +       if (!data)\n> +               return -ENOMEM;\n> +\n> +       data->nb.notifier_call = acpi_auto_secondary_notifier;\n> +       data->parent = parent;\n> +\n> +       ret = bus_register_notifier(&acpi_bus_type, &data->nb);\n> +       if (ret)\n> +               return ret;\n> +\n> +       ret = devm_add_action_or_reset(parent,\n> +                                      auto_secondary_unregister_notifier,\n> +                                      &data->nb);\n> +       if (ret)\n> +               return ret;\n> +\n> +       /* Device may have been already added. */\n> +       for (swnode = gpiochip_node_group; *swnode; swnode++) {\n> +               struct device *dev __free(put_device) =\n> +                       bus_find_device_by_name(&acpi_bus_type, NULL, (*swnode)->name);\n> +               if (dev) {\n> +                       ret = acpi_set_secondary_fwnode(parent, dev, *swnode);\n> +                       if (ret)\n> +                               return ret;\n> +               }\n> +       }\n> +\n> +       return 0;\n> +}\n> +\n>  static void x86_android_tablet_remove(struct platform_device *pdev)\n>  {\n>         int i;\n> @@ -391,7 +511,6 @@ static void x86_android_tablet_remove(struct platform_device *pdev)\n>\n>         software_node_unregister_node_group(gpio_button_swnodes);\n>         software_node_unregister_node_group(swnode_group);\n> -       software_node_unregister_node_group(gpiochip_node_group);\n>  }\n>\n>  static __init int x86_android_tablet_probe(struct platform_device *pdev)\n> @@ -427,9 +546,11 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev)\n>                 break;\n>         }\n>\n> -       ret = software_node_register_node_group(gpiochip_node_group);\n> -       if (ret)\n> +       ret = auto_secondary_fwnode_init(&pdev->dev);\n> +       if (ret) {\n> +               x86_android_tablet_remove(pdev);\n>                 return ret;\n> +       }\n>\n>         ret = software_node_register_node_group(dev_info->swnode_group);\n>         if (ret) {\n>\n> --\n> 2.47.3\n>","headers":{"Return-Path":"\n <linux-gpio+bounces-34667-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-gpio@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=dasMaZUC;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-gpio+bounces-34667-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"dasMaZUC\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201"],"Received":["from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fp3v26mnCz1xtJ\n\tfor <incoming@patchwork.ozlabs.org>; Sun, 05 Apr 2026 04:26:06 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 21CAF300D313\n\tfor <incoming@patchwork.ozlabs.org>; Sat,  4 Apr 2026 18:25:58 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 10D00336EE1;\n\tSat,  4 Apr 2026 18:25:57 +0000 (UTC)","from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id C70CC3375D5\n\tfor <linux-gpio@vger.kernel.org>; Sat,  4 Apr 2026 18:25:56 +0000 (UTC)","by smtp.kernel.org (Postfix) with ESMTPSA id A5E93C19421\n\tfor <linux-gpio@vger.kernel.org>; Sat,  4 Apr 2026 18:25:56 +0000 (UTC)","by mail-oi1-f170.google.com with SMTP id\n 5614622812f47-470145d7df5so749438b6e.0\n        for <linux-gpio@vger.kernel.org>;\n Sat, 04 Apr 2026 11:25:56 -0700 (PDT)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1775327156; cv=none;\n b=rlglZrtsmQJFy8k1R9NAe/iaSvNKsRdLA+YgmeBH7Dgw2Yy7/yNpdJkrELTlAwbsfRbQI/eN/biRiOPZ0mfwnO0Q2OE7WGu2ksPX7VrlrRz9sG/fCUio1RKjRZzMR0auicizaC9n3oK4eJDygkc5m3SbJlmDX2hLK/sIjtQdLb8=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1775327156; c=relaxed/simple;\n\tbh=HmVC8HG22vzlAHr9b9ZKLVJ7JJhmrXnAN67usYKy5N8=;\n\th=MIME-Version:References:In-Reply-To:From:Date:Message-ID:Subject:\n\t To:Cc:Content-Type;\n b=TMbX78TLoczr1nH8VC8fcor99Hc23FO9tUqD4s3RddRMT2lPL4rSi7+zrdbtIQgc5a/GeidLBLL0S4rXILwijH8N7+SUe5e6H39Kp1W6BMh4UM8HfAHBO44xrDhOaLThbnftitfZDDb+Ak8EXyyncljJMWPrWRny+FPVfib2jjw=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=dasMaZUC; arc=none smtp.client-ip=10.30.226.201","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1775327156;\n\tbh=HmVC8HG22vzlAHr9b9ZKLVJ7JJhmrXnAN67usYKy5N8=;\n\th=References:In-Reply-To:From:Date:Subject:To:Cc:From;\n\tb=dasMaZUC5EkFDx2TKERqqeWNVyhb4oojm4rJGiJ9uG9TX2ZtFQD2I1hVwM+pTTTrd\n\t 9tPcYq+2jwV0Qivdi9fSOJW6BeFkNIwz+X1QGStle9Jw6Zevcu64IRjVvjOAPHPivn\n\t JRjZdFuXb/Ihk1ZohNIu78gmuMMCX517ZR6hfp2EDq1NqgdHS0tGD3fwuQ774gCwjq\n\t rlIUxqgfdfTT/Wrs3C5Dja7FvXcNICUQ0YDPqsLK/ZdVwZtVbciurRWtyLwaOllJkt\n\t Q06x1xz4ukp6eVZWok518Fas4+/dsxqW8QOr+84yLM3ODguMdz/+qWwXjfrl8VuMsJ\n\t +GC4opymnJkPA==","X-Forwarded-Encrypted":"i=1;\n AJvYcCVb5MP9s7gpdUj8cvcwG5KKNQ60G6XVIDg+VFtZwaDBg2uQuqD8JXMreucc1Y1yWBm1r/8hAaXFDWjt@vger.kernel.org","X-Gm-Message-State":"AOJu0YxQE/R0GJqeZjmA/zYtv1/UHhjDWLiU1/UsFcfI2pjOgosRrp4K\n\tdRDaHi/B/0PMoQCyGDLec96jePGCfXb3J+hEGSWnCVhhKJ89MK8lljCCiJU4YBilXbLK7Ym28g9\n\t6RIKAYpbkrc2pMoEamITtrhRwHMGwin4=","X-Received":"by 2002:a05:6870:21d3:b0:417:3421:13ff with SMTP id\n 586e51a60fabf-4230ff4f728mr3820411fac.29.1775327155442; Sat, 04 Apr 2026\n 11:25:55 -0700 (PDT)","Precedence":"bulk","X-Mailing-List":"linux-gpio@vger.kernel.org","List-Id":"<linux-gpio.vger.kernel.org>","List-Subscribe":"<mailto:linux-gpio+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-gpio+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","References":"<20260402-baytrail-real-swnode-v2-0-6f5054a4cc07@oss.qualcomm.com>\n <20260402-baytrail-real-swnode-v2-4-6f5054a4cc07@oss.qualcomm.com>","In-Reply-To":"\n <20260402-baytrail-real-swnode-v2-4-6f5054a4cc07@oss.qualcomm.com>","From":"\"Rafael J. Wysocki\" <rafael@kernel.org>","Date":"Sat, 4 Apr 2026 20:25:43 +0200","X-Gmail-Original-Message-ID":"\n <CAJZ5v0iwfZPcFtM7Jv29bXFmh3zN0OaG9UfNY5iC5RpzRzp07w@mail.gmail.com>","X-Gm-Features":"AQROBzD6YmXrnAzgz9aL6fqWq1iOyolotQRnTtrF6brMuNKBBNGJLMNRaP4UCiA","Message-ID":"\n <CAJZ5v0iwfZPcFtM7Jv29bXFmh3zN0OaG9UfNY5iC5RpzRzp07w@mail.gmail.com>","Subject":"Re: [PATCH v2 4/4] platform/x86: x86-android-tablets: enable fwnode\n matching of GPIO chips","To":"Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>","Cc":"Andy Shevchenko <andriy.shevchenko@linux.intel.com>,\n Daniel Scally <djrscally@gmail.com>,\n  Heikki Krogerus <heikki.krogerus@linux.intel.com>,\n  Sakari Ailus <sakari.ailus@linux.intel.com>,\n  Greg Kroah-Hartman <gregkh@linuxfoundation.org>,\n \"Rafael J. Wysocki\" <rafael@kernel.org>,  Danilo Krummrich <dakr@kernel.org>,\n Mika Westerberg <mika.westerberg@linux.intel.com>,\n  Andy Shevchenko <andy@kernel.org>, Linus Walleij <linusw@kernel.org>,\n Hans de Goede <hansg@kernel.org>,\n =?utf-8?q?Ilpo_J=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com>,\n  Dmitry Torokhov <dmitry.torokhov@gmail.com>, Len Brown <lenb@kernel.org>,\n linux-acpi@vger.kernel.org,  driver-core@lists.linux.dev,\n linux-kernel@vger.kernel.org,  linux-gpio@vger.kernel.org,\n platform-driver-x86@vger.kernel.org,  brgl@kernel.org","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable"}}]