xref: /freebsd/sys/arm/mv/gpio.c (revision fdafd315)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2006 Benno Rice.
5  * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
6  * Copyright (c) 2017 Semihalf.
7  * All rights reserved.
8  *
9  * Adapted and extended for Marvell SoCs by Semihalf.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  * from: FreeBSD: //depot/projects/arm/src/sys/arm/xscale/pxa2x0/pxa2x0_gpio.c, rev 1
32  */
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/bus.h>
37 #include <sys/kernel.h>
38 #include <sys/lock.h>
39 #include <sys/interrupt.h>
40 #include <sys/module.h>
41 #include <sys/malloc.h>
42 #include <sys/mutex.h>
43 #include <sys/rman.h>
44 #include <sys/queue.h>
45 #include <sys/timetc.h>
46 #include <sys/callout.h>
47 #include <sys/gpio.h>
48 #include <machine/bus.h>
49 #include <machine/intr.h>
50 
51 #include <dev/gpio/gpiobusvar.h>
52 #include <dev/ofw/ofw_bus.h>
53 #include <dev/ofw/ofw_bus_subr.h>
54 
55 #include <arm/mv/mvvar.h>
56 #include <arm/mv/mvreg.h>
57 
58 #include "gpio_if.h"
59 
60 #define GPIO_MAX_INTR_COUNT	8
61 #define GPIO_PINS_PER_REG	32
62 #define GPIO_GENERIC_CAP	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |		\
63 				GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL |	\
64 				GPIO_PIN_TRISTATE | GPIO_PIN_PULLUP |		\
65 				GPIO_PIN_PULLDOWN | GPIO_PIN_INVIN |		\
66 				GPIO_PIN_INVOUT)
67 
68 #define DEBOUNCE_CHECK_MS	1
69 #define DEBOUNCE_LO_HI_MS	2
70 #define DEBOUNCE_HI_LO_MS	2
71 #define DEBOUNCE_CHECK_TICKS	((hz / 1000) * DEBOUNCE_CHECK_MS)
72 
73 struct mv_gpio_softc {
74 	device_t		dev;
75 	device_t		sc_busdev;
76 	struct resource	*	mem_res;
77 	int			mem_rid;
78 	struct resource	*	irq_res[GPIO_MAX_INTR_COUNT];
79 	int			irq_rid[GPIO_MAX_INTR_COUNT];
80 	struct intr_event *	gpio_events[MV_GPIO_MAX_NPINS];
81 	void			*ih_cookie[GPIO_MAX_INTR_COUNT];
82 	bus_space_tag_t		bst;
83 	bus_space_handle_t	bsh;
84 	uint32_t		offset;
85 	struct mtx		mutex;
86 	uint8_t			pin_num;	/* number of GPIO pins */
87 	uint8_t			irq_num;	/* number of real IRQs occupied by GPIO controller */
88 	struct gpio_pin		gpio_setup[MV_GPIO_MAX_NPINS];
89 
90 	/* Used for debouncing. */
91 	uint32_t		debounced_state_lo;
92 	uint32_t		debounced_state_hi;
93 	struct callout		**debounce_callouts;
94 	int			*debounce_counters;
95 };
96 
97 struct mv_gpio_pindev {
98 	device_t dev;
99 	int pin;
100 };
101 
102 static int	mv_gpio_probe(device_t);
103 static int	mv_gpio_attach(device_t);
104 static int	mv_gpio_intr(device_t, void *);
105 
106 static void	mv_gpio_double_edge_init(device_t, int);
107 
108 static int	mv_gpio_debounce_setup(device_t, int);
109 static int	mv_gpio_debounce_prepare(device_t, int);
110 static int	mv_gpio_debounce_init(device_t, int);
111 static void	mv_gpio_debounce_start(device_t, int);
112 static void	mv_gpio_debounce(void *);
113 static void	mv_gpio_debounced_state_set(device_t, int, uint8_t);
114 static uint32_t	mv_gpio_debounced_state_get(device_t, int);
115 
116 static void	mv_gpio_exec_intr_handlers(device_t, uint32_t, int);
117 static void	mv_gpio_intr_handler(device_t, int);
118 static uint32_t	mv_gpio_reg_read(device_t, uint32_t);
119 static void	mv_gpio_reg_write(device_t, uint32_t, uint32_t);
120 static void	mv_gpio_reg_set(device_t, uint32_t, uint32_t);
121 static void	mv_gpio_reg_clear(device_t, uint32_t, uint32_t);
122 
123 static void	mv_gpio_blink(device_t, uint32_t, uint8_t);
124 static void	mv_gpio_polarity(device_t, uint32_t, uint8_t, uint8_t);
125 static void	mv_gpio_level(device_t, uint32_t, uint8_t);
126 static void	mv_gpio_edge(device_t, uint32_t, uint8_t);
127 static void	mv_gpio_out_en(device_t, uint32_t, uint8_t);
128 static void	mv_gpio_int_ack(struct mv_gpio_pindev *);
129 static void	mv_gpio_value_set(device_t, uint32_t, uint8_t);
130 static uint32_t	mv_gpio_value_get(device_t, uint32_t, uint8_t);
131 
132 static void	mv_gpio_intr_mask(struct mv_gpio_pindev *);
133 static void	mv_gpio_intr_unmask(struct mv_gpio_pindev *);
134 
135 void mv_gpio_finish_intrhandler(struct mv_gpio_pindev *);
136 int mv_gpio_setup_intrhandler(device_t, const char *,
137     driver_filter_t *, void (*)(void *), void *,
138     int, int, void **);
139 int mv_gpio_configure(device_t, uint32_t, uint32_t, uint32_t);
140 void mv_gpio_out(device_t, uint32_t, uint8_t, uint8_t);
141 uint8_t mv_gpio_in(device_t, uint32_t);
142 
143 /*
144  * GPIO interface
145  */
146 static device_t mv_gpio_get_bus(device_t);
147 static int mv_gpio_pin_max(device_t, int *);
148 static int mv_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
149 static int mv_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
150 static int mv_gpio_pin_getname(device_t, uint32_t, char *);
151 static int mv_gpio_pin_setflags(device_t, uint32_t, uint32_t);
152 static int mv_gpio_pin_set(device_t, uint32_t, unsigned int);
153 static int mv_gpio_pin_get(device_t, uint32_t, unsigned int *);
154 static int mv_gpio_pin_toggle(device_t, uint32_t);
155 static int mv_gpio_map_gpios(device_t, phandle_t, phandle_t,
156     int, pcell_t *, uint32_t *, uint32_t *);
157 
158 #define MV_GPIO_LOCK()		mtx_lock_spin(&sc->mutex)
159 #define MV_GPIO_UNLOCK()	mtx_unlock_spin(&sc->mutex)
160 #define MV_GPIO_ASSERT_LOCKED()	mtx_assert(&sc->mutex, MA_OWNED)
161 
162 static device_method_t mv_gpio_methods[] = {
163 	DEVMETHOD(device_probe,		mv_gpio_probe),
164 	DEVMETHOD(device_attach,	mv_gpio_attach),
165 
166 	/* GPIO protocol */
167 	DEVMETHOD(gpio_get_bus,		mv_gpio_get_bus),
168 	DEVMETHOD(gpio_pin_max,		mv_gpio_pin_max),
169 	DEVMETHOD(gpio_pin_getname,	mv_gpio_pin_getname),
170 	DEVMETHOD(gpio_pin_getflags,	mv_gpio_pin_getflags),
171 	DEVMETHOD(gpio_pin_getcaps,	mv_gpio_pin_getcaps),
172 	DEVMETHOD(gpio_pin_setflags,	mv_gpio_pin_setflags),
173 	DEVMETHOD(gpio_pin_get,		mv_gpio_pin_get),
174 	DEVMETHOD(gpio_pin_set,		mv_gpio_pin_set),
175 	DEVMETHOD(gpio_pin_toggle,	mv_gpio_pin_toggle),
176 	DEVMETHOD(gpio_map_gpios,	mv_gpio_map_gpios),
177 
178 	DEVMETHOD_END
179 };
180 
181 static driver_t mv_gpio_driver = {
182 	"gpio",
183 	mv_gpio_methods,
184 	sizeof(struct mv_gpio_softc),
185 };
186 
187 EARLY_DRIVER_MODULE(mv_gpio, simplebus, mv_gpio_driver, 0, 0,
188     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST);
189 
190 struct ofw_compat_data compat_data[] = {
191 	{ "mrvl,gpio", 1 },
192 	{ "marvell,orion-gpio", 1 },
193 	{ NULL, 0 }
194 };
195 
196 static int
mv_gpio_probe(device_t dev)197 mv_gpio_probe(device_t dev)
198 {
199 	if (!ofw_bus_status_okay(dev))
200 		return (ENXIO);
201 
202 	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
203 		return (ENXIO);
204 
205 	device_set_desc(dev, "Marvell Integrated GPIO Controller");
206 	return (0);
207 }
208 
209 static int
mv_gpio_setup_interrupts(struct mv_gpio_softc * sc,phandle_t node)210 mv_gpio_setup_interrupts(struct mv_gpio_softc *sc, phandle_t node)
211 {
212 	phandle_t iparent;
213 	pcell_t irq_cells;
214 	int i, size;
215 
216 	/* Find root interrupt controller */
217 	iparent = ofw_bus_find_iparent(node);
218 	if (iparent == 0) {
219 		device_printf(sc->dev, "No interrupt-parrent found. "
220 				"Error in DTB\n");
221 		return (ENXIO);
222 	} else {
223 		/* While at parent - store interrupt cells prop */
224 		if (OF_searchencprop(OF_node_from_xref(iparent),
225 		    "#interrupt-cells", &irq_cells, sizeof(irq_cells)) == -1) {
226 			device_printf(sc->dev, "DTB: Missing #interrupt-cells "
227 			    "property in interrupt parent node\n");
228 			return (ENXIO);
229 		}
230 	}
231 
232 	size = OF_getproplen(node, "interrupts");
233 	if (size != -1) {
234 		size = size / sizeof(pcell_t);
235 		size = size / irq_cells;
236 		sc->irq_num = size;
237 		device_printf(sc->dev, "%d IRQs available\n", sc->irq_num);
238 	} else {
239 		device_printf(sc->dev, "ERROR: no interrupts entry found!\n");
240 		return (ENXIO);
241 	}
242 
243 	for (i = 0; i < sc->irq_num; i++) {
244 		sc->irq_rid[i] = i;
245 		sc->irq_res[i] = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ,
246 			&sc->irq_rid[i], RF_ACTIVE);
247 		if (!sc->irq_res[i]) {
248 			mtx_destroy(&sc->mutex);
249 			device_printf(sc->dev,
250 			    "could not allocate gpio%d interrupt\n", i+1);
251 			return (ENXIO);
252 		}
253 	}
254 
255 	device_printf(sc->dev, "Disable interrupts (offset = %x + EDGE(0x18)\n", sc->offset);
256 	/* Disable all interrupts */
257 	bus_space_write_4(sc->bst, sc->bsh, sc->offset + GPIO_INT_EDGE_MASK, 0);
258 	device_printf(sc->dev, "Disable interrupts (offset = %x + LEV(0x1C))\n", sc->offset);
259 	bus_space_write_4(sc->bst, sc->bsh, sc->offset + GPIO_INT_LEV_MASK, 0);
260 
261 	for (i = 0; i < sc->irq_num; i++) {
262 		device_printf(sc->dev, "Setup intr %d\n", i);
263 		if (bus_setup_intr(sc->dev, sc->irq_res[i],
264 		    INTR_TYPE_MISC,
265 		    (driver_filter_t *)mv_gpio_intr, NULL,
266 		    sc, &sc->ih_cookie[i]) != 0) {
267 			mtx_destroy(&sc->mutex);
268 			bus_release_resource(sc->dev, SYS_RES_IRQ,
269 				sc->irq_rid[i], sc->irq_res[i]);
270 			device_printf(sc->dev, "could not set up intr %d\n", i);
271 			return (ENXIO);
272 		}
273 	}
274 
275 	/* Clear interrupt status. */
276 	device_printf(sc->dev, "Clear int status (offset = %x)\n", sc->offset);
277 	bus_space_write_4(sc->bst, sc->bsh, sc->offset + GPIO_INT_CAUSE, 0);
278 
279 	sc->debounce_callouts = (struct callout **)malloc(sc->pin_num *
280 	    sizeof(struct callout *), M_DEVBUF, M_WAITOK | M_ZERO);
281 	if (sc->debounce_callouts == NULL)
282 		return (ENOMEM);
283 
284 	sc->debounce_counters = (int *)malloc(sc->pin_num * sizeof(int),
285 	    M_DEVBUF, M_WAITOK);
286 	if (sc->debounce_counters == NULL)
287 		return (ENOMEM);
288 
289 	return (0);
290 }
291 
292 static int
mv_gpio_attach(device_t dev)293 mv_gpio_attach(device_t dev)
294 {
295 	int i, rv;
296 	struct mv_gpio_softc *sc;
297 	phandle_t node;
298 	pcell_t pincnt = 0;
299 
300 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
301 	if (sc == NULL)
302 		return (ENXIO);
303 
304 	node = ofw_bus_get_node(dev);
305 	sc->dev = dev;
306 
307 	if (OF_getencprop(node, "pin-count", &pincnt, sizeof(pcell_t)) >= 0 ||
308 	    OF_getencprop(node, "ngpios", &pincnt, sizeof(pcell_t)) >= 0) {
309 		sc->pin_num = MIN(pincnt, MV_GPIO_MAX_NPINS);
310 		if (bootverbose)
311 			device_printf(dev, "%d pins available\n", sc->pin_num);
312 	} else {
313 		device_printf(dev, "ERROR: no pin-count or ngpios entry found!\n");
314 		return (ENXIO);
315 	}
316 
317 	if (OF_getencprop(node, "offset", &sc->offset, sizeof(sc->offset)) == -1)
318 		sc->offset = 0;
319 
320 	/* Assign generic capabilities to every gpio pin */
321 	for(i = 0; i < sc->pin_num; i++)
322 		sc->gpio_setup[i].gp_caps = GPIO_GENERIC_CAP;
323 
324 	mtx_init(&sc->mutex, device_get_nameunit(dev), NULL, MTX_SPIN);
325 
326 	sc->mem_rid = 0;
327 	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
328 		 RF_ACTIVE | RF_SHAREABLE );
329 
330 	if (!sc->mem_res) {
331 		mtx_destroy(&sc->mutex);
332 		device_printf(dev, "could not allocate memory window\n");
333 		return (ENXIO);
334 	}
335 
336 	sc->bst = rman_get_bustag(sc->mem_res);
337 	sc->bsh = rman_get_bushandle(sc->mem_res);
338 
339 	rv = mv_gpio_setup_interrupts(sc, node);
340 	if (rv != 0)
341 		return (rv);
342 
343 	sc->sc_busdev = gpiobus_attach_bus(dev);
344 	if (sc->sc_busdev == NULL) {
345 		mtx_destroy(&sc->mutex);
346 		bus_release_resource(dev, SYS_RES_IRQ,
347 			sc->irq_rid[i], sc->irq_res[i]);
348 		return (ENXIO);
349 	}
350 
351 	return (0);
352 }
353 
354 static int
mv_gpio_intr(device_t dev,void * arg)355 mv_gpio_intr(device_t dev, void *arg)
356 {
357 	uint32_t int_cause, gpio_val;
358 	struct mv_gpio_softc *sc;
359 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
360 
361 	MV_GPIO_LOCK();
362 
363 	/*
364 	 * According to documentation, edge sensitive interrupts are asserted
365 	 * when unmasked GPIO_INT_CAUSE register bits are set.
366 	 */
367 	int_cause = mv_gpio_reg_read(dev, GPIO_INT_CAUSE);
368 	int_cause &= mv_gpio_reg_read(dev, GPIO_INT_EDGE_MASK);
369 
370 	/*
371 	 * Level sensitive interrupts are asserted when unmasked GPIO_DATA_IN
372 	 * register bits are set.
373 	 */
374 	gpio_val = mv_gpio_reg_read(dev, GPIO_DATA_IN);
375 	gpio_val &= mv_gpio_reg_read(dev, GPIO_INT_LEV_MASK);
376 
377 	mv_gpio_exec_intr_handlers(dev, int_cause | gpio_val, 0);
378 
379 	MV_GPIO_UNLOCK();
380 
381 	return (FILTER_HANDLED);
382 }
383 
384 /*
385  * GPIO interrupt handling
386  */
387 
388 void
mv_gpio_finish_intrhandler(struct mv_gpio_pindev * s)389 mv_gpio_finish_intrhandler(struct mv_gpio_pindev *s)
390 {
391 	/* When we acheive full interrupt support
392 	 * This function will be opposite to
393 	 * mv_gpio_setup_intrhandler
394 	 */
395 
396 	/* Now it exists only to remind that
397 	 * there should be place to free mv_gpio_pindev
398 	 * allocated by mv_gpio_setup_intrhandler
399 	 */
400 	free(s, M_DEVBUF);
401 }
402 
403 int
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)404 mv_gpio_setup_intrhandler(device_t dev, const char *name, driver_filter_t *filt,
405     void (*hand)(void *), void *arg, int pin, int flags, void **cookiep)
406 {
407 	struct	intr_event *event;
408 	int	error;
409 	struct mv_gpio_pindev *s;
410 	struct mv_gpio_softc *sc;
411 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
412 	s = malloc(sizeof(struct mv_gpio_pindev), M_DEVBUF, M_NOWAIT | M_ZERO);
413 
414 	if (pin < 0 || pin >= sc->pin_num)
415 		return (ENXIO);
416 	event = sc->gpio_events[pin];
417 	if (event == NULL) {
418 		MV_GPIO_LOCK();
419 		if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_DEBOUNCE) {
420 			error = mv_gpio_debounce_init(dev, pin);
421 			if (error != 0) {
422 				MV_GPIO_UNLOCK();
423 				return (error);
424 			}
425 		} else if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_IRQ_DOUBLE_EDGE)
426 			mv_gpio_double_edge_init(dev, pin);
427 		MV_GPIO_UNLOCK();
428 		error = intr_event_create(&event, (void *)s, 0, pin,
429 		    (void (*)(void *))mv_gpio_intr_mask,
430 		    (void (*)(void *))mv_gpio_intr_unmask,
431 		    (void (*)(void *))mv_gpio_int_ack,
432 		    NULL,
433 		    "gpio%d:", pin);
434 		if (error != 0)
435 			return (error);
436 		sc->gpio_events[pin] = event;
437 	}
438 
439 	intr_event_add_handler(event, name, filt, hand, arg,
440 	    intr_priority(flags), flags, cookiep);
441 	return (0);
442 }
443 
444 static void
mv_gpio_intr_mask(struct mv_gpio_pindev * s)445 mv_gpio_intr_mask(struct mv_gpio_pindev *s)
446 {
447 	struct mv_gpio_softc *sc;
448 	sc = (struct mv_gpio_softc *)device_get_softc(s->dev);
449 
450 	if (s->pin >= sc->pin_num)
451 		return;
452 
453 	MV_GPIO_LOCK();
454 
455 	if (sc->gpio_setup[s->pin].gp_flags & (MV_GPIO_IN_IRQ_EDGE |
456 	    MV_GPIO_IN_IRQ_DOUBLE_EDGE))
457 		mv_gpio_edge(s->dev, s->pin, 0);
458 	else
459 		mv_gpio_level(s->dev, s->pin, 0);
460 
461 	/*
462 	 * The interrupt has to be acknowledged before scheduling an interrupt
463 	 * thread. This way we allow for interrupt source to trigger again
464 	 * (which can happen with shared IRQs e.g. PCI) while processing the
465 	 * current event.
466 	 */
467 	mv_gpio_int_ack(s);
468 
469 	MV_GPIO_UNLOCK();
470 
471 	return;
472 }
473 
474 static void
mv_gpio_intr_unmask(struct mv_gpio_pindev * s)475 mv_gpio_intr_unmask(struct mv_gpio_pindev *s)
476 {
477 	struct mv_gpio_softc *sc;
478 	sc = (struct mv_gpio_softc *)device_get_softc(s->dev);
479 
480 	if (s->pin >= sc->pin_num)
481 		return;
482 
483 	MV_GPIO_LOCK();
484 
485 	if (sc->gpio_setup[s->pin].gp_flags & (MV_GPIO_IN_IRQ_EDGE |
486 	    MV_GPIO_IN_IRQ_DOUBLE_EDGE))
487 		mv_gpio_edge(s->dev, s->pin, 1);
488 	else
489 		mv_gpio_level(s->dev, s->pin, 1);
490 
491 	MV_GPIO_UNLOCK();
492 
493 	return;
494 }
495 
496 static void
mv_gpio_exec_intr_handlers(device_t dev,uint32_t status,int high)497 mv_gpio_exec_intr_handlers(device_t dev, uint32_t status, int high)
498 {
499 	int i, pin;
500 	struct mv_gpio_softc *sc;
501 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
502 
503 	MV_GPIO_ASSERT_LOCKED();
504 
505 	i = 0;
506 	while (status != 0) {
507 		if (status & 1) {
508 			pin = (high ? (i + GPIO_PINS_PER_REG) : i);
509 			if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_DEBOUNCE)
510 				mv_gpio_debounce_start(dev, pin);
511 			else if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_IRQ_DOUBLE_EDGE) {
512 				mv_gpio_polarity(dev, pin, 0, 1);
513 				mv_gpio_intr_handler(dev, pin);
514 			} else
515 				mv_gpio_intr_handler(dev, pin);
516 		}
517 		status >>= 1;
518 		i++;
519 	}
520 }
521 
522 static void
mv_gpio_intr_handler(device_t dev,int pin)523 mv_gpio_intr_handler(device_t dev, int pin)
524 {
525 	struct intr_irqsrc isrc;
526 	struct mv_gpio_softc *sc;
527 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
528 
529 	MV_GPIO_ASSERT_LOCKED();
530 
531 #ifdef INTR_SOLO
532 	isrc.isrc_filter = NULL;
533 #endif
534 	isrc.isrc_event = sc->gpio_events[pin];
535 
536 	if (isrc.isrc_event == NULL ||
537 	    CK_SLIST_EMPTY(&isrc.isrc_event->ie_handlers))
538 		return;
539 
540 	intr_isrc_dispatch(&isrc, NULL);
541 }
542 
543 int
mv_gpio_configure(device_t dev,uint32_t pin,uint32_t flags,uint32_t mask)544 mv_gpio_configure(device_t dev, uint32_t pin, uint32_t flags, uint32_t mask)
545 {
546 	int error;
547 	struct mv_gpio_softc *sc;
548 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
549 	error = 0;
550 
551 	if (pin >= sc->pin_num)
552 		return (EINVAL);
553 
554 	/* check flags consistency */
555 	if (((flags & mask) & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) ==
556 	    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
557 		return (EINVAL);
558 
559 	if (mask & MV_GPIO_IN_DEBOUNCE) {
560 		if (sc->irq_num == 0)
561 			return (EINVAL);
562 		error = mv_gpio_debounce_prepare(dev, pin);
563 		if (error != 0)
564 			return (error);
565 	}
566 
567 	MV_GPIO_LOCK();
568 
569 	if ((mask & flags) & GPIO_PIN_INPUT)
570 		mv_gpio_out_en(dev, pin, 0);
571 	if ((mask & flags) & GPIO_PIN_OUTPUT) {
572 		if ((flags & mask) & GPIO_PIN_OPENDRAIN)
573 			mv_gpio_value_set(dev, pin, 0);
574 		else
575 			mv_gpio_value_set(dev, pin, 1);
576 		mv_gpio_out_en(dev, pin, 1);
577 	}
578 
579 	if (mask & MV_GPIO_OUT_BLINK)
580 		mv_gpio_blink(dev, pin, flags & MV_GPIO_OUT_BLINK);
581 	if (mask & MV_GPIO_IN_POL_LOW)
582 		mv_gpio_polarity(dev, pin, flags & MV_GPIO_IN_POL_LOW, 0);
583 	if (mask & MV_GPIO_IN_DEBOUNCE) {
584 		error = mv_gpio_debounce_setup(dev, pin);
585 		if (error) {
586 			MV_GPIO_UNLOCK();
587 			return (error);
588 		}
589 	}
590 
591 	sc->gpio_setup[pin].gp_flags &= ~(mask);
592 	sc->gpio_setup[pin].gp_flags |= (flags & mask);
593 
594 	MV_GPIO_UNLOCK();
595 
596 	return (0);
597 }
598 
599 static void
mv_gpio_double_edge_init(device_t dev,int pin)600 mv_gpio_double_edge_init(device_t dev, int pin)
601 {
602 	uint8_t raw_read;
603 	struct mv_gpio_softc *sc __unused;
604 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
605 
606 	MV_GPIO_ASSERT_LOCKED();
607 
608 	raw_read = (mv_gpio_value_get(dev, pin, 1) ? 1 : 0);
609 
610 	if (raw_read)
611 		mv_gpio_polarity(dev, pin, 1, 0);
612 	else
613 		mv_gpio_polarity(dev, pin, 0, 0);
614 }
615 
616 static int
mv_gpio_debounce_setup(device_t dev,int pin)617 mv_gpio_debounce_setup(device_t dev, int pin)
618 {
619 	struct callout *c;
620 	struct mv_gpio_softc *sc;
621 
622 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
623 
624 	MV_GPIO_ASSERT_LOCKED();
625 
626 	c = sc->debounce_callouts[pin];
627 	if (c == NULL)
628 		return (ENXIO);
629 
630 	if (callout_active(c))
631 		callout_deactivate(c);
632 
633 	callout_stop(c);
634 
635 	return (0);
636 }
637 
638 static int
mv_gpio_debounce_prepare(device_t dev,int pin)639 mv_gpio_debounce_prepare(device_t dev, int pin)
640 {
641 	struct callout *c;
642 	struct mv_gpio_softc *sc;
643 
644 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
645 
646 	c = sc->debounce_callouts[pin];
647 	if (c == NULL) {
648 		c = (struct callout *)malloc(sizeof(struct callout),
649 		    M_DEVBUF, M_WAITOK);
650 		sc->debounce_callouts[pin] = c;
651 		if (c == NULL)
652 			return (ENOMEM);
653 		callout_init(c, 1);
654 	}
655 
656 	return (0);
657 }
658 
659 static int
mv_gpio_debounce_init(device_t dev,int pin)660 mv_gpio_debounce_init(device_t dev, int pin)
661 {
662 	uint8_t raw_read;
663 	int *cnt;
664 	struct mv_gpio_softc *sc;
665 
666 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
667 
668 	MV_GPIO_ASSERT_LOCKED();
669 
670 	cnt = &sc->debounce_counters[pin];
671 	raw_read = (mv_gpio_value_get(dev, pin, 1) ? 1 : 0);
672 	if (raw_read) {
673 		mv_gpio_polarity(dev, pin, 1, 0);
674 		*cnt = DEBOUNCE_HI_LO_MS / DEBOUNCE_CHECK_MS;
675 	} else {
676 		mv_gpio_polarity(dev, pin, 0, 0);
677 		*cnt = DEBOUNCE_LO_HI_MS / DEBOUNCE_CHECK_MS;
678 	}
679 
680 	mv_gpio_debounced_state_set(dev, pin, raw_read);
681 
682 	return (0);
683 }
684 
685 static void
mv_gpio_debounce_start(device_t dev,int pin)686 mv_gpio_debounce_start(device_t dev, int pin)
687 {
688 	struct callout *c;
689 	struct mv_gpio_pindev s = {dev, pin};
690 	struct mv_gpio_pindev *sd;
691 	struct mv_gpio_softc *sc;
692 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
693 
694 	MV_GPIO_ASSERT_LOCKED();
695 
696 	c = sc->debounce_callouts[pin];
697 	if (c == NULL) {
698 		mv_gpio_int_ack(&s);
699 		return;
700 	}
701 
702 	if (callout_pending(c) || callout_active(c)) {
703 		mv_gpio_int_ack(&s);
704 		return;
705 	}
706 
707 	sd = (struct mv_gpio_pindev *)malloc(sizeof(struct mv_gpio_pindev),
708 	    M_DEVBUF, M_WAITOK);
709 	if (sd == NULL) {
710 		mv_gpio_int_ack(&s);
711 		return;
712 	}
713 	sd->pin = pin;
714 	sd->dev = dev;
715 
716 	callout_reset(c, DEBOUNCE_CHECK_TICKS, mv_gpio_debounce, sd);
717 }
718 
719 static void
mv_gpio_debounce(void * arg)720 mv_gpio_debounce(void *arg)
721 {
722 	uint8_t raw_read, last_state;
723 	int pin;
724 	device_t dev;
725 	int *debounce_counter;
726 	struct mv_gpio_softc *sc;
727 	struct mv_gpio_pindev *s;
728 
729 	s = (struct mv_gpio_pindev *)arg;
730 	dev = s->dev;
731 	pin = s->pin;
732 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
733 
734 	MV_GPIO_LOCK();
735 
736 	raw_read = (mv_gpio_value_get(dev, pin, 1) ? 1 : 0);
737 	last_state = (mv_gpio_debounced_state_get(dev, pin) ? 1 : 0);
738 	debounce_counter = &sc->debounce_counters[pin];
739 
740 	if (raw_read == last_state) {
741 		if (last_state)
742 			*debounce_counter = DEBOUNCE_HI_LO_MS /
743 			    DEBOUNCE_CHECK_MS;
744 		else
745 			*debounce_counter = DEBOUNCE_LO_HI_MS /
746 			    DEBOUNCE_CHECK_MS;
747 
748 		callout_reset(sc->debounce_callouts[pin],
749 		    DEBOUNCE_CHECK_TICKS, mv_gpio_debounce, arg);
750 	} else {
751 		*debounce_counter = *debounce_counter - 1;
752 		if (*debounce_counter != 0)
753 			callout_reset(sc->debounce_callouts[pin],
754 			    DEBOUNCE_CHECK_TICKS, mv_gpio_debounce, arg);
755 		else {
756 			mv_gpio_debounced_state_set(dev, pin, raw_read);
757 
758 			if (last_state)
759 				*debounce_counter = DEBOUNCE_HI_LO_MS /
760 				    DEBOUNCE_CHECK_MS;
761 			else
762 				*debounce_counter = DEBOUNCE_LO_HI_MS /
763 				    DEBOUNCE_CHECK_MS;
764 
765 			if (((sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_POL_LOW) &&
766 			    (raw_read == 0)) ||
767 			    (((sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_POL_LOW) == 0) &&
768 			    raw_read) ||
769 			    (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_IRQ_DOUBLE_EDGE))
770 				mv_gpio_intr_handler(dev, pin);
771 
772 			/* Toggle polarity for next edge. */
773 			mv_gpio_polarity(dev, pin, 0, 1);
774 
775 			free(arg, M_DEVBUF);
776 			callout_deactivate(sc->debounce_callouts[pin]);
777 		}
778 	}
779 
780 	MV_GPIO_UNLOCK();
781 }
782 
783 static void
mv_gpio_debounced_state_set(device_t dev,int pin,uint8_t new_state)784 mv_gpio_debounced_state_set(device_t dev, int pin, uint8_t new_state)
785 {
786 	uint32_t *old_state;
787 	struct mv_gpio_softc *sc;
788 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
789 
790 	MV_GPIO_ASSERT_LOCKED();
791 
792 	if (pin >= GPIO_PINS_PER_REG) {
793 		old_state = &sc->debounced_state_hi;
794 		pin -= GPIO_PINS_PER_REG;
795 	} else
796 		old_state = &sc->debounced_state_lo;
797 
798 	if (new_state)
799 		*old_state |= (1 << pin);
800 	else
801 		*old_state &= ~(1 << pin);
802 }
803 
804 static uint32_t
mv_gpio_debounced_state_get(device_t dev,int pin)805 mv_gpio_debounced_state_get(device_t dev, int pin)
806 {
807 	uint32_t *state;
808 	struct mv_gpio_softc *sc;
809 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
810 
811 	MV_GPIO_ASSERT_LOCKED();
812 
813 	if (pin >= GPIO_PINS_PER_REG) {
814 		state = &sc->debounced_state_hi;
815 		pin -= GPIO_PINS_PER_REG;
816 	} else
817 		state = &sc->debounced_state_lo;
818 
819 	return (*state & (1 << pin));
820 }
821 
822 void
mv_gpio_out(device_t dev,uint32_t pin,uint8_t val,uint8_t enable)823 mv_gpio_out(device_t dev, uint32_t pin, uint8_t val, uint8_t enable)
824 {
825 	struct mv_gpio_softc *sc;
826 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
827 
828 	MV_GPIO_LOCK();
829 
830 	mv_gpio_value_set(dev, pin, val);
831 	mv_gpio_out_en(dev, pin, enable);
832 
833 	MV_GPIO_UNLOCK();
834 }
835 
836 uint8_t
mv_gpio_in(device_t dev,uint32_t pin)837 mv_gpio_in(device_t dev, uint32_t pin)
838 {
839 	uint8_t state;
840 	struct mv_gpio_softc *sc;
841 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
842 
843 	MV_GPIO_ASSERT_LOCKED();
844 
845 	if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_DEBOUNCE) {
846 		if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_POL_LOW)
847 			state = (mv_gpio_debounced_state_get(dev, pin) ? 0 : 1);
848 		else
849 			state = (mv_gpio_debounced_state_get(dev, pin) ? 1 : 0);
850 	} else if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_IRQ_DOUBLE_EDGE) {
851 		if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_POL_LOW)
852 			state = (mv_gpio_value_get(dev, pin, 1) ? 0 : 1);
853 		else
854 			state = (mv_gpio_value_get(dev, pin, 1) ? 1 : 0);
855 	} else
856 		state = (mv_gpio_value_get(dev, pin, 0) ? 1 : 0);
857 
858 	return (state);
859 }
860 
861 static uint32_t
mv_gpio_reg_read(device_t dev,uint32_t reg)862 mv_gpio_reg_read(device_t dev, uint32_t reg)
863 {
864 	struct mv_gpio_softc *sc;
865 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
866 
867 	return (bus_space_read_4(sc->bst, sc->bsh, sc->offset + reg));
868 }
869 
870 static void
mv_gpio_reg_write(device_t dev,uint32_t reg,uint32_t val)871 mv_gpio_reg_write(device_t dev, uint32_t reg, uint32_t val)
872 {
873 	struct mv_gpio_softc *sc;
874 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
875 
876 	bus_space_write_4(sc->bst, sc->bsh, sc->offset + reg, val);
877 }
878 
879 static void
mv_gpio_reg_set(device_t dev,uint32_t reg,uint32_t pin)880 mv_gpio_reg_set(device_t dev, uint32_t reg, uint32_t pin)
881 {
882 	uint32_t reg_val;
883 
884 	reg_val = mv_gpio_reg_read(dev, reg);
885 	reg_val |= GPIO(pin);
886 	mv_gpio_reg_write(dev, reg, reg_val);
887 }
888 
889 static void
mv_gpio_reg_clear(device_t dev,uint32_t reg,uint32_t pin)890 mv_gpio_reg_clear(device_t dev, uint32_t reg, uint32_t pin)
891 {
892 	uint32_t reg_val;
893 
894 	reg_val = mv_gpio_reg_read(dev, reg);
895 	reg_val &= ~(GPIO(pin));
896 	mv_gpio_reg_write(dev, reg, reg_val);
897 }
898 
899 static void
mv_gpio_out_en(device_t dev,uint32_t pin,uint8_t enable)900 mv_gpio_out_en(device_t dev, uint32_t pin, uint8_t enable)
901 {
902 	uint32_t reg;
903 	struct mv_gpio_softc *sc;
904 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
905 
906 	if (pin >= sc->pin_num)
907 		return;
908 
909 	reg = GPIO_DATA_OUT_EN_CTRL;
910 
911 	if (enable)
912 		mv_gpio_reg_clear(dev, reg, pin);
913 	else
914 		mv_gpio_reg_set(dev, reg, pin);
915 }
916 
917 static void
mv_gpio_blink(device_t dev,uint32_t pin,uint8_t enable)918 mv_gpio_blink(device_t dev, uint32_t pin, uint8_t enable)
919 {
920 	uint32_t reg;
921 	struct mv_gpio_softc *sc;
922 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
923 
924 	if (pin >= sc->pin_num)
925 		return;
926 
927 	reg = GPIO_BLINK_EN;
928 
929 	if (enable)
930 		mv_gpio_reg_set(dev, reg, pin);
931 	else
932 		mv_gpio_reg_clear(dev, reg, pin);
933 }
934 
935 static void
mv_gpio_polarity(device_t dev,uint32_t pin,uint8_t enable,uint8_t toggle)936 mv_gpio_polarity(device_t dev, uint32_t pin, uint8_t enable, uint8_t toggle)
937 {
938 	uint32_t reg, reg_val;
939 	struct mv_gpio_softc *sc;
940 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
941 
942 	if (pin >= sc->pin_num)
943 		return;
944 
945 	reg = GPIO_DATA_IN_POLAR;
946 
947 	if (toggle) {
948 		reg_val = mv_gpio_reg_read(dev, reg) & GPIO(pin);
949 		if (reg_val)
950 			mv_gpio_reg_clear(dev, reg, pin);
951 		else
952 			mv_gpio_reg_set(dev, reg, pin);
953 	} else if (enable)
954 		mv_gpio_reg_set(dev, reg, pin);
955 	else
956 		mv_gpio_reg_clear(dev, reg, pin);
957 }
958 
959 static void
mv_gpio_level(device_t dev,uint32_t pin,uint8_t enable)960 mv_gpio_level(device_t dev, uint32_t pin, uint8_t enable)
961 {
962 	uint32_t reg;
963 	struct mv_gpio_softc *sc;
964 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
965 
966 	if (pin >= sc->pin_num)
967 		return;
968 
969 	reg = GPIO_INT_LEV_MASK;
970 
971 	if (enable)
972 		mv_gpio_reg_set(dev, reg, pin);
973 	else
974 		mv_gpio_reg_clear(dev, reg, pin);
975 }
976 
977 static void
mv_gpio_edge(device_t dev,uint32_t pin,uint8_t enable)978 mv_gpio_edge(device_t dev, uint32_t pin, uint8_t enable)
979 {
980 	uint32_t reg;
981 	struct mv_gpio_softc *sc;
982 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
983 
984 	if (pin >= sc->pin_num)
985 		return;
986 
987 	reg = GPIO_INT_EDGE_MASK;
988 
989 	if (enable)
990 		mv_gpio_reg_set(dev, reg, pin);
991 	else
992 		mv_gpio_reg_clear(dev, reg, pin);
993 }
994 
995 static void
mv_gpio_int_ack(struct mv_gpio_pindev * s)996 mv_gpio_int_ack(struct mv_gpio_pindev *s)
997 {
998 	uint32_t reg, pin;
999 	struct mv_gpio_softc *sc;
1000 	sc = (struct mv_gpio_softc *)device_get_softc(s->dev);
1001 	pin = s->pin;
1002 
1003 	if (pin >= sc->pin_num)
1004 		return;
1005 
1006 	reg = GPIO_INT_CAUSE;
1007 
1008 	mv_gpio_reg_clear(s->dev, reg, pin);
1009 }
1010 
1011 static uint32_t
mv_gpio_value_get(device_t dev,uint32_t pin,uint8_t exclude_polar)1012 mv_gpio_value_get(device_t dev, uint32_t pin, uint8_t exclude_polar)
1013 {
1014 	uint32_t reg, polar_reg, reg_val, polar_reg_val;
1015 	struct mv_gpio_softc *sc;
1016 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
1017 
1018 	if (pin >= sc->pin_num)
1019 		return (0);
1020 
1021 	reg = GPIO_DATA_IN;
1022 	polar_reg = GPIO_DATA_IN_POLAR;
1023 
1024 	reg_val = mv_gpio_reg_read(dev, reg);
1025 
1026 	if (exclude_polar) {
1027 		polar_reg_val = mv_gpio_reg_read(dev, polar_reg);
1028 		return ((reg_val & GPIO(pin)) ^ (polar_reg_val & GPIO(pin)));
1029 	} else
1030 		return (reg_val & GPIO(pin));
1031 }
1032 
1033 static void
mv_gpio_value_set(device_t dev,uint32_t pin,uint8_t val)1034 mv_gpio_value_set(device_t dev, uint32_t pin, uint8_t val)
1035 {
1036 	uint32_t reg;
1037 	struct mv_gpio_softc *sc;
1038 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
1039 
1040 	MV_GPIO_ASSERT_LOCKED();
1041 
1042 	if (pin >= sc->pin_num)
1043 		return;
1044 
1045 	reg = GPIO_DATA_OUT;
1046 
1047 	if (val)
1048 		mv_gpio_reg_set(dev, reg, pin);
1049 	else
1050 		mv_gpio_reg_clear(dev, reg, pin);
1051 }
1052 
1053 /*
1054  * GPIO interface methods
1055  */
1056 
1057 static int
mv_gpio_pin_max(device_t dev,int * maxpin)1058 mv_gpio_pin_max(device_t dev, int *maxpin)
1059 {
1060 	struct mv_gpio_softc *sc;
1061 	if (maxpin == NULL)
1062 		return (EINVAL);
1063 
1064 	sc = device_get_softc(dev);
1065 	*maxpin = sc->pin_num;
1066 
1067 	return (0);
1068 }
1069 
1070 static int
mv_gpio_pin_getcaps(device_t dev,uint32_t pin,uint32_t * caps)1071 mv_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
1072 {
1073 	struct mv_gpio_softc *sc = device_get_softc(dev);
1074 	if (caps == NULL)
1075 		return (EINVAL);
1076 
1077 	if (pin >= sc->pin_num)
1078 		return (EINVAL);
1079 
1080 	MV_GPIO_LOCK();
1081 	*caps = sc->gpio_setup[pin].gp_caps;
1082 	MV_GPIO_UNLOCK();
1083 
1084 	return (0);
1085 }
1086 
1087 static int
mv_gpio_pin_getflags(device_t dev,uint32_t pin,uint32_t * flags)1088 mv_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
1089 {
1090 	struct mv_gpio_softc *sc = device_get_softc(dev);
1091 	if (flags == NULL)
1092 		return (EINVAL);
1093 
1094 	if (pin >= sc->pin_num)
1095 		return (EINVAL);
1096 
1097 	MV_GPIO_LOCK();
1098 	*flags = sc->gpio_setup[pin].gp_flags;
1099 	MV_GPIO_UNLOCK();
1100 
1101 	return (0);
1102 }
1103 
1104 static int
mv_gpio_pin_getname(device_t dev,uint32_t pin,char * name)1105 mv_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
1106 {
1107 	struct mv_gpio_softc *sc = device_get_softc(dev);
1108 	if (name == NULL)
1109 		return (EINVAL);
1110 
1111 	if (pin >= sc->pin_num)
1112 		return (EINVAL);
1113 
1114 	MV_GPIO_LOCK();
1115 	memcpy(name, sc->gpio_setup[pin].gp_name, GPIOMAXNAME);
1116 	MV_GPIO_UNLOCK();
1117 
1118 	return (0);
1119 }
1120 
1121 static int
mv_gpio_pin_setflags(device_t dev,uint32_t pin,uint32_t flags)1122 mv_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
1123 {
1124 	int ret;
1125 	struct mv_gpio_softc *sc = device_get_softc(dev);
1126 	if (pin >= sc->pin_num)
1127 		return (EINVAL);
1128 
1129 	/* Check for unwanted flags. */
1130 	if ((flags & sc->gpio_setup[pin].gp_caps) != flags)
1131 		return (EINVAL);
1132 
1133 	ret = mv_gpio_configure(dev, pin, flags, ~0);
1134 
1135 	return (ret);
1136 }
1137 
1138 static int
mv_gpio_pin_set(device_t dev,uint32_t pin,unsigned int value)1139 mv_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
1140 {
1141 	struct mv_gpio_softc *sc = device_get_softc(dev);
1142 	if (pin >= sc->pin_num)
1143 		return (EINVAL);
1144 
1145 	MV_GPIO_LOCK();
1146 	mv_gpio_value_set(dev, pin, value);
1147 	MV_GPIO_UNLOCK();
1148 
1149 	return (0);
1150 }
1151 
1152 static int
mv_gpio_pin_get(device_t dev,uint32_t pin,unsigned int * value)1153 mv_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
1154 {
1155 	struct mv_gpio_softc *sc = device_get_softc(dev);
1156 	if (value == NULL)
1157 		return (EINVAL);
1158 
1159 	if (pin >= sc->pin_num)
1160 		return (EINVAL);
1161 
1162 	MV_GPIO_LOCK();
1163 	*value = mv_gpio_in(dev, pin);
1164 	MV_GPIO_UNLOCK();
1165 
1166 	return (0);
1167 }
1168 
1169 static int
mv_gpio_pin_toggle(device_t dev,uint32_t pin)1170 mv_gpio_pin_toggle(device_t dev, uint32_t pin)
1171 {
1172 	struct mv_gpio_softc *sc = device_get_softc(dev);
1173 	uint32_t value;
1174 	if (pin >= sc->pin_num)
1175 		return (EINVAL);
1176 
1177 	MV_GPIO_LOCK();
1178 	value = mv_gpio_in(dev, pin);
1179 	value = (~value) & 1;
1180 	mv_gpio_value_set(dev, pin, value);
1181 	MV_GPIO_UNLOCK();
1182 
1183 	return (0);
1184 }
1185 
1186 static device_t
mv_gpio_get_bus(device_t dev)1187 mv_gpio_get_bus(device_t dev)
1188 {
1189 	struct mv_gpio_softc *sc = device_get_softc(dev);
1190 
1191 	return (sc->sc_busdev);
1192 }
1193 
1194 static int
mv_gpio_map_gpios(device_t bus,phandle_t dev,phandle_t gparent,int gcells,pcell_t * gpios,uint32_t * pin,uint32_t * flags)1195 mv_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
1196     pcell_t *gpios, uint32_t *pin, uint32_t *flags)
1197 {
1198 	struct mv_gpio_softc *sc = device_get_softc(bus);
1199 
1200 	if (gpios[0] >= sc->pin_num)
1201 		return (EINVAL);
1202 
1203 	*pin = gpios[0];
1204 	*flags = gpios[1];
1205 	mv_gpio_configure(bus, *pin, *flags, ~0);
1206 
1207 	return (0);
1208 }
1209