Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Jul 2025 19:23:07 GMT
From:      Ahmad Khalifa <vexeduxr@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: cdba3a8f9fce - stable/14 - gpio: attach gpiobus when the controller is ready
Message-ID:  <202507071923.567JN7lb010769@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by vexeduxr:

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

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202507071923.567JN7lb010769>