xref: /freebsd/sys/arm/broadcom/bcm2835/bcm2835_gpio.c (revision 545ddfbe7d4fe8adfb862903b24eac1d5896c1ef)
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);
793