Author: skra
Date: Fri May  6 08:59:25 2016
New Revision: 299166
URL: https://svnweb.freebsd.org/changeset/base/299166

Log:
  INTRNG - support new interrupt mapping type INTR_MAP_DATA_GPIO
  introduced in r298738.

Modified:
  head/sys/arm/ti/ti_gpio.c

Modified: head/sys/arm/ti/ti_gpio.c
==============================================================================
--- head/sys/arm/ti/ti_gpio.c   Fri May  6 08:56:46 2016        (r299165)
+++ head/sys/arm/ti/ti_gpio.c   Fri May  6 08:59:25 2016        (r299166)
@@ -946,7 +946,7 @@ ti_gpio_pic_enable_intr(device_t dev, st
 }
 
 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
         *              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, str
        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);
 
        /*
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to