[PATCH v2 1/3] bcma: gpio: Add and register software node for GPIO controller
Dmitry Torokhov <[email protected]> Mon, 13 Jul 2026 14:58:22 -0700
| Newsgroups | org.kernel.vger.linux-mips,org.kernel.vger.linux-kernel,org.kernel.vger.linux-wireless |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- 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