Author: loos
Date: Sat Jan 31 19:32:14 2015
New Revision: 277996
URL: https://svnweb.freebsd.org/changeset/base/277996

Log:
  Implement GPIO_GET_BUS() method for all GPIO drivers.
  
  Add helper routines to deal with attach and detach of gpiobus and gpioc
  devices that are common to all drivers.

Modified:
  head/sys/arm/allwinner/a10_gpio.c
  head/sys/arm/altera/socfpga/socfpga_gpio.c
  head/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
  head/sys/arm/freescale/imx/imx_gpio.c
  head/sys/arm/freescale/vybrid/vf_gpio.c
  head/sys/arm/lpc/lpc_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/arm/ti/ti_gpio.h
  head/sys/arm/xilinx/zy7_gpio.c
  head/sys/arm/xscale/ixp425/avila_gpio.c
  head/sys/arm/xscale/ixp425/cambria_gpio.c
  head/sys/dev/gpio/gpiobus.c
  head/sys/dev/gpio/gpiobusvar.h
  head/sys/mips/atheros/ar71xx_gpio.c
  head/sys/mips/atheros/ar71xx_gpiovar.h
  head/sys/mips/cavium/octeon_gpio.c
  head/sys/mips/cavium/octeon_gpiovar.h
  head/sys/mips/rt305x/rt305x_gpio.c
  head/sys/mips/rt305x/rt305x_gpiovar.h

Modified: head/sys/arm/allwinner/a10_gpio.c
==============================================================================
--- head/sys/arm/allwinner/a10_gpio.c   Sat Jan 31 19:29:28 2015        
(r277995)
+++ head/sys/arm/allwinner/a10_gpio.c   Sat Jan 31 19:32:14 2015        
(r277996)
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/intr.h>
 
 #include <dev/fdt/fdt_common.h>
+#include <dev/gpio/gpiobusvar.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
@@ -75,6 +76,7 @@ __FBSDID("$FreeBSD$");
 
 struct a10_gpio_softc {
        device_t                sc_dev;
+       device_t                sc_busdev;
        struct mtx              sc_mtx;
        struct resource *       sc_mem_res;
        struct resource *       sc_irq_res;
@@ -217,6 +219,16 @@ a10_gpio_pin_configure(struct a10_gpio_s
        A10_GPIO_UNLOCK(sc);
 }
 
+static device_t
+a10_gpio_get_bus(device_t dev)
+{
+       struct a10_gpio_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       return (sc->sc_busdev);
+}
+
 static int
 a10_gpio_pin_max(device_t dev, int *maxpin)
 {
@@ -458,13 +470,12 @@ a10_gpio_attach(device_t dev)
                sc->sc_gpio_pins[i].gp_flags = a10_gpio_func_flag(func);
        }
        sc->sc_gpio_npins = i;
-
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
-
        a10_gpio_sc = sc;
+       sc->sc_busdev = gpiobus_attach_bus(dev);
+       if (sc->sc_busdev == NULL)
+               goto fail;
 
-       return (bus_generic_attach(dev));
+       return (0);
 
 fail:
        if (sc->sc_irq_res)
@@ -490,6 +501,7 @@ static device_method_t a10_gpio_methods[
        DEVMETHOD(device_detach,        a10_gpio_detach),
 
        /* GPIO protocol */
+       DEVMETHOD(gpio_get_bus,         a10_gpio_get_bus),
        DEVMETHOD(gpio_pin_max,         a10_gpio_pin_max),
        DEVMETHOD(gpio_pin_getname,     a10_gpio_pin_getname),
        DEVMETHOD(gpio_pin_getflags,    a10_gpio_pin_getflags),

Modified: head/sys/arm/altera/socfpga/socfpga_gpio.c
==============================================================================
--- head/sys/arm/altera/socfpga/socfpga_gpio.c  Sat Jan 31 19:29:28 2015        
(r277995)
+++ head/sys/arm/altera/socfpga/socfpga_gpio.c  Sat Jan 31 19:32:14 2015        
(r277996)
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/gpio.h>
 
 #include <dev/fdt/fdt_common.h>
+#include <dev/gpio/gpiobusvar.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
@@ -107,6 +108,7 @@ enum port_no {
 /*
  * GPIO interface
  */
+static device_t socfpga_gpio_get_bus(device_t);
 static int socfpga_gpio_pin_max(device_t, int *);
 static int socfpga_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
 static int socfpga_gpio_pin_getname(device_t, uint32_t, char *);
@@ -122,6 +124,7 @@ struct socfpga_gpio_softc {
        bus_space_handle_t      bsh;
 
        device_t                dev;
+       device_t                busdev;
        struct mtx              sc_mtx;
        int                     gpio_npins;
        struct gpio_pin         gpio_pins[NR_GPIO_MAX];
@@ -196,11 +199,24 @@ socfpga_gpio_attach(device_t dev)
                snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
                    "socfpga_gpio%d.%d", device_get_unit(dev), i);
        }
+       sc->busdev = gpiobus_attach_bus(dev);
+       if (sc->busdev == NULL) {
+               bus_release_resources(dev, socfpga_gpio_spec, sc->res);
+               mtx_destroy(&sc->sc_mtx);
+               return (ENXIO);
+       }
+
+       return (0);
+}
 
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
+static device_t
+socfpga_gpio_get_bus(device_t dev)
+{
+       struct socfpga_gpio_softc *sc;
+
+       sc = device_get_softc(dev);
 
-       return (bus_generic_attach(dev));
+       return (sc->busdev);
 }
 
 static int
@@ -415,6 +431,7 @@ static device_method_t socfpga_gpio_meth
        DEVMETHOD(device_attach,        socfpga_gpio_attach),
 
        /* GPIO protocol */
+       DEVMETHOD(gpio_get_bus,         socfpga_gpio_get_bus),
        DEVMETHOD(gpio_pin_max,         socfpga_gpio_pin_max),
        DEVMETHOD(gpio_pin_getname,     socfpga_gpio_pin_getname),
        DEVMETHOD(gpio_pin_getcaps,     socfpga_gpio_pin_getcaps),

Modified: head/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
==============================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2835_gpio.c        Sat Jan 31 19:29:28 
2015        (r277995)
+++ head/sys/arm/broadcom/bcm2835/bcm2835_gpio.c        Sat Jan 31 19:32:14 
2015        (r277996)
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/intr.h>
 
 #include <dev/fdt/fdt_common.h>
+#include <dev/gpio/gpiobusvar.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
@@ -83,6 +84,7 @@ struct bcm_gpio_sysctl {
 
 struct bcm_gpio_softc {
        device_t                sc_dev;
+       device_t                sc_busdev;
        struct mtx              sc_mtx;
        struct resource *       sc_res[BCM_GPIO_IRQS + 1];
        bus_space_tag_t         sc_bst;
@@ -317,6 +319,16 @@ bcm_gpio_pin_configure(struct bcm_gpio_s
        BCM_GPIO_UNLOCK(sc);
 }
 
+static device_t
+bcm_gpio_get_bus(device_t dev)
+{
+       struct bcm_gpio_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       return (sc->sc_busdev);
+}
+
 static int
 bcm_gpio_pin_max(device_t dev, int *maxpin)
 {
@@ -709,13 +721,12 @@ bcm_gpio_attach(device_t dev)
                i++;
        }
        sc->sc_gpio_npins = i;
-
        bcm_gpio_sysctl_init(sc);
+       sc->sc_busdev = gpiobus_attach_bus(dev);
+       if (sc->sc_busdev == NULL)
+               goto fail;
 
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
-
-       return (bus_generic_attach(dev));
+       return (0);
 
 fail:
        bus_release_resources(dev, bcm_gpio_res_spec, sc->sc_res);
@@ -746,6 +757,7 @@ static device_method_t bcm_gpio_methods[
        DEVMETHOD(device_detach,        bcm_gpio_detach),
 
        /* GPIO protocol */
+       DEVMETHOD(gpio_get_bus,         bcm_gpio_get_bus),
        DEVMETHOD(gpio_pin_max,         bcm_gpio_pin_max),
        DEVMETHOD(gpio_pin_getname,     bcm_gpio_pin_getname),
        DEVMETHOD(gpio_pin_getflags,    bcm_gpio_pin_getflags),

Modified: head/sys/arm/freescale/imx/imx_gpio.c
==============================================================================
--- head/sys/arm/freescale/imx/imx_gpio.c       Sat Jan 31 19:29:28 2015        
(r277995)
+++ head/sys/arm/freescale/imx/imx_gpio.c       Sat Jan 31 19:32:14 2015        
(r277996)
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/resource.h>
 
 #include <dev/fdt/fdt_common.h>
+#include <dev/gpio/gpiobusvar.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
@@ -92,6 +93,7 @@ __FBSDID("$FreeBSD$");
 
 struct imx51_gpio_softc {
        device_t                dev;
+       device_t                sc_busdev;
        struct mtx              sc_mtx;
        struct resource         *sc_res[11]; /* 1 x mem, 2 x IRQ, 8 x IRQ */
        void                    *gpio_ih[11]; /* 1 ptr is not a big waste */
@@ -145,6 +147,7 @@ static int imx51_gpio_intr(void *);
 /*
  * GPIO interface
  */
+static device_t imx51_gpio_get_bus(device_t);
 static int imx51_gpio_pin_max(device_t, int *);
 static int imx51_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
 static int imx51_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
@@ -179,6 +182,16 @@ imx51_gpio_pin_configure(struct imx51_gp
        GPIO_UNLOCK(sc);
 }
 
+static device_t
+imx51_gpio_get_bus(device_t dev)
+{
+       struct imx51_gpio_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       return (sc->sc_busdev);
+}
+
 static int
 imx51_gpio_pin_max(device_t dev, int *maxpin)
 {
@@ -427,11 +440,13 @@ imx51_gpio_attach(device_t dev)
                snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
                    "imx_gpio%d.%d", device_get_unit(dev), i);
        }
+       sc->sc_busdev = gpiobus_attach_bus(dev);
+       if (sc->sc_busdev == NULL) {
+               imx51_gpio_detach(dev);
+               return (ENXIO);
+       }
 
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
-
-       return (bus_generic_attach(dev));
+       return (0);
 }
 
 static int
@@ -444,7 +459,7 @@ imx51_gpio_detach(device_t dev)
 
        KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
 
-       bus_generic_detach(dev);
+       gpiobus_detach_bus(dev);
        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]);
@@ -462,6 +477,7 @@ static device_method_t imx51_gpio_method
        DEVMETHOD(device_detach,        imx51_gpio_detach),
 
        /* GPIO protocol */
+       DEVMETHOD(gpio_get_bus,         imx51_gpio_get_bus),
        DEVMETHOD(gpio_pin_max,         imx51_gpio_pin_max),
        DEVMETHOD(gpio_pin_getname,     imx51_gpio_pin_getname),
        DEVMETHOD(gpio_pin_getflags,    imx51_gpio_pin_getflags),

Modified: head/sys/arm/freescale/vybrid/vf_gpio.c
==============================================================================
--- head/sys/arm/freescale/vybrid/vf_gpio.c     Sat Jan 31 19:29:28 2015        
(r277995)
+++ head/sys/arm/freescale/vybrid/vf_gpio.c     Sat Jan 31 19:32:14 2015        
(r277996)
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/gpio.h>
 
 #include <dev/fdt/fdt_common.h>
+#include <dev/gpio/gpiobusvar.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
@@ -74,6 +75,7 @@ __FBSDID("$FreeBSD$");
 /*
  * GPIO interface
  */
+static device_t vf_gpio_get_bus(device_t);
 static int vf_gpio_pin_max(device_t, int *);
 static int vf_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
 static int vf_gpio_pin_getname(device_t, uint32_t, char *);
@@ -88,6 +90,7 @@ struct vf_gpio_softc {
        bus_space_tag_t         bst;
        bus_space_handle_t      bsh;
 
+       device_t                sc_busdev;
        struct mtx              sc_mtx;
        int                     gpio_npins;
        struct gpio_pin         gpio_pins[NGPIO];
@@ -147,10 +150,24 @@ vf_gpio_attach(device_t dev)
                    "vf_gpio%d.%d", device_get_unit(dev), i);
        }
 
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
+       sc->sc_busdev = gpiobus_attach_bus(dev);
+       if (sc->sc_busdev == NULL) {
+               bus_release_resources(dev, vf_gpio_spec, sc->res);
+               mtx_destroy(&sc->sc_mtx);
+               return (ENXIO);
+       }
+
+       return (0);
+}
+
+static device_t
+vf_gpio_get_bus(device_t dev)
+{
+       struct vf_gpio_softc *sc;
+
+       sc = device_get_softc(dev);
 
-       return (bus_generic_attach(dev));
+       return (sc->sc_busdev);
 }
 
 static int
@@ -348,6 +365,7 @@ static device_method_t vf_gpio_methods[]
        DEVMETHOD(device_attach,        vf_gpio_attach),
 
        /* GPIO protocol */
+       DEVMETHOD(gpio_get_bus,         vf_gpio_get_bus),
        DEVMETHOD(gpio_pin_max,         vf_gpio_pin_max),
        DEVMETHOD(gpio_pin_getname,     vf_gpio_pin_getname),
        DEVMETHOD(gpio_pin_getcaps,     vf_gpio_pin_getcaps),

Modified: head/sys/arm/lpc/lpc_gpio.c
==============================================================================
--- head/sys/arm/lpc/lpc_gpio.c Sat Jan 31 19:29:28 2015        (r277995)
+++ head/sys/arm/lpc/lpc_gpio.c Sat Jan 31 19:32:14 2015        (r277996)
@@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/intr.h>
 #include <machine/fdt.h>
 
+#include <dev/gpio/gpiobusvar.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
@@ -90,6 +91,7 @@ __FBSDID("$FreeBSD$");
 struct lpc_gpio_softc
 {
        device_t                lg_dev;
+       device_t                lg_busdev;
        struct resource *       lg_res;
        bus_space_tag_t         lg_bst;
        bus_space_handle_t      lg_bsh;
@@ -135,6 +137,7 @@ static int lpc_gpio_probe(device_t);
 static int lpc_gpio_attach(device_t);
 static int lpc_gpio_detach(device_t);
 
+static device_t lpc_gpio_get_bus(device_t);
 static int lpc_gpio_pin_max(device_t, int *);
 static int lpc_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
 static int lpc_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
@@ -192,10 +195,13 @@ lpc_gpio_attach(device_t dev)
 
        lpc_gpio_sc = sc;
 
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
+       sc->lg_busdev = gpiobus_attach_bus(dev);
+       if (sc->lg_busdev == NULL) {
+               bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->lg_res);
+               return (ENXIO);
+       }
 
-       return (bus_generic_attach(dev));
+       return (0);
 }
 
 static int
@@ -204,6 +210,16 @@ lpc_gpio_detach(device_t dev)
        return (EBUSY);
 }
 
+static device_t
+lpc_gpio_get_bus(device_t dev)
+{
+       struct lpc_gpio_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       return (sc->lg_busdev);
+}
+
 static int
 lpc_gpio_pin_max(device_t dev, int *npins)
 {
@@ -527,6 +543,7 @@ static device_method_t lpc_gpio_methods[
        DEVMETHOD(device_detach,        lpc_gpio_detach),
 
        /* GPIO interface */
+       DEVMETHOD(gpio_get_bus,         lpc_gpio_get_bus),
        DEVMETHOD(gpio_pin_max,         lpc_gpio_pin_max),
        DEVMETHOD(gpio_pin_getcaps,     lpc_gpio_pin_getcaps),
        DEVMETHOD(gpio_pin_getflags,    lpc_gpio_pin_getflags),

Modified: head/sys/arm/rockchip/rk30xx_gpio.c
==============================================================================
--- head/sys/arm/rockchip/rk30xx_gpio.c Sat Jan 31 19:29:28 2015        
(r277995)
+++ head/sys/arm/rockchip/rk30xx_gpio.c Sat Jan 31 19:32:14 2015        
(r277996)
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/intr.h>
 
 #include <dev/fdt/fdt_common.h>
+#include <dev/gpio/gpiobusvar.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
@@ -73,6 +74,7 @@ __FBSDID("$FreeBSD$");
 
 struct rk30_gpio_softc {
        device_t                sc_dev;
+       device_t                sc_busdev;
        struct mtx              sc_mtx;
        struct resource *       sc_mem_res;
        struct resource *       sc_irq_res;
@@ -210,6 +212,16 @@ rk30_gpio_pin_configure(struct rk30_gpio
        RK30_GPIO_UNLOCK(sc);
 }
 
+static device_t
+rk30_gpio_get_bus(device_t dev)
+{
+       struct rk30_gpio_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       return (sc->sc_busdev);
+}
+
 static int
 rk30_gpio_pin_max(device_t dev, int *maxpin)
 {
@@ -449,15 +461,13 @@ rk30_gpio_attach(device_t dev)
                sc->sc_gpio_pins[i].gp_flags = rk30_gpio_get_function(sc, i);
        }
        sc->sc_gpio_npins = i;
-
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
-
        rk30_gpio_sc = sc;
-
        rk30_gpio_init();
-       
-       return (bus_generic_attach(dev));
+       sc->sc_busdev = gpiobus_attach_bus(dev);
+       if (sc->sc_busdev == NULL)
+               goto fail;
+
+       return (0);
 
 fail:
        if (sc->sc_irq_res)
@@ -483,6 +493,7 @@ static device_method_t rk30_gpio_methods
        DEVMETHOD(device_detach,        rk30_gpio_detach),
 
        /* GPIO protocol */
+       DEVMETHOD(gpio_get_bus,         rk30_gpio_get_bus),
        DEVMETHOD(gpio_pin_max,         rk30_gpio_pin_max),
        DEVMETHOD(gpio_pin_getname,     rk30_gpio_pin_getname),
        DEVMETHOD(gpio_pin_getflags,    rk30_gpio_pin_getflags),

Modified: head/sys/arm/samsung/exynos/exynos5_pad.c
==============================================================================
--- head/sys/arm/samsung/exynos/exynos5_pad.c   Sat Jan 31 19:29:28 2015        
(r277995)
+++ head/sys/arm/samsung/exynos/exynos5_pad.c   Sat Jan 31 19:32:14 2015        
(r277996)
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mutex.h>
 #include <sys/gpio.h>
 
+#include <dev/gpio/gpiobusvar.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
@@ -82,6 +83,7 @@ __FBSDID("$FreeBSD$");
 /*
  * GPIO interface
  */
+static device_t pad_get_bus(device_t);
 static int pad_pin_max(device_t, int *);
 static int pad_pin_getcaps(device_t, uint32_t, uint32_t *);
 static int pad_pin_getname(device_t, uint32_t, char *);
@@ -111,6 +113,7 @@ struct pad_softc {
        struct gpio_pin         gpio_pins[MAX_NGPIO];
        void                    *gpio_ih[MAX_PORTS];
        device_t                dev;
+       device_t                busdev;
        int                     model;
        struct resource_spec    *pad_spec;
        struct gpio_bank        *gpio_map;
@@ -558,11 +561,11 @@ pad_attach(device_t dev)
                snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
                    "pad%d.%d", device_get_unit(dev), i);
        }
+       sc->busdev = gpiobus_attach_bus(dev);
+       if (sc->busdev == NULL)
+               goto fail;
 
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
-
-       return (bus_generic_attach(dev));
+       return (0);
 
 fail:
        for (i = 0; i < sc->nports; i++) {
@@ -576,6 +579,16 @@ fail:
        return (ENXIO);
 }
 
+static device_t
+pad_get_bus(device_t dev)
+{
+       struct pad_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       return (sc->busdev);
+}
+
 static int
 pad_pin_max(device_t dev, int *maxpin)
 {
@@ -817,6 +830,7 @@ static device_method_t pad_methods[] = {
        DEVMETHOD(device_attach,        pad_attach),
 
        /* GPIO protocol */
+       DEVMETHOD(gpio_get_bus,         pad_get_bus),
        DEVMETHOD(gpio_pin_max,         pad_pin_max),
        DEVMETHOD(gpio_pin_getname,     pad_pin_getname),
        DEVMETHOD(gpio_pin_getcaps,     pad_pin_getcaps),

Modified: head/sys/arm/ti/ti_gpio.c
==============================================================================
--- head/sys/arm/ti/ti_gpio.c   Sat Jan 31 19:29:28 2015        (r277995)
+++ head/sys/arm/ti/ti_gpio.c   Sat Jan 31 19:32:14 2015        (r277996)
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
 #include <arm/ti/ti_prcm.h>
 
 #include <dev/fdt/fdt_common.h>
+#include <dev/gpio/gpiobusvar.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
@@ -309,6 +310,16 @@ ti_gpio_intr_status(struct ti_gpio_softc
        return (reg);
 }
 
+static device_t
+ti_gpio_get_bus(device_t dev)
+{
+       struct ti_gpio_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       return (sc->sc_busdev);
+}
+
 /**
  *     ti_gpio_pin_max - Returns the maximum number of GPIO pins
  *     @dev: gpio device handle
@@ -815,12 +826,13 @@ ti_gpio_attach(device_t dev)
                        }
                }
        }
+       sc->sc_busdev = gpiobus_attach_bus(dev);
+       if (sc->sc_busdev == NULL) {
+               ti_gpio_detach(dev);
+               return (ENXIO);
+       }
 
-       /* Finish of the probe call */
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
-
-       return (bus_generic_attach(dev));
+       return (0);
 }
 
 /**
@@ -849,7 +861,7 @@ ti_gpio_detach(device_t dev)
                if (sc->sc_mem_res[i] != NULL)
                        ti_gpio_intr_clr(sc, i, 0xffffffff);
        }
-       bus_generic_detach(dev);
+       gpiobus_detach_bus(dev);
        if (sc->sc_events)
                free(sc->sc_events, M_DEVBUF);
        if (sc->sc_irq_polarity)
@@ -1065,6 +1077,7 @@ static device_method_t ti_gpio_methods[]
        DEVMETHOD(device_detach, ti_gpio_detach),
 
        /* GPIO protocol */
+       DEVMETHOD(gpio_get_bus, ti_gpio_get_bus),
        DEVMETHOD(gpio_pin_max, ti_gpio_pin_max),
        DEVMETHOD(gpio_pin_getname, ti_gpio_pin_getname),
        DEVMETHOD(gpio_pin_getflags, ti_gpio_pin_getflags),

Modified: head/sys/arm/ti/ti_gpio.h
==============================================================================
--- head/sys/arm/ti/ti_gpio.h   Sat Jan 31 19:29:28 2015        (r277995)
+++ head/sys/arm/ti/ti_gpio.h   Sat Jan 31 19:32:14 2015        (r277996)
@@ -46,6 +46,7 @@
  */
 struct ti_gpio_softc {
        device_t                sc_dev;
+       device_t                sc_busdev;
 
        /* Interrupt trigger type and level. */
        enum intr_trigger       *sc_irq_trigger;

Modified: head/sys/arm/xilinx/zy7_gpio.c
==============================================================================
--- head/sys/arm/xilinx/zy7_gpio.c      Sat Jan 31 19:29:28 2015        
(r277995)
+++ head/sys/arm/xilinx/zy7_gpio.c      Sat Jan 31 19:32:14 2015        
(r277996)
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/stdarg.h>
 
 #include <dev/fdt/fdt_common.h>
+#include <dev/gpio/gpiobusvar.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
@@ -88,6 +89,7 @@ __FBSDID("$FreeBSD$");
 
 struct zy7_gpio_softc {
        device_t        dev;
+       device_t        busdev;
        struct mtx      sc_mtx;
        struct resource *mem_res;       /* Memory resource */
 };
@@ -113,6 +115,15 @@ struct zy7_gpio_softc {
 #define ZY7_GPIO_INT_POLARITY(b)       (0x0220+0x40*(b)) /* int polarity */
 #define ZY7_GPIO_INT_ANY(b)            (0x0224+0x40*(b)) /* any edge */
 
+static device_t
+zy7_gpio_get_bus(device_t dev)
+{
+       struct zy7_gpio_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       return (sc->busdev);
+}
 
 static int
 zy7_gpio_pin_max(device_t dev, int *maxpin)
@@ -329,10 +340,13 @@ zy7_gpio_attach(device_t dev)
        /* Completely reset. */
        zy7_gpio_hw_reset(sc);
 
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
+       sc->busdev = gpiobus_attach_bus(dev);
+       if (sc->busdev == NULL) {
+               zy7_gpio_detach(dev);
+               return (ENOMEM);
+       }
 
-       return (bus_generic_attach(dev));
+       return (0);
 }
 
 static int
@@ -340,7 +354,7 @@ zy7_gpio_detach(device_t dev)
 {
        struct zy7_gpio_softc *sc = device_get_softc(dev);
 
-       bus_generic_detach(dev);
+       gpiobus_detach_bus(dev);
 
        if (sc->mem_res != NULL) {
                /* Release memory resource. */
@@ -360,6 +374,7 @@ static device_method_t zy7_gpio_methods[
        DEVMETHOD(device_detach,        zy7_gpio_detach),
 
        /* GPIO protocol */
+       DEVMETHOD(gpio_get_bus,         zy7_gpio_get_bus),
        DEVMETHOD(gpio_pin_max,         zy7_gpio_pin_max),
        DEVMETHOD(gpio_pin_getname,     zy7_gpio_pin_getname),
        DEVMETHOD(gpio_pin_getflags,    zy7_gpio_pin_getflags),

Modified: head/sys/arm/xscale/ixp425/avila_gpio.c
==============================================================================
--- head/sys/arm/xscale/ixp425/avila_gpio.c     Sat Jan 31 19:29:28 2015        
(r277995)
+++ head/sys/arm/xscale/ixp425/avila_gpio.c     Sat Jan 31 19:32:14 2015        
(r277996)
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/resource.h>
 #include <arm/xscale/ixp425/ixp425reg.h>
 #include <arm/xscale/ixp425/ixp425var.h>
+#include <dev/gpio/gpiobusvar.h>
 
 #include "gpio_if.h"
 
@@ -60,6 +61,7 @@ __FBSDID("$FreeBSD$");
 
 struct avila_gpio_softc {
        device_t                sc_dev;
+       device_t                sc_busdev;
        bus_space_tag_t         sc_iot;
        bus_space_handle_t      sc_gpio_ioh;
        uint32_t                sc_valid;
@@ -116,6 +118,7 @@ static int avila_gpio_detach(device_t de
 /*
  * GPIO interface
  */
+static device_t avila_gpio_get_bus(device_t);
 static int avila_gpio_pin_max(device_t dev, int *maxpin);
 static int avila_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
 static int avila_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
@@ -162,6 +165,16 @@ avila_gpio_pin_configure(struct avila_gp
        }
 }
 
+static device_t
+avila_gpio_get_bus(device_t dev)
+{
+       struct avila_gpio_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       return (sc->sc_busdev);
+}
+
 static int
 avila_gpio_pin_max(device_t dev, int *maxpin)
 {
@@ -310,10 +323,11 @@ avila_gpio_attach(device_t dev)
                sc->sc_valid |= 1 << p->pin;
        }
 
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
+       sc->sc_busdev = gpiobus_attach_bus(dev);
+       if (sc->sc_busdev == NULL)
+               return (ENXIO);
 
-       return (bus_generic_attach(dev));
+       return (0);
 #undef N
 }
 
@@ -321,7 +335,7 @@ static int
 avila_gpio_detach(device_t dev)
 {
 
-       bus_generic_detach(dev);
+       gpiobus_detach_bus(dev);
 
        return(0);
 }
@@ -332,6 +346,7 @@ static device_method_t gpio_avila_method
        DEVMETHOD(device_detach, avila_gpio_detach),
 
        /* GPIO protocol */
+       DEVMETHOD(gpio_get_bus, avila_gpio_get_bus),
        DEVMETHOD(gpio_pin_max, avila_gpio_pin_max),
        DEVMETHOD(gpio_pin_getname, avila_gpio_pin_getname),
        DEVMETHOD(gpio_pin_getflags, avila_gpio_pin_getflags),

Modified: head/sys/arm/xscale/ixp425/cambria_gpio.c
==============================================================================
--- head/sys/arm/xscale/ixp425/cambria_gpio.c   Sat Jan 31 19:29:28 2015        
(r277995)
+++ head/sys/arm/xscale/ixp425/cambria_gpio.c   Sat Jan 31 19:32:14 2015        
(r277996)
@@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
 #include <arm/xscale/ixp425/ixp425var.h>
 #include <arm/xscale/ixp425/ixdp425reg.h>
 
+#include <dev/gpio/gpiobusvar.h>
 #include <dev/iicbus/iiconf.h>
 #include <dev/iicbus/iicbus.h>
 
@@ -79,6 +80,7 @@ __FBSDID("$FreeBSD$");
 #define        GPIO_PINS               5
 struct cambria_gpio_softc {
        device_t                sc_dev;
+       device_t                sc_busdev;
        bus_space_tag_t         sc_iot;
        bus_space_handle_t      sc_gpio_ioh;
         struct mtx             sc_mtx;
@@ -119,6 +121,7 @@ static int cambria_gpio_detach(device_t 
 /*
  * GPIO interface
  */
+static device_t cambria_gpio_get_bus(device_t);
 static int cambria_gpio_pin_max(device_t dev, int *maxpin);
 static int cambria_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t 
*caps);
 static int cambria_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
@@ -261,6 +264,16 @@ cambria_gpio_write(struct cambria_gpio_s
        return (0);
 }
 
+static device_t
+cambria_gpio_get_bus(device_t dev)
+{
+       struct cambria_gpio_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       return (sc->sc_busdev);
+}
+
 static int
 cambria_gpio_pin_max(device_t dev, int *maxpin)
 {
@@ -438,10 +451,13 @@ cambria_gpio_attach(device_t dev)
                cambria_gpio_pin_setflags(dev, pin, p->flags);
        }
 
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
+       sc->sc_busdev = gpiobus_attach_bus(dev);
+       if (sc->sc_busdev == NULL) {
+               mtx_destroy(&sc->sc_mtx);
+               return (ENXIO);
+       }
 
-       return (bus_generic_attach(dev));
+       return (0);
 }
 
 static int
@@ -451,8 +467,7 @@ cambria_gpio_detach(device_t dev)
 
        KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
 
-       bus_generic_detach(dev);
-
+       gpiobus_detach_bus(dev);
        mtx_destroy(&sc->sc_mtx);
 
        return(0);
@@ -464,6 +479,7 @@ static device_method_t cambria_gpio_meth
        DEVMETHOD(device_detach, cambria_gpio_detach),
 
        /* GPIO protocol */
+       DEVMETHOD(gpio_get_bus, cambria_gpio_get_bus),
        DEVMETHOD(gpio_pin_max, cambria_gpio_pin_max),
        DEVMETHOD(gpio_pin_getname, cambria_gpio_pin_getname),
        DEVMETHOD(gpio_pin_getflags, cambria_gpio_pin_getflags),

Modified: head/sys/dev/gpio/gpiobus.c
==============================================================================
--- head/sys/dev/gpio/gpiobus.c Sat Jan 31 19:29:28 2015        (r277995)
+++ head/sys/dev/gpio/gpiobus.c Sat Jan 31 19:32:14 2015        (r277996)
@@ -131,6 +131,30 @@ gpiobus_print_pins(struct gpiobus_ivar *
        strlcat(buf, tmp, buflen);
 }
 
+device_t
+gpiobus_attach_bus(device_t dev)
+{
+       device_t busdev;
+
+       busdev = device_add_child(dev, "gpiobus", -1);
+       if (busdev == NULL)
+               return (NULL);
+       if (device_add_child(dev, "gpioc", -1) == NULL) {
+               device_delete_child(dev, busdev);
+               return (NULL);
+       }
+       bus_generic_attach(dev);
+
+       return (busdev);
+}
+
+int
+gpiobus_detach_bus(device_t dev)
+{
+
+       return (bus_generic_detach(dev));
+}
+
 int
 gpiobus_init_softc(device_t dev)
 {

Modified: head/sys/dev/gpio/gpiobusvar.h
==============================================================================
--- head/sys/dev/gpio/gpiobusvar.h      Sat Jan 31 19:29:28 2015        
(r277995)
+++ head/sys/dev/gpio/gpiobusvar.h      Sat Jan 31 19:32:14 2015        
(r277996)
@@ -95,6 +95,8 @@ gpio_map_gpios(device_t bus, phandle_t d
 device_t ofw_gpiobus_add_fdt_child(device_t, phandle_t);
 #endif
 int gpio_check_flags(uint32_t, uint32_t);
+device_t gpiobus_attach_bus(device_t);
+int gpiobus_detach_bus(device_t);
 int gpiobus_init_softc(device_t);
 
 extern driver_t gpiobus_driver;

Modified: head/sys/mips/atheros/ar71xx_gpio.c
==============================================================================
--- head/sys/mips/atheros/ar71xx_gpio.c Sat Jan 31 19:29:28 2015        
(r277995)
+++ head/sys/mips/atheros/ar71xx_gpio.c Sat Jan 31 19:32:14 2015        
(r277996)
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
 #include <mips/atheros/ar71xx_gpiovar.h>
 #include <mips/atheros/ar933xreg.h>
 #include <mips/atheros/ar934xreg.h>
+#include <dev/gpio/gpiobusvar.h>
 
 #include "gpio_if.h"
 
@@ -79,6 +80,7 @@ static void ar71xx_gpio_intr(void *arg);
 /*
  * GPIO interface
  */
+static device_t ar71xx_gpio_get_bus(device_t);
 static int ar71xx_gpio_pin_max(device_t dev, int *maxpin);
 static int ar71xx_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
 static int ar71xx_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
@@ -135,6 +137,16 @@ ar71xx_gpio_pin_configure(struct ar71xx_
        }
 }
 
+static device_t
+ar71xx_gpio_get_bus(device_t dev)
+{
+       struct ar71xx_gpio_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       return (sc->busdev);
+}
+
 static int
 ar71xx_gpio_pin_max(device_t dev, int *maxpin)
 {
@@ -433,10 +445,13 @@ ar71xx_gpio_attach(device_t dev)
                        ar71xx_gpio_pin_set(dev, j, 1);
                }
        }
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
+       sc->busdev = gpiobus_attach_bus(dev);
+       if (sc->busdev == NULL) {
+               ar71xx_gpio_detach(dev);
+               return (ENXIO);
+       }
 
-       return (bus_generic_attach(dev));
+       return (0);
 }
 
 static int
@@ -446,7 +461,7 @@ ar71xx_gpio_detach(device_t dev)
 
        KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized"));
 
-       bus_generic_detach(dev);
+       gpiobus_detach_bus(dev);
        if (sc->gpio_ih)
                bus_teardown_intr(dev, sc->gpio_irq_res, sc->gpio_ih);
        if (sc->gpio_irq_res)
@@ -468,6 +483,7 @@ static device_method_t ar71xx_gpio_metho
        DEVMETHOD(device_detach, ar71xx_gpio_detach),
 
        /* GPIO protocol */
+       DEVMETHOD(gpio_get_bus, ar71xx_gpio_get_bus),
        DEVMETHOD(gpio_pin_max, ar71xx_gpio_pin_max),
        DEVMETHOD(gpio_pin_getname, ar71xx_gpio_pin_getname),
        DEVMETHOD(gpio_pin_getflags, ar71xx_gpio_pin_getflags),

Modified: head/sys/mips/atheros/ar71xx_gpiovar.h
==============================================================================
--- head/sys/mips/atheros/ar71xx_gpiovar.h      Sat Jan 31 19:29:28 2015        
(r277995)
+++ head/sys/mips/atheros/ar71xx_gpiovar.h      Sat Jan 31 19:32:14 2015        
(r277996)
@@ -57,6 +57,7 @@
 
 struct ar71xx_gpio_softc {
        device_t                dev;
+       device_t                busdev;
        struct mtx              gpio_mtx;
        struct resource         *gpio_mem_res;
        int                     gpio_mem_rid;

Modified: head/sys/mips/cavium/octeon_gpio.c
==============================================================================
--- head/sys/mips/cavium/octeon_gpio.c  Sat Jan 31 19:29:28 2015        
(r277995)
+++ head/sys/mips/cavium/octeon_gpio.c  Sat Jan 31 19:32:14 2015        
(r277996)
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
 #include <mips/cavium/octeon_irq.h>
 
 #include <mips/cavium/octeon_gpiovar.h>
+#include <dev/gpio/gpiobusvar.h>
 
 #include "gpio_if.h"
 
@@ -90,6 +91,7 @@ static void octeon_gpio_intr(void *arg);
 /*
  * GPIO interface
  */
+static device_t octeon_gpio_get_bus(device_t);
 static int octeon_gpio_pin_max(device_t dev, int *maxpin);
 static int octeon_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
 static int octeon_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
@@ -134,6 +136,16 @@ octeon_gpio_pin_configure(struct octeon_
        GPIO_UNLOCK(sc);
 }
 
+static device_t
+octeon_gpio_get_bus(device_t dev)
+{
+       struct octeon_gpio_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       return (sc->busdev);
+}
+
 static int
 octeon_gpio_pin_max(device_t dev, int *maxpin)
 {
@@ -434,11 +446,13 @@ octeon_gpio_attach(device_t dev)
                            gpio_cfgx.s.int_en, gpio_cfgx.s.int_type ? "rising 
edge" : "level");
                }
        }
+       sc->busdev = gpiobus_attach_bus(dev);
+       if (sc->busdev == NULL) {
+               octeon_gpio_detach(dev);
+               return (ENXIO);
+       }
 
-       device_add_child(dev, "gpioc", -1);
-       device_add_child(dev, "gpiobus", -1);
-
-       return (bus_generic_attach(dev));
+       return (0);
 }
 
 static int
@@ -457,7 +471,7 @@ octeon_gpio_detach(device_t dev)
                        bus_release_resource(dev, SYS_RES_IRQ,
                            sc->gpio_irq_rid[i], sc->gpio_irq_res[i]);
        }
-       bus_generic_detach(dev);
+       gpiobus_detach_bus(dev);
        mtx_destroy(&sc->gpio_mtx);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to