svn commit: r332024 - head/sys/arm/mv

Marcin Wojtas mw at FreeBSD.org
Wed Apr 4 13:20:30 UTC 2018


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 <pdk at 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 ***


More information about the svn-src-all mailing list