xref: /freebsd/sys/arm/allwinner/aw_gpio.c (revision d5b0e70f7e04d971691517ce1304d86a1e367e2e)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org>
5  * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
6  * Copyright (c) 2012 Luiz Otavio O Souza.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  */
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/bus.h>
37 
38 #include <sys/kernel.h>
39 #include <sys/module.h>
40 #include <sys/rman.h>
41 #include <sys/lock.h>
42 #include <sys/mutex.h>
43 #include <sys/gpio.h>
44 #include <sys/proc.h>
45 
46 #include <machine/bus.h>
47 #include <machine/resource.h>
48 #include <machine/intr.h>
49 
50 #include <dev/gpio/gpiobusvar.h>
51 #include <dev/ofw/ofw_bus.h>
52 #include <dev/ofw/ofw_bus_subr.h>
53 #include <dev/fdt/fdt_pinctrl.h>
54 
55 #include <arm/allwinner/aw_machdep.h>
56 #include <arm/allwinner/allwinner_pinctrl.h>
57 #include <dev/extres/clk/clk.h>
58 #include <dev/extres/hwreset/hwreset.h>
59 #include <dev/extres/regulator/regulator.h>
60 
61 #if defined(__aarch64__)
62 #include "opt_soc.h"
63 #endif
64 
65 #include "pic_if.h"
66 #include "gpio_if.h"
67 
68 #define	AW_GPIO_DEFAULT_CAPS	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |	\
69 	  GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN);
70 
71 #define	AW_GPIO_INTR_CAPS	(GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH |	\
72 	  GPIO_INTR_EDGE_RISING | GPIO_INTR_EDGE_FALLING | GPIO_INTR_EDGE_BOTH)
73 
74 #define	AW_GPIO_NONE		0
75 #define	AW_GPIO_PULLUP		1
76 #define	AW_GPIO_PULLDOWN	2
77 
78 #define	AW_GPIO_INPUT		0
79 #define	AW_GPIO_OUTPUT		1
80 
81 #define	AW_GPIO_DRV_MASK	0x3
82 #define	AW_GPIO_PUD_MASK	0x3
83 
84 #define	AW_PINCTRL	1
85 #define	AW_R_PINCTRL	2
86 
87 struct aw_gpio_conf {
88 	struct allwinner_padconf *padconf;
89 	const char *banks;
90 };
91 
92 /* Defined in aw_padconf.c */
93 #ifdef SOC_ALLWINNER_A10
94 extern struct allwinner_padconf a10_padconf;
95 struct aw_gpio_conf a10_gpio_conf = {
96 	.padconf = &a10_padconf,
97 	.banks = "abcdefghi",
98 };
99 #endif
100 
101 /* Defined in a13_padconf.c */
102 #ifdef SOC_ALLWINNER_A13
103 extern struct allwinner_padconf a13_padconf;
104 struct aw_gpio_conf a13_gpio_conf = {
105 	.padconf = &a13_padconf,
106 	.banks = "bcdefg",
107 };
108 #endif
109 
110 /* Defined in a20_padconf.c */
111 #ifdef SOC_ALLWINNER_A20
112 extern struct allwinner_padconf a20_padconf;
113 struct aw_gpio_conf a20_gpio_conf = {
114 	.padconf = &a20_padconf,
115 	.banks = "abcdefghi",
116 };
117 #endif
118 
119 /* Defined in a31_padconf.c */
120 #ifdef SOC_ALLWINNER_A31
121 extern struct allwinner_padconf a31_padconf;
122 struct aw_gpio_conf a31_gpio_conf = {
123 	.padconf = &a31_padconf,
124 	.banks = "abcdefgh",
125 };
126 #endif
127 
128 /* Defined in a31s_padconf.c */
129 #ifdef SOC_ALLWINNER_A31S
130 extern struct allwinner_padconf a31s_padconf;
131 struct aw_gpio_conf a31s_gpio_conf = {
132 	.padconf = &a31s_padconf,
133 	.banks = "abcdefgh",
134 };
135 #endif
136 
137 #if defined(SOC_ALLWINNER_A31) || defined(SOC_ALLWINNER_A31S)
138 extern struct allwinner_padconf a31_r_padconf;
139 struct aw_gpio_conf a31_r_gpio_conf = {
140 	.padconf = &a31_r_padconf,
141 	.banks = "lm",
142 };
143 #endif
144 
145 /* Defined in a33_padconf.c */
146 #ifdef SOC_ALLWINNER_A33
147 extern struct allwinner_padconf a33_padconf;
148 struct aw_gpio_conf a33_gpio_conf = {
149 	.padconf = &a33_padconf,
150 	.banks = "bcdefgh",
151 };
152 #endif
153 
154 /* Defined in h3_padconf.c */
155 #if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5)
156 extern struct allwinner_padconf h3_padconf;
157 extern struct allwinner_padconf h3_r_padconf;
158 struct aw_gpio_conf h3_gpio_conf = {
159 	.padconf = &h3_padconf,
160 	.banks = "acdefg",
161 };
162 struct aw_gpio_conf h3_r_gpio_conf = {
163 	.padconf = &h3_r_padconf,
164 	.banks = "l",
165 };
166 #endif
167 
168 /* Defined in a83t_padconf.c */
169 #ifdef SOC_ALLWINNER_A83T
170 extern struct allwinner_padconf a83t_padconf;
171 extern struct allwinner_padconf a83t_r_padconf;
172 struct aw_gpio_conf a83t_gpio_conf = {
173 	.padconf = &a83t_padconf,
174 	.banks = "bcdefgh"
175 };
176 struct aw_gpio_conf a83t_r_gpio_conf = {
177 	.padconf = &a83t_r_padconf,
178 	.banks = "l",
179 };
180 #endif
181 
182 /* Defined in a64_padconf.c */
183 #ifdef SOC_ALLWINNER_A64
184 extern struct allwinner_padconf a64_padconf;
185 extern struct allwinner_padconf a64_r_padconf;
186 struct aw_gpio_conf a64_gpio_conf = {
187 	.padconf = &a64_padconf,
188 	.banks = "bcdefgh",
189 };
190 struct aw_gpio_conf a64_r_gpio_conf = {
191 	.padconf = &a64_r_padconf,
192 	.banks = "l",
193 };
194 #endif
195 
196 /* Defined in h6_padconf.c */
197 #ifdef SOC_ALLWINNER_H6
198 extern struct allwinner_padconf h6_padconf;
199 extern struct allwinner_padconf h6_r_padconf;
200 struct aw_gpio_conf h6_gpio_conf = {
201 	.padconf = &h6_padconf,
202 	.banks = "cdfgh",
203 };
204 struct aw_gpio_conf h6_r_gpio_conf = {
205 	.padconf = &h6_r_padconf,
206 	.banks = "lm",
207 };
208 #endif
209 
210 static struct ofw_compat_data compat_data[] = {
211 #ifdef SOC_ALLWINNER_A10
212 	{"allwinner,sun4i-a10-pinctrl",		(uintptr_t)&a10_gpio_conf},
213 #endif
214 #ifdef SOC_ALLWINNER_A13
215 	{"allwinner,sun5i-a13-pinctrl",		(uintptr_t)&a13_gpio_conf},
216 #endif
217 #ifdef SOC_ALLWINNER_A20
218 	{"allwinner,sun7i-a20-pinctrl",		(uintptr_t)&a20_gpio_conf},
219 #endif
220 #ifdef SOC_ALLWINNER_A31
221 	{"allwinner,sun6i-a31-pinctrl",		(uintptr_t)&a31_gpio_conf},
222 #endif
223 #ifdef SOC_ALLWINNER_A31S
224 	{"allwinner,sun6i-a31s-pinctrl",	(uintptr_t)&a31s_gpio_conf},
225 #endif
226 #if defined(SOC_ALLWINNER_A31) || defined(SOC_ALLWINNER_A31S)
227 	{"allwinner,sun6i-a31-r-pinctrl",	(uintptr_t)&a31_r_gpio_conf},
228 #endif
229 #ifdef SOC_ALLWINNER_A33
230 	{"allwinner,sun6i-a33-pinctrl",		(uintptr_t)&a33_gpio_conf},
231 #endif
232 #ifdef SOC_ALLWINNER_A83T
233 	{"allwinner,sun8i-a83t-pinctrl",	(uintptr_t)&a83t_gpio_conf},
234 	{"allwinner,sun8i-a83t-r-pinctrl",	(uintptr_t)&a83t_r_gpio_conf},
235 #endif
236 #if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5)
237 	{"allwinner,sun8i-h3-pinctrl",		(uintptr_t)&h3_gpio_conf},
238 	{"allwinner,sun50i-h5-pinctrl",		(uintptr_t)&h3_gpio_conf},
239 	{"allwinner,sun8i-h3-r-pinctrl",	(uintptr_t)&h3_r_gpio_conf},
240 #endif
241 #ifdef SOC_ALLWINNER_A64
242 	{"allwinner,sun50i-a64-pinctrl",	(uintptr_t)&a64_gpio_conf},
243 	{"allwinner,sun50i-a64-r-pinctrl",	(uintptr_t)&a64_r_gpio_conf},
244 #endif
245 #ifdef SOC_ALLWINNER_H6
246 	{"allwinner,sun50i-h6-pinctrl",	(uintptr_t)&h6_gpio_conf},
247 	{"allwinner,sun50i-h6-r-pinctrl",	(uintptr_t)&h6_r_gpio_conf},
248 #endif
249 	{NULL,	0}
250 };
251 
252 struct clk_list {
253 	TAILQ_ENTRY(clk_list)	next;
254 	clk_t			clk;
255 };
256 
257 struct gpio_irqsrc {
258 	struct intr_irqsrc	isrc;
259 	u_int			irq;
260 	uint32_t		mode;
261 	uint32_t		pin;
262 	uint32_t		bank;
263 	uint32_t		intnum;
264 	uint32_t		intfunc;
265 	uint32_t		oldfunc;
266 	bool			enabled;
267 };
268 
269 #define	AW_GPIO_MEMRES		0
270 #define	AW_GPIO_IRQRES		1
271 #define	AW_GPIO_RESSZ		2
272 
273 struct aw_gpio_softc {
274 	device_t		sc_dev;
275 	device_t		sc_busdev;
276 	struct resource *	sc_res[AW_GPIO_RESSZ];
277 	struct mtx		sc_mtx;
278 	struct resource *	sc_mem_res;
279 	struct resource *	sc_irq_res;
280 	void *			sc_intrhand;
281 	struct aw_gpio_conf	*conf;
282 	TAILQ_HEAD(, clk_list)		clk_list;
283 
284 	struct gpio_irqsrc 	*gpio_pic_irqsrc;
285 	int			nirqs;
286 };
287 
288 static struct resource_spec aw_gpio_res_spec[] = {
289 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
290 	{ SYS_RES_IRQ,		0,	RF_ACTIVE | RF_SHAREABLE },
291 	{ -1,			0,	0 }
292 };
293 
294 #define	AW_GPIO_LOCK(_sc)		mtx_lock_spin(&(_sc)->sc_mtx)
295 #define	AW_GPIO_UNLOCK(_sc)		mtx_unlock_spin(&(_sc)->sc_mtx)
296 #define	AW_GPIO_LOCK_ASSERT(_sc)	mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
297 
298 #define	AW_GPIO_GP_CFG(_bank, _idx)	0x00 + ((_bank) * 0x24) + ((_idx) << 2)
299 #define	AW_GPIO_GP_DAT(_bank)		0x10 + ((_bank) * 0x24)
300 #define	AW_GPIO_GP_DRV(_bank, _idx)	0x14 + ((_bank) * 0x24) + ((_idx) << 2)
301 #define	AW_GPIO_GP_PUL(_bank, _idx)	0x1c + ((_bank) * 0x24) + ((_idx) << 2)
302 
303 #define	AW_GPIO_GP_INT_BASE(_bank)	(0x200 + 0x20 * _bank)
304 
305 #define	AW_GPIO_GP_INT_CFG(_bank, _pin)	(AW_GPIO_GP_INT_BASE(_bank) + (0x4 * ((_pin) / 8)))
306 #define	AW_GPIO_GP_INT_CTL(_bank)	(AW_GPIO_GP_INT_BASE(_bank) + 0x10)
307 #define	AW_GPIO_GP_INT_STA(_bank)	(AW_GPIO_GP_INT_BASE(_bank) + 0x14)
308 #define	AW_GPIO_GP_INT_DEB(_bank)	(AW_GPIO_GP_INT_BASE(_bank) + 0x18)
309 
310 #define	AW_GPIO_INT_EDGE_POSITIVE	0x0
311 #define	AW_GPIO_INT_EDGE_NEGATIVE	0x1
312 #define	AW_GPIO_INT_LEVEL_HIGH		0x2
313 #define	AW_GPIO_INT_LEVEL_LOW		0x3
314 #define	AW_GPIO_INT_EDGE_BOTH		0x4
315 
316 static char *aw_gpio_parse_function(phandle_t node);
317 static const char **aw_gpio_parse_pins(phandle_t node, int *pins_nb);
318 static uint32_t aw_gpio_parse_bias(phandle_t node);
319 static int aw_gpio_parse_drive_strength(phandle_t node, uint32_t *drive);
320 
321 static int aw_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value);
322 static int aw_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value);
323 static int aw_gpio_pin_get_locked(struct aw_gpio_softc *sc, uint32_t pin, unsigned int *value);
324 static int aw_gpio_pin_set_locked(struct aw_gpio_softc *sc, uint32_t pin, unsigned int value);
325 
326 static void aw_gpio_intr(void *arg);
327 static void aw_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc);
328 static void aw_gpio_pic_disable_intr_locked(struct aw_gpio_softc *sc, struct intr_irqsrc *isrc);
329 static void aw_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc);
330 static int aw_gpio_register_isrcs(struct aw_gpio_softc *sc);
331 
332 #define	AW_GPIO_WRITE(_sc, _off, _val)		\
333 	bus_write_4((_sc)->sc_res[AW_GPIO_MEMRES], _off, _val)
334 #define	AW_GPIO_READ(_sc, _off)		\
335 	bus_read_4((_sc)->sc_res[AW_GPIO_MEMRES], _off)
336 
337 static uint32_t
338 aw_gpio_get_function(struct aw_gpio_softc *sc, uint32_t pin)
339 {
340 	uint32_t bank, func, offset;
341 
342 	/* Must be called with lock held. */
343 	AW_GPIO_LOCK_ASSERT(sc);
344 
345 	if (pin > sc->conf->padconf->npins)
346 		return (0);
347 	bank = sc->conf->padconf->pins[pin].port;
348 	pin = sc->conf->padconf->pins[pin].pin;
349 	offset = ((pin & 0x07) << 2);
350 
351 	func = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(bank, pin >> 3));
352 
353 	return ((func >> offset) & 0x7);
354 }
355 
356 static int
357 aw_gpio_set_function(struct aw_gpio_softc *sc, uint32_t pin, uint32_t f)
358 {
359 	uint32_t bank, data, offset;
360 
361 	/* Check if the function exists in the padconf data */
362 	if (sc->conf->padconf->pins[pin].functions[f] == NULL)
363 		return (EINVAL);
364 
365 	/* Must be called with lock held. */
366 	AW_GPIO_LOCK_ASSERT(sc);
367 
368 	bank = sc->conf->padconf->pins[pin].port;
369 	pin = sc->conf->padconf->pins[pin].pin;
370 	offset = ((pin & 0x07) << 2);
371 
372 	data = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(bank, pin >> 3));
373 	data &= ~(7 << offset);
374 	data |= (f << offset);
375 	AW_GPIO_WRITE(sc, AW_GPIO_GP_CFG(bank, pin >> 3), data);
376 
377 	return (0);
378 }
379 
380 static uint32_t
381 aw_gpio_get_pud(struct aw_gpio_softc *sc, uint32_t pin)
382 {
383 	uint32_t bank, offset, val;
384 
385 	/* Must be called with lock held. */
386 	AW_GPIO_LOCK_ASSERT(sc);
387 
388 	bank = sc->conf->padconf->pins[pin].port;
389 	pin = sc->conf->padconf->pins[pin].pin;
390 	offset = ((pin & 0x0f) << 1);
391 
392 	val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(bank, pin >> 4));
393 
394 	return ((val >> offset) & AW_GPIO_PUD_MASK);
395 }
396 
397 static void
398 aw_gpio_set_pud(struct aw_gpio_softc *sc, uint32_t pin, uint32_t state)
399 {
400 	uint32_t bank, offset, val;
401 
402 	if (aw_gpio_get_pud(sc, pin) == state)
403 		return;
404 
405 	/* Must be called with lock held. */
406 	AW_GPIO_LOCK_ASSERT(sc);
407 
408 	bank = sc->conf->padconf->pins[pin].port;
409 	pin = sc->conf->padconf->pins[pin].pin;
410 	offset = ((pin & 0x0f) << 1);
411 
412 	val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(bank, pin >> 4));
413 	val &= ~(AW_GPIO_PUD_MASK << offset);
414 	val |= (state << offset);
415 	AW_GPIO_WRITE(sc, AW_GPIO_GP_PUL(bank, pin >> 4), val);
416 }
417 
418 static uint32_t
419 aw_gpio_get_drv(struct aw_gpio_softc *sc, uint32_t pin)
420 {
421 	uint32_t bank, offset, val;
422 
423 	/* Must be called with lock held. */
424 	AW_GPIO_LOCK_ASSERT(sc);
425 
426 	bank = sc->conf->padconf->pins[pin].port;
427 	pin = sc->conf->padconf->pins[pin].pin;
428 	offset = ((pin & 0x0f) << 1);
429 
430 	val = AW_GPIO_READ(sc, AW_GPIO_GP_DRV(bank, pin >> 4));
431 
432 	return ((val >> offset) & AW_GPIO_DRV_MASK);
433 }
434 
435 static void
436 aw_gpio_set_drv(struct aw_gpio_softc *sc, uint32_t pin, uint32_t drive)
437 {
438 	uint32_t bank, offset, val;
439 
440 	if (aw_gpio_get_drv(sc, pin) == drive)
441 		return;
442 
443 	/* Must be called with lock held. */
444 	AW_GPIO_LOCK_ASSERT(sc);
445 
446 	bank = sc->conf->padconf->pins[pin].port;
447 	pin = sc->conf->padconf->pins[pin].pin;
448 	offset = ((pin & 0x0f) << 1);
449 
450 	val = AW_GPIO_READ(sc, AW_GPIO_GP_DRV(bank, pin >> 4));
451 	val &= ~(AW_GPIO_DRV_MASK << offset);
452 	val |= (drive << offset);
453 	AW_GPIO_WRITE(sc, AW_GPIO_GP_DRV(bank, pin >> 4), val);
454 }
455 
456 static int
457 aw_gpio_pin_configure(struct aw_gpio_softc *sc, uint32_t pin, uint32_t flags)
458 {
459 	u_int val;
460 	int err = 0;
461 
462 	/* Must be called with lock held. */
463 	AW_GPIO_LOCK_ASSERT(sc);
464 
465 	if (pin > sc->conf->padconf->npins)
466 		return (EINVAL);
467 
468 	/* Manage input/output. */
469 	if (flags & GPIO_PIN_INPUT) {
470 		err = aw_gpio_set_function(sc, pin, AW_GPIO_INPUT);
471 	} else if ((flags & GPIO_PIN_OUTPUT) &&
472 	    aw_gpio_get_function(sc, pin) != AW_GPIO_OUTPUT) {
473 		if (flags & GPIO_PIN_PRESET_LOW) {
474 			aw_gpio_pin_set_locked(sc, pin, 0);
475 		} else if (flags & GPIO_PIN_PRESET_HIGH) {
476 			aw_gpio_pin_set_locked(sc, pin, 1);
477 		} else {
478 			/* Read the pin and preset output to current state. */
479 			err = aw_gpio_set_function(sc, pin, AW_GPIO_INPUT);
480 			if (err == 0) {
481 				aw_gpio_pin_get_locked(sc, pin, &val);
482 				aw_gpio_pin_set_locked(sc, pin, val);
483 			}
484 		}
485 		if (err == 0)
486 			err = aw_gpio_set_function(sc, pin, AW_GPIO_OUTPUT);
487 	}
488 
489 	if (err)
490 		return (err);
491 
492 	/* Manage Pull-up/pull-down. */
493 	if (flags & GPIO_PIN_PULLUP)
494 		aw_gpio_set_pud(sc, pin, AW_GPIO_PULLUP);
495 	else if (flags & GPIO_PIN_PULLDOWN)
496 		aw_gpio_set_pud(sc, pin, AW_GPIO_PULLDOWN);
497 	else
498 		aw_gpio_set_pud(sc, pin, AW_GPIO_NONE);
499 
500 	return (0);
501 }
502 
503 static device_t
504 aw_gpio_get_bus(device_t dev)
505 {
506 	struct aw_gpio_softc *sc;
507 
508 	sc = device_get_softc(dev);
509 
510 	return (sc->sc_busdev);
511 }
512 
513 static int
514 aw_gpio_pin_max(device_t dev, int *maxpin)
515 {
516 	struct aw_gpio_softc *sc;
517 
518 	sc = device_get_softc(dev);
519 
520 	*maxpin = sc->conf->padconf->npins - 1;
521 	return (0);
522 }
523 
524 static int
525 aw_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
526 {
527 	struct aw_gpio_softc *sc;
528 
529 	sc = device_get_softc(dev);
530 	if (pin >= sc->conf->padconf->npins)
531 		return (EINVAL);
532 
533 	*caps = AW_GPIO_DEFAULT_CAPS;
534 	if (sc->conf->padconf->pins[pin].eint_func != 0)
535 		*caps |= AW_GPIO_INTR_CAPS;
536 
537 	return (0);
538 }
539 
540 static int
541 aw_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
542 {
543 	struct aw_gpio_softc *sc;
544 	uint32_t func;
545 	uint32_t pud;
546 
547 	sc = device_get_softc(dev);
548 	if (pin >= sc->conf->padconf->npins)
549 		return (EINVAL);
550 
551 	AW_GPIO_LOCK(sc);
552 	func = aw_gpio_get_function(sc, pin);
553 	switch (func) {
554 	case AW_GPIO_INPUT:
555 		*flags = GPIO_PIN_INPUT;
556 		break;
557 	case AW_GPIO_OUTPUT:
558 		*flags = GPIO_PIN_OUTPUT;
559 		break;
560 	default:
561 		*flags = 0;
562 		break;
563 	}
564 
565 	pud = aw_gpio_get_pud(sc, pin);
566 	switch (pud) {
567 	case AW_GPIO_PULLDOWN:
568 		*flags |= GPIO_PIN_PULLDOWN;
569 		break;
570 	case AW_GPIO_PULLUP:
571 		*flags |= GPIO_PIN_PULLUP;
572 		break;
573 	default:
574 		break;
575 	}
576 
577 	AW_GPIO_UNLOCK(sc);
578 
579 	return (0);
580 }
581 
582 static int
583 aw_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
584 {
585 	struct aw_gpio_softc *sc;
586 
587 	sc = device_get_softc(dev);
588 	if (pin >= sc->conf->padconf->npins)
589 		return (EINVAL);
590 
591 	snprintf(name, GPIOMAXNAME - 1, "%s",
592 	    sc->conf->padconf->pins[pin].name);
593 	name[GPIOMAXNAME - 1] = '\0';
594 
595 	return (0);
596 }
597 
598 static int
599 aw_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
600 {
601 	struct aw_gpio_softc *sc;
602 	int err;
603 
604 	sc = device_get_softc(dev);
605 	if (pin > sc->conf->padconf->npins)
606 		return (EINVAL);
607 
608 	AW_GPIO_LOCK(sc);
609 	err = aw_gpio_pin_configure(sc, pin, flags);
610 	AW_GPIO_UNLOCK(sc);
611 
612 	return (err);
613 }
614 
615 static int
616 aw_gpio_pin_set_locked(struct aw_gpio_softc *sc, uint32_t pin,
617     unsigned int value)
618 {
619 	uint32_t bank, data;
620 
621 	AW_GPIO_LOCK_ASSERT(sc);
622 
623 	if (pin > sc->conf->padconf->npins)
624 		return (EINVAL);
625 
626 	bank = sc->conf->padconf->pins[pin].port;
627 	pin = sc->conf->padconf->pins[pin].pin;
628 
629 	data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
630 	if (value)
631 		data |= (1 << pin);
632 	else
633 		data &= ~(1 << pin);
634 	AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank), data);
635 
636 	return (0);
637 }
638 
639 static int
640 aw_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
641 {
642 	struct aw_gpio_softc *sc;
643 	int ret;
644 
645 	sc = device_get_softc(dev);
646 
647 	AW_GPIO_LOCK(sc);
648 	ret = aw_gpio_pin_set_locked(sc, pin, value);
649 	AW_GPIO_UNLOCK(sc);
650 
651 	return (ret);
652 }
653 
654 static int
655 aw_gpio_pin_get_locked(struct aw_gpio_softc *sc,uint32_t pin,
656     unsigned int *val)
657 {
658 	uint32_t bank, reg_data;
659 
660 	AW_GPIO_LOCK_ASSERT(sc);
661 
662 	if (pin > sc->conf->padconf->npins)
663 		return (EINVAL);
664 
665 	bank = sc->conf->padconf->pins[pin].port;
666 	pin = sc->conf->padconf->pins[pin].pin;
667 
668 	reg_data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
669 	*val = (reg_data & (1 << pin)) ? 1 : 0;
670 
671 	return (0);
672 }
673 
674 static char *
675 aw_gpio_parse_function(phandle_t node)
676 {
677 	char *function;
678 
679 	if (OF_getprop_alloc(node, "function",
680 	    (void **)&function) != -1)
681 		return (function);
682 	if (OF_getprop_alloc(node, "allwinner,function",
683 	    (void **)&function) != -1)
684 		return (function);
685 
686 	return (NULL);
687 }
688 
689 static const char **
690 aw_gpio_parse_pins(phandle_t node, int *pins_nb)
691 {
692 	const char **pinlist;
693 
694 	*pins_nb = ofw_bus_string_list_to_array(node, "pins", &pinlist);
695 	if (*pins_nb > 0)
696 		return (pinlist);
697 
698 	*pins_nb = ofw_bus_string_list_to_array(node, "allwinner,pins",
699 	    &pinlist);
700 	if (*pins_nb > 0)
701 		return (pinlist);
702 
703 	return (NULL);
704 }
705 
706 static uint32_t
707 aw_gpio_parse_bias(phandle_t node)
708 {
709 	uint32_t bias;
710 
711 	if (OF_getencprop(node, "pull", &bias, sizeof(bias)) != -1)
712 		return (bias);
713 	if (OF_getencprop(node, "allwinner,pull", &bias, sizeof(bias)) != -1)
714 		return (bias);
715 	if (OF_hasprop(node, "bias-disable"))
716 		return (AW_GPIO_NONE);
717 	if (OF_hasprop(node, "bias-pull-up"))
718 		return (AW_GPIO_PULLUP);
719 	if (OF_hasprop(node, "bias-pull-down"))
720 		return (AW_GPIO_PULLDOWN);
721 
722 	return (AW_GPIO_NONE);
723 }
724 
725 static int
726 aw_gpio_parse_drive_strength(phandle_t node, uint32_t *drive)
727 {
728 	uint32_t drive_str;
729 
730 	if (OF_getencprop(node, "drive", drive, sizeof(*drive)) != -1)
731 		return (0);
732 	if (OF_getencprop(node, "allwinner,drive", drive, sizeof(*drive)) != -1)
733 		return (0);
734 	if (OF_getencprop(node, "drive-strength", &drive_str,
735 	    sizeof(drive_str)) != -1) {
736 		*drive = (drive_str / 10) - 1;
737 		return (0);
738 	}
739 
740 	return (1);
741 }
742 
743 static int
744 aw_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
745 {
746 	struct aw_gpio_softc *sc;
747 	int ret;
748 
749 	sc = device_get_softc(dev);
750 
751 	AW_GPIO_LOCK(sc);
752 	ret = aw_gpio_pin_get_locked(sc, pin, val);
753 	AW_GPIO_UNLOCK(sc);
754 
755 	return (ret);
756 }
757 
758 static int
759 aw_gpio_pin_toggle(device_t dev, uint32_t pin)
760 {
761 	struct aw_gpio_softc *sc;
762 	uint32_t bank, data;
763 
764 	sc = device_get_softc(dev);
765 	if (pin > sc->conf->padconf->npins)
766 		return (EINVAL);
767 
768 	bank = sc->conf->padconf->pins[pin].port;
769 	pin = sc->conf->padconf->pins[pin].pin;
770 
771 	AW_GPIO_LOCK(sc);
772 	data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
773 	if (data & (1 << pin))
774 		data &= ~(1 << pin);
775 	else
776 		data |= (1 << pin);
777 	AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank), data);
778 	AW_GPIO_UNLOCK(sc);
779 
780 	return (0);
781 }
782 
783 static int
784 aw_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins,
785     uint32_t change_pins, uint32_t *orig_pins)
786 {
787 	struct aw_gpio_softc *sc;
788 	uint32_t bank, data, pin;
789 
790 	sc = device_get_softc(dev);
791 	if (first_pin > sc->conf->padconf->npins)
792 		return (EINVAL);
793 
794 	/*
795 	 * We require that first_pin refers to the first pin in a bank, because
796 	 * this API is not about convenience, it's for making a set of pins
797 	 * change simultaneously (required) with reasonably high performance
798 	 * (desired); we need to do a read-modify-write on a single register.
799 	 */
800 	bank = sc->conf->padconf->pins[first_pin].port;
801 	pin = sc->conf->padconf->pins[first_pin].pin;
802 	if (pin != 0)
803 		return (EINVAL);
804 
805 	AW_GPIO_LOCK(sc);
806 	data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
807 	if ((clear_pins | change_pins) != 0)
808 		AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank),
809 		    (data & ~clear_pins) ^ change_pins);
810 	AW_GPIO_UNLOCK(sc);
811 
812 	if (orig_pins != NULL)
813 		*orig_pins = data;
814 
815 	return (0);
816 }
817 
818 static int
819 aw_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins,
820     uint32_t *pin_flags)
821 {
822 	struct aw_gpio_softc *sc;
823 	uint32_t pin;
824 	int err;
825 
826 	sc = device_get_softc(dev);
827 	if (first_pin > sc->conf->padconf->npins)
828 		return (EINVAL);
829 
830 	if (sc->conf->padconf->pins[first_pin].pin != 0)
831 		return (EINVAL);
832 
833 	/*
834 	 * The configuration for a bank of pins is scattered among several
835 	 * registers; we cannot g'tee to simultaneously change the state of all
836 	 * the pins in the flags array.  So just loop through the array
837 	 * configuring each pin for now.  If there was a strong need, it might
838 	 * be possible to support some limited simultaneous config, such as
839 	 * adjacent groups of 8 pins that line up the same as the config regs.
840 	 */
841 	for (err = 0, pin = first_pin; err == 0 && pin < num_pins; ++pin) {
842 		if (pin_flags[pin] & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
843 			err = aw_gpio_pin_configure(sc, pin, pin_flags[pin]);
844 	}
845 
846 	return (err);
847 }
848 
849 static int
850 aw_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
851     pcell_t *gpios, uint32_t *pin, uint32_t *flags)
852 {
853 	struct aw_gpio_softc *sc;
854 	int i;
855 
856 	sc = device_get_softc(bus);
857 
858 	/* The GPIO pins are mapped as: <gpio-phandle bank pin flags>. */
859 	for (i = 0; i < sc->conf->padconf->npins; i++)
860 		if (sc->conf->padconf->pins[i].port == gpios[0] &&
861 		    sc->conf->padconf->pins[i].pin == gpios[1]) {
862 			*pin = i;
863 			break;
864 		}
865 	*flags = gpios[gcells - 1];
866 
867 	return (0);
868 }
869 
870 static int
871 aw_find_pinnum_by_name(struct aw_gpio_softc *sc, const char *pinname)
872 {
873 	int i;
874 
875 	for (i = 0; i < sc->conf->padconf->npins; i++)
876 		if (!strcmp(pinname, sc->conf->padconf->pins[i].name))
877 			return i;
878 
879 	return (-1);
880 }
881 
882 static int
883 aw_find_pin_func(struct aw_gpio_softc *sc, int pin, const char *func)
884 {
885 	int i;
886 
887 	for (i = 0; i < AW_MAX_FUNC_BY_PIN; i++)
888 		if (sc->conf->padconf->pins[pin].functions[i] &&
889 		    !strcmp(func, sc->conf->padconf->pins[pin].functions[i]))
890 			return (i);
891 
892 	return (-1);
893 }
894 
895 static int
896 aw_fdt_configure_pins(device_t dev, phandle_t cfgxref)
897 {
898 	struct aw_gpio_softc *sc;
899 	phandle_t node;
900 	const char **pinlist = NULL;
901 	char *pin_function = NULL;
902 	uint32_t pin_drive, pin_pull;
903 	int pins_nb, pin_num, pin_func, i, ret;
904 	bool set_drive;
905 
906 	sc = device_get_softc(dev);
907 	node = OF_node_from_xref(cfgxref);
908 	ret = 0;
909 	set_drive = false;
910 
911 	/* Getting all prop for configuring pins */
912 	pinlist = aw_gpio_parse_pins(node, &pins_nb);
913 	if (pinlist == NULL)
914 		return (ENOENT);
915 
916 	pin_function = aw_gpio_parse_function(node);
917 	if (pin_function == NULL) {
918 		ret = ENOENT;
919 		goto out;
920 	}
921 
922 	if (aw_gpio_parse_drive_strength(node, &pin_drive) == 0)
923 		set_drive = true;
924 
925 	pin_pull = aw_gpio_parse_bias(node);
926 
927 	/* Configure each pin to the correct function, drive and pull */
928 	for (i = 0; i < pins_nb; i++) {
929 		pin_num = aw_find_pinnum_by_name(sc, pinlist[i]);
930 		if (pin_num == -1) {
931 			ret = ENOENT;
932 			goto out;
933 		}
934 		pin_func = aw_find_pin_func(sc, pin_num, pin_function);
935 		if (pin_func == -1) {
936 			ret = ENOENT;
937 			goto out;
938 		}
939 
940 		AW_GPIO_LOCK(sc);
941 
942 		if (aw_gpio_get_function(sc, pin_num) != pin_func)
943 			aw_gpio_set_function(sc, pin_num, pin_func);
944 		if (set_drive)
945 			aw_gpio_set_drv(sc, pin_num, pin_drive);
946 		if (pin_pull != AW_GPIO_NONE)
947 			aw_gpio_set_pud(sc, pin_num, pin_pull);
948 
949 		AW_GPIO_UNLOCK(sc);
950 	}
951 
952  out:
953 	OF_prop_free(pinlist);
954 	OF_prop_free(pin_function);
955 	return (ret);
956 }
957 
958 static void
959 aw_gpio_enable_bank_supply(void *arg)
960 {
961 	struct aw_gpio_softc *sc = arg;
962 	regulator_t vcc_supply;
963 	char bank_reg_name[16];
964 	int i, nbanks;
965 
966 	nbanks = strlen(sc->conf->banks);
967 	for (i = 0; i < nbanks; i++) {
968 		snprintf(bank_reg_name, sizeof(bank_reg_name), "vcc-p%c-supply",
969 		    sc->conf->banks[i]);
970 
971 		if (regulator_get_by_ofw_property(sc->sc_dev, 0, bank_reg_name, &vcc_supply) == 0) {
972 			if (bootverbose)
973 				device_printf(sc->sc_dev,
974 				    "Enabling regulator for gpio bank %c\n",
975 				    sc->conf->banks[i]);
976 			if (regulator_enable(vcc_supply) != 0) {
977 				device_printf(sc->sc_dev,
978 				    "Cannot enable regulator for bank %c\n",
979 				    sc->conf->banks[i]);
980 			}
981 		}
982 	}
983 }
984 
985 static int
986 aw_gpio_probe(device_t dev)
987 {
988 
989 	if (!ofw_bus_status_okay(dev))
990 		return (ENXIO);
991 
992 	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
993 		return (ENXIO);
994 
995 	device_set_desc(dev, "Allwinner GPIO/Pinmux controller");
996 	return (BUS_PROBE_DEFAULT);
997 }
998 
999 static int
1000 aw_gpio_attach(device_t dev)
1001 {
1002 	int error;
1003 	phandle_t gpio;
1004 	struct aw_gpio_softc *sc;
1005 	struct clk_list *clkp, *clkp_tmp;
1006 	clk_t clk;
1007 	hwreset_t rst = NULL;
1008 	int off, err, clkret;
1009 
1010 	sc = device_get_softc(dev);
1011 	sc->sc_dev = dev;
1012 
1013 	mtx_init(&sc->sc_mtx, "aw gpio", "gpio", MTX_SPIN);
1014 
1015 	if (bus_alloc_resources(dev, aw_gpio_res_spec, sc->sc_res) != 0) {
1016 		device_printf(dev, "cannot allocate device resources\n");
1017 		return (ENXIO);
1018 	}
1019 
1020 	if (bus_setup_intr(dev, sc->sc_res[AW_GPIO_IRQRES],
1021 	    INTR_TYPE_CLK | INTR_MPSAFE, NULL, aw_gpio_intr, sc,
1022 	    &sc->sc_intrhand)) {
1023 		device_printf(dev, "cannot setup interrupt handler\n");
1024 		goto fail;
1025 	}
1026 
1027 	/* Find our node. */
1028 	gpio = ofw_bus_get_node(sc->sc_dev);
1029 	if (!OF_hasprop(gpio, "gpio-controller"))
1030 		/* Node is not a GPIO controller. */
1031 		goto fail;
1032 
1033 	/* Use the right pin data for the current SoC */
1034 	sc->conf = (struct aw_gpio_conf *)ofw_bus_search_compatible(dev,
1035 	    compat_data)->ocd_data;
1036 
1037 	if (hwreset_get_by_ofw_idx(dev, 0, 0, &rst) == 0) {
1038 		error = hwreset_deassert(rst);
1039 		if (error != 0) {
1040 			device_printf(dev, "cannot de-assert reset\n");
1041 			goto fail;
1042 		}
1043 	}
1044 
1045 	TAILQ_INIT(&sc->clk_list);
1046 	for (off = 0, clkret = 0; clkret == 0; off++) {
1047 		clkret = clk_get_by_ofw_index(dev, 0, off, &clk);
1048 		if (clkret != 0)
1049 			break;
1050 		err = clk_enable(clk);
1051 		if (err != 0) {
1052 			device_printf(dev, "Could not enable clock %s\n",
1053 			    clk_get_name(clk));
1054 			goto fail;
1055 		}
1056 		clkp = malloc(sizeof(*clkp), M_DEVBUF, M_WAITOK | M_ZERO);
1057 		clkp->clk = clk;
1058 		TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next);
1059 	}
1060 	if (clkret != 0 && clkret != ENOENT) {
1061 		device_printf(dev, "Could not find clock at offset %d (%d)\n",
1062 		    off, clkret);
1063 		goto fail;
1064 	}
1065 
1066 	aw_gpio_register_isrcs(sc);
1067 	intr_pic_register(dev, OF_xref_from_node(ofw_bus_get_node(dev)));
1068 
1069 	sc->sc_busdev = gpiobus_attach_bus(dev);
1070 	if (sc->sc_busdev == NULL)
1071 		goto fail;
1072 
1073 	/*
1074 	 * Register as a pinctrl device
1075 	 */
1076 	fdt_pinctrl_register(dev, "pins");
1077 	fdt_pinctrl_configure_tree(dev);
1078 	fdt_pinctrl_register(dev, "allwinner,pins");
1079 	fdt_pinctrl_configure_tree(dev);
1080 
1081 	config_intrhook_oneshot(aw_gpio_enable_bank_supply, sc);
1082 
1083 	return (0);
1084 
1085 fail:
1086 	if (sc->sc_irq_res)
1087 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
1088 	if (sc->sc_mem_res)
1089 		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
1090 	mtx_destroy(&sc->sc_mtx);
1091 
1092 	/* Disable clock */
1093 	TAILQ_FOREACH_SAFE(clkp, &sc->clk_list, next, clkp_tmp) {
1094 		err = clk_disable(clkp->clk);
1095 		if (err != 0)
1096 			device_printf(dev, "Could not disable clock %s\n",
1097 			    clk_get_name(clkp->clk));
1098 		err = clk_release(clkp->clk);
1099 		if (err != 0)
1100 			device_printf(dev, "Could not release clock %s\n",
1101 			    clk_get_name(clkp->clk));
1102 		TAILQ_REMOVE(&sc->clk_list, clkp, next);
1103 		free(clkp, M_DEVBUF);
1104 	}
1105 
1106 	/* Assert resets */
1107 	if (rst) {
1108 		hwreset_assert(rst);
1109 		hwreset_release(rst);
1110 	}
1111 
1112 	return (ENXIO);
1113 }
1114 
1115 static int
1116 aw_gpio_detach(device_t dev)
1117 {
1118 
1119 	return (EBUSY);
1120 }
1121 
1122 static void
1123 aw_gpio_intr(void *arg)
1124 {
1125 	struct aw_gpio_softc *sc;
1126 	struct intr_irqsrc *isrc;
1127 	uint32_t reg;
1128 	int irq;
1129 
1130 	sc = (struct aw_gpio_softc *)arg;
1131 
1132 	AW_GPIO_LOCK(sc);
1133 	for (irq = 0; irq < sc->nirqs; irq++) {
1134 		if (!sc->gpio_pic_irqsrc[irq].enabled)
1135 			continue;
1136 
1137 		reg = AW_GPIO_READ(sc, AW_GPIO_GP_INT_STA(sc->gpio_pic_irqsrc[irq].bank));
1138 		if (!(reg & (1 << sc->gpio_pic_irqsrc[irq].intnum)))
1139 			continue;
1140 
1141 		isrc = &sc->gpio_pic_irqsrc[irq].isrc;
1142 		if (intr_isrc_dispatch(isrc, curthread->td_intr_frame) != 0) {
1143 			aw_gpio_pic_disable_intr_locked(sc, isrc);
1144 			aw_gpio_pic_post_filter(sc->sc_dev, isrc);
1145 			device_printf(sc->sc_dev, "Stray irq %u disabled\n", irq);
1146 		}
1147 	}
1148 	AW_GPIO_UNLOCK(sc);
1149 }
1150 
1151 /*
1152  * Interrupts support
1153  */
1154 
1155 static int
1156 aw_gpio_register_isrcs(struct aw_gpio_softc *sc)
1157 {
1158 	const char *name;
1159 	int nirqs;
1160 	int pin;
1161 	int err;
1162 
1163 	name = device_get_nameunit(sc->sc_dev);
1164 
1165 	for (nirqs = 0, pin = 0; pin < sc->conf->padconf->npins; pin++) {
1166 		if (sc->conf->padconf->pins[pin].eint_func == 0)
1167 			continue;
1168 
1169 		nirqs++;
1170 	}
1171 
1172 	sc->gpio_pic_irqsrc = malloc(sizeof(*sc->gpio_pic_irqsrc) * nirqs,
1173 	    M_DEVBUF, M_WAITOK | M_ZERO);
1174 	for (nirqs = 0, pin = 0; pin < sc->conf->padconf->npins; pin++) {
1175 		if (sc->conf->padconf->pins[pin].eint_func == 0)
1176 			continue;
1177 
1178 		sc->gpio_pic_irqsrc[nirqs].pin = pin;
1179 		sc->gpio_pic_irqsrc[nirqs].bank = sc->conf->padconf->pins[pin].eint_bank;
1180 		sc->gpio_pic_irqsrc[nirqs].intnum = sc->conf->padconf->pins[pin].eint_num;
1181 		sc->gpio_pic_irqsrc[nirqs].intfunc = sc->conf->padconf->pins[pin].eint_func;
1182 		sc->gpio_pic_irqsrc[nirqs].irq = nirqs;
1183 		sc->gpio_pic_irqsrc[nirqs].mode = GPIO_INTR_CONFORM;
1184 
1185 		err = intr_isrc_register(&sc->gpio_pic_irqsrc[nirqs].isrc,
1186 		    sc->sc_dev, 0, "%s,%s", name,
1187 		    sc->conf->padconf->pins[pin].functions[sc->conf->padconf->pins[pin].eint_func]);
1188 		if (err) {
1189 			device_printf(sc->sc_dev, "intr_isrs_register failed for irq %d\n", nirqs);
1190 		}
1191 
1192 		nirqs++;
1193 	}
1194 
1195 	sc->nirqs = nirqs;
1196 
1197 	return (0);
1198 }
1199 
1200 static void
1201 aw_gpio_pic_disable_intr_locked(struct aw_gpio_softc *sc, struct intr_irqsrc *isrc)
1202 {
1203 	u_int irq;
1204 	uint32_t reg;
1205 
1206 	AW_GPIO_LOCK_ASSERT(sc);
1207 	irq = ((struct gpio_irqsrc *)isrc)->irq;
1208 	reg = AW_GPIO_READ(sc, AW_GPIO_GP_INT_CTL(sc->gpio_pic_irqsrc[irq].bank));
1209 	reg &= ~(1 << sc->gpio_pic_irqsrc[irq].intnum);
1210 	AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_CTL(sc->gpio_pic_irqsrc[irq].bank), reg);
1211 
1212 	sc->gpio_pic_irqsrc[irq].enabled = false;
1213 }
1214 
1215 static void
1216 aw_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
1217 {
1218 	struct aw_gpio_softc *sc;
1219 
1220 	sc = device_get_softc(dev);
1221 
1222 	AW_GPIO_LOCK(sc);
1223 	aw_gpio_pic_disable_intr_locked(sc, isrc);
1224 	AW_GPIO_UNLOCK(sc);
1225 }
1226 
1227 static void
1228 aw_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
1229 {
1230 	struct aw_gpio_softc *sc;
1231 	u_int irq;
1232 	uint32_t reg;
1233 
1234 	sc = device_get_softc(dev);
1235 	irq = ((struct gpio_irqsrc *)isrc)->irq;
1236 	AW_GPIO_LOCK(sc);
1237 	reg = AW_GPIO_READ(sc, AW_GPIO_GP_INT_CTL(sc->gpio_pic_irqsrc[irq].bank));
1238 	reg |= 1 << sc->gpio_pic_irqsrc[irq].intnum;
1239 	AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_CTL(sc->gpio_pic_irqsrc[irq].bank), reg);
1240 	AW_GPIO_UNLOCK(sc);
1241 
1242 	sc->gpio_pic_irqsrc[irq].enabled = true;
1243 }
1244 
1245 static int
1246 aw_gpio_pic_map_gpio(struct aw_gpio_softc *sc, struct intr_map_data_gpio *dag,
1247     u_int *irqp, u_int *mode)
1248 {
1249 	u_int irq;
1250 	int pin;
1251 
1252 	irq = dag->gpio_pin_num;
1253 
1254 	for (pin = 0; pin < sc->nirqs; pin++)
1255 		if (sc->gpio_pic_irqsrc[pin].pin == irq)
1256 			break;
1257 	if (pin == sc->nirqs) {
1258 		device_printf(sc->sc_dev, "Invalid interrupt number %u\n", irq);
1259 		return (EINVAL);
1260 	}
1261 
1262 	switch (dag->gpio_intr_mode) {
1263 	case GPIO_INTR_LEVEL_LOW:
1264 	case GPIO_INTR_LEVEL_HIGH:
1265 	case GPIO_INTR_EDGE_RISING:
1266 	case GPIO_INTR_EDGE_FALLING:
1267 	case GPIO_INTR_EDGE_BOTH:
1268 		break;
1269 	default:
1270 		device_printf(sc->sc_dev, "Unsupported interrupt mode 0x%8x\n",
1271 		    dag->gpio_intr_mode);
1272 		return (EINVAL);
1273 	}
1274 
1275 	*irqp = pin;
1276 	if (mode != NULL)
1277 		*mode = dag->gpio_intr_mode;
1278 
1279 	return (0);
1280 }
1281 
1282 static int
1283 aw_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
1284     struct intr_irqsrc **isrcp)
1285 {
1286 	struct aw_gpio_softc *sc;
1287 	u_int irq;
1288 	int err;
1289 
1290 	sc = device_get_softc(dev);
1291 	switch (data->type) {
1292 	case INTR_MAP_DATA_GPIO:
1293 		err = aw_gpio_pic_map_gpio(sc,
1294 		    (struct intr_map_data_gpio *)data,
1295 		  &irq, NULL);
1296 		break;
1297 	default:
1298 		return (ENOTSUP);
1299 	};
1300 
1301 	if (err == 0)
1302 		*isrcp = &sc->gpio_pic_irqsrc[irq].isrc;
1303 	return (0);
1304 }
1305 
1306 static int
1307 aw_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
1308     struct resource *res, struct intr_map_data *data)
1309 {
1310 	struct aw_gpio_softc *sc;
1311 	uint32_t irqcfg;
1312 	uint32_t pinidx, reg;
1313 	u_int irq, mode;
1314 	int err;
1315 
1316 	sc = device_get_softc(dev);
1317 
1318 	err = 0;
1319 	switch (data->type) {
1320 	case INTR_MAP_DATA_GPIO:
1321 		err = aw_gpio_pic_map_gpio(sc,
1322 		    (struct intr_map_data_gpio *)data,
1323 		  &irq, &mode);
1324 		if (err != 0)
1325 			return (err);
1326 		break;
1327 	default:
1328 		return (ENOTSUP);
1329 	};
1330 
1331 	pinidx = (sc->gpio_pic_irqsrc[irq].intnum % 8) * 4;
1332 
1333 	AW_GPIO_LOCK(sc);
1334 	switch (mode) {
1335 	case GPIO_INTR_LEVEL_LOW:
1336 		irqcfg = AW_GPIO_INT_LEVEL_LOW << pinidx;
1337 		break;
1338 	case GPIO_INTR_LEVEL_HIGH:
1339 		irqcfg = AW_GPIO_INT_LEVEL_HIGH << pinidx;
1340 		break;
1341 	case GPIO_INTR_EDGE_RISING:
1342 		irqcfg = AW_GPIO_INT_EDGE_POSITIVE << pinidx;
1343 		break;
1344 	case GPIO_INTR_EDGE_FALLING:
1345 		irqcfg = AW_GPIO_INT_EDGE_NEGATIVE << pinidx;
1346 		break;
1347 	case GPIO_INTR_EDGE_BOTH:
1348 		irqcfg = AW_GPIO_INT_EDGE_BOTH << pinidx;
1349 		break;
1350 	}
1351 
1352 	/* Switch the pin to interrupt mode */
1353 	sc->gpio_pic_irqsrc[irq].oldfunc = aw_gpio_get_function(sc,
1354 	    sc->gpio_pic_irqsrc[irq].pin);
1355 	aw_gpio_set_function(sc, sc->gpio_pic_irqsrc[irq].pin,
1356 	    sc->gpio_pic_irqsrc[irq].intfunc);
1357 
1358 	/* Write interrupt mode */
1359 	reg = AW_GPIO_READ(sc,
1360 	    AW_GPIO_GP_INT_CFG(sc->gpio_pic_irqsrc[irq].bank,
1361 	    sc->gpio_pic_irqsrc[irq].intnum));
1362 	reg &= ~(0xF << pinidx);
1363 	reg |= irqcfg;
1364 	AW_GPIO_WRITE(sc,
1365 	    AW_GPIO_GP_INT_CFG(sc->gpio_pic_irqsrc[irq].bank,
1366 	    sc->gpio_pic_irqsrc[irq].intnum),
1367 	    reg);
1368 
1369 	AW_GPIO_UNLOCK(sc);
1370 
1371 	return (0);
1372 }
1373 
1374 static int
1375 aw_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
1376     struct resource *res, struct intr_map_data *data)
1377 {
1378 	struct aw_gpio_softc *sc;
1379 	struct gpio_irqsrc *gi;
1380 
1381 	sc = device_get_softc(dev);
1382 	gi = (struct gpio_irqsrc *)isrc;
1383 
1384 	/* Switch back the pin to it's original function */
1385 	AW_GPIO_LOCK(sc);
1386 	aw_gpio_set_function(sc, gi->pin, gi->oldfunc);
1387 	AW_GPIO_UNLOCK(sc);
1388 
1389 	return (0);
1390 }
1391 
1392 static void
1393 aw_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc)
1394 {
1395 	struct aw_gpio_softc *sc;
1396 	struct gpio_irqsrc *gi;
1397 
1398 	sc = device_get_softc(dev);
1399 	gi = (struct gpio_irqsrc *)isrc;
1400 
1401 	arm_irq_memory_barrier(0);
1402 	AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_STA(gi->bank), 1 << gi->intnum);
1403 }
1404 
1405 static void
1406 aw_gpio_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
1407 {
1408 	struct aw_gpio_softc *sc;
1409 	struct gpio_irqsrc *gi;
1410 
1411 	sc = device_get_softc(dev);
1412 	gi = (struct gpio_irqsrc *)isrc;
1413 
1414 	arm_irq_memory_barrier(0);
1415 	AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_STA(gi->bank), 1 << gi->intnum);
1416 	aw_gpio_pic_enable_intr(dev, isrc);
1417 }
1418 
1419 static void
1420 aw_gpio_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
1421 {
1422 	struct aw_gpio_softc *sc;
1423 
1424 	sc = device_get_softc(dev);
1425 	aw_gpio_pic_disable_intr_locked(sc, isrc);
1426 }
1427 
1428 /*
1429  * OFWBUS Interface
1430  */
1431 static phandle_t
1432 aw_gpio_get_node(device_t dev, device_t bus)
1433 {
1434 
1435 	/* We only have one child, the GPIO bus, which needs our own node. */
1436 	return (ofw_bus_get_node(dev));
1437 }
1438 
1439 static device_method_t aw_gpio_methods[] = {
1440 	/* Device interface */
1441 	DEVMETHOD(device_probe,		aw_gpio_probe),
1442 	DEVMETHOD(device_attach,	aw_gpio_attach),
1443 	DEVMETHOD(device_detach,	aw_gpio_detach),
1444 
1445 	/* Interrupt controller interface */
1446 	DEVMETHOD(pic_disable_intr,	aw_gpio_pic_disable_intr),
1447 	DEVMETHOD(pic_enable_intr,	aw_gpio_pic_enable_intr),
1448 	DEVMETHOD(pic_map_intr,		aw_gpio_pic_map_intr),
1449 	DEVMETHOD(pic_setup_intr,	aw_gpio_pic_setup_intr),
1450 	DEVMETHOD(pic_teardown_intr,	aw_gpio_pic_teardown_intr),
1451 	DEVMETHOD(pic_post_filter,	aw_gpio_pic_post_filter),
1452 	DEVMETHOD(pic_post_ithread,	aw_gpio_pic_post_ithread),
1453 	DEVMETHOD(pic_pre_ithread,	aw_gpio_pic_pre_ithread),
1454 
1455 	/* GPIO protocol */
1456 	DEVMETHOD(gpio_get_bus,		aw_gpio_get_bus),
1457 	DEVMETHOD(gpio_pin_max,		aw_gpio_pin_max),
1458 	DEVMETHOD(gpio_pin_getname,	aw_gpio_pin_getname),
1459 	DEVMETHOD(gpio_pin_getflags,	aw_gpio_pin_getflags),
1460 	DEVMETHOD(gpio_pin_getcaps,	aw_gpio_pin_getcaps),
1461 	DEVMETHOD(gpio_pin_setflags,	aw_gpio_pin_setflags),
1462 	DEVMETHOD(gpio_pin_get,		aw_gpio_pin_get),
1463 	DEVMETHOD(gpio_pin_set,		aw_gpio_pin_set),
1464 	DEVMETHOD(gpio_pin_toggle,	aw_gpio_pin_toggle),
1465 	DEVMETHOD(gpio_pin_access_32,	aw_gpio_pin_access_32),
1466 	DEVMETHOD(gpio_pin_config_32,	aw_gpio_pin_config_32),
1467 	DEVMETHOD(gpio_map_gpios,	aw_gpio_map_gpios),
1468 
1469 	/* ofw_bus interface */
1470 	DEVMETHOD(ofw_bus_get_node,	aw_gpio_get_node),
1471 
1472         /* fdt_pinctrl interface */
1473 	DEVMETHOD(fdt_pinctrl_configure,aw_fdt_configure_pins),
1474 
1475 	DEVMETHOD_END
1476 };
1477 
1478 static driver_t aw_gpio_driver = {
1479 	"gpio",
1480 	aw_gpio_methods,
1481 	sizeof(struct aw_gpio_softc),
1482 };
1483 
1484 EARLY_DRIVER_MODULE(aw_gpio, simplebus, aw_gpio_driver, 0, 0,
1485     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
1486