Author: mw
Date: Wed Apr  4 13:20:29 2018
New Revision: 332024
URL: https://svnweb.freebsd.org/changeset/base/332024

Log:
  Enable Marvell gpio driver to work with many controllers
  
  This patch moves all global data structures into mv_gpio_softc,
  and puts device_t parameter to functions calls everywhere where needed.
  As a result, we can create multiple driver instances.
  
  Removed names in function declaration to keep style.
  
  Submitted by: Patryk Duda <p...@semihalf.com>
  Obtained from: Semihalf
  Sponsored by: Stormshield
  Differential Revision: https://reviews.freebsd.org/D14755

Modified:
  head/sys/arm/mv/gpio.c
  head/sys/arm/mv/mvreg.h

Modified: head/sys/arm/mv/gpio.c
==============================================================================
--- head/sys/arm/mv/gpio.c      Wed Apr  4 13:16:00 2018        (r332023)
+++ head/sys/arm/mv/gpio.c      Wed Apr  4 13:20:29 2018        (r332024)
@@ -71,13 +71,14 @@ struct mv_gpio_softc {
        int                     mem_rid;
        struct resource *       irq_res[GPIO_MAX_INTR_COUNT];
        int                     irq_rid[GPIO_MAX_INTR_COUNT];
+       struct intr_event *     gpio_events[MV_GPIO_MAX_NPINS];
        void                    *ih_cookie[GPIO_MAX_INTR_COUNT];
        bus_space_tag_t         bst;
        bus_space_handle_t      bsh;
        struct mtx              mutex;
        uint8_t                 pin_num;        /* number of GPIO pins */
        uint8_t                 irq_num;        /* number of real IRQs occupied 
by GPIO controller */
-       uint8_t                 use_high;
+       struct gpio_pin         gpio_setup[MV_GPIO_MAX_NPINS];
 
        /* Used for debouncing. */
        uint32_t                debounced_state_lo;
@@ -86,52 +87,56 @@ struct mv_gpio_softc {
        int                     *debounce_counters;
 };
 
-static struct mv_gpio_softc *mv_gpio_softc = NULL;
-static uint32_t        gpio_setup[MV_GPIO_MAX_NPINS];
+struct mv_gpio_pindev {
+       device_t dev;
+       int pin;
+};
 
 static int     mv_gpio_probe(device_t);
 static int     mv_gpio_attach(device_t);
-static int     mv_gpio_intr(void *);
-static int     mv_gpio_init(void);
+static int     mv_gpio_intr(device_t, void *);
+static int     mv_gpio_init(device_t);
 
-static void    mv_gpio_double_edge_init(int pin);
+static void    mv_gpio_double_edge_init(device_t, int);
 
-static int     mv_gpio_debounce_setup(int pin);
-static int     mv_gpio_debounce_init(int pin);
-static void    mv_gpio_debounce_start(int pin);
-static int     mv_gpio_debounce_prepare(int pin);
-static void    mv_gpio_debounce(void *arg);
-static void    mv_gpio_debounced_state_set(int pin, uint8_t new_state);
-static uint32_t        mv_gpio_debounced_state_get(int pin);
+static int     mv_gpio_debounce_setup(device_t, int);
+static int     mv_gpio_debounce_prepare(device_t, int);
+static int     mv_gpio_debounce_init(device_t, int);
+static void    mv_gpio_debounce_start(device_t, int);
+static void    mv_gpio_debounce(void *);
+static void    mv_gpio_debounced_state_set(device_t, int, uint8_t);
+static uint32_t        mv_gpio_debounced_state_get(device_t, int);
 
-static void    mv_gpio_exec_intr_handlers(uint32_t status, int high);
-static void    mv_gpio_intr_handler(int pin);
-static uint32_t        mv_gpio_reg_read(uint32_t reg);
-static void    mv_gpio_reg_write(uint32_t reg, uint32_t val);
-static void    mv_gpio_reg_set(uint32_t reg, uint32_t val);
-static void    mv_gpio_reg_clear(uint32_t reg, uint32_t val);
+static void    mv_gpio_exec_intr_handlers(device_t, uint32_t, int);
+static void    mv_gpio_intr_handler(device_t, int);
+static uint32_t        mv_gpio_reg_read(device_t, uint32_t);
+static void    mv_gpio_reg_write(device_t, uint32_t, uint32_t);
+static void    mv_gpio_reg_set(device_t, uint32_t, uint32_t);
+static void    mv_gpio_reg_clear(device_t, uint32_t, uint32_t);
 
-static void    mv_gpio_blink(uint32_t pin, uint8_t enable);
-static void    mv_gpio_polarity(uint32_t pin, uint8_t enable, uint8_t toggle);
-static void    mv_gpio_level(uint32_t pin, uint8_t enable);
-static void    mv_gpio_edge(uint32_t pin, uint8_t enable);
-static void    mv_gpio_out_en(uint32_t pin, uint8_t enable);
-static void    mv_gpio_int_ack(uint32_t pin);
-static void    mv_gpio_value_set(uint32_t pin, uint8_t val);
-static uint32_t        mv_gpio_value_get(uint32_t pin, uint8_t exclude_polar);
+static void    mv_gpio_blink(device_t, uint32_t, uint8_t);
+static void    mv_gpio_polarity(device_t, uint32_t, uint8_t, uint8_t);
+static void    mv_gpio_level(device_t, uint32_t, uint8_t);
+static void    mv_gpio_edge(device_t, uint32_t, uint8_t);
+static void    mv_gpio_out_en(device_t, uint32_t, uint8_t);
+static void    mv_gpio_int_ack(struct mv_gpio_pindev *);
+static void    mv_gpio_value_set(device_t, uint32_t, uint8_t);
+static uint32_t        mv_gpio_value_get(device_t, uint32_t, uint8_t);
 
-static void    mv_gpio_intr_mask(int pin);
-static void    mv_gpio_intr_unmask(int pin);
-int mv_gpio_setup_intrhandler(const char *name, driver_filter_t *filt,
-    void (*hand)(void *), void *arg, int pin, int flags, void **cookiep);
+static void    mv_gpio_intr_mask(struct mv_gpio_pindev *);
+static void    mv_gpio_intr_unmask(struct mv_gpio_pindev *);
 
-int mv_gpio_configure(uint32_t pin, uint32_t flags, uint32_t mask);
-void mv_gpio_out(uint32_t pin, uint8_t val, uint8_t enable);
-uint8_t mv_gpio_in(uint32_t pin);
+void mv_gpio_finish_intrhandler(struct mv_gpio_pindev *);
+int mv_gpio_setup_intrhandler(device_t, const char *,
+    driver_filter_t *, void (*)(void *), void *,
+    int, int, void **);
+int mv_gpio_configure(device_t, uint32_t, uint32_t, uint32_t);
+void mv_gpio_out(device_t, uint32_t, uint8_t, uint8_t);
+uint8_t mv_gpio_in(device_t, uint32_t);
 
-#define MV_GPIO_LOCK()         mtx_lock_spin(&mv_gpio_softc->mutex)
-#define MV_GPIO_UNLOCK()       mtx_unlock_spin(&mv_gpio_softc->mutex)
-#define MV_GPIO_ASSERT_LOCKED()        mtx_assert(&mv_gpio_softc->mutex, 
MA_OWNED)
+#define MV_GPIO_LOCK()         mtx_lock_spin(&sc->mutex)
+#define MV_GPIO_UNLOCK()       mtx_unlock_spin(&sc->mutex)
+#define MV_GPIO_ASSERT_LOCKED()        mtx_assert(&sc->mutex, MA_OWNED)
 
 static device_method_t mv_gpio_methods[] = {
        DEVMETHOD(device_probe,         mv_gpio_probe),
@@ -149,14 +154,14 @@ static devclass_t mv_gpio_devclass;
 
 DRIVER_MODULE(gpio, simplebus, mv_gpio_driver, mv_gpio_devclass, 0, 0);
 
-typedef int (*gpios_phandler_t)(phandle_t, pcell_t *, int);
+typedef int (*gpios_phandler_t)(device_t, phandle_t, pcell_t *, int);
 
 struct gpio_ctrl_entry {
        const char              *compat;
        gpios_phandler_t        handler;
 };
 
-static int mv_handle_gpios_prop(phandle_t ctrl, pcell_t *gpios, int len);
+static int mv_handle_gpios_prop(device_t, phandle_t, pcell_t *, int);
 int gpio_get_config_from_dt(void);
 
 struct gpio_ctrl_entry gpio_controllers[] = {
@@ -192,10 +197,6 @@ mv_gpio_attach(device_t dev)
        if (sc == NULL)
                return (ENXIO);
 
-       if (mv_gpio_softc != NULL)
-               return (ENXIO);
-       mv_gpio_softc = sc;
-
        /* Get chip id and revision */
        soc_id(&dev_id, &rev_id);
 
@@ -205,13 +206,11 @@ mv_gpio_attach(device_t dev)
            dev_id == MV_DEV_MV78100_Z0 ) {
                sc->pin_num = 32;
                sc->irq_num = 4;
-               sc->use_high = 0;
 
        } else if (dev_id == MV_DEV_88F6281 ||
            dev_id == MV_DEV_88F6282) {
                sc->pin_num = 50;
                sc->irq_num = 7;
-               sc->use_high = 1;
 
        } else {
                if (OF_getencprop(ofw_bus_get_node(dev), "pin-count", &pincnt,
@@ -294,15 +293,6 @@ mv_gpio_attach(device_t dev)
        bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_EDGE_MASK, 0);
        bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_LEV_MASK, 0);
 
-       if (sc->use_high) {
-               bus_space_write_4(sc->bst, sc->bsh,
-                   GPIO_HI_INT_EDGE_MASK, 0);
-               bus_space_write_4(sc->bst, sc->bsh,
-                   GPIO_HI_INT_LEV_MASK, 0);
-               bus_space_write_4(sc->bst, sc->bsh,
-                   GPIO_HI_INT_CAUSE, 0);
-       }
-
        for (i = 0; i < sc->irq_num; i++) {
                if (bus_setup_intr(dev, sc->irq_res[i],
                    INTR_TYPE_MISC,
@@ -316,7 +306,7 @@ mv_gpio_attach(device_t dev)
                }
        }
 
-       error = mv_gpio_init();
+       error = mv_gpio_init(dev);
        if (error) {
                device_printf(dev, "WARNING: failed to initialize GPIO pins, "
                    "error = %d\n", error);
@@ -325,14 +315,18 @@ mv_gpio_attach(device_t dev)
        /* Clear interrupt status. */
        bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_CAUSE, 0);
 
+       device_add_child(dev, "gpioc", device_get_unit(dev));
+       device_add_child(dev, "gpiobus", device_get_unit(dev));
+
        return (0);
 }
 
 static int
-mv_gpio_intr(void *arg)
+mv_gpio_intr(device_t dev, void *arg)
 {
        uint32_t int_cause, gpio_val;
-       uint32_t int_cause_hi, gpio_val_hi;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
        MV_GPIO_LOCK();
 
@@ -340,31 +334,18 @@ mv_gpio_intr(void *arg)
         * According to documentation, edge sensitive interrupts are asserted
         * when unmasked GPIO_INT_CAUSE register bits are set.
         */
-       int_cause = mv_gpio_reg_read(GPIO_INT_CAUSE);
-       int_cause &= mv_gpio_reg_read(GPIO_INT_EDGE_MASK);
+       int_cause = mv_gpio_reg_read(dev, GPIO_INT_CAUSE);
+       int_cause &= mv_gpio_reg_read(dev, GPIO_INT_EDGE_MASK);
 
        /*
         * Level sensitive interrupts are asserted when unmasked GPIO_DATA_IN
         * register bits are set.
         */
-       gpio_val = mv_gpio_reg_read(GPIO_DATA_IN);
-       gpio_val &= mv_gpio_reg_read(GPIO_INT_LEV_MASK);
+       gpio_val = mv_gpio_reg_read(dev, GPIO_DATA_IN);
+       gpio_val &= mv_gpio_reg_read(dev, GPIO_INT_LEV_MASK);
 
-       int_cause_hi = 0;
-       gpio_val_hi = 0;
-       if (mv_gpio_softc->use_high) {
-               int_cause_hi = mv_gpio_reg_read(GPIO_HI_INT_CAUSE);
-               int_cause_hi &= mv_gpio_reg_read(GPIO_HI_INT_EDGE_MASK);
+       mv_gpio_exec_intr_handlers(dev, int_cause | gpio_val, 0);
 
-               gpio_val_hi = mv_gpio_reg_read(GPIO_HI_DATA_IN);
-               gpio_val_hi &= mv_gpio_reg_read(GPIO_HI_INT_LEV_MASK);
-       }
-
-       mv_gpio_exec_intr_handlers(int_cause | gpio_val, 0);
-
-       if (mv_gpio_softc->use_high)
-               mv_gpio_exec_intr_handlers(int_cause_hi | gpio_val_hi, 1);
-
        MV_GPIO_UNLOCK();
 
        return (FILTER_HANDLED);
@@ -374,31 +355,47 @@ mv_gpio_intr(void *arg)
  * GPIO interrupt handling
  */
 
-static struct intr_event *gpio_events[MV_GPIO_MAX_NPINS];
+void
+mv_gpio_finish_intrhandler(struct mv_gpio_pindev *s)
+{
+       /* When we acheive full interrupt support
+        * This function will be opposite to
+        * mv_gpio_setup_intrhandler
+        */
 
+       /* Now it exists only to remind that
+        * there should be place to free mv_gpio_pindev
+        * allocated by mv_gpio_setup_intrhandler
+        */
+       free(s, M_DEVBUF);
+}
+
 int
-mv_gpio_setup_intrhandler(const char *name, driver_filter_t *filt,
+mv_gpio_setup_intrhandler(device_t dev, const char *name, driver_filter_t 
*filt,
     void (*hand)(void *), void *arg, int pin, int flags, void **cookiep)
 {
        struct  intr_event *event;
        int     error;
+       struct mv_gpio_pindev *s;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
+       s = malloc(sizeof(struct mv_gpio_pindev), M_DEVBUF, M_NOWAIT | M_ZERO);
 
-       if (pin < 0 || pin >= mv_gpio_softc->pin_num)
+       if (pin < 0 || pin >= sc->pin_num)
                return (ENXIO);
-       event = gpio_events[pin];
+       event = sc->gpio_events[pin];
        if (event == NULL) {
                MV_GPIO_LOCK();
-               if (gpio_setup[pin] & MV_GPIO_IN_DEBOUNCE) {
-                       error = mv_gpio_debounce_init(pin);
+               if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_DEBOUNCE) {
+                       error = mv_gpio_debounce_init(dev, pin);
                        if (error != 0) {
                                MV_GPIO_UNLOCK();
                                return (error);
                        }
-               } else if (gpio_setup[pin] & MV_GPIO_IN_IRQ_DOUBLE_EDGE)
-                       mv_gpio_double_edge_init(pin);
+               } else if (sc->gpio_setup[pin].gp_flags & 
MV_GPIO_IN_IRQ_DOUBLE_EDGE)
+                       mv_gpio_double_edge_init(dev, pin);
                MV_GPIO_UNLOCK();
-
-               error = intr_event_create(&event, (void *)pin, 0, pin,
+               error = intr_event_create(&event, (void *)s, 0, pin,
                    (void (*)(void *))mv_gpio_intr_mask,
                    (void (*)(void *))mv_gpio_intr_unmask,
                    (void (*)(void *))mv_gpio_int_ack,
@@ -406,7 +403,7 @@ mv_gpio_setup_intrhandler(const char *name, driver_fil
                    "gpio%d:", pin);
                if (error != 0)
                        return (error);
-               gpio_events[pin] = event;
+               sc->gpio_events[pin] = event;
        }
 
        intr_event_add_handler(event, name, filt, hand, arg,
@@ -414,19 +411,22 @@ mv_gpio_setup_intrhandler(const char *name, driver_fil
        return (0);
 }
 
-void
-mv_gpio_intr_mask(int pin)
+static void
+mv_gpio_intr_mask(struct mv_gpio_pindev *s)
 {
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(s->dev);
 
-       if (pin >= mv_gpio_softc->pin_num)
+       if (s->pin >= sc->pin_num)
                return;
 
        MV_GPIO_LOCK();
 
-       if (gpio_setup[pin] & (MV_GPIO_IN_IRQ_EDGE | 
MV_GPIO_IN_IRQ_DOUBLE_EDGE))
-               mv_gpio_edge(pin, 0);
+       if (sc->gpio_setup[s->pin].gp_flags & (MV_GPIO_IN_IRQ_EDGE |
+           MV_GPIO_IN_IRQ_DOUBLE_EDGE))
+               mv_gpio_edge(s->dev, s->pin, 0);
        else
-               mv_gpio_level(pin, 0);
+               mv_gpio_level(s->dev, s->pin, 0);
 
        /*
         * The interrupt has to be acknowledged before scheduling an interrupt
@@ -434,32 +434,41 @@ mv_gpio_intr_mask(int pin)
         * (which can happen with shared IRQs e.g. PCI) while processing the
         * current event.
         */
-       mv_gpio_int_ack(pin);
+       mv_gpio_int_ack(s);
 
        MV_GPIO_UNLOCK();
+
+       return;
 }
 
-void
-mv_gpio_intr_unmask(int pin)
+static void
+mv_gpio_intr_unmask(struct mv_gpio_pindev *s)
 {
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(s->dev);
 
-       if (pin >= mv_gpio_softc->pin_num)
+       if (s->pin >= sc->pin_num)
                return;
 
        MV_GPIO_LOCK();
 
-       if (gpio_setup[pin] & (MV_GPIO_IN_IRQ_EDGE | 
MV_GPIO_IN_IRQ_DOUBLE_EDGE))
-               mv_gpio_edge(pin, 1);
+       if (sc->gpio_setup[s->pin].gp_flags & (MV_GPIO_IN_IRQ_EDGE |
+           MV_GPIO_IN_IRQ_DOUBLE_EDGE))
+               mv_gpio_edge(s->dev, s->pin, 1);
        else
-               mv_gpio_level(pin, 1);
+               mv_gpio_level(s->dev, s->pin, 1);
 
        MV_GPIO_UNLOCK();
+
+       return;
 }
 
 static void
-mv_gpio_exec_intr_handlers(uint32_t status, int high)
+mv_gpio_exec_intr_handlers(device_t dev, uint32_t status, int high)
 {
        int i, pin;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
        MV_GPIO_ASSERT_LOCKED();
 
@@ -467,13 +476,13 @@ mv_gpio_exec_intr_handlers(uint32_t status, int high)
        while (status != 0) {
                if (status & 1) {
                        pin = (high ? (i + GPIO_PINS_PER_REG) : i);
-                       if (gpio_setup[pin] & MV_GPIO_IN_DEBOUNCE)
-                               mv_gpio_debounce_start(pin);
-                       else if (gpio_setup[pin] & MV_GPIO_IN_IRQ_DOUBLE_EDGE) {
-                               mv_gpio_polarity(pin, 0, 1);
-                               mv_gpio_intr_handler(pin);
+                       if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_DEBOUNCE)
+                               mv_gpio_debounce_start(dev, pin);
+                       else if (sc->gpio_setup[pin].gp_flags & 
MV_GPIO_IN_IRQ_DOUBLE_EDGE) {
+                               mv_gpio_polarity(dev, pin, 0, 1);
+                               mv_gpio_intr_handler(dev, pin);
                        } else
-                               mv_gpio_intr_handler(pin);
+                               mv_gpio_intr_handler(dev, pin);
                }
                status >>= 1;
                i++;
@@ -481,17 +490,19 @@ mv_gpio_exec_intr_handlers(uint32_t status, int high)
 }
 
 static void
-mv_gpio_intr_handler(int pin)
+mv_gpio_intr_handler(device_t dev, int pin)
 {
 #ifdef INTRNG
        struct intr_irqsrc isrc;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
        MV_GPIO_ASSERT_LOCKED();
 
 #ifdef INTR_SOLO
        isrc.isrc_filter = NULL;
 #endif
-       isrc.isrc_event = gpio_events[pin];
+       isrc.isrc_event = sc->gpio_events[pin];
 
        if (isrc.isrc_event == NULL || 
TAILQ_EMPTY(&isrc.isrc_event->ie_handlers))
                return;
@@ -501,11 +512,14 @@ mv_gpio_intr_handler(int pin)
 }
 
 int
-mv_gpio_configure(uint32_t pin, uint32_t flags, uint32_t mask)
+mv_gpio_configure(device_t dev, uint32_t pin, uint32_t flags, uint32_t mask)
 {
        int error;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
+       error = 0;
 
-       if (pin >= mv_gpio_softc->pin_num)
+       if (pin >= sc->pin_num)
                return (EINVAL);
 
        /* check flags consistency */
@@ -514,7 +528,7 @@ mv_gpio_configure(uint32_t pin, uint32_t flags, uint32
                return (EINVAL);
 
        if (mask & MV_GPIO_IN_DEBOUNCE) {
-               error = mv_gpio_debounce_prepare(pin);
+               error = mv_gpio_debounce_prepare(dev, pin);
                if (error != 0)
                        return (error);
        }
@@ -522,19 +536,19 @@ mv_gpio_configure(uint32_t pin, uint32_t flags, uint32
        MV_GPIO_LOCK();
 
        if (mask & MV_GPIO_OUT_BLINK)
-               mv_gpio_blink(pin, flags & MV_GPIO_OUT_BLINK);
+               mv_gpio_blink(dev, pin, flags & MV_GPIO_OUT_BLINK);
        if (mask & MV_GPIO_IN_POL_LOW)
-               mv_gpio_polarity(pin, flags & MV_GPIO_IN_POL_LOW, 0);
+               mv_gpio_polarity(dev, pin, flags & MV_GPIO_IN_POL_LOW, 0);
        if (mask & MV_GPIO_IN_DEBOUNCE) {
-               error = mv_gpio_debounce_setup(pin);
+               error = mv_gpio_debounce_setup(dev, pin);
                if (error) {
                        MV_GPIO_UNLOCK();
                        return (error);
                }
        }
 
-       gpio_setup[pin] &= ~(mask);
-       gpio_setup[pin] |= (flags & mask);
+       sc->gpio_setup[pin].gp_flags &= ~(mask);
+       sc->gpio_setup[pin].gp_flags |= (flags & mask);
 
        MV_GPIO_UNLOCK();
 
@@ -542,28 +556,33 @@ mv_gpio_configure(uint32_t pin, uint32_t flags, uint32
 }
 
 static void
-mv_gpio_double_edge_init(int pin)
+mv_gpio_double_edge_init(device_t dev, int pin)
 {
        uint8_t raw_read;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
        MV_GPIO_ASSERT_LOCKED();
 
-       raw_read = (mv_gpio_value_get(pin, 1) ? 1 : 0);
+       raw_read = (mv_gpio_value_get(dev, pin, 1) ? 1 : 0);
 
        if (raw_read)
-               mv_gpio_polarity(pin, 1, 0);
+               mv_gpio_polarity(dev, pin, 1, 0);
        else
-               mv_gpio_polarity(pin, 0, 0);
+               mv_gpio_polarity(dev, pin, 0, 0);
 }
 
 static int
-mv_gpio_debounce_setup(int pin)
+mv_gpio_debounce_setup(device_t dev, int pin)
 {
        struct callout *c;
+       struct mv_gpio_softc *sc;
 
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
+
        MV_GPIO_ASSERT_LOCKED();
 
-       c = mv_gpio_softc->debounce_callouts[pin];
+       c = sc->debounce_callouts[pin];
        if (c == NULL)
                return (ENXIO);
 
@@ -576,12 +595,12 @@ mv_gpio_debounce_setup(int pin)
 }
 
 static int
-mv_gpio_debounce_prepare(int pin)
+mv_gpio_debounce_prepare(device_t dev, int pin)
 {
        struct callout *c;
        struct mv_gpio_softc *sc;
 
-       sc = (struct mv_gpio_softc *)mv_gpio_softc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
        c = sc->debounce_callouts[pin];
        if (c == NULL) {
@@ -597,58 +616,63 @@ mv_gpio_debounce_prepare(int pin)
 }
 
 static int
-mv_gpio_debounce_init(int pin)
+mv_gpio_debounce_init(device_t dev, int pin)
 {
        uint8_t raw_read;
        int *cnt;
+       struct mv_gpio_softc *sc;
 
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
+
        MV_GPIO_ASSERT_LOCKED();
 
-       cnt = &mv_gpio_softc->debounce_counters[pin];
-
-       raw_read = (mv_gpio_value_get(pin, 1) ? 1 : 0);
+       cnt = &sc->debounce_counters[pin];
+       raw_read = (mv_gpio_value_get(dev, pin, 1) ? 1 : 0);
        if (raw_read) {
-               mv_gpio_polarity(pin, 1, 0);
+               mv_gpio_polarity(dev, pin, 1, 0);
                *cnt = DEBOUNCE_HI_LO_MS / DEBOUNCE_CHECK_MS;
        } else {
-               mv_gpio_polarity(pin, 0, 0);
+               mv_gpio_polarity(dev, pin, 0, 0);
                *cnt = DEBOUNCE_LO_HI_MS / DEBOUNCE_CHECK_MS;
        }
 
-       mv_gpio_debounced_state_set(pin, raw_read);
+       mv_gpio_debounced_state_set(dev, pin, raw_read);
 
        return (0);
 }
 
 static void
-mv_gpio_debounce_start(int pin)
+mv_gpio_debounce_start(device_t dev, int pin)
 {
        struct callout *c;
-       int *debounced_pin;
+       struct mv_gpio_pindev s = {dev, pin};
+       struct mv_gpio_pindev *sd;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
        MV_GPIO_ASSERT_LOCKED();
 
-       c = mv_gpio_softc->debounce_callouts[pin];
+       c = sc->debounce_callouts[pin];
        if (c == NULL) {
-               mv_gpio_int_ack(pin);
+               mv_gpio_int_ack(&s);
                return;
        }
 
        if (callout_pending(c) || callout_active(c)) {
-               mv_gpio_int_ack(pin);
+               mv_gpio_int_ack(&s);
                return;
        }
 
-       debounced_pin = (int *)malloc(sizeof(int), M_DEVBUF,
-           M_WAITOK);
-       if (debounced_pin == NULL) {
-               mv_gpio_int_ack(pin);
+       sd = (struct mv_gpio_pindev *)malloc(sizeof(struct mv_gpio_pindev),
+           M_DEVBUF, M_WAITOK);
+       if (sd == NULL) {
+               mv_gpio_int_ack(&s);
                return;
        }
-       *debounced_pin = pin;
+       sd->pin = pin;
+       sd->dev = dev;
 
-       callout_reset(c, DEBOUNCE_CHECK_TICKS, mv_gpio_debounce,
-           debounced_pin);
+       callout_reset(c, DEBOUNCE_CHECK_TICKS, mv_gpio_debounce, sd);
 }
 
 static void
@@ -656,15 +680,21 @@ mv_gpio_debounce(void *arg)
 {
        uint8_t raw_read, last_state;
        int pin;
+       device_t dev;
        int *debounce_counter;
+       struct mv_gpio_softc *sc;
+       struct mv_gpio_pindev *s;
 
-       pin = *((int *)arg);
+       s = (struct mv_gpio_pindev *)arg;
+       dev = s->dev;
+       pin = s->pin;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
        MV_GPIO_LOCK();
 
-       raw_read = (mv_gpio_value_get(pin, 1) ? 1 : 0);
-       last_state = (mv_gpio_debounced_state_get(pin) ? 1 : 0);
-       debounce_counter = &mv_gpio_softc->debounce_counters[pin];
+       raw_read = (mv_gpio_value_get(dev, pin, 1) ? 1 : 0);
+       last_state = (mv_gpio_debounced_state_get(dev, pin) ? 1 : 0);
+       debounce_counter = &sc->debounce_counters[pin];
 
        if (raw_read == last_state) {
                if (last_state)
@@ -674,15 +704,15 @@ mv_gpio_debounce(void *arg)
                        *debounce_counter = DEBOUNCE_LO_HI_MS /
                            DEBOUNCE_CHECK_MS;
 
-               callout_reset(mv_gpio_softc->debounce_callouts[pin],
+               callout_reset(sc->debounce_callouts[pin],
                    DEBOUNCE_CHECK_TICKS, mv_gpio_debounce, arg);
        } else {
                *debounce_counter = *debounce_counter - 1;
                if (*debounce_counter != 0)
-                       callout_reset(mv_gpio_softc->debounce_callouts[pin],
+                       callout_reset(sc->debounce_callouts[pin],
                            DEBOUNCE_CHECK_TICKS, mv_gpio_debounce, arg);
                else {
-                       mv_gpio_debounced_state_set(pin, raw_read);
+                       mv_gpio_debounced_state_set(dev, pin, raw_read);
 
                        if (last_state)
                                *debounce_counter = DEBOUNCE_HI_LO_MS /
@@ -691,19 +721,18 @@ mv_gpio_debounce(void *arg)
                                *debounce_counter = DEBOUNCE_LO_HI_MS /
                                    DEBOUNCE_CHECK_MS;
 
-                       if (((gpio_setup[pin] & MV_GPIO_IN_POL_LOW) &&
+                       if (((sc->gpio_setup[pin].gp_flags & 
MV_GPIO_IN_POL_LOW) &&
                            (raw_read == 0)) ||
-                           (((gpio_setup[pin] & MV_GPIO_IN_POL_LOW) == 0) &&
+                           (((sc->gpio_setup[pin].gp_flags & 
MV_GPIO_IN_POL_LOW) == 0) &&
                            raw_read) ||
-                           (gpio_setup[pin] & MV_GPIO_IN_IRQ_DOUBLE_EDGE))
-                               mv_gpio_intr_handler(pin);
+                           (sc->gpio_setup[pin].gp_flags & 
MV_GPIO_IN_IRQ_DOUBLE_EDGE))
+                               mv_gpio_intr_handler(dev, pin);
 
                        /* Toggle polarity for next edge. */
-                       mv_gpio_polarity(pin, 0, 1);
+                       mv_gpio_polarity(dev, pin, 0, 1);
 
                        free(arg, M_DEVBUF);
-                       callout_deactivate(mv_gpio_softc->
-                           debounce_callouts[pin]);
+                       callout_deactivate(sc->debounce_callouts[pin]);
                }
        }
 
@@ -711,17 +740,19 @@ mv_gpio_debounce(void *arg)
 }
 
 static void
-mv_gpio_debounced_state_set(int pin, uint8_t new_state)
+mv_gpio_debounced_state_set(device_t dev, int pin, uint8_t new_state)
 {
        uint32_t *old_state;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
        MV_GPIO_ASSERT_LOCKED();
 
        if (pin >= GPIO_PINS_PER_REG) {
-               old_state = &mv_gpio_softc->debounced_state_hi;
+               old_state = &sc->debounced_state_hi;
                pin -= GPIO_PINS_PER_REG;
        } else
-               old_state = &mv_gpio_softc->debounced_state_lo;
+               old_state = &sc->debounced_state_lo;
 
        if (new_state)
                *old_state |= (1 << pin);
@@ -730,265 +761,255 @@ mv_gpio_debounced_state_set(int pin, uint8_t new_state
 }
 
 static uint32_t
-mv_gpio_debounced_state_get(int pin)
+mv_gpio_debounced_state_get(device_t dev, int pin)
 {
        uint32_t *state;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
        MV_GPIO_ASSERT_LOCKED();
 
        if (pin >= GPIO_PINS_PER_REG) {
-               state = &mv_gpio_softc->debounced_state_hi;
+               state = &sc->debounced_state_hi;
                pin -= GPIO_PINS_PER_REG;
        } else
-               state = &mv_gpio_softc->debounced_state_lo;
+               state = &sc->debounced_state_lo;
 
        return (*state & (1 << pin));
 }
 
 void
-mv_gpio_out(uint32_t pin, uint8_t val, uint8_t enable)
+mv_gpio_out(device_t dev, uint32_t pin, uint8_t val, uint8_t enable)
 {
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
        MV_GPIO_LOCK();
 
-       mv_gpio_value_set(pin, val);
-       mv_gpio_out_en(pin, enable);
+       mv_gpio_value_set(dev, pin, val);
+       mv_gpio_out_en(dev, pin, enable);
 
        MV_GPIO_UNLOCK();
 }
 
 uint8_t
-mv_gpio_in(uint32_t pin)
+mv_gpio_in(device_t dev, uint32_t pin)
 {
        uint8_t state;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
        MV_GPIO_LOCK();
 
-       if (gpio_setup[pin] & MV_GPIO_IN_DEBOUNCE) {
-               if (gpio_setup[pin] & MV_GPIO_IN_POL_LOW)
-                       state = (mv_gpio_debounced_state_get(pin) ? 0 : 1);
+       if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_DEBOUNCE) {
+               if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_POL_LOW)
+                       state = (mv_gpio_debounced_state_get(dev, pin) ? 0 : 1);
                else
-                       state = (mv_gpio_debounced_state_get(pin) ? 1 : 0);
-       } else if (gpio_setup[pin] & MV_GPIO_IN_IRQ_DOUBLE_EDGE) {
-               if (gpio_setup[pin] & MV_GPIO_IN_POL_LOW)
-                       state = (mv_gpio_value_get(pin, 1) ? 0 : 1);
+                       state = (mv_gpio_debounced_state_get(dev, pin) ? 1 : 0);
+       } else if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_IRQ_DOUBLE_EDGE) {
+               if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_POL_LOW)
+                       state = (mv_gpio_value_get(dev, pin, 1) ? 0 : 1);
                else
-                       state = (mv_gpio_value_get(pin, 1) ? 1 : 0);
+                       state = (mv_gpio_value_get(dev, pin, 1) ? 1 : 0);
        } else
-               state = (mv_gpio_value_get(pin, 0) ? 1 : 0);
+               state = (mv_gpio_value_get(dev, pin, 0) ? 1 : 0);
 
-       MV_GPIO_UNLOCK();
 
        return (state);
 }
 
 static uint32_t
-mv_gpio_reg_read(uint32_t reg)
+mv_gpio_reg_read(device_t dev, uint32_t reg)
 {
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
-       return (bus_space_read_4(mv_gpio_softc->bst,
-           mv_gpio_softc->bsh, reg));
+       return (bus_space_read_4(sc->bst, sc->bsh, reg));
 }
 
 static void
-mv_gpio_reg_write(uint32_t reg, uint32_t val)
+mv_gpio_reg_write(device_t dev, uint32_t reg, uint32_t val)
 {
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
-       bus_space_write_4(mv_gpio_softc->bst,
-           mv_gpio_softc->bsh, reg, val);
+       bus_space_write_4(sc->bst, sc->bsh, reg, val);
 }
 
 static void
-mv_gpio_reg_set(uint32_t reg, uint32_t pin)
+mv_gpio_reg_set(device_t dev, uint32_t reg, uint32_t pin)
 {
        uint32_t reg_val;
 
-       reg_val = mv_gpio_reg_read(reg);
+       reg_val = mv_gpio_reg_read(dev, reg);
        reg_val |= GPIO(pin);
-       mv_gpio_reg_write(reg, reg_val);
+       mv_gpio_reg_write(dev, reg, reg_val);
 }
 
 static void
-mv_gpio_reg_clear(uint32_t reg, uint32_t pin)
+mv_gpio_reg_clear(device_t dev, uint32_t reg, uint32_t pin)
 {
        uint32_t reg_val;
 
-       reg_val = mv_gpio_reg_read(reg);
+       reg_val = mv_gpio_reg_read(dev, reg);
        reg_val &= ~(GPIO(pin));
-       mv_gpio_reg_write(reg, reg_val);
+       mv_gpio_reg_write(dev, reg, reg_val);
 }
 
 static void
-mv_gpio_out_en(uint32_t pin, uint8_t enable)
+mv_gpio_out_en(device_t dev, uint32_t pin, uint8_t enable)
 {
        uint32_t reg;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
-       if (pin >= mv_gpio_softc->pin_num)
+       if (pin >= sc->pin_num)
                return;
 
-       if (pin >= GPIO_PINS_PER_REG) {
-               reg = GPIO_HI_DATA_OUT_EN_CTRL;
-               pin -= GPIO_PINS_PER_REG;
-       } else
-               reg = GPIO_DATA_OUT_EN_CTRL;
+       reg = GPIO_DATA_OUT_EN_CTRL;
 
        if (enable)
-               mv_gpio_reg_clear(reg, pin);
+               mv_gpio_reg_clear(dev, reg, pin);
        else
-               mv_gpio_reg_set(reg, pin);
+               mv_gpio_reg_set(dev, reg, pin);
 }
 
 static void
-mv_gpio_blink(uint32_t pin, uint8_t enable)
+mv_gpio_blink(device_t dev, uint32_t pin, uint8_t enable)
 {
        uint32_t reg;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
-       if (pin >= mv_gpio_softc->pin_num)
+       if (pin >= sc->pin_num)
                return;
 
-       if (pin >= GPIO_PINS_PER_REG) {
-               reg = GPIO_HI_BLINK_EN;
-               pin -= GPIO_PINS_PER_REG;
-       } else
-               reg = GPIO_BLINK_EN;
+       reg = GPIO_BLINK_EN;
 
        if (enable)
-               mv_gpio_reg_set(reg, pin);
+               mv_gpio_reg_set(dev, reg, pin);
        else
-               mv_gpio_reg_clear(reg, pin);
+               mv_gpio_reg_clear(dev, reg, pin);
 }
 
 static void
-mv_gpio_polarity(uint32_t pin, uint8_t enable, uint8_t toggle)
+mv_gpio_polarity(device_t dev, uint32_t pin, uint8_t enable, uint8_t toggle)
 {
        uint32_t reg, reg_val;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
-       if (pin >= mv_gpio_softc->pin_num)
+       if (pin >= sc->pin_num)
                return;
 
-       if (pin >= GPIO_PINS_PER_REG) {
-               reg = GPIO_HI_DATA_IN_POLAR;
-               pin -= GPIO_PINS_PER_REG;
-       } else
-               reg = GPIO_DATA_IN_POLAR;
+       reg = GPIO_DATA_IN_POLAR;
 
        if (toggle) {
-               reg_val = mv_gpio_reg_read(reg) & GPIO(pin);
+               reg_val = mv_gpio_reg_read(dev, reg) & GPIO(pin);
                if (reg_val)
-                       mv_gpio_reg_clear(reg, pin);
+                       mv_gpio_reg_clear(dev, reg, pin);
                else
-                       mv_gpio_reg_set(reg, pin);
+                       mv_gpio_reg_set(dev, reg, pin);
        } else if (enable)
-               mv_gpio_reg_set(reg, pin);
+               mv_gpio_reg_set(dev, reg, pin);
        else
-               mv_gpio_reg_clear(reg, pin);
+               mv_gpio_reg_clear(dev, reg, pin);
 }
 
 static void
-mv_gpio_level(uint32_t pin, uint8_t enable)
+mv_gpio_level(device_t dev, uint32_t pin, uint8_t enable)
 {
        uint32_t reg;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
-       if (pin >= mv_gpio_softc->pin_num)
+       if (pin >= sc->pin_num)
                return;
 
-       if (pin >= GPIO_PINS_PER_REG) {
-               reg = GPIO_HI_INT_LEV_MASK;
-               pin -= GPIO_PINS_PER_REG;
-       } else
-               reg = GPIO_INT_LEV_MASK;
+       reg = GPIO_INT_LEV_MASK;
 
        if (enable)
-               mv_gpio_reg_set(reg, pin);
+               mv_gpio_reg_set(dev, reg, pin);
        else
-               mv_gpio_reg_clear(reg, pin);
+               mv_gpio_reg_clear(dev, reg, pin);
 }
 
 static void
-mv_gpio_edge(uint32_t pin, uint8_t enable)
+mv_gpio_edge(device_t dev, uint32_t pin, uint8_t enable)
 {
        uint32_t reg;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
-       if (pin >= mv_gpio_softc->pin_num)
+       if (pin >= sc->pin_num)
                return;
 
-       if (pin >= GPIO_PINS_PER_REG) {
-               reg = GPIO_HI_INT_EDGE_MASK;
-               pin -= GPIO_PINS_PER_REG;
-       } else
-               reg = GPIO_INT_EDGE_MASK;
+       reg = GPIO_INT_EDGE_MASK;
 
        if (enable)
-               mv_gpio_reg_set(reg, pin);
+               mv_gpio_reg_set(dev, reg, pin);
        else
-               mv_gpio_reg_clear(reg, pin);
+               mv_gpio_reg_clear(dev, reg, pin);
 }
 
 static void
-mv_gpio_int_ack(uint32_t pin)
+mv_gpio_int_ack(struct mv_gpio_pindev *s)
 {
-       uint32_t reg;
+       uint32_t reg, pin;
+       struct mv_gpio_softc *sc;
+       sc = (struct mv_gpio_softc *)device_get_softc(s->dev);
+       pin = s->pin;
 
-       if (pin >= mv_gpio_softc->pin_num)
+       if (pin >= sc->pin_num)
                return;
 
-       if (pin >= GPIO_PINS_PER_REG) {
-               reg = GPIO_HI_INT_CAUSE;
-               pin -= GPIO_PINS_PER_REG;
-       } else
-               reg = GPIO_INT_CAUSE;
+       reg = GPIO_INT_CAUSE;
 

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to