Clean up and fix the device detach routine and the failure path on GPIO

drivers.

This paves the way for upcoming work.
This commit is contained in:
loos 2015-01-31 12:17:07 +00:00
parent 4b26a78e58
commit a2924f5fee
10 changed files with 76 additions and 51 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);