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