]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/broadcom/bcm2835/bcm2835_gpio.c
Merge OpenSSL 1.0.1k.
[FreeBSD/FreeBSD.git] / sys / arm / broadcom / bcm2835 / bcm2835_gpio.c
1 /*-
2  * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
3  * Copyright (c) 2012 Luiz Otavio O Souza.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  */
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/bus.h>
34
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/rman.h>
38 #include <sys/lock.h>
39 #include <sys/mutex.h>
40 #include <sys/gpio.h>
41 #include <sys/sysctl.h>
42
43 #include <machine/bus.h>
44 #include <machine/cpu.h>
45 #include <machine/cpufunc.h>
46 #include <machine/resource.h>
47 #include <machine/fdt.h>
48 #include <machine/intr.h>
49
50 #include <dev/fdt/fdt_common.h>
51 #include <dev/ofw/ofw_bus.h>
52 #include <dev/ofw/ofw_bus_subr.h>
53
54 #include <arm/broadcom/bcm2835/bcm2835_gpio.h>
55
56 #include "gpio_if.h"
57
58 #ifdef DEBUG
59 #define dprintf(fmt, args...) do { printf("%s(): ", __func__);   \
60     printf(fmt,##args); } while (0)
61 #else
62 #define dprintf(fmt, args...)
63 #endif
64
65 #define BCM_GPIO_PINS           54
66 #define BCM_GPIO_DEFAULT_CAPS   (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |     \
67     GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)
68
69 struct bcm_gpio_sysctl {
70         struct bcm_gpio_softc   *sc;
71         uint32_t                pin;
72 };
73
74 struct bcm_gpio_softc {
75         device_t                sc_dev;
76         struct mtx              sc_mtx;
77         struct resource *       sc_mem_res;
78         struct resource *       sc_irq_res;
79         bus_space_tag_t         sc_bst;
80         bus_space_handle_t      sc_bsh;
81         void *                  sc_intrhand;
82         int                     sc_gpio_npins;
83         int                     sc_ro_npins;
84         int                     sc_ro_pins[BCM_GPIO_PINS];
85         struct gpio_pin         sc_gpio_pins[BCM_GPIO_PINS];
86         struct bcm_gpio_sysctl  sc_sysctl[BCM_GPIO_PINS];
87 };
88
89 enum bcm_gpio_pud {
90         BCM_GPIO_NONE,
91         BCM_GPIO_PULLDOWN,
92         BCM_GPIO_PULLUP,
93 };
94
95 #define BCM_GPIO_LOCK(_sc)      mtx_lock(&_sc->sc_mtx)
96 #define BCM_GPIO_UNLOCK(_sc)    mtx_unlock(&_sc->sc_mtx)
97 #define BCM_GPIO_LOCK_ASSERT(_sc)       mtx_assert(&_sc->sc_mtx, MA_OWNED)
98
99 #define BCM_GPIO_GPFSEL(_bank)  0x00 + _bank * 4
100 #define BCM_GPIO_GPSET(_bank)   0x1c + _bank * 4
101 #define BCM_GPIO_GPCLR(_bank)   0x28 + _bank * 4
102 #define BCM_GPIO_GPLEV(_bank)   0x34 + _bank * 4
103 #define BCM_GPIO_GPPUD(_bank)   0x94
104 #define BCM_GPIO_GPPUDCLK(_bank)        0x98 + _bank * 4
105
106 #define BCM_GPIO_WRITE(_sc, _off, _val)         \
107     bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val)
108 #define BCM_GPIO_READ(_sc, _off)                \
109     bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off)
110
111 static int
112 bcm_gpio_pin_is_ro(struct bcm_gpio_softc *sc, int pin)
113 {
114         int i;
115
116         for (i = 0; i < sc->sc_ro_npins; i++)
117                 if (pin == sc->sc_ro_pins[i])
118                         return (1);
119         return (0);
120 }
121
122 static uint32_t
123 bcm_gpio_get_function(struct bcm_gpio_softc *sc, uint32_t pin)
124 {
125         uint32_t bank, func, offset;
126
127         /* Five banks, 10 pins per bank, 3 bits per pin. */
128         bank = pin / 10;
129         offset = (pin - bank * 10) * 3;
130
131         BCM_GPIO_LOCK(sc);
132         func = (BCM_GPIO_READ(sc, BCM_GPIO_GPFSEL(bank)) >> offset) & 7;
133         BCM_GPIO_UNLOCK(sc);
134
135         return (func);
136 }
137
138 static void
139 bcm_gpio_func_str(uint32_t nfunc, char *buf, int bufsize)
140 {
141
142         switch (nfunc) {
143         case BCM_GPIO_INPUT:
144                 strncpy(buf, "input", bufsize);
145                 break;
146         case BCM_GPIO_OUTPUT:
147                 strncpy(buf, "output", bufsize);
148                 break;
149         case BCM_GPIO_ALT0:
150                 strncpy(buf, "alt0", bufsize);
151                 break;
152         case BCM_GPIO_ALT1:
153                 strncpy(buf, "alt1", bufsize);
154                 break;
155         case BCM_GPIO_ALT2:
156                 strncpy(buf, "alt2", bufsize);
157                 break;
158         case BCM_GPIO_ALT3:
159                 strncpy(buf, "alt3", bufsize);
160                 break;
161         case BCM_GPIO_ALT4:
162                 strncpy(buf, "alt4", bufsize);
163                 break;
164         case BCM_GPIO_ALT5:
165                 strncpy(buf, "alt5", bufsize);
166                 break;
167         default:
168                 strncpy(buf, "invalid", bufsize);
169         }
170 }
171
172 static int
173 bcm_gpio_str_func(char *func, uint32_t *nfunc)
174 {
175
176         if (strcasecmp(func, "input") == 0)
177                 *nfunc = BCM_GPIO_INPUT;
178         else if (strcasecmp(func, "output") == 0)
179                 *nfunc = BCM_GPIO_OUTPUT;
180         else if (strcasecmp(func, "alt0") == 0)
181                 *nfunc = BCM_GPIO_ALT0;
182         else if (strcasecmp(func, "alt1") == 0)
183                 *nfunc = BCM_GPIO_ALT1;
184         else if (strcasecmp(func, "alt2") == 0)
185                 *nfunc = BCM_GPIO_ALT2;
186         else if (strcasecmp(func, "alt3") == 0)
187                 *nfunc = BCM_GPIO_ALT3;
188         else if (strcasecmp(func, "alt4") == 0)
189                 *nfunc = BCM_GPIO_ALT4;
190         else if (strcasecmp(func, "alt5") == 0)
191                 *nfunc = BCM_GPIO_ALT5;
192         else
193                 return (-1);
194
195         return (0);
196 }
197
198 static uint32_t
199 bcm_gpio_func_flag(uint32_t nfunc)
200 {
201
202         switch (nfunc) {
203         case BCM_GPIO_INPUT:
204                 return (GPIO_PIN_INPUT);
205         case BCM_GPIO_OUTPUT:
206                 return (GPIO_PIN_OUTPUT);
207         }
208         return (0);
209 }
210
211 static void
212 bcm_gpio_set_function(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t f)
213 {
214         uint32_t bank, data, offset;
215
216         /* Must be called with lock held. */
217         BCM_GPIO_LOCK_ASSERT(sc);
218
219         /* Five banks, 10 pins per bank, 3 bits per pin. */
220         bank = pin / 10;
221         offset = (pin - bank * 10) * 3;
222
223         data = BCM_GPIO_READ(sc, BCM_GPIO_GPFSEL(bank));
224         data &= ~(7 << offset);
225         data |= (f << offset);
226         BCM_GPIO_WRITE(sc, BCM_GPIO_GPFSEL(bank), data);
227 }
228
229 static void
230 bcm_gpio_set_pud(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t state)
231 {
232         uint32_t bank, offset;
233
234         /* Must be called with lock held. */
235         BCM_GPIO_LOCK_ASSERT(sc);
236
237         bank = pin / 32;
238         offset = pin - 32 * bank;
239
240         BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUD(0), state);
241         BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), (1 << offset));
242         BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUD(0), 0);
243         BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), 0);
244 }
245
246 void
247 bcm_gpio_set_alternate(device_t dev, uint32_t pin, uint32_t nfunc)
248 {
249         struct bcm_gpio_softc *sc;
250         int i;
251
252         sc = device_get_softc(dev);
253         BCM_GPIO_LOCK(sc);
254
255         /* Disable pull-up or pull-down on pin. */
256         bcm_gpio_set_pud(sc, pin, BCM_GPIO_NONE);
257
258         /* And now set the pin function. */
259         bcm_gpio_set_function(sc, pin, nfunc);
260
261         /* Update the pin flags. */
262         for (i = 0; i < sc->sc_gpio_npins; i++) {
263                 if (sc->sc_gpio_pins[i].gp_pin == pin)
264                         break;
265         }
266         if (i < sc->sc_gpio_npins)
267                 sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(nfunc);
268
269         BCM_GPIO_UNLOCK(sc);
270 }
271
272 static void
273 bcm_gpio_pin_configure(struct bcm_gpio_softc *sc, struct gpio_pin *pin,
274     unsigned int flags)
275 {
276
277         BCM_GPIO_LOCK(sc);
278
279         /*
280          * Manage input/output.
281          */
282         if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
283                 pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
284                 if (flags & GPIO_PIN_OUTPUT) {
285                         pin->gp_flags |= GPIO_PIN_OUTPUT;
286                         bcm_gpio_set_function(sc, pin->gp_pin,
287                             BCM_GPIO_OUTPUT);
288                 } else {
289                         pin->gp_flags |= GPIO_PIN_INPUT;
290                         bcm_gpio_set_function(sc, pin->gp_pin,
291                             BCM_GPIO_INPUT);
292                 }
293         }
294
295         /* Manage Pull-up/pull-down. */
296         pin->gp_flags &= ~(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN);
297         if (flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) {
298                 if (flags & GPIO_PIN_PULLUP) {
299                         pin->gp_flags |= GPIO_PIN_PULLUP;
300                         bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_PULLUP);
301                 } else {
302                         pin->gp_flags |= GPIO_PIN_PULLDOWN;
303                         bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_PULLDOWN);
304                 }
305         } else 
306                 bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_NONE);
307
308         BCM_GPIO_UNLOCK(sc);
309 }
310
311 static int
312 bcm_gpio_pin_max(device_t dev, int *maxpin)
313 {
314
315         *maxpin = BCM_GPIO_PINS - 1;
316         return (0);
317 }
318
319 static int
320 bcm_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
321 {
322         struct bcm_gpio_softc *sc = device_get_softc(dev);
323         int i;
324
325         for (i = 0; i < sc->sc_gpio_npins; i++) {
326                 if (sc->sc_gpio_pins[i].gp_pin == pin)
327                         break;
328         }
329
330         if (i >= sc->sc_gpio_npins)
331                 return (EINVAL);
332
333         BCM_GPIO_LOCK(sc);
334         *caps = sc->sc_gpio_pins[i].gp_caps;
335         BCM_GPIO_UNLOCK(sc);
336
337         return (0);
338 }
339
340 static int
341 bcm_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
342 {
343         struct bcm_gpio_softc *sc = device_get_softc(dev);
344         int i;
345
346         for (i = 0; i < sc->sc_gpio_npins; i++) {
347                 if (sc->sc_gpio_pins[i].gp_pin == pin)
348                         break;
349         }
350
351         if (i >= sc->sc_gpio_npins)
352                 return (EINVAL);
353
354         BCM_GPIO_LOCK(sc);
355         *flags = sc->sc_gpio_pins[i].gp_flags;
356         BCM_GPIO_UNLOCK(sc);
357
358         return (0);
359 }
360
361 static int
362 bcm_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
363 {
364         struct bcm_gpio_softc *sc = device_get_softc(dev);
365         int i;
366
367         for (i = 0; i < sc->sc_gpio_npins; i++) {
368                 if (sc->sc_gpio_pins[i].gp_pin == pin)
369                         break;
370         }
371
372         if (i >= sc->sc_gpio_npins)
373                 return (EINVAL);
374
375         BCM_GPIO_LOCK(sc);
376         memcpy(name, sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME);
377         BCM_GPIO_UNLOCK(sc);
378
379         return (0);
380 }
381
382 static int
383 bcm_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
384 {
385         struct bcm_gpio_softc *sc = device_get_softc(dev);
386         int i;
387
388         for (i = 0; i < sc->sc_gpio_npins; i++) {
389                 if (sc->sc_gpio_pins[i].gp_pin == pin)
390                         break;
391         }
392
393         if (i >= sc->sc_gpio_npins)
394                 return (EINVAL);
395
396         /* We never touch on read-only/reserved pins. */
397         if (bcm_gpio_pin_is_ro(sc, pin))
398                 return (EINVAL);
399
400         bcm_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
401
402         return (0);
403 }
404
405 static int
406 bcm_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
407 {
408         struct bcm_gpio_softc *sc = device_get_softc(dev);
409         uint32_t bank, offset;
410         int i;
411
412         for (i = 0; i < sc->sc_gpio_npins; i++) {
413                 if (sc->sc_gpio_pins[i].gp_pin == pin)
414                         break;
415         }
416
417         if (i >= sc->sc_gpio_npins)
418                 return (EINVAL);
419
420         /* We never write to read-only/reserved pins. */
421         if (bcm_gpio_pin_is_ro(sc, pin))
422                 return (EINVAL);
423
424         bank = pin / 32;
425         offset = pin - 32 * bank;
426
427         BCM_GPIO_LOCK(sc);
428         if (value)
429                 BCM_GPIO_WRITE(sc, BCM_GPIO_GPSET(bank), (1 << offset));
430         else
431                 BCM_GPIO_WRITE(sc, BCM_GPIO_GPCLR(bank), (1 << offset));
432         BCM_GPIO_UNLOCK(sc);
433
434         return (0);
435 }
436
437 static int
438 bcm_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
439 {
440         struct bcm_gpio_softc *sc = device_get_softc(dev);
441         uint32_t bank, offset, reg_data;
442         int i;
443
444         for (i = 0; i < sc->sc_gpio_npins; i++) {
445                 if (sc->sc_gpio_pins[i].gp_pin == pin)
446                         break;
447         }
448
449         if (i >= sc->sc_gpio_npins)
450                 return (EINVAL);
451
452         bank = pin / 32;
453         offset = pin - 32 * bank;
454
455         BCM_GPIO_LOCK(sc);
456         reg_data = BCM_GPIO_READ(sc, BCM_GPIO_GPLEV(bank));
457         BCM_GPIO_UNLOCK(sc);
458         *val = (reg_data & (1 << offset)) ? 1 : 0;
459
460         return (0);
461 }
462
463 static int
464 bcm_gpio_pin_toggle(device_t dev, uint32_t pin)
465 {
466         struct bcm_gpio_softc *sc = device_get_softc(dev);
467         uint32_t bank, data, offset;
468         int i;
469
470         for (i = 0; i < sc->sc_gpio_npins; i++) {
471                 if (sc->sc_gpio_pins[i].gp_pin == pin)
472                         break;
473         }
474
475         if (i >= sc->sc_gpio_npins)
476                 return (EINVAL);
477
478         /* We never write to read-only/reserved pins. */
479         if (bcm_gpio_pin_is_ro(sc, pin))
480                 return (EINVAL);
481
482         bank = pin / 32;
483         offset = pin - 32 * bank;
484
485         BCM_GPIO_LOCK(sc);
486         data = BCM_GPIO_READ(sc, BCM_GPIO_GPLEV(bank));
487         if (data & (1 << offset))
488                 BCM_GPIO_WRITE(sc, BCM_GPIO_GPCLR(bank), (1 << offset));
489         else
490                 BCM_GPIO_WRITE(sc, BCM_GPIO_GPSET(bank), (1 << offset));
491         BCM_GPIO_UNLOCK(sc);
492
493         return (0);
494 }
495
496 static int
497 bcm_gpio_get_ro_pins(struct bcm_gpio_softc *sc)
498 {
499         int i, len;
500         pcell_t pins[BCM_GPIO_PINS];
501         phandle_t gpio;
502
503         /* Find the gpio node to start. */
504         gpio = ofw_bus_get_node(sc->sc_dev);
505
506         len = OF_getproplen(gpio, "broadcom,read-only");
507         if (len < 0 || len > sizeof(pins))
508                 return (-1);
509
510         if (OF_getprop(gpio, "broadcom,read-only", &pins, len) < 0)
511                 return (-1);
512
513         sc->sc_ro_npins = len / sizeof(pcell_t);
514
515         device_printf(sc->sc_dev, "read-only pins: ");
516         for (i = 0; i < sc->sc_ro_npins; i++) {
517                 sc->sc_ro_pins[i] = fdt32_to_cpu(pins[i]);
518                 if (i > 0)
519                         printf(",");
520                 printf("%d", sc->sc_ro_pins[i]);
521         }
522         if (i > 0)
523                 printf(".");
524         printf("\n");
525
526         return (0);
527 }
528
529 static int
530 bcm_gpio_func_proc(SYSCTL_HANDLER_ARGS)
531 {
532         char buf[16];
533         struct bcm_gpio_softc *sc;
534         struct bcm_gpio_sysctl *sc_sysctl;
535         uint32_t nfunc;
536         int error;
537
538         sc_sysctl = arg1;
539         sc = sc_sysctl->sc;
540
541         /* Get the current pin function. */
542         nfunc = bcm_gpio_get_function(sc, sc_sysctl->pin);
543         bcm_gpio_func_str(nfunc, buf, sizeof(buf));
544
545         error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
546         if (error != 0 || req->newptr == NULL)
547                 return (error);
548
549         /* Parse the user supplied string and check for a valid pin function. */
550         if (bcm_gpio_str_func(buf, &nfunc) != 0)
551                 return (EINVAL);
552
553         /* Update the pin alternate function. */
554         bcm_gpio_set_alternate(sc->sc_dev, sc_sysctl->pin, nfunc);
555
556         return (0);
557 }
558
559 static void
560 bcm_gpio_sysctl_init(struct bcm_gpio_softc *sc)
561 {
562         char pinbuf[3];
563         struct bcm_gpio_sysctl *sc_sysctl;
564         struct sysctl_ctx_list *ctx;
565         struct sysctl_oid *tree_node, *pin_node, *pinN_node;
566         struct sysctl_oid_list *tree, *pin_tree, *pinN_tree;
567         int i;
568
569         /*
570          * Add per-pin sysctl tree/handlers.
571          */
572         ctx = device_get_sysctl_ctx(sc->sc_dev);
573         tree_node = device_get_sysctl_tree(sc->sc_dev);
574         tree = SYSCTL_CHILDREN(tree_node);
575         pin_node = SYSCTL_ADD_NODE(ctx, tree, OID_AUTO, "pin",
576             CTLFLAG_RD, NULL, "GPIO Pins");
577         pin_tree = SYSCTL_CHILDREN(pin_node);
578
579         for (i = 0; i < sc->sc_gpio_npins; i++) {
580
581                 snprintf(pinbuf, sizeof(pinbuf), "%d", i);
582                 pinN_node = SYSCTL_ADD_NODE(ctx, pin_tree, OID_AUTO, pinbuf,
583                     CTLFLAG_RD, NULL, "GPIO Pin");
584                 pinN_tree = SYSCTL_CHILDREN(pinN_node);
585
586                 sc->sc_sysctl[i].sc = sc;
587                 sc_sysctl = &sc->sc_sysctl[i];
588                 sc_sysctl->sc = sc;
589                 sc_sysctl->pin = sc->sc_gpio_pins[i].gp_pin;
590                 SYSCTL_ADD_PROC(ctx, pinN_tree, OID_AUTO, "function",
591                     CTLFLAG_RW | CTLTYPE_STRING, sc_sysctl,
592                     sizeof(struct bcm_gpio_sysctl), bcm_gpio_func_proc,
593                     "A", "Pin Function");
594         }
595 }
596
597 static int
598 bcm_gpio_get_reserved_pins(struct bcm_gpio_softc *sc)
599 {
600         int i, j, len, npins;
601         pcell_t pins[BCM_GPIO_PINS];
602         phandle_t gpio, node, reserved;
603         char name[32];
604
605         /* Get read-only pins. */
606         if (bcm_gpio_get_ro_pins(sc) != 0)
607                 return (-1);
608
609         /* Find the gpio/reserved pins node to start. */
610         gpio = ofw_bus_get_node(sc->sc_dev);
611         node = OF_child(gpio);
612         
613         /*
614          * Find reserved node
615          */
616         reserved = 0;
617         while ((node != 0) && (reserved == 0)) {
618                 len = OF_getprop(node, "name", name,
619                     sizeof(name) - 1);
620                 name[len] = 0;
621                 if (strcmp(name, "reserved") == 0)
622                         reserved = node;
623                 node = OF_peer(node);
624         }
625
626         if (reserved == 0)
627                 return (-1);
628
629         /* Get the reserved pins. */
630         len = OF_getproplen(reserved, "broadcom,pins");
631         if (len < 0 || len > sizeof(pins))
632                 return (-1);
633
634         if (OF_getprop(reserved, "broadcom,pins", &pins, len) < 0)
635                 return (-1);
636
637         npins = len / sizeof(pcell_t);
638
639         j = 0;
640         device_printf(sc->sc_dev, "reserved pins: ");
641         for (i = 0; i < npins; i++) {
642                 if (i > 0)
643                         printf(",");
644                 printf("%d", fdt32_to_cpu(pins[i]));
645                 /* Some pins maybe already on the list of read-only pins. */
646                 if (bcm_gpio_pin_is_ro(sc, fdt32_to_cpu(pins[i])))
647                         continue;
648                 sc->sc_ro_pins[j++ + sc->sc_ro_npins] = fdt32_to_cpu(pins[i]);
649         }
650         sc->sc_ro_npins += j;
651         if (i > 0)
652                 printf(".");
653         printf("\n");
654
655         return (0);
656 }
657
658 static int
659 bcm_gpio_probe(device_t dev)
660 {
661
662         if (!ofw_bus_status_okay(dev))
663                 return (ENXIO);
664
665         if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-gpio"))
666                 return (ENXIO);
667
668         device_set_desc(dev, "BCM2708/2835 GPIO controller");
669         return (BUS_PROBE_DEFAULT);
670 }
671
672 static int
673 bcm_gpio_attach(device_t dev)
674 {
675         struct bcm_gpio_softc *sc = device_get_softc(dev);
676         uint32_t func;
677         int i, j, rid;
678         phandle_t gpio;
679
680         sc->sc_dev = dev;
681
682         mtx_init(&sc->sc_mtx, "bcm gpio", "gpio", MTX_DEF);
683
684         rid = 0;
685         sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
686             RF_ACTIVE);
687         if (!sc->sc_mem_res) {
688                 device_printf(dev, "cannot allocate memory window\n");
689                 return (ENXIO);
690         }
691
692         sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
693         sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
694
695         rid = 0;
696         sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
697             RF_ACTIVE);
698         if (!sc->sc_irq_res) {
699                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
700                 device_printf(dev, "cannot allocate interrupt\n");
701                 return (ENXIO);
702         }
703
704         /* Find our node. */
705         gpio = ofw_bus_get_node(sc->sc_dev);
706
707         if (!OF_hasprop(gpio, "gpio-controller"))
708                 /* Node is not a GPIO controller. */
709                 goto fail;
710
711         /*
712          * Find the read-only pins.  These are pins we never touch or bad
713          * things could happen.
714          */
715         if (bcm_gpio_get_reserved_pins(sc) == -1)
716                 goto fail;
717
718         /* Initialize the software controlled pins. */
719         for (i = 0, j = 0; j < BCM_GPIO_PINS; j++) {
720                 if (bcm_gpio_pin_is_ro(sc, j))
721                         continue;
722                 snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME,
723                     "pin %d", j);
724                 func = bcm_gpio_get_function(sc, j);
725                 sc->sc_gpio_pins[i].gp_pin = j;
726                 sc->sc_gpio_pins[i].gp_caps = BCM_GPIO_DEFAULT_CAPS;
727                 sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(func);
728                 i++;
729         }
730         sc->sc_gpio_npins = i;
731
732         bcm_gpio_sysctl_init(sc);
733
734         device_add_child(dev, "gpioc", -1);
735         device_add_child(dev, "gpiobus", -1);
736
737         return (bus_generic_attach(dev));
738
739 fail:
740         if (sc->sc_irq_res)
741                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
742         if (sc->sc_mem_res)
743                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
744         return (ENXIO);
745 }
746
747 static int
748 bcm_gpio_detach(device_t dev)
749 {
750
751         return (EBUSY);
752 }
753
754 static phandle_t
755 bcm_gpio_get_node(device_t bus, device_t dev)
756 {
757
758         /* We only have one child, the GPIO bus, which needs our own node. */
759         return (ofw_bus_get_node(bus));
760 }
761
762 static device_method_t bcm_gpio_methods[] = {
763         /* Device interface */
764         DEVMETHOD(device_probe,         bcm_gpio_probe),
765         DEVMETHOD(device_attach,        bcm_gpio_attach),
766         DEVMETHOD(device_detach,        bcm_gpio_detach),
767
768         /* GPIO protocol */
769         DEVMETHOD(gpio_pin_max,         bcm_gpio_pin_max),
770         DEVMETHOD(gpio_pin_getname,     bcm_gpio_pin_getname),
771         DEVMETHOD(gpio_pin_getflags,    bcm_gpio_pin_getflags),
772         DEVMETHOD(gpio_pin_getcaps,     bcm_gpio_pin_getcaps),
773         DEVMETHOD(gpio_pin_setflags,    bcm_gpio_pin_setflags),
774         DEVMETHOD(gpio_pin_get,         bcm_gpio_pin_get),
775         DEVMETHOD(gpio_pin_set,         bcm_gpio_pin_set),
776         DEVMETHOD(gpio_pin_toggle,      bcm_gpio_pin_toggle),
777
778         /* ofw_bus interface */
779         DEVMETHOD(ofw_bus_get_node,     bcm_gpio_get_node),
780
781         DEVMETHOD_END
782 };
783
784 static devclass_t bcm_gpio_devclass;
785
786 static driver_t bcm_gpio_driver = {
787         "gpio",
788         bcm_gpio_methods,
789         sizeof(struct bcm_gpio_softc),
790 };
791
792 DRIVER_MODULE(bcm_gpio, simplebus, bcm_gpio_driver, bcm_gpio_devclass, 0, 0);