Author: loos
Date: Sat Jan 31 12:17:07 2015
New Revision: 277968
URL: https://svnweb.freebsd.org/changeset/base/277968

Log:
  Clean up and fix the device detach routine and the failure path on GPIO
  drivers.
  
  This paves the way for upcoming work.

Modified:
  head/sys/arm/allwinner/a10_gpio.c
  head/sys/arm/altera/socfpga/socfpga_gpio.c
  head/sys/arm/freescale/imx/imx_gpio.c
  head/sys/arm/freescale/vybrid/vf_gpio.c
  head/sys/arm/rockchip/rk30xx_gpio.c
  head/sys/arm/samsung/exynos/exynos5_pad.c
  head/sys/arm/ti/ti_gpio.c
  head/sys/mips/atheros/ar71xx_gpio.c
  head/sys/mips/cavium/octeon_gpio.c
  head/sys/mips/rt305x/rt305x_gpio.c

Modified: head/sys/arm/allwinner/a10_gpio.c
==============================================================================
--- head/sys/arm/allwinner/a10_gpio.c   Sat Jan 31 11:24:26 2015        
(r277967)
+++ head/sys/arm/allwinner/a10_gpio.c   Sat Jan 31 12:17:07 2015        
(r277968)
@@ -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);
 }
 

Modified: head/sys/arm/altera/socfpga/socfpga_gpio.c
==============================================================================
--- head/sys/arm/altera/socfpga/socfpga_gpio.c  Sat Jan 31 11:24:26 2015        
(r277967)
+++ head/sys/arm/altera/socfpga/socfpga_gpio.c  Sat Jan 31 12:17:07 2015        
(r277968)
@@ -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);
        }
 

Modified: head/sys/arm/freescale/imx/imx_gpio.c
==============================================================================
--- head/sys/arm/freescale/imx/imx_gpio.c       Sat Jan 31 11:24:26 2015        
(r277967)
+++ head/sys/arm/freescale/imx/imx_gpio.c       Sat Jan 31 12:17:07 2015        
(r277968)
@@ -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);

Modified: head/sys/arm/freescale/vybrid/vf_gpio.c
==============================================================================
--- head/sys/arm/freescale/vybrid/vf_gpio.c     Sat Jan 31 11:24:26 2015        
(r277967)
+++ head/sys/arm/freescale/vybrid/vf_gpio.c     Sat Jan 31 12:17:07 2015        
(r277968)
@@ -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);
        }
 

Modified: head/sys/arm/rockchip/rk30xx_gpio.c
==============================================================================
--- head/sys/arm/rockchip/rk30xx_gpio.c Sat Jan 31 11:24:26 2015        
(r277967)
+++ head/sys/arm/rockchip/rk30xx_gpio.c Sat Jan 31 12:17:07 2015        
(r277968)
@@ -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);
 }
 

Modified: head/sys/arm/samsung/exynos/exynos5_pad.c
==============================================================================
--- head/sys/arm/samsung/exynos/exynos5_pad.c   Sat Jan 31 11:24:26 2015        
(r277967)
+++ head/sys/arm/samsung/exynos/exynos5_pad.c   Sat Jan 31 12:17:07 2015        
(r277968)
@@ -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

Modified: head/sys/arm/ti/ti_gpio.c
==============================================================================
--- head/sys/arm/ti/ti_gpio.c   Sat Jan 31 11:24:26 2015        (r277967)
+++ head/sys/arm/ti/ti_gpio.c   Sat Jan 31 12:17:07 2015        (r277968)
@@ -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);

Modified: head/sys/mips/atheros/ar71xx_gpio.c
==============================================================================
--- head/sys/mips/atheros/ar71xx_gpio.c Sat Jan 31 11:24:26 2015        
(r277967)
+++ head/sys/mips/atheros/ar71xx_gpio.c Sat Jan 31 12:17:07 2015        
(r277968)
@@ -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);

Modified: head/sys/mips/cavium/octeon_gpio.c
==============================================================================
--- head/sys/mips/cavium/octeon_gpio.c  Sat Jan 31 11:24:26 2015        
(r277967)
+++ head/sys/mips/cavium/octeon_gpio.c  Sat Jan 31 12:17:07 2015        
(r277968)
@@ -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);

Modified: head/sys/mips/rt305x/rt305x_gpio.c
==============================================================================
--- head/sys/mips/rt305x/rt305x_gpio.c  Sat Jan 31 11:24:26 2015        
(r277967)
+++ head/sys/mips/rt305x/rt305x_gpio.c  Sat Jan 31 12:17:07 2015        
(r277968)
@@ -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);
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to