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:
parent
4b26a78e58
commit
a2924f5fee
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user