summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/arm/allwinner/a10_gpio.c7
-rw-r--r--sys/arm/altera/socfpga/socfpga_gpio.c1
-rw-r--r--sys/arm/freescale/imx/imx_gpio.c17
-rw-r--r--sys/arm/freescale/vybrid/vf_gpio.c1
-rw-r--r--sys/arm/rockchip/rk30xx_gpio.c13
-rw-r--r--sys/arm/samsung/exynos/exynos5_pad.c19
-rw-r--r--sys/arm/ti/ti_gpio.c28
-rw-r--r--sys/mips/atheros/ar71xx_gpio.c16
-rw-r--r--sys/mips/cavium/octeon_gpio.c11
-rw-r--r--sys/mips/rt305x/rt305x_gpio.c14
10 files changed, 76 insertions, 51 deletions
diff --git a/sys/arm/allwinner/a10_gpio.c b/sys/arm/allwinner/a10_gpio.c
index 23bf399..12d6989 100644
--- a/sys/arm/allwinner/a10_gpio.c
+++ b/sys/arm/allwinner/a10_gpio.c
@@ -427,7 +427,7 @@ a10_gpio_attach(device_t dev)
RF_ACTIVE);
if (!sc->sc_mem_res) {
device_printf(dev, "cannot allocate memory window\n");
- return (ENXIO);
+ goto fail;
}
sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
@@ -437,9 +437,8 @@ a10_gpio_attach(device_t dev)
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (!sc->sc_irq_res) {
- bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
device_printf(dev, "cannot allocate interrupt\n");
- return (ENXIO);
+ goto fail;
}
/* Find our node. */
@@ -472,6 +471,8 @@ fail:
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+ mtx_destroy(&sc->sc_mtx);
+
return (ENXIO);
}
diff --git a/sys/arm/altera/socfpga/socfpga_gpio.c b/sys/arm/altera/socfpga/socfpga_gpio.c
index 196c1e9..1a50c7c 100644
--- a/sys/arm/altera/socfpga/socfpga_gpio.c
+++ b/sys/arm/altera/socfpga/socfpga_gpio.c
@@ -163,6 +163,7 @@ socfpga_gpio_attach(device_t dev)
if (bus_alloc_resources(dev, socfpga_gpio_spec, sc->res)) {
device_printf(dev, "could not allocate resources\n");
+ mtx_destroy(&sc->sc_mtx);
return (ENXIO);
}
diff --git a/sys/arm/freescale/imx/imx_gpio.c b/sys/arm/freescale/imx/imx_gpio.c
index c23f75b..911c9bbb 100644
--- a/sys/arm/freescale/imx/imx_gpio.c
+++ b/sys/arm/freescale/imx/imx_gpio.c
@@ -389,6 +389,8 @@ imx51_gpio_attach(device_t dev)
if (bus_alloc_resources(dev, imx_gpio_spec, sc->sc_res)) {
device_printf(dev, "could not allocate resources\n");
+ bus_release_resources(dev, imx_gpio_spec, sc->sc_res);
+ mtx_destroy(&sc->sc_mtx);
return (ENXIO);
}
@@ -411,6 +413,7 @@ imx51_gpio_attach(device_t dev)
imx51_gpio_intr, NULL, sc, &sc->gpio_ih[irq]))) {
device_printf(dev,
"WARNING: unable to register interrupt handler\n");
+ imx51_gpio_detach(dev);
return (ENXIO);
}
}
@@ -434,6 +437,7 @@ imx51_gpio_attach(device_t dev)
static int
imx51_gpio_detach(device_t dev)
{
+ int irq;
struct imx51_gpio_softc *sc;
sc = device_get_softc(dev);
@@ -441,13 +445,12 @@ imx51_gpio_detach(device_t dev)
KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
bus_generic_detach(dev);
-
- if (sc->sc_res[3])
- bus_release_resources(dev, imx_gpio0irq_spec, &sc->sc_res[3]);
-
- if (sc->sc_res[0])
- bus_release_resources(dev, imx_gpio_spec, sc->sc_res);
-
+ for (irq = 1; irq <= sc->sc_l_irq; irq ++) {
+ if (sc->gpio_ih[irq])
+ bus_teardown_intr(dev, sc->sc_res[irq], sc->gpio_ih[irq]);
+ }
+ bus_release_resources(dev, imx_gpio0irq_spec, &sc->sc_res[3]);
+ bus_release_resources(dev, imx_gpio_spec, sc->sc_res);
mtx_destroy(&sc->sc_mtx);
return(0);
diff --git a/sys/arm/freescale/vybrid/vf_gpio.c b/sys/arm/freescale/vybrid/vf_gpio.c
index a31ff78..1fcf329 100644
--- a/sys/arm/freescale/vybrid/vf_gpio.c
+++ b/sys/arm/freescale/vybrid/vf_gpio.c
@@ -125,6 +125,7 @@ vf_gpio_attach(device_t dev)
if (bus_alloc_resources(dev, vf_gpio_spec, sc->res)) {
device_printf(dev, "could not allocate resources\n");
+ mtx_destroy(&sc->sc_mtx);
return (ENXIO);
}
diff --git a/sys/arm/rockchip/rk30xx_gpio.c b/sys/arm/rockchip/rk30xx_gpio.c
index 6eb7db7..0728dbf 100644
--- a/sys/arm/rockchip/rk30xx_gpio.c
+++ b/sys/arm/rockchip/rk30xx_gpio.c
@@ -399,13 +399,14 @@ rk30_gpio_attach(device_t dev)
if (rk30_gpio_sc)
return (ENXIO);
sc->sc_dev = dev;
+ mtx_init(&sc->sc_mtx, "rk30 gpio", "gpio", MTX_DEF);
rid = 0;
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (!sc->sc_mem_res) {
device_printf(dev, "cannot allocate memory window\n");
- return (ENXIO);
+ goto fail;
}
sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
@@ -421,17 +422,15 @@ rk30_gpio_attach(device_t dev)
if (sc->sc_bank == -1) {
device_printf(dev,
"unsupported device unit (only GPIO0..3 are supported)\n");
- bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
- return (ENXIO);
+ goto fail;
}
rid = 0;
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (!sc->sc_irq_res) {
- bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
device_printf(dev, "cannot allocate interrupt\n");
- return (ENXIO);
+ goto fail;
}
/* Find our node. */
@@ -441,8 +440,6 @@ rk30_gpio_attach(device_t dev)
/* Node is not a GPIO controller. */
goto fail;
- mtx_init(&sc->sc_mtx, "rk30 gpio", "gpio", MTX_DEF);
-
/* Initialize the software controlled pins. */
for (i = 0; i < RK30_GPIO_PINS; i++) {
snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME,
@@ -467,6 +464,8 @@ fail:
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+ mtx_destroy(&sc->sc_mtx);
+
return (ENXIO);
}
diff --git a/sys/arm/samsung/exynos/exynos5_pad.c b/sys/arm/samsung/exynos/exynos5_pad.c
index c28ebb1..0e58bf5 100644
--- a/sys/arm/samsung/exynos/exynos5_pad.c
+++ b/sys/arm/samsung/exynos/exynos5_pad.c
@@ -509,12 +509,12 @@ pad_attach(device_t dev)
sc->nports = 5;
break;
default:
- return (-1);
+ goto fail;
};
if (bus_alloc_resources(dev, sc->pad_spec, sc->res)) {
device_printf(dev, "could not allocate resources\n");
- return (ENXIO);
+ goto fail;
}
/* Memory interface */
@@ -534,9 +534,9 @@ pad_attach(device_t dev)
NULL, sc, &sc->gpio_ih[i]))) {
device_printf(dev,
"ERROR: Unable to register interrupt handler\n");
- return (ENXIO);
+ goto fail;
}
- };
+ }
for (i = 0; i < sc->gpio_npins; i++) {
sc->gpio_pins[i].gp_pin = i;
@@ -563,6 +563,17 @@ pad_attach(device_t dev)
device_add_child(dev, "gpiobus", -1);
return (bus_generic_attach(dev));
+
+fail:
+ for (i = 0; i < sc->nports; i++) {
+ if (sc->gpio_ih[i])
+ bus_teardown_intr(dev, sc->res[sc->nports + i],
+ sc->gpio_ih[i]);
+ }
+ bus_release_resources(dev, sc->pad_spec, sc->res);
+ mtx_destroy(&sc->sc_mtx);
+
+ return (ENXIO);
}
static int
diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c
index ed24958..8874ff3 100644
--- a/sys/arm/ti/ti_gpio.c
+++ b/sys/arm/ti/ti_gpio.c
@@ -113,6 +113,7 @@ __FBSDID("$FreeBSD$");
#define TI_GPIO_MASK(p) (1U << ((p) % PINS_PER_BANK))
static struct ti_gpio_softc *ti_gpio_sc = NULL;
+static int ti_gpio_detach(device_t);
static u_int
ti_max_gpio_banks(void)
@@ -763,21 +764,21 @@ ti_gpio_attach(device_t dev)
*/
if (bus_alloc_resources(dev, ti_gpio_mem_spec, sc->sc_mem_res) != 0) {
device_printf(dev, "Error: could not allocate mem resources\n");
+ ti_gpio_detach(dev);
return (ENXIO);
}
/* Request the IRQ resources */
if (bus_alloc_resources(dev, ti_gpio_irq_spec, sc->sc_irq_res) != 0) {
- bus_release_resources(dev, ti_gpio_mem_spec, sc->sc_mem_res);
device_printf(dev, "Error: could not allocate irq resources\n");
+ ti_gpio_detach(dev);
return (ENXIO);
}
/* Setup the IRQ resources */
if (ti_gpio_attach_intr(dev) != 0) {
- ti_gpio_detach_intr(dev);
- bus_release_resources(dev, ti_gpio_irq_spec, sc->sc_irq_res);
- bus_release_resources(dev, ti_gpio_mem_spec, sc->sc_mem_res);
+ device_printf(dev, "Error: could not setup irq handlers\n");
+ ti_gpio_detach(dev);
return (ENXIO);
}
@@ -809,11 +810,7 @@ ti_gpio_attach(device_t dev)
/* Initialize the GPIO module. */
err = ti_gpio_bank_init(dev, i);
if (err != 0) {
- ti_gpio_detach_intr(dev);
- bus_release_resources(dev, ti_gpio_irq_spec,
- sc->sc_irq_res);
- bus_release_resources(dev, ti_gpio_mem_spec,
- sc->sc_mem_res);
+ ti_gpio_detach(dev);
return (err);
}
}
@@ -852,18 +849,17 @@ ti_gpio_detach(device_t dev)
if (sc->sc_mem_res[i] != NULL)
ti_gpio_intr_clr(sc, i, 0xffffffff);
}
-
bus_generic_detach(dev);
-
- free(sc->sc_events, M_DEVBUF);
- free(sc->sc_irq_polarity, M_DEVBUF);
- free(sc->sc_irq_trigger, M_DEVBUF);
-
+ if (sc->sc_events)
+ free(sc->sc_events, M_DEVBUF);
+ if (sc->sc_irq_polarity)
+ free(sc->sc_irq_polarity, M_DEVBUF);
+ if (sc->sc_irq_trigger)
+ free(sc->sc_irq_trigger, M_DEVBUF);
/* Release the memory and IRQ resources. */
ti_gpio_detach_intr(dev);
bus_release_resources(dev, ti_gpio_irq_spec, sc->sc_irq_res);
bus_release_resources(dev, ti_gpio_mem_spec, sc->sc_mem_res);
-
TI_GPIO_LOCK_DESTROY(sc);
return (0);
diff --git a/sys/mips/atheros/ar71xx_gpio.c b/sys/mips/atheros/ar71xx_gpio.c
index 45ac8ff..b48e4a6 100644
--- a/sys/mips/atheros/ar71xx_gpio.c
+++ b/sys/mips/atheros/ar71xx_gpio.c
@@ -341,7 +341,6 @@ static int
ar71xx_gpio_attach(device_t dev)
{
struct ar71xx_gpio_softc *sc = device_get_softc(dev);
- int error = 0;
int i, j, maxpin;
int mask, pinon;
uint32_t oe;
@@ -358,14 +357,14 @@ ar71xx_gpio_attach(device_t dev)
if (sc->gpio_mem_res == NULL) {
device_printf(dev, "couldn't map memory\n");
- error = ENXIO;
ar71xx_gpio_detach(dev);
- return(error);
+ return (ENXIO);
}
if ((sc->gpio_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&sc->gpio_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
device_printf(dev, "unable to allocate IRQ resource\n");
+ ar71xx_gpio_detach(dev);
return (ENXIO);
}
@@ -373,6 +372,7 @@ ar71xx_gpio_attach(device_t dev)
ar71xx_gpio_filter, ar71xx_gpio_intr, sc, &sc->gpio_ih))) {
device_printf(dev,
"WARNING: unable to register interrupt handler\n");
+ ar71xx_gpio_detach(dev);
return (ENXIO);
}
@@ -447,12 +447,16 @@ ar71xx_gpio_detach(device_t dev)
KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized"));
bus_generic_detach(dev);
-
+ if (sc->gpio_ih)
+ bus_teardown_intr(dev, sc->gpio_irq_res, sc->gpio_ih);
+ if (sc->gpio_irq_res)
+ bus_release_resource(dev, SYS_RES_IRQ, sc->gpio_irq_rid,
+ sc->gpio_irq_res);
if (sc->gpio_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, sc->gpio_mem_rid,
sc->gpio_mem_res);
-
- free(sc->gpio_pins, M_DEVBUF);
+ if (sc->gpio_pins)
+ free(sc->gpio_pins, M_DEVBUF);
mtx_destroy(&sc->gpio_mtx);
return(0);
diff --git a/sys/mips/cavium/octeon_gpio.c b/sys/mips/cavium/octeon_gpio.c
index 3686848..1053976 100644
--- a/sys/mips/cavium/octeon_gpio.c
+++ b/sys/mips/cavium/octeon_gpio.c
@@ -383,6 +383,7 @@ octeon_gpio_attach(device_t dev)
OCTEON_IRQ_GPIO0 + i, OCTEON_IRQ_GPIO0 + i, 1,
RF_SHAREABLE | RF_ACTIVE)) == NULL) {
device_printf(dev, "unable to allocate IRQ resource\n");
+ octeon_gpio_detach(dev);
return (ENXIO);
}
@@ -392,6 +393,7 @@ octeon_gpio_attach(device_t dev)
&(sc->gpio_intr_cookies[i]), &sc->gpio_ih[i]))) {
device_printf(dev,
"WARNING: unable to register interrupt handler\n");
+ octeon_gpio_detach(dev);
return (ENXIO);
}
}
@@ -448,11 +450,14 @@ octeon_gpio_detach(device_t dev)
KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized"));
for ( i = 0; i < OCTEON_GPIO_IRQS; i++) {
- bus_release_resource(dev, SYS_RES_IRQ,
- sc->gpio_irq_rid[i], sc->gpio_irq_res[i]);
+ if (sc->gpio_ih[i])
+ bus_teardown_intr(dev, sc->gpio_irq_res[i],
+ sc->gpio_ih[i]);
+ if (sc->gpio_irq_res[i])
+ bus_release_resource(dev, SYS_RES_IRQ,
+ sc->gpio_irq_rid[i], sc->gpio_irq_res[i]);
}
bus_generic_detach(dev);
-
mtx_destroy(&sc->gpio_mtx);
return(0);
diff --git a/sys/mips/rt305x/rt305x_gpio.c b/sys/mips/rt305x/rt305x_gpio.c
index a5d7254..bf03bd1 100644
--- a/sys/mips/rt305x/rt305x_gpio.c
+++ b/sys/mips/rt305x/rt305x_gpio.c
@@ -430,7 +430,7 @@ static int
rt305x_gpio_attach(device_t dev)
{
struct rt305x_gpio_softc *sc = device_get_softc(dev);
- int error = 0, i;
+ int i;
uint64_t avlpins = 0;
sc->reset_gpio = DAP1350_RESET_GPIO;
@@ -446,14 +446,14 @@ rt305x_gpio_attach(device_t dev)
if (sc->gpio_mem_res == NULL) {
device_printf(dev, "couldn't map memory\n");
- error = ENXIO;
rt305x_gpio_detach(dev);
- return(error);
+ return (ENXIO);
}
if ((sc->gpio_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&sc->gpio_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
device_printf(dev, "unable to allocate IRQ resource\n");
+ rt305x_gpio_detach(dev);
return (ENXIO);
}
@@ -462,6 +462,7 @@ rt305x_gpio_attach(device_t dev)
rt305x_gpio_intr, NULL, sc, &sc->gpio_ih))) {
device_printf(dev,
"WARNING: unable to register interrupt handler\n");
+ rt305x_gpio_detach(dev);
return (ENXIO);
}
@@ -515,11 +516,14 @@ rt305x_gpio_detach(device_t dev)
KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized"));
bus_generic_detach(dev);
-
+ if (sc->gpio_ih)
+ bus_teardown_intr(dev, sc->gpio_irq_res, sc->gpio_ih);
+ if (sc->gpio_irq_res)
+ bus_release_resource(dev, SYS_RES_IRQ, sc->gpio_irq_rid,
+ sc->gpio_irq_res);
if (sc->gpio_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, sc->gpio_mem_rid,
sc->gpio_mem_res);
-
mtx_destroy(&sc->gpio_mtx);
return(0);
OpenPOWER on IntegriCloud