diff options
author | Svatopluk Kraus <skra@FreeBSD.org> | 2016-05-06 08:59:25 +0000 |
---|---|---|
committer | Svatopluk Kraus <skra@FreeBSD.org> | 2016-05-06 08:59:25 +0000 |
commit | 1a251c538f893b87c462a81decc7745fbdd3d586 (patch) | |
tree | 0f9bffa671302972c0c8fc74608411d0f6414a10 /sys/arm/ti/ti_gpio.c | |
parent | 2202c37926cbdd42b775379aac215b4a8292723b (diff) | |
download | src-1a251c538f893b87c462a81decc7745fbdd3d586.tar.gz src-1a251c538f893b87c462a81decc7745fbdd3d586.zip |
INTRNG - support new interrupt mapping type INTR_MAP_DATA_GPIO
introduced in r298738.
Notes
Notes:
svn path=/head/; revision=299166
Diffstat (limited to 'sys/arm/ti/ti_gpio.c')
-rw-r--r-- | sys/arm/ti/ti_gpio.c | 72 |
1 files changed, 50 insertions, 22 deletions
diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c index 510e2cc71b67..830af3da7836 100644 --- a/sys/arm/ti/ti_gpio.c +++ b/sys/arm/ti/ti_gpio.c @@ -946,7 +946,7 @@ ti_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc) } static int -ti_gpio_pic_map_fdt(struct ti_gpio_softc *sc, u_int ncells, pcell_t *cells, +ti_gpio_pic_map_fdt(struct ti_gpio_softc *sc, struct intr_map_data_fdt *daf, u_int *irqp, uint32_t *modep) { uint32_t mode; @@ -960,45 +960,76 @@ ti_gpio_pic_map_fdt(struct ti_gpio_softc *sc, u_int ncells, pcell_t *cells, * 4 = active high level-sensitive. * 8 = active low level-sensitive. */ - if (ncells != 2 || cells[0] >= sc->sc_maxpin) + if (daf->ncells != 2 || daf->cells[0] >= sc->sc_maxpin) return (EINVAL); /* Only reasonable modes are supported. */ - if (cells[1] == 1) + if (daf->cells[1] == 1) mode = GPIO_INTR_EDGE_RISING; - else if (cells[1] == 2) + else if (daf->cells[1] == 2) mode = GPIO_INTR_EDGE_FALLING; - else if (cells[1] == 3) + else if (daf->cells[1] == 3) mode = GPIO_INTR_EDGE_BOTH; - else if (cells[1] == 4) + else if (daf->cells[1] == 4) mode = GPIO_INTR_LEVEL_HIGH; - else if (cells[1] == 8) + else if (daf->cells[1] == 8) mode = GPIO_INTR_LEVEL_LOW; else return (EINVAL); - *irqp = cells[0]; + *irqp = daf->cells[0]; if (modep != NULL) *modep = mode; return (0); } static int +ti_gpio_pic_map_gpio(struct ti_gpio_softc *sc, struct intr_map_data_gpio *dag, + u_int *irqp, uint32_t *modep) +{ + uint32_t mode; + + if (dag->gpio_pin_num >= sc->sc_maxpin) + return (EINVAL); + + mode = dag->gpio_intr_mode; + if (mode != GPIO_INTR_LEVEL_LOW && mode != GPIO_INTR_LEVEL_HIGH && + mode != GPIO_INTR_EDGE_RISING && mode != GPIO_INTR_EDGE_FALLING && + mode != GPIO_INTR_EDGE_BOTH) + return (EINVAL); + + *irqp = dag->gpio_pin_num; + if (modep != NULL) + *modep = mode; + return (0); +} + +static int +ti_gpio_pic_map(struct ti_gpio_softc *sc, struct intr_map_data *data, + u_int *irqp, uint32_t *modep) +{ + + switch (data->type) { + case INTR_MAP_DATA_FDT: + return (ti_gpio_pic_map_fdt(sc, + (struct intr_map_data_fdt *)data, irqp, modep)); + case INTR_MAP_DATA_GPIO: + return (ti_gpio_pic_map_gpio(sc, + (struct intr_map_data_gpio *)data, irqp, modep)); + default: + return (ENOTSUP); + } +} + +static int ti_gpio_pic_map_intr(device_t dev, struct intr_map_data *data, struct intr_irqsrc **isrcp) { int error; u_int irq; - struct ti_gpio_softc *sc; - struct intr_map_data_fdt *daf; - - if (data->type != INTR_MAP_DATA_FDT) - return (ENOTSUP); - - sc = device_get_softc(dev); - daf = (struct intr_map_data_fdt *)data; + struct ti_gpio_softc *sc = device_get_softc(dev); - error = ti_gpio_pic_map_fdt(sc, daf->ncells, daf->cells, &irq, NULL); + error = ti_gpio_pic_map(sc, data, &irq, NULL); if (error == 0) *isrcp = &sc->sc_isrcs[irq].tgi_isrc; return (error); @@ -1040,18 +1071,15 @@ ti_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, uint32_t mode; struct ti_gpio_softc *sc; struct ti_gpio_irqsrc *tgi; - struct intr_map_data_fdt *daf; - if (data == NULL || data->type != INTR_MAP_DATA_FDT) + if (data == NULL) return (ENOTSUP); sc = device_get_softc(dev); tgi = (struct ti_gpio_irqsrc *)isrc; - daf = (struct intr_map_data_fdt *)data; /* Get and check config for an interrupt. */ - if (ti_gpio_pic_map_fdt(sc, daf->ncells, daf->cells, &irq, - &mode) != 0 || tgi->tgi_irq != irq) + if (ti_gpio_pic_map(sc, data, &irq, &mode) != 0 || tgi->tgi_irq != irq) return (EINVAL); /* |