The branch main has been updated by vexeduxr:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=4695e3aa7c685c092cb4b2662bee16c31be790f8

commit 4695e3aa7c685c092cb4b2662bee16c31be790f8
Author:     Ahmad Khalifa <vexed...@freebsd.org>
AuthorDate: 2025-07-04 13:52:00 +0000
Commit:     Ahmad Khalifa <vexed...@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);
 }
 

Reply via email to