From 5e1a5939929b3ae8ec6f7e44ddd1b51b3c542cc6 Mon Sep 17 00:00:00 2001 From: loos Date: Sat, 31 Jan 2015 19:32:14 +0000 Subject: 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. --- sys/arm/freescale/imx/imx_gpio.c | 26 +++++++++++++++++++++----- sys/arm/freescale/vybrid/vf_gpio.c | 24 +++++++++++++++++++++--- 2 files changed, 42 insertions(+), 8 deletions(-) (limited to 'sys/arm/freescale') diff --git a/sys/arm/freescale/imx/imx_gpio.c b/sys/arm/freescale/imx/imx_gpio.c index 911c9bbb..e70b710 100644 --- a/sys/arm/freescale/imx/imx_gpio.c +++ b/sys/arm/freescale/imx/imx_gpio.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -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_gpio_softc *sc, struct gpio_pin *pin, 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_methods[] = { 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), diff --git a/sys/arm/freescale/vybrid/vf_gpio.c b/sys/arm/freescale/vybrid/vf_gpio.c index 1fcf329..4f458a1 100644 --- a/sys/arm/freescale/vybrid/vf_gpio.c +++ b/sys/arm/freescale/vybrid/vf_gpio.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -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), -- cgit v1.1