Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Jul 2025 14:07:18 GMT
From:      Ahmad Khalifa <vexeduxr@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 4695e3aa7c68 - main - gpio: attach gpiobus when the controller is ready
Message-ID:  <202507041407.564E7I9g080690@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }
 



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