diff options
author | loos <loos@FreeBSD.org> | 2015-01-30 18:18:09 +0000 |
---|---|---|
committer | loos <loos@FreeBSD.org> | 2015-01-30 18:18:09 +0000 |
commit | e3f22b06c2c688b83ce678ab2e33f5116a970dbf (patch) | |
tree | af0dd05b3f93a0d9e275ab72702763e55d360322 | |
parent | ccde4975e682f6415957a5fe36397a63d090e1c8 (diff) | |
download | FreeBSD-src-e3f22b06c2c688b83ce678ab2e33f5116a970dbf.zip FreeBSD-src-e3f22b06c2c688b83ce678ab2e33f5116a970dbf.tar.gz |
The BCM2835 GPIO controller uses has interrupt lines and not only one.
Allocate all four, we will use them soon.
Simplificate the allocation of memory and interrupt resources with a single
bus_alloc_resources() call instead of doing them separately.
Destroy the mutex in case of errors.
-rw-r--r-- | sys/arm/broadcom/bcm2835/bcm2835_gpio.c | 52 |
1 files changed, 23 insertions, 29 deletions
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c index 82d704b..43a1ddc 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c @@ -62,10 +62,20 @@ __FBSDID("$FreeBSD$"); #define dprintf(fmt, args...) #endif +#define BCM_GPIO_IRQS 4 #define BCM_GPIO_PINS 54 #define BCM_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN) +static struct resource_spec bcm_gpio_res_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { SYS_RES_IRQ, 0, RF_ACTIVE }, + { SYS_RES_IRQ, 1, RF_ACTIVE }, + { SYS_RES_IRQ, 2, RF_ACTIVE }, + { SYS_RES_IRQ, 3, RF_ACTIVE }, + { -1, 0, 0 } +}; + struct bcm_gpio_sysctl { struct bcm_gpio_softc *sc; uint32_t pin; @@ -74,8 +84,7 @@ struct bcm_gpio_sysctl { struct bcm_gpio_softc { device_t sc_dev; struct mtx sc_mtx; - struct resource * sc_mem_res; - struct resource * sc_irq_res; + struct resource * sc_res[BCM_GPIO_IRQS + 1]; bus_space_tag_t sc_bst; bus_space_handle_t sc_bsh; void * sc_intrhand; @@ -660,34 +669,20 @@ bcm_gpio_probe(device_t dev) static int bcm_gpio_attach(device_t dev) { - struct bcm_gpio_softc *sc = device_get_softc(dev); - uint32_t func; - int i, j, rid; + int i, j; phandle_t gpio; + struct bcm_gpio_softc *sc; + uint32_t func; + sc = device_get_softc(dev); sc->sc_dev = dev; - mtx_init(&sc->sc_mtx, "bcm 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); - } - - sc->sc_bst = rman_get_bustag(sc->sc_mem_res); - sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); - - 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); + if (bus_alloc_resources(dev, bcm_gpio_res_spec, sc->sc_res) != 0) { + device_printf(dev, "cannot allocate resources\n"); + goto fail; } + sc->sc_bst = rman_get_bustag(sc->sc_res[0]); + sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]); /* Find our node. */ gpio = ofw_bus_get_node(sc->sc_dev); @@ -723,10 +718,9 @@ bcm_gpio_attach(device_t dev) return (bus_generic_attach(dev)); fail: - if (sc->sc_irq_res) - 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); + bus_release_resources(dev, bcm_gpio_res_spec, sc->sc_res); + mtx_destroy(&sc->sc_mtx); + return (ENXIO); } |