summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorloos <loos@FreeBSD.org>2015-01-30 18:18:09 +0000
committerloos <loos@FreeBSD.org>2015-01-30 18:18:09 +0000
commite3f22b06c2c688b83ce678ab2e33f5116a970dbf (patch)
treeaf0dd05b3f93a0d9e275ab72702763e55d360322
parentccde4975e682f6415957a5fe36397a63d090e1c8 (diff)
downloadFreeBSD-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.c52
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);
}
OpenPOWER on IntegriCloud