]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/gpio/gpiobus.c
MFV r355071: libbsdxml (expat) 2.2.9.
[FreeBSD/FreeBSD.git] / sys / dev / gpio / gpiobus.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2009 Oleksandr Tymoshenko <gonzo@freebsd.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/gpio.h>
36 #ifdef INTRNG
37 #include <sys/intr.h>
38 #endif
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
41 #include <sys/module.h>
42
43 #include <dev/gpio/gpiobusvar.h>
44
45 #include "gpiobus_if.h"
46
47 #undef GPIOBUS_DEBUG
48 #ifdef GPIOBUS_DEBUG
49 #define dprintf printf
50 #else
51 #define dprintf(x, arg...)
52 #endif
53
54 static void gpiobus_print_pins(struct gpiobus_ivar *, char *, size_t);
55 static int gpiobus_parse_pins(struct gpiobus_softc *, device_t, int);
56 static int gpiobus_probe(device_t);
57 static int gpiobus_attach(device_t);
58 static int gpiobus_detach(device_t);
59 static int gpiobus_suspend(device_t);
60 static int gpiobus_resume(device_t);
61 static void gpiobus_probe_nomatch(device_t, device_t);
62 static int gpiobus_print_child(device_t, device_t);
63 static int gpiobus_child_location_str(device_t, device_t, char *, size_t);
64 static int gpiobus_child_pnpinfo_str(device_t, device_t, char *, size_t);
65 static device_t gpiobus_add_child(device_t, u_int, const char *, int);
66 static void gpiobus_hinted_child(device_t, const char *, int);
67
68 /*
69  * GPIOBUS interface
70  */
71 static int gpiobus_acquire_bus(device_t, device_t, int);
72 static void gpiobus_release_bus(device_t, device_t);
73 static int gpiobus_pin_setflags(device_t, device_t, uint32_t, uint32_t);
74 static int gpiobus_pin_getflags(device_t, device_t, uint32_t, uint32_t*);
75 static int gpiobus_pin_getcaps(device_t, device_t, uint32_t, uint32_t*);
76 static int gpiobus_pin_set(device_t, device_t, uint32_t, unsigned int);
77 static int gpiobus_pin_get(device_t, device_t, uint32_t, unsigned int*);
78 static int gpiobus_pin_toggle(device_t, device_t, uint32_t);
79
80 /*
81  * XXX -> Move me to better place - gpio_subr.c?
82  * Also, this function must be changed when interrupt configuration
83  * data will be moved into struct resource.
84  */
85 #ifdef INTRNG
86
87 struct resource *
88 gpio_alloc_intr_resource(device_t consumer_dev, int *rid, u_int alloc_flags,
89     gpio_pin_t pin, uint32_t intr_mode)
90 {
91         u_int irq;
92         struct intr_map_data_gpio *gpio_data;
93         struct resource *res;
94
95         gpio_data = (struct intr_map_data_gpio *)intr_alloc_map_data(
96             INTR_MAP_DATA_GPIO, sizeof(*gpio_data), M_WAITOK | M_ZERO);
97         gpio_data->gpio_pin_num = pin->pin;
98         gpio_data->gpio_pin_flags = pin->flags;
99         gpio_data->gpio_intr_mode = intr_mode;
100
101         irq = intr_map_irq(pin->dev, 0, (struct intr_map_data *)gpio_data);
102         res = bus_alloc_resource(consumer_dev, SYS_RES_IRQ, rid, irq, irq, 1,
103             alloc_flags);
104         if (res == NULL) {
105                 intr_free_intr_map_data((struct intr_map_data *)gpio_data);
106                 return (NULL);
107         }
108         rman_set_virtual(res, gpio_data);
109         return (res);
110 }
111 #else
112 struct resource *
113 gpio_alloc_intr_resource(device_t consumer_dev, int *rid, u_int alloc_flags,
114     gpio_pin_t pin, uint32_t intr_mode)
115 {
116
117         return (NULL);
118 }
119 #endif
120
121 int
122 gpio_check_flags(uint32_t caps, uint32_t flags)
123 {
124
125         /* Filter unwanted flags. */
126         flags &= caps;
127
128         /* Cannot mix input/output together. */
129         if (flags & GPIO_PIN_INPUT && flags & GPIO_PIN_OUTPUT)
130                 return (EINVAL);
131         /* Cannot mix pull-up/pull-down together. */
132         if (flags & GPIO_PIN_PULLUP && flags & GPIO_PIN_PULLDOWN)
133                 return (EINVAL);
134
135         return (0);
136 }
137
138 static void
139 gpiobus_print_pins(struct gpiobus_ivar *devi, char *buf, size_t buflen)
140 {
141         char tmp[128];
142         int i, range_start, range_stop, need_coma;
143
144         if (devi->npins == 0)
145                 return;
146
147         need_coma = 0;
148         range_start = range_stop = devi->pins[0];
149         for (i = 1; i < devi->npins; i++) {
150                 if (devi->pins[i] != (range_stop + 1)) {
151                         if (need_coma)
152                                 strlcat(buf, ",", buflen);
153                         memset(tmp, 0, sizeof(tmp));
154                         if (range_start != range_stop)
155                                 snprintf(tmp, sizeof(tmp) - 1, "%d-%d",
156                                     range_start, range_stop);
157                         else
158                                 snprintf(tmp, sizeof(tmp) - 1, "%d",
159                                     range_start);
160                         strlcat(buf, tmp, buflen);
161
162                         range_start = range_stop = devi->pins[i];
163                         need_coma = 1;
164                 }
165                 else
166                         range_stop++;
167         }
168
169         if (need_coma)
170                 strlcat(buf, ",", buflen);
171         memset(tmp, 0, sizeof(tmp));
172         if (range_start != range_stop)
173                 snprintf(tmp, sizeof(tmp) - 1, "%d-%d",
174                     range_start, range_stop);
175         else
176                 snprintf(tmp, sizeof(tmp) - 1, "%d",
177                     range_start);
178         strlcat(buf, tmp, buflen);
179 }
180
181 device_t
182 gpiobus_attach_bus(device_t dev)
183 {
184         device_t busdev;
185
186         busdev = device_add_child(dev, "gpiobus", -1);
187         if (busdev == NULL)
188                 return (NULL);
189         if (device_add_child(dev, "gpioc", -1) == NULL) {
190                 device_delete_child(dev, busdev);
191                 return (NULL);
192         }
193 #ifdef FDT
194         ofw_gpiobus_register_provider(dev);
195 #endif
196         bus_generic_attach(dev);
197
198         return (busdev);
199 }
200
201 int
202 gpiobus_detach_bus(device_t dev)
203 {
204         int err;
205
206 #ifdef FDT
207         ofw_gpiobus_unregister_provider(dev);
208 #endif
209         err = bus_generic_detach(dev);
210         if (err != 0)
211                 return (err);
212
213         return (device_delete_children(dev));
214 }
215
216 int
217 gpiobus_init_softc(device_t dev)
218 {
219         struct gpiobus_softc *sc;
220
221         sc = GPIOBUS_SOFTC(dev);
222         sc->sc_busdev = dev;
223         sc->sc_dev = device_get_parent(dev);
224         sc->sc_intr_rman.rm_type = RMAN_ARRAY;
225         sc->sc_intr_rman.rm_descr = "GPIO Interrupts";
226         if (rman_init(&sc->sc_intr_rman) != 0 ||
227             rman_manage_region(&sc->sc_intr_rman, 0, ~0) != 0)
228                 panic("%s: failed to set up rman.", __func__);
229
230         if (GPIO_PIN_MAX(sc->sc_dev, &sc->sc_npins) != 0)
231                 return (ENXIO);
232
233         KASSERT(sc->sc_npins >= 0, ("GPIO device with no pins"));
234
235         /* Pins = GPIO_PIN_MAX() + 1 */
236         sc->sc_npins++;
237
238         sc->sc_pins = malloc(sizeof(*sc->sc_pins) * sc->sc_npins, M_DEVBUF,
239             M_NOWAIT | M_ZERO);
240         if (sc->sc_pins == NULL)
241                 return (ENOMEM);
242
243         /* Initialize the bus lock. */
244         GPIOBUS_LOCK_INIT(sc);
245
246         return (0);
247 }
248
249 int
250 gpiobus_alloc_ivars(struct gpiobus_ivar *devi)
251 {
252
253         /* Allocate pins and flags memory. */
254         devi->pins = malloc(sizeof(uint32_t) * devi->npins, M_DEVBUF,
255             M_NOWAIT | M_ZERO);
256         if (devi->pins == NULL)
257                 return (ENOMEM);
258         return (0);
259 }
260
261 void
262 gpiobus_free_ivars(struct gpiobus_ivar *devi)
263 {
264
265         if (devi->pins) {
266                 free(devi->pins, M_DEVBUF);
267                 devi->pins = NULL;
268         }
269         devi->npins = 0;
270 }
271
272 int
273 gpiobus_acquire_pin(device_t bus, uint32_t pin)
274 {
275         struct gpiobus_softc *sc;
276
277         sc = device_get_softc(bus);
278         /* Consistency check. */
279         if (pin >= sc->sc_npins) {
280                 device_printf(bus,
281                     "invalid pin %d, max: %d\n", pin, sc->sc_npins - 1);
282                 return (-1);
283         }
284         /* Mark pin as mapped and give warning if it's already mapped. */
285         if (sc->sc_pins[pin].mapped) {
286                 device_printf(bus, "warning: pin %d is already mapped\n", pin);
287                 return (-1);
288         }
289         sc->sc_pins[pin].mapped = 1;
290
291         return (0);
292 }
293
294 /* Release mapped pin */
295 int
296 gpiobus_release_pin(device_t bus, uint32_t pin)
297 {
298         struct gpiobus_softc *sc;
299
300         sc = device_get_softc(bus);
301         /* Consistency check. */
302         if (pin >= sc->sc_npins) {
303                 device_printf(bus,
304                     "gpiobus_acquire_pin: invalid pin %d, max=%d\n",
305                     pin, sc->sc_npins - 1);
306                 return (-1);
307         }
308
309         if (!sc->sc_pins[pin].mapped) {
310                 device_printf(bus, "gpiobus_acquire_pin: pin %d is not mapped\n", pin);
311                 return (-1);
312         }
313         sc->sc_pins[pin].mapped = 0;
314
315         return (0);
316 }
317
318 static int
319 gpiobus_acquire_child_pins(device_t dev, device_t child)
320 {
321         struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
322         int i;
323
324         for (i = 0; i < devi->npins; i++) {
325                 /* Reserve the GPIO pin. */
326                 if (gpiobus_acquire_pin(dev, devi->pins[i]) != 0) {
327                         device_printf(child, "cannot acquire pin %d\n",
328                             devi->pins[i]);
329                         while (--i >= 0) {
330                                 (void)gpiobus_release_pin(dev,
331                                     devi->pins[i]);
332                         }
333                         gpiobus_free_ivars(devi);
334                         return (EBUSY);
335                 }
336         }
337         for (i = 0; i < devi->npins; i++) {
338                 /* Use the child name as pin name. */
339                 GPIOBUS_PIN_SETNAME(dev, devi->pins[i],
340                     device_get_nameunit(child));
341
342         }
343         return (0);
344 }
345
346 static int
347 gpiobus_parse_pins(struct gpiobus_softc *sc, device_t child, int mask)
348 {
349         struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
350         int i, npins;
351
352         npins = 0;
353         for (i = 0; i < 32; i++) {
354                 if (mask & (1 << i))
355                         npins++;
356         }
357         if (npins == 0) {
358                 device_printf(child, "empty pin mask\n");
359                 return (EINVAL);
360         }
361         devi->npins = npins;
362         if (gpiobus_alloc_ivars(devi) != 0) {
363                 device_printf(child, "cannot allocate device ivars\n");
364                 return (EINVAL);
365         }
366         npins = 0;
367         for (i = 0; i < 32; i++) {
368                 if ((mask & (1 << i)) == 0)
369                         continue;
370                 devi->pins[npins++] = i;
371         }
372
373         if (gpiobus_acquire_child_pins(sc->sc_busdev, child) != 0)
374                 return (EINVAL);
375         return (0);
376 }
377
378 static int
379 gpiobus_parse_pin_list(struct gpiobus_softc *sc, device_t child,
380     const char *pins)
381 {
382         struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
383         const char *p;
384         char *endp;
385         unsigned long pin;
386         int i, npins;
387
388         npins = 0;
389         p = pins;
390         for (;;) {
391                 pin = strtoul(p, &endp, 0);
392                 if (endp == p)
393                         break;
394                 npins++;
395                 if (*endp == '\0')
396                         break;
397                 p = endp + 1;
398         }
399
400         if (*endp != '\0') {
401                 device_printf(child, "garbage in the pin list: %s\n", endp);
402                 return (EINVAL);
403         }
404         if (npins == 0) {
405                 device_printf(child, "empty pin list\n");
406                 return (EINVAL);
407         }
408
409         devi->npins = npins;
410         if (gpiobus_alloc_ivars(devi) != 0) {
411                 device_printf(child, "cannot allocate device ivars\n");
412                 return (EINVAL);
413         }
414
415         i = 0;
416         p = pins;
417         for (;;) {
418                 pin = strtoul(p, &endp, 0);
419
420                 devi->pins[i] = pin;
421
422                 if (*endp == '\0')
423                         break;
424                 i++;
425                 p = endp + 1;
426         }
427
428         if (gpiobus_acquire_child_pins(sc->sc_busdev, child) != 0)
429                 return (EINVAL);
430         return (0);
431 }
432
433 static int
434 gpiobus_probe(device_t dev)
435 {
436         device_set_desc(dev, "GPIO bus");
437
438         return (BUS_PROBE_GENERIC);
439 }
440
441 static int
442 gpiobus_attach(device_t dev)
443 {
444         int err;
445
446         err = gpiobus_init_softc(dev);
447         if (err != 0)
448                 return (err);
449
450         /*
451          * Get parent's pins and mark them as unmapped
452          */
453         bus_generic_probe(dev);
454         bus_enumerate_hinted_children(dev);
455
456         return (bus_generic_attach(dev));
457 }
458
459 /*
460  * Since this is not a self-enumerating bus, and since we always add
461  * children in attach, we have to always delete children here.
462  */
463 static int
464 gpiobus_detach(device_t dev)
465 {
466         struct gpiobus_softc *sc;
467         struct gpiobus_ivar *devi;
468         device_t *devlist;
469         int i, err, ndevs;
470
471         sc = GPIOBUS_SOFTC(dev);
472         KASSERT(mtx_initialized(&sc->sc_mtx),
473             ("gpiobus mutex not initialized"));
474         GPIOBUS_LOCK_DESTROY(sc);
475
476         if ((err = bus_generic_detach(dev)) != 0)
477                 return (err);
478
479         if ((err = device_get_children(dev, &devlist, &ndevs)) != 0)
480                 return (err);
481         for (i = 0; i < ndevs; i++) {
482                 devi = GPIOBUS_IVAR(devlist[i]);
483                 gpiobus_free_ivars(devi);
484                 resource_list_free(&devi->rl);
485                 free(devi, M_DEVBUF);
486                 device_delete_child(dev, devlist[i]);
487         }
488         free(devlist, M_TEMP);
489         rman_fini(&sc->sc_intr_rman);
490         if (sc->sc_pins) {
491                 for (i = 0; i < sc->sc_npins; i++) {
492                         if (sc->sc_pins[i].name != NULL)
493                                 free(sc->sc_pins[i].name, M_DEVBUF);
494                         sc->sc_pins[i].name = NULL;
495                 }
496                 free(sc->sc_pins, M_DEVBUF);
497                 sc->sc_pins = NULL;
498         }
499
500         return (0);
501 }
502
503 static int
504 gpiobus_suspend(device_t dev)
505 {
506
507         return (bus_generic_suspend(dev));
508 }
509
510 static int
511 gpiobus_resume(device_t dev)
512 {
513
514         return (bus_generic_resume(dev));
515 }
516
517 static void
518 gpiobus_probe_nomatch(device_t dev, device_t child)
519 {
520         char pins[128];
521         struct gpiobus_ivar *devi;
522
523         devi = GPIOBUS_IVAR(child);
524         memset(pins, 0, sizeof(pins));
525         gpiobus_print_pins(devi, pins, sizeof(pins));
526         if (devi->npins > 1)
527                 device_printf(dev, "<unknown device> at pins %s", pins);
528         else
529                 device_printf(dev, "<unknown device> at pin %s", pins);
530         resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%jd");
531         printf("\n");
532 }
533
534 static int
535 gpiobus_print_child(device_t dev, device_t child)
536 {
537         char pins[128];
538         int retval = 0;
539         struct gpiobus_ivar *devi;
540
541         devi = GPIOBUS_IVAR(child);
542         memset(pins, 0, sizeof(pins));
543         retval += bus_print_child_header(dev, child);
544         if (devi->npins > 0) {
545                 if (devi->npins > 1)
546                         retval += printf(" at pins ");
547                 else
548                         retval += printf(" at pin ");
549                 gpiobus_print_pins(devi, pins, sizeof(pins));
550                 retval += printf("%s", pins);
551         }
552         resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%jd");
553         retval += bus_print_child_footer(dev, child);
554
555         return (retval);
556 }
557
558 static int
559 gpiobus_child_location_str(device_t bus, device_t child, char *buf,
560     size_t buflen)
561 {
562         struct gpiobus_ivar *devi;
563
564         devi = GPIOBUS_IVAR(child);
565         if (devi->npins > 1)
566                 strlcpy(buf, "pins=", buflen);
567         else
568                 strlcpy(buf, "pin=", buflen);
569         gpiobus_print_pins(devi, buf, buflen);
570
571         return (0);
572 }
573
574 static int
575 gpiobus_child_pnpinfo_str(device_t bus, device_t child, char *buf,
576     size_t buflen)
577 {
578
579         *buf = '\0';
580         return (0);
581 }
582
583 static device_t
584 gpiobus_add_child(device_t dev, u_int order, const char *name, int unit)
585 {
586         device_t child;
587         struct gpiobus_ivar *devi;
588
589         child = device_add_child_ordered(dev, order, name, unit);
590         if (child == NULL) 
591                 return (child);
592         devi = malloc(sizeof(struct gpiobus_ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
593         if (devi == NULL) {
594                 device_delete_child(dev, child);
595                 return (NULL);
596         }
597         resource_list_init(&devi->rl);
598         device_set_ivars(child, devi);
599
600         return (child);
601 }
602
603 static void
604 gpiobus_hinted_child(device_t bus, const char *dname, int dunit)
605 {
606         struct gpiobus_softc *sc = GPIOBUS_SOFTC(bus);
607         struct gpiobus_ivar *devi;
608         device_t child;
609         const char *pins;
610         int irq, pinmask;
611
612         child = BUS_ADD_CHILD(bus, 0, dname, dunit);
613         devi = GPIOBUS_IVAR(child);
614         if (resource_int_value(dname, dunit, "pins", &pinmask) == 0) {
615                 if (gpiobus_parse_pins(sc, child, pinmask)) {
616                         resource_list_free(&devi->rl);
617                         free(devi, M_DEVBUF);
618                         device_delete_child(bus, child);
619                         return;
620                 }
621         }
622         else if (resource_string_value(dname, dunit, "pin_list", &pins) == 0) {
623                 if (gpiobus_parse_pin_list(sc, child, pins)) {
624                         resource_list_free(&devi->rl);
625                         free(devi, M_DEVBUF);
626                         device_delete_child(bus, child);
627                         return;
628                 }
629         }
630         if (resource_int_value(dname, dunit, "irq", &irq) == 0) {
631                 if (bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1) != 0)
632                         device_printf(bus,
633                             "warning: bus_set_resource() failed\n");
634         }
635 }
636
637 static int
638 gpiobus_set_resource(device_t dev, device_t child, int type, int rid,
639     rman_res_t start, rman_res_t count)
640 {
641         struct gpiobus_ivar *devi;
642         struct resource_list_entry *rle;
643
644         dprintf("%s: entry (%p, %p, %d, %d, %p, %ld)\n",
645             __func__, dev, child, type, rid, (void *)(intptr_t)start, count);
646         devi = GPIOBUS_IVAR(child);
647         rle = resource_list_add(&devi->rl, type, rid, start,
648             start + count - 1, count);
649         if (rle == NULL)
650                 return (ENXIO);
651
652         return (0);
653 }
654
655 static int
656 gpiobus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
657 {
658         struct gpiobus_ivar *devi;
659
660         devi = GPIOBUS_IVAR(child);
661         switch (which) {
662         case GPIOBUS_IVAR_NPINS:
663                 *result = devi->npins;
664                 break;
665         case GPIOBUS_IVAR_PINS:
666                 /* Children do not ever need to directly examine this. */
667                 return (ENOTSUP);
668         default:
669                 return (ENOENT);
670         }
671
672         return (0);
673 }
674
675 static int
676 gpiobus_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
677 {
678         struct gpiobus_ivar *devi;
679         const uint32_t *ptr;
680         int i;
681
682         devi = GPIOBUS_IVAR(child);
683         switch (which) {
684         case GPIOBUS_IVAR_NPINS:
685                 /* GPIO ivars are set once. */
686                 if (devi->npins != 0) {
687                         return (EBUSY);
688                 }
689                 devi->npins = value;
690                 if (gpiobus_alloc_ivars(devi) != 0) {
691                         device_printf(child, "cannot allocate device ivars\n");
692                         devi->npins = 0;
693                         return (ENOMEM);
694                 }
695                 break;
696         case GPIOBUS_IVAR_PINS:
697                 ptr = (const uint32_t *)value;
698                 for (i = 0; i < devi->npins; i++)
699                         devi->pins[i] = ptr[i];
700                 if (gpiobus_acquire_child_pins(dev, child) != 0)
701                         return (EBUSY);
702                 break;
703         default:
704                 return (ENOENT);
705         }
706
707         return (0);
708 }
709
710 static struct resource *
711 gpiobus_alloc_resource(device_t bus, device_t child, int type, int *rid,
712     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
713 {
714         struct gpiobus_softc *sc;
715         struct resource *rv;
716         struct resource_list *rl;
717         struct resource_list_entry *rle;
718         int isdefault;
719
720         if (type != SYS_RES_IRQ)
721                 return (NULL);
722         isdefault = (RMAN_IS_DEFAULT_RANGE(start, end) && count == 1);
723         rle = NULL;
724         if (isdefault) {
725                 rl = BUS_GET_RESOURCE_LIST(bus, child);
726                 if (rl == NULL)
727                         return (NULL);
728                 rle = resource_list_find(rl, type, *rid);
729                 if (rle == NULL)
730                         return (NULL);
731                 if (rle->res != NULL)
732                         panic("%s: resource entry is busy", __func__);
733                 start = rle->start;
734                 count = rle->count;
735                 end = rle->end;
736         }
737         sc = device_get_softc(bus);
738         rv = rman_reserve_resource(&sc->sc_intr_rman, start, end, count, flags,
739             child);
740         if (rv == NULL)
741                 return (NULL);
742         rman_set_rid(rv, *rid);
743         if ((flags & RF_ACTIVE) != 0 &&
744             bus_activate_resource(child, type, *rid, rv) != 0) {
745                 rman_release_resource(rv);
746                 return (NULL);
747         }
748
749         return (rv);
750 }
751
752 static int
753 gpiobus_release_resource(device_t bus __unused, device_t child, int type,
754     int rid, struct resource *r)
755 {
756         int error;
757
758         if (rman_get_flags(r) & RF_ACTIVE) {
759                 error = bus_deactivate_resource(child, type, rid, r);
760                 if (error)
761                         return (error);
762         }
763
764         return (rman_release_resource(r));
765 }
766
767 static struct resource_list *
768 gpiobus_get_resource_list(device_t bus __unused, device_t child)
769 {
770         struct gpiobus_ivar *ivar;
771
772         ivar = GPIOBUS_IVAR(child);
773
774         return (&ivar->rl);
775 }
776
777 static int
778 gpiobus_acquire_bus(device_t busdev, device_t child, int how)
779 {
780         struct gpiobus_softc *sc;
781
782         sc = device_get_softc(busdev);
783         GPIOBUS_ASSERT_UNLOCKED(sc);
784         GPIOBUS_LOCK(sc);
785         if (sc->sc_owner != NULL) {
786                 if (sc->sc_owner == child)
787                         panic("%s: %s still owns the bus.",
788                             device_get_nameunit(busdev),
789                             device_get_nameunit(child));
790                 if (how == GPIOBUS_DONTWAIT) {
791                         GPIOBUS_UNLOCK(sc);
792                         return (EWOULDBLOCK);
793                 }
794                 while (sc->sc_owner != NULL)
795                         mtx_sleep(sc, &sc->sc_mtx, 0, "gpiobuswait", 0);
796         }
797         sc->sc_owner = child;
798         GPIOBUS_UNLOCK(sc);
799
800         return (0);
801 }
802
803 static void
804 gpiobus_release_bus(device_t busdev, device_t child)
805 {
806         struct gpiobus_softc *sc;
807
808         sc = device_get_softc(busdev);
809         GPIOBUS_ASSERT_UNLOCKED(sc);
810         GPIOBUS_LOCK(sc);
811         if (sc->sc_owner == NULL)
812                 panic("%s: %s releasing unowned bus.",
813                     device_get_nameunit(busdev),
814                     device_get_nameunit(child));
815         if (sc->sc_owner != child)
816                 panic("%s: %s trying to release bus owned by %s",
817                     device_get_nameunit(busdev),
818                     device_get_nameunit(child),
819                     device_get_nameunit(sc->sc_owner));
820         sc->sc_owner = NULL;
821         wakeup(sc);
822         GPIOBUS_UNLOCK(sc);
823 }
824
825 static int
826 gpiobus_pin_setflags(device_t dev, device_t child, uint32_t pin, 
827     uint32_t flags)
828 {
829         struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
830         struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
831         uint32_t caps;
832
833         if (pin >= devi->npins)
834                 return (EINVAL);
835         if (GPIO_PIN_GETCAPS(sc->sc_dev, devi->pins[pin], &caps) != 0)
836                 return (EINVAL);
837         if (gpio_check_flags(caps, flags) != 0)
838                 return (EINVAL);
839
840         return (GPIO_PIN_SETFLAGS(sc->sc_dev, devi->pins[pin], flags));
841 }
842
843 static int
844 gpiobus_pin_getflags(device_t dev, device_t child, uint32_t pin, 
845     uint32_t *flags)
846 {
847         struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
848         struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
849
850         if (pin >= devi->npins)
851                 return (EINVAL);
852
853         return GPIO_PIN_GETFLAGS(sc->sc_dev, devi->pins[pin], flags);
854 }
855
856 static int
857 gpiobus_pin_getcaps(device_t dev, device_t child, uint32_t pin, 
858     uint32_t *caps)
859 {
860         struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
861         struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
862
863         if (pin >= devi->npins)
864                 return (EINVAL);
865
866         return GPIO_PIN_GETCAPS(sc->sc_dev, devi->pins[pin], caps);
867 }
868
869 static int
870 gpiobus_pin_set(device_t dev, device_t child, uint32_t pin, 
871     unsigned int value)
872 {
873         struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
874         struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
875
876         if (pin >= devi->npins)
877                 return (EINVAL);
878
879         return GPIO_PIN_SET(sc->sc_dev, devi->pins[pin], value);
880 }
881
882 static int
883 gpiobus_pin_get(device_t dev, device_t child, uint32_t pin, 
884     unsigned int *value)
885 {
886         struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
887         struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
888
889         if (pin >= devi->npins)
890                 return (EINVAL);
891
892         return GPIO_PIN_GET(sc->sc_dev, devi->pins[pin], value);
893 }
894
895 static int
896 gpiobus_pin_toggle(device_t dev, device_t child, uint32_t pin)
897 {
898         struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
899         struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
900
901         if (pin >= devi->npins)
902                 return (EINVAL);
903
904         return GPIO_PIN_TOGGLE(sc->sc_dev, devi->pins[pin]);
905 }
906
907 static int
908 gpiobus_pin_getname(device_t dev, uint32_t pin, char *name)
909 {
910         struct gpiobus_softc *sc;
911
912         sc = GPIOBUS_SOFTC(dev);
913         if (pin > sc->sc_npins)
914                 return (EINVAL);
915         /* Did we have a name for this pin ? */
916         if (sc->sc_pins[pin].name != NULL) {
917                 memcpy(name, sc->sc_pins[pin].name, GPIOMAXNAME);
918                 return (0);
919         }
920
921         /* Return the default pin name. */
922         return (GPIO_PIN_GETNAME(device_get_parent(dev), pin, name));
923 }
924
925 static int
926 gpiobus_pin_setname(device_t dev, uint32_t pin, const char *name)
927 {
928         struct gpiobus_softc *sc;
929
930         sc = GPIOBUS_SOFTC(dev);
931         if (pin > sc->sc_npins)
932                 return (EINVAL);
933         if (name == NULL)
934                 return (EINVAL);
935         /* Save the pin name. */
936         if (sc->sc_pins[pin].name == NULL)
937                 sc->sc_pins[pin].name = malloc(GPIOMAXNAME, M_DEVBUF,
938                     M_WAITOK | M_ZERO);
939         strlcpy(sc->sc_pins[pin].name, name, GPIOMAXNAME);
940
941         return (0);
942 }
943
944 static device_method_t gpiobus_methods[] = {
945         /* Device interface */
946         DEVMETHOD(device_probe,         gpiobus_probe),
947         DEVMETHOD(device_attach,        gpiobus_attach),
948         DEVMETHOD(device_detach,        gpiobus_detach),
949         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
950         DEVMETHOD(device_suspend,       gpiobus_suspend),
951         DEVMETHOD(device_resume,        gpiobus_resume),
952
953         /* Bus interface */
954         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
955         DEVMETHOD(bus_config_intr,      bus_generic_config_intr),
956         DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
957         DEVMETHOD(bus_set_resource,     gpiobus_set_resource),
958         DEVMETHOD(bus_alloc_resource,   gpiobus_alloc_resource),
959         DEVMETHOD(bus_release_resource, gpiobus_release_resource),
960         DEVMETHOD(bus_activate_resource,        bus_generic_activate_resource),
961         DEVMETHOD(bus_deactivate_resource,      bus_generic_deactivate_resource),
962         DEVMETHOD(bus_get_resource_list,        gpiobus_get_resource_list),
963         DEVMETHOD(bus_add_child,        gpiobus_add_child),
964         DEVMETHOD(bus_probe_nomatch,    gpiobus_probe_nomatch),
965         DEVMETHOD(bus_print_child,      gpiobus_print_child),
966         DEVMETHOD(bus_child_pnpinfo_str, gpiobus_child_pnpinfo_str),
967         DEVMETHOD(bus_child_location_str, gpiobus_child_location_str),
968         DEVMETHOD(bus_hinted_child,     gpiobus_hinted_child),
969         DEVMETHOD(bus_read_ivar,        gpiobus_read_ivar),
970         DEVMETHOD(bus_write_ivar,       gpiobus_write_ivar),
971
972         /* GPIO protocol */
973         DEVMETHOD(gpiobus_acquire_bus,  gpiobus_acquire_bus),
974         DEVMETHOD(gpiobus_release_bus,  gpiobus_release_bus),
975         DEVMETHOD(gpiobus_pin_getflags, gpiobus_pin_getflags),
976         DEVMETHOD(gpiobus_pin_getcaps,  gpiobus_pin_getcaps),
977         DEVMETHOD(gpiobus_pin_setflags, gpiobus_pin_setflags),
978         DEVMETHOD(gpiobus_pin_get,      gpiobus_pin_get),
979         DEVMETHOD(gpiobus_pin_set,      gpiobus_pin_set),
980         DEVMETHOD(gpiobus_pin_toggle,   gpiobus_pin_toggle),
981         DEVMETHOD(gpiobus_pin_getname,  gpiobus_pin_getname),
982         DEVMETHOD(gpiobus_pin_setname,  gpiobus_pin_setname),
983
984         DEVMETHOD_END
985 };
986
987 driver_t gpiobus_driver = {
988         "gpiobus",
989         gpiobus_methods,
990         sizeof(struct gpiobus_softc)
991 };
992
993 devclass_t      gpiobus_devclass;
994
995 EARLY_DRIVER_MODULE(gpiobus, gpio, gpiobus_driver, gpiobus_devclass, 0, 0,
996     BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
997 MODULE_VERSION(gpiobus, 1);