git: 4695e3aa7c68 - main - gpio: attach gpiobus when the controller is ready
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 04 Jul 2025 14:07:18 UTC
The branch main has been updated by vexeduxr:
URL: https://cgit.FreeBSD.org/src/commit/?id=4695e3aa7c685c092cb4b2662bee16c31be790f8
commit 4695e3aa7c685c092cb4b2662bee16c31be790f8
Author: Ahmad Khalifa <vexeduxr@FreeBSD.org>
AuthorDate: 2025-07-04 13:52:00 +0000
Commit: Ahmad Khalifa <vexeduxr@FreeBSD.org>
CommitDate: 2025-07-04 13:56:00 +0000
gpio: attach gpiobus when the controller is ready
Only attach gpiobus when the controller is fully initialized. Children
of gpiobus expect this to be the case.
Reviewed by: mmel, imp, andrew
Approved by: imp (mentor)
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D51088
---
sys/arm/allwinner/aw_gpio.c | 8 ++++----
sys/arm/broadcom/bcm2835/bcm2835_gpio.c | 6 +++---
sys/arm/nvidia/as3722_gpio.c | 2 +-
sys/arm64/apple/apple_pinctrl.c | 20 ++++++++++----------
sys/arm64/nvidia/tegra210/max77620_gpio.c | 2 +-
sys/arm64/rockchip/rk_gpio.c | 12 ++++++------
sys/dev/gpio/pl061.c | 12 ++++++++++--
sys/dev/gpio/pl061.h | 1 +
sys/dev/gpio/pl061_acpi.c | 15 ++++-----------
sys/dev/gpio/pl061_fdt.c | 15 ++++-----------
sys/dev/gpio/qoriq_gpio.c | 11 ++++++-----
sys/dev/iicbus/gpio/tca64xx.c | 3 +--
sys/powerpc/mpc85xx/mpc85xx_gpio.c | 4 ++--
13 files changed, 53 insertions(+), 58 deletions(-)
diff --git a/sys/arm/allwinner/aw_gpio.c b/sys/arm/allwinner/aw_gpio.c
index 18b47bab12d9..2061e38a155f 100644
--- a/sys/arm/allwinner/aw_gpio.c
+++ b/sys/arm/allwinner/aw_gpio.c
@@ -1154,10 +1154,6 @@ aw_gpio_attach(device_t dev)
aw_gpio_register_isrcs(sc);
intr_pic_register(dev, OF_xref_from_node(ofw_bus_get_node(dev)));
- sc->sc_busdev = gpiobus_attach_bus(dev);
- if (sc->sc_busdev == NULL)
- goto fail;
-
/*
* Register as a pinctrl device
*/
@@ -1166,6 +1162,10 @@ aw_gpio_attach(device_t dev)
fdt_pinctrl_register(dev, "allwinner,pins");
fdt_pinctrl_configure_tree(dev);
+ sc->sc_busdev = gpiobus_attach_bus(dev);
+ if (sc->sc_busdev == NULL)
+ goto fail;
+
config_intrhook_oneshot(aw_gpio_enable_bank_supply, sc);
return (0);
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
index e4fc57b79ba5..48d1d2af5abc 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
@@ -837,12 +837,12 @@ bcm_gpio_attach(device_t dev)
}
sc->sc_gpio_npins = i;
bcm_gpio_sysctl_init(sc);
- sc->sc_busdev = gpiobus_attach_bus(dev);
- if (sc->sc_busdev == NULL)
- goto fail;
fdt_pinctrl_register(dev, "brcm,pins");
fdt_pinctrl_configure_tree(dev);
+ sc->sc_busdev = gpiobus_attach_bus(dev);
+ if (sc->sc_busdev == NULL)
+ goto fail;
return (0);
diff --git a/sys/arm/nvidia/as3722_gpio.c b/sys/arm/nvidia/as3722_gpio.c
index 073d057884c9..f7b3d4d43bab 100644
--- a/sys/arm/nvidia/as3722_gpio.c
+++ b/sys/arm/nvidia/as3722_gpio.c
@@ -544,7 +544,7 @@ as3722_gpio_attach(struct as3722_softc *sc, phandle_t node)
sc->gpio_pins = malloc(sizeof(struct as3722_gpio_pin *) *
sc->gpio_npins, M_AS3722_GPIO, M_WAITOK | M_ZERO);
- sc->gpio_busdev = gpiobus_attach_bus(sc->dev);
+ sc->gpio_busdev = gpiobus_add_bus(sc->dev);
if (sc->gpio_busdev == NULL)
return (ENXIO);
for (i = 0; i < sc->gpio_npins; i++) {
diff --git a/sys/arm64/apple/apple_pinctrl.c b/sys/arm64/apple/apple_pinctrl.c
index ec2dd5907024..ebaaccea1d99 100644
--- a/sys/arm64/apple/apple_pinctrl.c
+++ b/sys/arm64/apple/apple_pinctrl.c
@@ -161,22 +161,22 @@ apple_pinctrl_attach(device_t dev)
goto error;
}
+ fdt_pinctrl_register(dev, "pinmux");
+ fdt_pinctrl_configure_tree(dev);
+
+ if (OF_hasprop(node, "interrupt-controller")) {
+ sc->sc_irqs = mallocarray(sc->sc_ngpios,
+ sizeof(*sc->sc_irqs), M_DEVBUF, M_ZERO | M_WAITOK);
+ intr_pic_register(dev,
+ OF_xref_from_node(ofw_bus_get_node(dev)));
+ }
+
sc->sc_busdev = gpiobus_attach_bus(dev);
if (sc->sc_busdev == NULL) {
device_printf(dev, "failed to attach gpiobus\n");
goto error;
}
- fdt_pinctrl_register(dev, "pinmux");
- fdt_pinctrl_configure_tree(dev);
-
- if (!OF_hasprop(node, "interrupt-controller"))
- return (0);
-
- sc->sc_irqs = mallocarray(sc->sc_ngpios,
- sizeof(*sc->sc_irqs), M_DEVBUF, M_ZERO | M_WAITOK);
- intr_pic_register(dev, OF_xref_from_node(ofw_bus_get_node(dev)));
-
return (0);
error:
mtx_destroy(&sc->sc_mtx);
diff --git a/sys/arm64/nvidia/tegra210/max77620_gpio.c b/sys/arm64/nvidia/tegra210/max77620_gpio.c
index 8dcf98099dac..5d91e23324c7 100644
--- a/sys/arm64/nvidia/tegra210/max77620_gpio.c
+++ b/sys/arm64/nvidia/tegra210/max77620_gpio.c
@@ -672,7 +672,7 @@ max77620_gpio_attach(struct max77620_softc *sc, phandle_t node)
sx_init(&sc->gpio_lock, "MAX77620 GPIO lock");
- sc->gpio_busdev = gpiobus_attach_bus(sc->dev);
+ sc->gpio_busdev = gpiobus_add_bus(sc->dev);
if (sc->gpio_busdev == NULL)
return (ENXIO);
diff --git a/sys/arm64/rockchip/rk_gpio.c b/sys/arm64/rockchip/rk_gpio.c
index a86392f16624..847bc7394dd0 100644
--- a/sys/arm64/rockchip/rk_gpio.c
+++ b/sys/arm64/rockchip/rk_gpio.c
@@ -362,12 +362,6 @@ rk_gpio_attach(device_t dev)
return (ENXIO);
}
- sc->sc_busdev = gpiobus_attach_bus(dev);
- if (sc->sc_busdev == NULL) {
- rk_gpio_detach(dev);
- return (ENXIO);
- }
-
/* Set the cached value to unknown */
for (i = 0; i < RK_GPIO_MAX_PINS; i++)
sc->pin_cached[i].is_gpio = 2;
@@ -377,6 +371,12 @@ rk_gpio_attach(device_t dev)
sc->swporta_ddr = rk_gpio_read_4(sc, RK_GPIO_SWPORTA_DDR);
RK_GPIO_UNLOCK(sc);
+ sc->sc_busdev = gpiobus_attach_bus(dev);
+ if (sc->sc_busdev == NULL) {
+ rk_gpio_detach(dev);
+ return (ENXIO);
+ }
+
return (0);
}
diff --git a/sys/dev/gpio/pl061.c b/sys/dev/gpio/pl061.c
index cc39790322b6..87d4310a6396 100644
--- a/sys/dev/gpio/pl061.c
+++ b/sys/dev/gpio/pl061.c
@@ -487,14 +487,21 @@ pl061_attach(device_t dev)
}
}
+ mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "pl061", MTX_SPIN);
+
+ if (sc->sc_xref != 0 && !intr_pic_register(dev, sc->sc_xref)) {
+ device_printf(dev, "couldn't register PIC\n");
+ PL061_LOCK_DESTROY(sc);
+ goto free_isrc;
+ }
+
sc->sc_busdev = gpiobus_attach_bus(dev);
if (sc->sc_busdev == NULL) {
device_printf(dev, "couldn't attach gpio bus\n");
+ PL061_LOCK_DESTROY(sc);
goto free_isrc;
}
- mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "pl061", MTX_SPIN);
-
return (0);
free_isrc:
@@ -503,6 +510,7 @@ free_isrc:
* for (irq = 0; irq < PL061_NUM_GPIO; irq++)
* intr_isrc_deregister(PIC_INTR_ISRC(sc, irq));
*/
+ bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_hdlr);
bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irq_rid,
sc->sc_irq_res);
free_pic:
diff --git a/sys/dev/gpio/pl061.h b/sys/dev/gpio/pl061.h
index 809a1168493d..d9fe23e502b1 100644
--- a/sys/dev/gpio/pl061.h
+++ b/sys/dev/gpio/pl061.h
@@ -46,6 +46,7 @@ struct pl061_softc {
struct resource *sc_mem_res;
struct resource *sc_irq_res;
void *sc_irq_hdlr;
+ intptr_t sc_xref;
int sc_mem_rid;
int sc_irq_rid;
struct pl061_pin_irqsrc sc_isrcs[PL061_NUM_GPIO];
diff --git a/sys/dev/gpio/pl061_acpi.c b/sys/dev/gpio/pl061_acpi.c
index f5885025083e..8e9921261e4e 100644
--- a/sys/dev/gpio/pl061_acpi.c
+++ b/sys/dev/gpio/pl061_acpi.c
@@ -67,19 +67,12 @@ pl061_acpi_probe(device_t dev)
static int
pl061_acpi_attach(device_t dev)
{
- int error;
+ struct pl061_softc *sc;
- error = pl061_attach(dev);
- if (error != 0)
- return (error);
+ sc = device_get_softc(dev);
+ sc->sc_xref = ACPI_GPIO_XREF;
- if (!intr_pic_register(dev, ACPI_GPIO_XREF)) {
- device_printf(dev, "couldn't register PIC\n");
- pl061_detach(dev);
- error = ENXIO;
- }
-
- return (error);
+ return (pl061_attach(dev));
}
static device_method_t pl061_acpi_methods[] = {
diff --git a/sys/dev/gpio/pl061_fdt.c b/sys/dev/gpio/pl061_fdt.c
index aa22298b43c6..681b3ccdfdeb 100644
--- a/sys/dev/gpio/pl061_fdt.c
+++ b/sys/dev/gpio/pl061_fdt.c
@@ -61,19 +61,12 @@ pl061_fdt_probe(device_t dev)
static int
pl061_fdt_attach(device_t dev)
{
- int error;
+ struct pl061_softc *sc;
- error = pl061_attach(dev);
- if (error != 0)
- return (error);
+ sc = device_get_softc(dev);
+ sc->sc_xref = OF_xref_from_node(ofw_bus_get_node(dev));
- if (!intr_pic_register(dev, OF_xref_from_node(ofw_bus_get_node(dev)))) {
- device_printf(dev, "couldn't register PIC\n");
- pl061_detach(dev);
- error = ENXIO;
- }
-
- return (error);
+ return (pl061_attach(dev));
}
static device_method_t pl061_fdt_methods[] = {
diff --git a/sys/dev/gpio/qoriq_gpio.c b/sys/dev/gpio/qoriq_gpio.c
index 25dfccede29f..8b44cd256c79 100644
--- a/sys/dev/gpio/qoriq_gpio.c
+++ b/sys/dev/gpio/qoriq_gpio.c
@@ -369,11 +369,6 @@ qoriq_gpio_attach(device_t dev)
for (i = 0; i <= MAXPIN; i++)
sc->sc_pins[i].gp_caps = DEFAULT_CAPS;
- sc->busdev = gpiobus_attach_bus(dev);
- if (sc->busdev == NULL) {
- qoriq_gpio_detach(dev);
- return (ENOMEM);
- }
/*
* Enable the GPIO Input Buffer for all GPIOs.
* This is safe on devices without a GPIBE register, because those
@@ -384,6 +379,12 @@ qoriq_gpio_attach(device_t dev)
OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev);
+ sc->busdev = gpiobus_attach_bus(dev);
+ if (sc->busdev == NULL) {
+ qoriq_gpio_detach(dev);
+ return (ENOMEM);
+ }
+
return (0);
}
diff --git a/sys/dev/iicbus/gpio/tca64xx.c b/sys/dev/iicbus/gpio/tca64xx.c
index 3b3bca9936f1..cd011ae9be75 100644
--- a/sys/dev/iicbus/gpio/tca64xx.c
+++ b/sys/dev/iicbus/gpio/tca64xx.c
@@ -261,14 +261,13 @@ tca64xx_attach(device_t dev)
sc->addr = iicbus_get_addr(dev);
mtx_init(&sc->mtx, "tca64xx gpio", "gpio", MTX_DEF);
+ OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev);
sc->busdev = gpiobus_attach_bus(dev);
if (sc->busdev == NULL) {
device_printf(dev, "Could not create busdev child\n");
return (ENXIO);
}
- OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev);
-
#ifdef DEBUG
switch (sc->chip) {
case TCA6416_TYPE:
diff --git a/sys/powerpc/mpc85xx/mpc85xx_gpio.c b/sys/powerpc/mpc85xx/mpc85xx_gpio.c
index 0f333feb747f..cb96d768adef 100644
--- a/sys/powerpc/mpc85xx/mpc85xx_gpio.c
+++ b/sys/powerpc/mpc85xx/mpc85xx_gpio.c
@@ -226,14 +226,14 @@ mpc85xx_gpio_attach(device_t dev)
return (ENOMEM);
}
+ OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev);
+
sc->busdev = gpiobus_attach_bus(dev);
if (sc->busdev == NULL) {
mpc85xx_gpio_detach(dev);
return (ENOMEM);
}
- OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev);
-
return (0);
}