Date: Mon, 23 May 2016 18:16:21 +0000 (UTC) From: Svatopluk Kraus <skra@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r300529 - head/sys/arm/freescale/imx Message-ID: <201605231816.u4NIGLwO026261@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: skra Date: Mon May 23 18:16:21 2016 New Revision: 300529 URL: https://svnweb.freebsd.org/changeset/base/300529 Log: INTRNG - support new interrupt mapping type INTR_MAP_DATA_GPIO introduced in r298738. Reviewed by: ian Modified: head/sys/arm/freescale/imx/imx_gpio.c Modified: head/sys/arm/freescale/imx/imx_gpio.c ============================================================================== --- head/sys/arm/freescale/imx/imx_gpio.c Mon May 23 18:12:52 2016 (r300528) +++ head/sys/arm/freescale/imx/imx_gpio.c Mon May 23 18:16:21 2016 (r300529) @@ -88,7 +88,14 @@ __FBSDID("$FreeBSD$"); #define IMX_GPIO_ISR_REG 0x018 /* Interrupt Status Register */ #define IMX_GPIO_EDGE_REG 0x01C /* Edge Detect Register */ +#ifdef INTRNG +#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ + GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH | GPIO_INTR_EDGE_RISING | \ + GPIO_INTR_EDGE_FALLING ) +#else #define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT) +#endif + #define NGPIO 32 #ifdef INTRNG @@ -156,15 +163,12 @@ static int imx51_gpio_pin_toggle(device_ #ifdef INTRNG static int -gpio_pic_map_fdt(device_t dev, u_int ncells, pcell_t *cells, u_int *irqp, - uint32_t *modep) +gpio_pic_map_fdt(struct imx51_gpio_softc *sc, struct intr_map_data_fdt *daf, + u_int *irqp, uint32_t *modep) { - struct imx51_gpio_softc *sc; - u_int irq, tripol; + u_int irq; uint32_t mode; - sc = device_get_softc(dev); - /* * From devicetree/bindings/gpio/fsl-imx-gpio.txt: * #interrupt-cells: 2. The first cell is the GPIO number. The second @@ -176,18 +180,17 @@ gpio_pic_map_fdt(device_t dev, u_int nce * We can do any single one of these modes, but nothing in combo. */ - if (ncells != 2) { + if (daf->ncells != 2) { device_printf(sc->dev, "Invalid #interrupt-cells\n"); return (EINVAL); } - irq = cells[0]; - tripol = cells[1]; + irq = daf->cells[0]; if (irq >= sc->gpio_npins) { device_printf(sc->dev, "Invalid interrupt number %u\n", irq); return (EINVAL); } - switch (tripol) { + switch (daf->cells[1]) { case 1: mode = GPIO_INTR_EDGE_RISING; break; @@ -202,7 +205,7 @@ gpio_pic_map_fdt(device_t dev, u_int nce break; default: device_printf(sc->dev, "Unsupported interrupt mode 0x%2x\n", - tripol); + daf->cells[1]); return (ENOTSUP); } *irqp = irq; @@ -212,23 +215,61 @@ gpio_pic_map_fdt(device_t dev, u_int nce } static int +gpio_pic_map_gpio(struct imx51_gpio_softc *sc, struct intr_map_data_gpio *dag, + u_int *irqp, uint32_t *modep) +{ + u_int irq; + uint32_t mode; + + irq = dag->gpio_pin_num; + if (irq >= sc->gpio_npins) { + device_printf(sc->dev, "Invalid interrupt number %u\n", irq); + 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) { + device_printf(sc->dev, "Unsupported interrupt mode 0x%8x\n", + mode); + return (EINVAL); + } + + *irqp = irq; + if (modep != NULL) + *modep = mode; + return (0); +} + +static int +gpio_pic_map(struct imx51_gpio_softc *sc, struct intr_map_data *data, + u_int *irqp, uint32_t *modep) +{ + + switch (data->type) { + case INTR_MAP_DATA_FDT: + return (gpio_pic_map_fdt(sc, (struct intr_map_data_fdt *)data, + irqp, modep)); + case INTR_MAP_DATA_GPIO: + return (gpio_pic_map_gpio(sc, (struct intr_map_data_gpio *)data, + irqp, modep)); + default: + return (ENOTSUP); + } +} + +static int gpio_pic_map_intr(device_t dev, struct intr_map_data *data, struct intr_irqsrc **isrcp) { int error; u_int irq; - struct intr_map_data_fdt *daf; struct imx51_gpio_softc *sc; - if (data->type != INTR_MAP_DATA_FDT) - return (ENOTSUP); - - daf = (struct intr_map_data_fdt *)data; - error = gpio_pic_map_fdt(dev, daf->ncells, daf->cells, &irq, NULL); - if (error == 0) { - sc = device_get_softc(dev); + sc = device_get_softc(dev); + error = gpio_pic_map(sc, data, &irq, NULL); + if (error == 0) *isrcp = &sc->gpio_pic_irqsrc[irq].gi_isrc; - } return (error); } @@ -257,21 +298,20 @@ static int gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, struct resource *res, struct intr_map_data *data) { - struct intr_map_data_fdt *daf; struct imx51_gpio_softc *sc; struct gpio_irqsrc *gi; int error, icfg; u_int irq, reg, shift, wrk; uint32_t mode; + if (data == NULL) + return (ENOTSUP); + sc = device_get_softc(dev); gi = (struct gpio_irqsrc *)isrc; /* Get config for interrupt. */ - if (data == NULL || data->type != INTR_MAP_DATA_FDT) - return (ENOTSUP); - daf = (struct intr_map_data_fdt *)data; - error = gpio_pic_map_fdt(dev, daf->ncells, daf->cells, &irq, &mode); + error = gpio_pic_map(sc, data, &irq, &mode); if (error != 0) return (error); if (gi->gi_irq != irq)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605231816.u4NIGLwO026261>