[PATCH v2 1/3] bcma: gpio: Add and register software node for GPIO controller
From: Dmitry Torokhov
Date: Mon Jul 13 2026 - 17:59:14 EST
We want to convert the legacy gpio-keys platform device on BCM47XX
boards to use software nodes. To do this properly and allow
referencing the GPIO controller by address rather than relying on
name-based matching (which is being removed from the gpiolib core),
we need to associate the GPIO controller with a software node.
Introduce bcma_gpio_swnode, register it if the device does not
already have a firmware node, and associate it with the gpio_chip.
Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx>
---
drivers/bcma/driver_gpio.c | 43 +++++++++++++++++++++++++++++++++++++------
include/linux/bcma/bcma.h | 2 ++
2 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c
index 658c7e2ac8bf..ea45222f2fa0 100644
--- a/drivers/bcma/driver_gpio.c
+++ b/drivers/bcma/driver_gpio.c
@@ -19,6 +19,11 @@
#define BCMA_GPIO_MAX_PINS 32
+const struct software_node bcma_gpio_swnode = {
+ .name = "bcma-gpio",
+};
+EXPORT_SYMBOL_GPL(bcma_gpio_swnode);
+
static int bcma_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
{
struct bcma_drv_cc *cc = gpiochip_get_data(chip);
@@ -190,7 +195,20 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
chip->direction_input = bcma_gpio_direction_input;
chip->direction_output = bcma_gpio_direction_output;
chip->parent = bus->dev;
- chip->fwnode = dev_fwnode(&cc->core->dev);
+
+ /*
+ * Register software node only for the host SoC bus, unless there is
+ * already a firmware node assigned. There is only one SoC instance
+ * in the system, so there are no concerns with registration conflicts.
+ */
+ if (bus->hosttype == BCMA_HOSTTYPE_SOC && !dev_fwnode(&cc->core->dev)) {
+ err = software_node_register(&bcma_gpio_swnode);
+ if (err)
+ return err;
+ chip->fwnode = software_node_fwnode(&bcma_gpio_swnode);
+ } else {
+ chip->fwnode = dev_fwnode(&cc->core->dev);
+ }
switch (bus->chipinfo.id) {
case BCMA_CHIP_ID_BCM4707:
@@ -219,20 +237,33 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
err = bcma_gpio_irq_init(cc);
if (err)
- return err;
+ goto err_unregister_swnode;
err = gpiochip_add_data(chip, cc);
- if (err) {
- bcma_gpio_irq_exit(cc);
- return err;
- }
+ if (err)
+ goto err_irq_exit;
return 0;
+
+err_irq_exit:
+ bcma_gpio_irq_exit(cc);
+err_unregister_swnode:
+ if (bus->hosttype == BCMA_HOSTTYPE_SOC &&
+ chip->fwnode && is_software_node(chip->fwnode)) {
+ software_node_unregister(&bcma_gpio_swnode);
+ chip->fwnode = NULL;
+ }
+ return err;
}
int bcma_gpio_unregister(struct bcma_drv_cc *cc)
{
bcma_gpio_irq_exit(cc);
gpiochip_remove(&cc->gpio);
+ if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC &&
+ cc->gpio.fwnode && is_software_node(cc->gpio.fwnode)) {
+ software_node_unregister(&bcma_gpio_swnode);
+ cc->gpio.fwnode = NULL;
+ }
return 0;
}
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index f02cb3909375..17fc50190014 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -486,4 +486,6 @@ extern u32 bcma_core_dma_translation(struct bcma_device *core);
extern unsigned int bcma_core_irq(struct bcma_device *core, int num);
+extern const struct software_node bcma_gpio_swnode;
+
#endif /* LINUX_BCMA_H_ */
--
2.55.0.795.g602f6c329a-goog