gpio_intel: Slightly simplify interface to chipset-specific code. master
authorImre Vadász <imre@vdsz.com>
Sun, 1 May 2016 15:10:45 +0000 (17:10 +0200)
committerImre Vadász <imre@vdsz.com>
Sun, 1 May 2016 15:36:24 +0000 (17:36 +0200)
* The intidx value in struct pin_intr_map is slightly redundant at the
  moment, but it avoids needless lookups for now.

sys/bus/gpio/gpio_intel/gpio_cherryview.c
sys/bus/gpio/gpio_intel/gpio_intel.c
sys/bus/gpio/gpio_intel/gpio_intel_var.h

index 6665773..e42e1d8 100644 (file)
@@ -86,11 +86,11 @@ static void gpio_cherryview_intr(void *arg);
 static int     gpio_cherryview_map_intr(struct gpio_intel_softc *sc,
                    uint16_t pin, int trigger, int polarity, int termination);
 static void    gpio_cherryview_unmap_intr(struct gpio_intel_softc *sc,
-                   uint16_t pin);
-static int     gpio_cherryview_establish_intr(struct gpio_intel_softc *sc,
-                   uint16_t pin, void *arg, driver_intr_t *handler);
-static void    gpio_cherryview_disestablish_intr(struct gpio_intel_softc *sc,
-                   uint16_t pin);
+                   struct pin_intr_map *map);
+static void    gpio_cherryview_enable_intr(struct gpio_intel_softc *sc,
+                   struct pin_intr_map *map);
+static void    gpio_cherryview_disable_intr(struct gpio_intel_softc *sc,
+                   struct pin_intr_map *map);
 static int     gpio_cherryview_read_pin(struct gpio_intel_softc *sc,
                    uint16_t pin);
 static void    gpio_cherryview_write_pin(struct gpio_intel_softc *sc,
@@ -101,8 +101,8 @@ static struct gpio_intel_fns gpio_cherryview_fns = {
        .intr = gpio_cherryview_intr,
        .map_intr = gpio_cherryview_map_intr,
        .unmap_intr = gpio_cherryview_unmap_intr,
-       .establish_intr = gpio_cherryview_establish_intr,
-       .disestablish_intr = gpio_cherryview_disestablish_intr,
+       .enable_intr = gpio_cherryview_enable_intr,
+       .disable_intr = gpio_cherryview_disable_intr,
        .read_pin = gpio_cherryview_read_pin,
        .write_pin = gpio_cherryview_write_pin,
 };
@@ -362,8 +362,7 @@ gpio_cherryview_map_intr(struct gpio_intel_softc *sc, uint16_t pin, int trigger,
        }
 
        sc->intrmaps[i].pin = pin;
-       sc->intrmaps[i].arg = NULL;
-       sc->intrmaps[i].handler = NULL;
+       sc->intrmaps[i].intidx = i;
        sc->intrmaps[i].orig_intcfg = intcfg;
        sc->intrmaps[i].orig_gpiocfg = gpiocfg;
 
@@ -376,88 +375,70 @@ gpio_cherryview_map_intr(struct gpio_intel_softc *sc, uint16_t pin, int trigger,
 }
 
 static void
-gpio_cherryview_unmap_intr(struct gpio_intel_softc *sc, uint16_t pin)
+gpio_cherryview_unmap_intr(struct gpio_intel_softc *sc,
+    struct pin_intr_map *map)
 {
        uint32_t reg, intcfg, gpiocfg;
-       int i;
+       uint16_t pin = map->pin;
 
-       for (i = 0; i < 16; i++) {
-               if (sc->intrmaps[i].pin == pin) {
-                       intcfg = sc->intrmaps[i].orig_intcfg;
-                       intcfg &= CHV_GPIO_CTL1_INTCFG_MASK;
-
-                       gpiocfg = sc->intrmaps[i].orig_gpiocfg;
-                       gpiocfg &= CHV_GPIO_CTL0_GPIOCFG_MASK;
-
-                       sc->intrmaps[i].pin = -1;
-                       sc->intrmaps[i].arg = NULL;
-                       sc->intrmaps[i].handler = NULL;
-                       sc->intrmaps[i].is_level = 0;
-                       sc->intrmaps[i].orig_intcfg = 0;
-                       sc->intrmaps[i].orig_gpiocfg = 0;
-
-                       /* Restore interrupt configuration if needed */
-                       reg = chvgpio_read(sc, PIN_CTL1(pin));
-                       if ((reg & CHV_GPIO_CTL1_INTCFG_MASK) != intcfg) {
-                               reg &= ~CHV_GPIO_CTL1_INTCFG_MASK;
-                               reg |= intcfg;
-                               chvgpio_write(sc, PIN_CTL1(pin), reg);
-                       }
+       intcfg = map->orig_intcfg;
+       intcfg &= CHV_GPIO_CTL1_INTCFG_MASK;
 
-                       /* Restore gpio configuration if needed */
-                       reg = chvgpio_read(sc, PIN_CTL0(pin));
-                       if ((reg & CHV_GPIO_CTL0_GPIOCFG_MASK) != gpiocfg) {
-                               reg &= ~CHV_GPIO_CTL0_GPIOCFG_MASK;
-                               reg |= gpiocfg;
-                               chvgpio_write(sc, PIN_CTL0(pin), reg);
-                       }
-               }
+       gpiocfg = map->orig_gpiocfg;
+       gpiocfg &= CHV_GPIO_CTL0_GPIOCFG_MASK;
+
+       map->pin = -1;
+       map->intidx = -1;
+       map->is_level = 0;
+       map->orig_intcfg = 0;
+       map->orig_gpiocfg = 0;
+
+       /* Restore interrupt configuration if needed */
+       reg = chvgpio_read(sc, PIN_CTL1(pin));
+       if ((reg & CHV_GPIO_CTL1_INTCFG_MASK) != intcfg) {
+               reg &= ~CHV_GPIO_CTL1_INTCFG_MASK;
+               reg |= intcfg;
+               chvgpio_write(sc, PIN_CTL1(pin), reg);
+       }
+
+       /* Restore gpio configuration if needed */
+       reg = chvgpio_read(sc, PIN_CTL0(pin));
+       if ((reg & CHV_GPIO_CTL0_GPIOCFG_MASK) != gpiocfg) {
+               reg &= ~CHV_GPIO_CTL0_GPIOCFG_MASK;
+               reg |= gpiocfg;
+               chvgpio_write(sc, PIN_CTL0(pin), reg);
        }
 }
 
-static int
-gpio_cherryview_establish_intr(struct gpio_intel_softc *sc, uint16_t pin,
-    void *arg, driver_intr_t *handler)
+static void
+gpio_cherryview_enable_intr(struct gpio_intel_softc *sc,
+    struct pin_intr_map *map)
 {
        uint32_t reg;
-       int i;
 
-       for (i = 0; i < 16; i++) {
-               if (sc->intrmaps[i].pin == pin) {
-                       sc->intrmaps[i].arg = arg;
-                       sc->intrmaps[i].handler = handler;
-
-                       /* clear interrupt status flag */
-                       chvgpio_write(sc, CHV_GPIO_REG_IS, (1U << i));
-
-                       /* unmask interrupt */
-                       reg = chvgpio_read(sc, CHV_GPIO_REG_MASK);
-                       reg |= (1U << i);
-                       chvgpio_write(sc, CHV_GPIO_REG_MASK, reg);
-                       return (0);
-               }
-       }
+       KKASSERT(map->intidx >= 0);
 
-       return (ENOENT);
+       /* clear interrupt status flag */
+       chvgpio_write(sc, CHV_GPIO_REG_IS, (1U << map->intidx));
+
+       /* unmask interrupt */
+       reg = chvgpio_read(sc, CHV_GPIO_REG_MASK);
+       reg |= (1U << map->intidx);
+       chvgpio_write(sc, CHV_GPIO_REG_MASK, reg);
 }
 
 static void
-gpio_cherryview_disestablish_intr(struct gpio_intel_softc *sc, uint16_t pin)
+gpio_cherryview_disable_intr(struct gpio_intel_softc *sc,
+    struct pin_intr_map *map)
 {
        uint32_t reg;
-       int i;
 
-       for (i = 0; i < 16; i++) {
-               if (sc->intrmaps[i].pin == pin) {
-                       /* mask interrupt line */
-                       reg = chvgpio_read(sc, CHV_GPIO_REG_MASK);
-                       reg &= ~(1U << i);
-                       chvgpio_write(sc, CHV_GPIO_REG_MASK, reg);
-
-                       sc->intrmaps[i].arg = NULL;
-                       sc->intrmaps[i].handler = NULL;
-               }
-       }
+       KKASSERT(map->intidx >= 0);
+
+       /* mask interrupt line */
+       reg = chvgpio_read(sc, CHV_GPIO_REG_MASK);
+       reg &= ~(1U << map->intidx);
+       chvgpio_write(sc, CHV_GPIO_REG_MASK, reg);
 }
 
 static int
index 64ce049..09acffd 100644 (file)
@@ -215,12 +215,16 @@ gpio_intel_alloc_intr(device_t dev, u_int pin, int trigger, int polarity,
                ret = sc->fns->map_intr(sc, pin, trigger, polarity,
                    termination);
                if (ret == 0) {
+                       /* XXX map_intr should return the pin_intr_map */
                        for (i = 0; i < NELEM(sc->intrmaps); i++) {
                                if (sc->intrmaps[i].pin == pin)
                                        map = &sc->intrmaps[i];
                        }
-                       if (map != NULL)
+                       if (map != NULL) {
                                *cookiep = map;
+                               map->arg = NULL;
+                               map->handler = NULL;
+                       }
                }
        } else {
                device_printf(sc->dev, "%s: Invalid pin %d\n", __func__, pin);
@@ -241,7 +245,9 @@ gpio_intel_free_intr(device_t dev, void *cookie)
        KKASSERT(gpio_intel_pin_exists(sc, map->pin));
 
        lockmgr(&sc->lk, LK_EXCLUSIVE);
-       sc->fns->unmap_intr(sc, map->pin);
+       map->arg = NULL;
+       map->handler = NULL;
+       sc->fns->unmap_intr(sc, map);
        lockmgr(&sc->lk, LK_RELEASE);
 }
 
@@ -255,7 +261,9 @@ gpio_intel_setup_intr(device_t dev, void *cookie, void *arg,
        KKASSERT(gpio_intel_pin_exists(sc, map->pin));
 
        lockmgr(&sc->lk, LK_EXCLUSIVE);
-       sc->fns->establish_intr(sc, map->pin, arg, handler);
+       map->arg = arg;
+       map->handler = handler;
+       sc->fns->enable_intr(sc, map);
        lockmgr(&sc->lk, LK_RELEASE);
 }
 
@@ -268,7 +276,9 @@ gpio_intel_teardown_intr(device_t dev, void *cookie)
        KKASSERT(gpio_intel_pin_exists(sc, map->pin));
 
        lockmgr(&sc->lk, LK_EXCLUSIVE);
-       sc->fns->disestablish_intr(sc, map->pin);
+       sc->fns->disable_intr(sc, map);
+       map->arg = NULL;
+       map->handler = NULL;
        lockmgr(&sc->lk, LK_RELEASE);
 }
 
index 3e20a4f..b248416 100644 (file)
@@ -8,6 +8,7 @@ struct pinrange {
 
 struct pin_intr_map {
        int pin;
+       int intidx;
        void *arg;
        driver_intr_t *handler;
        int is_level;
@@ -31,11 +32,11 @@ typedef     void(*gpio_intel_init_fn)(struct gpio_intel_softc *sc);
 typedef        int(*gpio_intel_map_intr_fn)(struct gpio_intel_softc *sc,
            uint16_t pin, int trigger, int polarity, int termination);
 typedef        void(*gpio_intel_unmap_intr_fn)(struct gpio_intel_softc *sc,
-           uint16_t pin);
-typedef        int(*gpio_intel_establish_intr_fn)(struct gpio_intel_softc *sc,
-           uint16_t pin, void *arg, driver_intr_t);
-typedef        void(*gpio_intel_disestablish_intr_fn)(struct gpio_intel_softc *sc,
-           uint16_t pin);
+           struct pin_intr_map *map);
+typedef        void(*gpio_intel_enable_intr_fn)(struct gpio_intel_softc *sc,
+           struct pin_intr_map *map);
+typedef        void(*gpio_intel_disable_intr_fn)(struct gpio_intel_softc *sc,
+           struct pin_intr_map *map);
 typedef        void(*gpio_intel_write_pin_fn)(struct gpio_intel_softc *sc,
            uint16_t pin, int value);
 typedef        int(*gpio_intel_read_pin_fn)(struct gpio_intel_softc *sc,
@@ -46,8 +47,8 @@ struct gpio_intel_fns {
        driver_intr_t           *intr;
        gpio_intel_map_intr_fn  map_intr;
        gpio_intel_unmap_intr_fn unmap_intr;
-       gpio_intel_establish_intr_fn establish_intr;
-       gpio_intel_disestablish_intr_fn disestablish_intr;
+       gpio_intel_enable_intr_fn enable_intr;
+       gpio_intel_disable_intr_fn disable_intr;
        gpio_intel_write_pin_fn write_pin;
        gpio_intel_read_pin_fn  read_pin;
 };