bcma: gpio: Add and register software node for GPIO controller

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@gmail.com>
Tested-by: Waldemar Brodkorb <wbx@openadk.org>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
This commit is contained in:
Dmitry Torokhov
2026-07-17 12:46:24 +02:00
committed by Thomas Bogendoerfer
parent 4a352e45cc
commit 8595a96891
2 changed files with 39 additions and 6 deletions
+37 -6
View File
@@ -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;
}
+2
View File
@@ -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_ */