The branch stable/14 has been updated by vexeduxr:

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

commit cdba3a8f9fce453774833f2f1123536cd17003b8
Author:     Ahmad Khalifa <vexed...@freebsd.org>
AuthorDate: 2025-07-04 13:52:00 +0000
Commit:     Ahmad Khalifa <vexed...@freebsd.org>
CommitDate: 2025-07-07 18:51:47 +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
    
    (cherry picked from commit 4695e3aa7c685c092cb4b2662bee16c31be790f8)
---
 sys/arm/allwinner/aw_gpio.c               |  8 ++++----
 sys/arm/broadcom/bcm2835/bcm2835_gpio.c   |  6 +++---
 sys/arm/nvidia/as3722_gpio.c              |  2 +-
 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 ++--
 12 files changed, 43 insertions(+), 48 deletions(-)

diff --git a/sys/arm/allwinner/aw_gpio.c b/sys/arm/allwinner/aw_gpio.c
index 1229d5bb146d..b180ef226c15 100644
--- a/sys/arm/allwinner/aw_gpio.c
+++ b/sys/arm/allwinner/aw_gpio.c
@@ -1076,10 +1076,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
         */
@@ -1088,6 +1084,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 f7ae3c99d0f4..0f823ce3e0c1 100644
--- a/sys/arm/nvidia/as3722_gpio.c
+++ b/sys/arm/nvidia/as3722_gpio.c
@@ -545,7 +545,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/nvidia/tegra210/max77620_gpio.c 
b/sys/arm64/nvidia/tegra210/max77620_gpio.c
index 0021aab151de..b60d62a3e0c3 100644
--- a/sys/arm64/nvidia/tegra210/max77620_gpio.c
+++ b/sys/arm64/nvidia/tegra210/max77620_gpio.c
@@ -673,7 +673,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 b1175963a5e4..5a96ea2d0cb4 100644
--- a/sys/arm64/rockchip/rk_gpio.c
+++ b/sys/arm64/rockchip/rk_gpio.c
@@ -363,12 +363,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;
@@ -378,6 +372,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 1a12710ababa..1d7a1439ea76 100644
--- a/sys/dev/gpio/pl061.c
+++ b/sys/dev/gpio/pl061.c
@@ -485,14 +485,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:
@@ -501,6 +508,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 d2531fa94faf..ba927af27f1c 100644
--- a/sys/dev/gpio/pl061_acpi.c
+++ b/sys/dev/gpio/pl061_acpi.c
@@ -68,19 +68,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 352f21560d72..c001b8eb232e 100644
--- a/sys/dev/gpio/pl061_fdt.c
+++ b/sys/dev/gpio/pl061_fdt.c
@@ -62,19 +62,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 5dabe03b775a..a82bd88757e5 100644
--- a/sys/dev/gpio/qoriq_gpio.c
+++ b/sys/dev/gpio/qoriq_gpio.c
@@ -370,11 +370,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
@@ -385,6 +380,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 a129c8727c8a..90c38438cdf3 100644
--- a/sys/dev/iicbus/gpio/tca64xx.c
+++ b/sys/dev/iicbus/gpio/tca64xx.c
@@ -262,14 +262,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 f8c46a9975ae..43ac63ab7031 100644
--- a/sys/powerpc/mpc85xx/mpc85xx_gpio.c
+++ b/sys/powerpc/mpc85xx/mpc85xx_gpio.c
@@ -227,14 +227,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