29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/bus.h> 33#include <sys/gpio.h> 34#include <sys/kernel.h> 35#include <sys/malloc.h> 36#include <sys/module.h> 37 38#include <dev/gpio/gpiobusvar.h> 39 40#include "gpiobus_if.h" 41 42#undef GPIOBUS_DEBUG 43#ifdef GPIOBUS_DEBUG 44#define dprintf printf 45#else 46#define dprintf(x, arg...) 47#endif 48 49static void gpiobus_print_pins(struct gpiobus_ivar *, char *, size_t); 50static int gpiobus_parse_pins(struct gpiobus_softc *, device_t, int); 51static int gpiobus_probe(device_t); 52static int gpiobus_attach(device_t); 53static int gpiobus_detach(device_t); 54static int gpiobus_suspend(device_t); 55static int gpiobus_resume(device_t); 56static int gpiobus_print_child(device_t, device_t); 57static int gpiobus_child_location_str(device_t, device_t, char *, size_t); 58static int gpiobus_child_pnpinfo_str(device_t, device_t, char *, size_t); 59static device_t gpiobus_add_child(device_t, u_int, const char *, int); 60static void gpiobus_hinted_child(device_t, const char *, int); 61 62/* 63 * GPIOBUS interface 64 */ 65static int gpiobus_acquire_bus(device_t, device_t, int); 66static void gpiobus_release_bus(device_t, device_t); 67static int gpiobus_pin_setflags(device_t, device_t, uint32_t, uint32_t); 68static int gpiobus_pin_getflags(device_t, device_t, uint32_t, uint32_t*); 69static int gpiobus_pin_getcaps(device_t, device_t, uint32_t, uint32_t*); 70static int gpiobus_pin_set(device_t, device_t, uint32_t, unsigned int); 71static int gpiobus_pin_get(device_t, device_t, uint32_t, unsigned int*); 72static int gpiobus_pin_toggle(device_t, device_t, uint32_t); 73 74int 75gpio_check_flags(uint32_t caps, uint32_t flags) 76{ 77 78 /* Check for unwanted flags. */ 79 if ((flags & caps) == 0 || (flags & caps) != flags) 80 return (EINVAL); 81 /* Cannot mix input/output together. */ 82 if (flags & GPIO_PIN_INPUT && flags & GPIO_PIN_OUTPUT) 83 return (EINVAL); 84 /* Cannot mix pull-up/pull-down together. */ 85 if (flags & GPIO_PIN_PULLUP && flags & GPIO_PIN_PULLDOWN) 86 return (EINVAL); 87 88 return (0); 89} 90 91static void 92gpiobus_print_pins(struct gpiobus_ivar *devi, char *buf, size_t buflen) 93{ 94 char tmp[128]; 95 int i, range_start, range_stop, need_coma; 96 97 if (devi->npins == 0) 98 return; 99 100 need_coma = 0; 101 range_start = range_stop = devi->pins[0]; 102 for (i = 1; i < devi->npins; i++) { 103 if (devi->pins[i] != (range_stop + 1)) { 104 if (need_coma) 105 strlcat(buf, ",", buflen); 106 memset(tmp, 0, sizeof(tmp)); 107 if (range_start != range_stop) 108 snprintf(tmp, sizeof(tmp) - 1, "%d-%d", 109 range_start, range_stop); 110 else 111 snprintf(tmp, sizeof(tmp) - 1, "%d", 112 range_start); 113 strlcat(buf, tmp, buflen); 114 115 range_start = range_stop = devi->pins[i]; 116 need_coma = 1; 117 } 118 else 119 range_stop++; 120 } 121 122 if (need_coma) 123 strlcat(buf, ",", buflen); 124 memset(tmp, 0, sizeof(tmp)); 125 if (range_start != range_stop) 126 snprintf(tmp, sizeof(tmp) - 1, "%d-%d", 127 range_start, range_stop); 128 else 129 snprintf(tmp, sizeof(tmp) - 1, "%d", 130 range_start); 131 strlcat(buf, tmp, buflen); 132} 133
| 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/bus.h> 33#include <sys/gpio.h> 34#include <sys/kernel.h> 35#include <sys/malloc.h> 36#include <sys/module.h> 37 38#include <dev/gpio/gpiobusvar.h> 39 40#include "gpiobus_if.h" 41 42#undef GPIOBUS_DEBUG 43#ifdef GPIOBUS_DEBUG 44#define dprintf printf 45#else 46#define dprintf(x, arg...) 47#endif 48 49static void gpiobus_print_pins(struct gpiobus_ivar *, char *, size_t); 50static int gpiobus_parse_pins(struct gpiobus_softc *, device_t, int); 51static int gpiobus_probe(device_t); 52static int gpiobus_attach(device_t); 53static int gpiobus_detach(device_t); 54static int gpiobus_suspend(device_t); 55static int gpiobus_resume(device_t); 56static int gpiobus_print_child(device_t, device_t); 57static int gpiobus_child_location_str(device_t, device_t, char *, size_t); 58static int gpiobus_child_pnpinfo_str(device_t, device_t, char *, size_t); 59static device_t gpiobus_add_child(device_t, u_int, const char *, int); 60static void gpiobus_hinted_child(device_t, const char *, int); 61 62/* 63 * GPIOBUS interface 64 */ 65static int gpiobus_acquire_bus(device_t, device_t, int); 66static void gpiobus_release_bus(device_t, device_t); 67static int gpiobus_pin_setflags(device_t, device_t, uint32_t, uint32_t); 68static int gpiobus_pin_getflags(device_t, device_t, uint32_t, uint32_t*); 69static int gpiobus_pin_getcaps(device_t, device_t, uint32_t, uint32_t*); 70static int gpiobus_pin_set(device_t, device_t, uint32_t, unsigned int); 71static int gpiobus_pin_get(device_t, device_t, uint32_t, unsigned int*); 72static int gpiobus_pin_toggle(device_t, device_t, uint32_t); 73 74int 75gpio_check_flags(uint32_t caps, uint32_t flags) 76{ 77 78 /* Check for unwanted flags. */ 79 if ((flags & caps) == 0 || (flags & caps) != flags) 80 return (EINVAL); 81 /* Cannot mix input/output together. */ 82 if (flags & GPIO_PIN_INPUT && flags & GPIO_PIN_OUTPUT) 83 return (EINVAL); 84 /* Cannot mix pull-up/pull-down together. */ 85 if (flags & GPIO_PIN_PULLUP && flags & GPIO_PIN_PULLDOWN) 86 return (EINVAL); 87 88 return (0); 89} 90 91static void 92gpiobus_print_pins(struct gpiobus_ivar *devi, char *buf, size_t buflen) 93{ 94 char tmp[128]; 95 int i, range_start, range_stop, need_coma; 96 97 if (devi->npins == 0) 98 return; 99 100 need_coma = 0; 101 range_start = range_stop = devi->pins[0]; 102 for (i = 1; i < devi->npins; i++) { 103 if (devi->pins[i] != (range_stop + 1)) { 104 if (need_coma) 105 strlcat(buf, ",", buflen); 106 memset(tmp, 0, sizeof(tmp)); 107 if (range_start != range_stop) 108 snprintf(tmp, sizeof(tmp) - 1, "%d-%d", 109 range_start, range_stop); 110 else 111 snprintf(tmp, sizeof(tmp) - 1, "%d", 112 range_start); 113 strlcat(buf, tmp, buflen); 114 115 range_start = range_stop = devi->pins[i]; 116 need_coma = 1; 117 } 118 else 119 range_stop++; 120 } 121 122 if (need_coma) 123 strlcat(buf, ",", buflen); 124 memset(tmp, 0, sizeof(tmp)); 125 if (range_start != range_stop) 126 snprintf(tmp, sizeof(tmp) - 1, "%d-%d", 127 range_start, range_stop); 128 else 129 snprintf(tmp, sizeof(tmp) - 1, "%d", 130 range_start); 131 strlcat(buf, tmp, buflen); 132} 133
|
135gpiobus_init_softc(device_t dev) 136{ 137 struct gpiobus_softc *sc; 138 139 sc = GPIOBUS_SOFTC(dev); 140 sc->sc_busdev = dev; 141 sc->sc_dev = device_get_parent(dev); 142 sc->sc_intr_rman.rm_type = RMAN_ARRAY; 143 sc->sc_intr_rman.rm_descr = "GPIO Interrupts"; 144 if (rman_init(&sc->sc_intr_rman) != 0 || 145 rman_manage_region(&sc->sc_intr_rman, 0, ~0) != 0) 146 panic("%s: failed to set up rman.", __func__); 147 148 if (GPIO_PIN_MAX(sc->sc_dev, &sc->sc_npins) != 0) 149 return (ENXIO); 150 151 KASSERT(sc->sc_npins != 0, ("GPIO device with no pins")); 152 153 /* Pins = GPIO_PIN_MAX() + 1 */ 154 sc->sc_npins++; 155 156 sc->sc_pins_mapped = malloc(sizeof(int) * sc->sc_npins, M_DEVBUF, 157 M_NOWAIT | M_ZERO); 158 if (sc->sc_pins_mapped == NULL) 159 return (ENOMEM); 160 161 /* Initialize the bus lock. */ 162 GPIOBUS_LOCK_INIT(sc); 163 164 return (0); 165} 166 167static int 168gpiobus_parse_pins(struct gpiobus_softc *sc, device_t child, int mask) 169{ 170 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 171 int i, npins; 172 173 npins = 0; 174 for (i = 0; i < 32; i++) { 175 if (mask & (1 << i)) 176 npins++; 177 } 178 179 if (npins == 0) { 180 device_printf(child, "empty pin mask\n"); 181 return (EINVAL); 182 } 183 184 devi->npins = npins; 185 devi->pins = malloc(sizeof(uint32_t) * devi->npins, M_DEVBUF, 186 M_NOWAIT | M_ZERO); 187 188 if (!devi->pins) 189 return (ENOMEM); 190 191 npins = 0; 192 for (i = 0; i < 32; i++) { 193 194 if ((mask & (1 << i)) == 0) 195 continue; 196 197 if (i >= sc->sc_npins) { 198 device_printf(child, 199 "invalid pin %d, max: %d\n", i, sc->sc_npins - 1); 200 free(devi->pins, M_DEVBUF); 201 return (EINVAL); 202 } 203 204 devi->pins[npins++] = i; 205 /* 206 * Mark pin as mapped and give warning if it's already mapped 207 */ 208 if (sc->sc_pins_mapped[i]) { 209 device_printf(child, 210 "warning: pin %d is already mapped\n", i); 211 free(devi->pins, M_DEVBUF); 212 return (EINVAL); 213 } 214 sc->sc_pins_mapped[i] = 1; 215 } 216 217 return (0); 218} 219 220static int 221gpiobus_probe(device_t dev) 222{ 223 device_set_desc(dev, "GPIO bus"); 224 225 return (BUS_PROBE_GENERIC); 226} 227 228static int 229gpiobus_attach(device_t dev) 230{ 231 int err; 232 233 err = gpiobus_init_softc(dev); 234 if (err != 0) 235 return (err); 236 237 /* 238 * Get parent's pins and mark them as unmapped 239 */ 240 bus_generic_probe(dev); 241 bus_enumerate_hinted_children(dev); 242 243 return (bus_generic_attach(dev)); 244} 245 246/* 247 * Since this is not a self-enumerating bus, and since we always add 248 * children in attach, we have to always delete children here. 249 */ 250static int 251gpiobus_detach(device_t dev) 252{ 253 struct gpiobus_softc *sc; 254 struct gpiobus_ivar *devi; 255 device_t *devlist; 256 int i, err, ndevs; 257 258 sc = GPIOBUS_SOFTC(dev); 259 KASSERT(mtx_initialized(&sc->sc_mtx), 260 ("gpiobus mutex not initialized")); 261 GPIOBUS_LOCK_DESTROY(sc); 262 263 if ((err = bus_generic_detach(dev)) != 0) 264 return (err); 265 266 if ((err = device_get_children(dev, &devlist, &ndevs)) != 0) 267 return (err); 268 for (i = 0; i < ndevs; i++) { 269 device_delete_child(dev, devlist[i]); 270 devi = GPIOBUS_IVAR(devlist[i]); 271 if (devi->pins) { 272 free(devi->pins, M_DEVBUF); 273 devi->pins = NULL; 274 } 275 } 276 free(devlist, M_TEMP); 277 278 if (sc->sc_pins_mapped) { 279 free(sc->sc_pins_mapped, M_DEVBUF); 280 sc->sc_pins_mapped = NULL; 281 } 282 283 return (0); 284} 285 286static int 287gpiobus_suspend(device_t dev) 288{ 289 290 return (bus_generic_suspend(dev)); 291} 292 293static int 294gpiobus_resume(device_t dev) 295{ 296 297 return (bus_generic_resume(dev)); 298} 299 300static int 301gpiobus_print_child(device_t dev, device_t child) 302{ 303 char pins[128]; 304 int retval = 0; 305 struct gpiobus_ivar *devi; 306 307 devi = GPIOBUS_IVAR(child); 308 memset(pins, 0, sizeof(pins)); 309 retval += bus_print_child_header(dev, child); 310 retval += printf(" at pin(s) "); 311 gpiobus_print_pins(devi, pins, sizeof(pins)); 312 retval += printf("%s", pins); 313 resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%ld"); 314 retval += bus_print_child_footer(dev, child); 315 316 return (retval); 317} 318 319static int 320gpiobus_child_location_str(device_t bus, device_t child, char *buf, 321 size_t buflen) 322{ 323 struct gpiobus_ivar *devi; 324 325 devi = GPIOBUS_IVAR(child); 326 strlcpy(buf, "pin(s)=", buflen); 327 gpiobus_print_pins(devi, buf, buflen); 328 329 return (0); 330} 331 332static int 333gpiobus_child_pnpinfo_str(device_t bus, device_t child, char *buf, 334 size_t buflen) 335{ 336 337 *buf = '\0'; 338 return (0); 339} 340 341static device_t 342gpiobus_add_child(device_t dev, u_int order, const char *name, int unit) 343{ 344 device_t child; 345 struct gpiobus_ivar *devi; 346 347 child = device_add_child_ordered(dev, order, name, unit); 348 if (child == NULL) 349 return (child); 350 devi = malloc(sizeof(struct gpiobus_ivar), M_DEVBUF, M_NOWAIT | M_ZERO); 351 if (devi == NULL) { 352 device_delete_child(dev, child); 353 return (0); 354 } 355 resource_list_init(&devi->rl); 356 device_set_ivars(child, devi); 357 358 return (child); 359} 360 361static void 362gpiobus_hinted_child(device_t bus, const char *dname, int dunit) 363{ 364 struct gpiobus_softc *sc = GPIOBUS_SOFTC(bus); 365 struct gpiobus_ivar *devi; 366 device_t child; 367 int irq, pins; 368 369 child = BUS_ADD_CHILD(bus, 0, dname, dunit); 370 devi = GPIOBUS_IVAR(child); 371 resource_int_value(dname, dunit, "pins", &pins); 372 if (gpiobus_parse_pins(sc, child, pins)) 373 device_delete_child(bus, child); 374 if (resource_int_value(dname, dunit, "irq", &irq) == 0) { 375 if (bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1) != 0) 376 device_printf(bus, 377 "warning: bus_set_resource() failed\n"); 378 } 379} 380 381static int 382gpiobus_set_resource(device_t dev, device_t child, int type, int rid, 383 u_long start, u_long count) 384{ 385 struct gpiobus_ivar *devi; 386 struct resource_list_entry *rle; 387 388 dprintf("%s: entry (%p, %p, %d, %d, %p, %ld)\n", 389 __func__, dev, child, type, rid, (void *)(intptr_t)start, count); 390 devi = GPIOBUS_IVAR(child); 391 rle = resource_list_add(&devi->rl, type, rid, start, 392 start + count - 1, count); 393 if (rle == NULL) 394 return (ENXIO); 395 396 return (0); 397} 398 399static struct resource * 400gpiobus_alloc_resource(device_t bus, device_t child, int type, int *rid, 401 u_long start, u_long end, u_long count, u_int flags) 402{ 403 struct gpiobus_softc *sc; 404 struct resource *rv; 405 struct resource_list *rl; 406 struct resource_list_entry *rle; 407 int isdefault; 408 409 if (type != SYS_RES_IRQ) 410 return (NULL); 411 isdefault = (start == 0UL && end == ~0UL && count == 1); 412 rle = NULL; 413 if (isdefault) { 414 rl = BUS_GET_RESOURCE_LIST(bus, child); 415 if (rl == NULL) 416 return (NULL); 417 rle = resource_list_find(rl, type, *rid); 418 if (rle == NULL) 419 return (NULL); 420 if (rle->res != NULL) 421 panic("%s: resource entry is busy", __func__); 422 start = rle->start; 423 count = rle->count; 424 end = rle->end; 425 } 426 sc = device_get_softc(bus); 427 rv = rman_reserve_resource(&sc->sc_intr_rman, start, end, count, flags, 428 child); 429 if (rv == NULL) 430 return (NULL); 431 rman_set_rid(rv, *rid); 432 if ((flags & RF_ACTIVE) != 0 && 433 bus_activate_resource(child, type, *rid, rv) != 0) { 434 rman_release_resource(rv); 435 return (NULL); 436 } 437 438 return (rv); 439} 440 441static int 442gpiobus_release_resource(device_t bus __unused, device_t child, int type, 443 int rid, struct resource *r) 444{ 445 int error; 446 447 if (rman_get_flags(r) & RF_ACTIVE) { 448 error = bus_deactivate_resource(child, type, rid, r); 449 if (error) 450 return (error); 451 } 452 453 return (rman_release_resource(r)); 454} 455 456static struct resource_list * 457gpiobus_get_resource_list(device_t bus __unused, device_t child) 458{ 459 struct gpiobus_ivar *ivar; 460 461 ivar = GPIOBUS_IVAR(child); 462 463 return (&ivar->rl); 464} 465 466static int 467gpiobus_acquire_bus(device_t busdev, device_t child, int how) 468{ 469 struct gpiobus_softc *sc; 470 471 sc = device_get_softc(busdev); 472 GPIOBUS_ASSERT_UNLOCKED(sc); 473 GPIOBUS_LOCK(sc); 474 if (sc->sc_owner != NULL) { 475 if (how == GPIOBUS_DONTWAIT) { 476 GPIOBUS_UNLOCK(sc); 477 return (EWOULDBLOCK); 478 } 479 while (sc->sc_owner != NULL) 480 mtx_sleep(sc, &sc->sc_mtx, 0, "gpiobuswait", 0); 481 } 482 sc->sc_owner = child; 483 GPIOBUS_UNLOCK(sc); 484 485 return (0); 486} 487 488static void 489gpiobus_release_bus(device_t busdev, device_t child) 490{ 491 struct gpiobus_softc *sc; 492 493 sc = device_get_softc(busdev); 494 GPIOBUS_ASSERT_UNLOCKED(sc); 495 GPIOBUS_LOCK(sc); 496 if (sc->sc_owner == NULL) 497 panic("gpiobus: releasing unowned bus."); 498 if (sc->sc_owner != child) 499 panic("gpiobus: you don't own the bus. game over."); 500 sc->sc_owner = NULL; 501 wakeup(sc); 502 GPIOBUS_UNLOCK(sc); 503} 504 505static int 506gpiobus_pin_setflags(device_t dev, device_t child, uint32_t pin, 507 uint32_t flags) 508{ 509 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); 510 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 511 uint32_t caps; 512 513 if (pin >= devi->npins) 514 return (EINVAL); 515 if (GPIO_PIN_GETCAPS(sc->sc_dev, devi->pins[pin], &caps) != 0) 516 return (EINVAL); 517 if (gpio_check_flags(caps, flags) != 0) 518 return (EINVAL); 519 520 return (GPIO_PIN_SETFLAGS(sc->sc_dev, devi->pins[pin], flags)); 521} 522 523static int 524gpiobus_pin_getflags(device_t dev, device_t child, uint32_t pin, 525 uint32_t *flags) 526{ 527 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); 528 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 529 530 if (pin >= devi->npins) 531 return (EINVAL); 532 533 return GPIO_PIN_GETFLAGS(sc->sc_dev, devi->pins[pin], flags); 534} 535 536static int 537gpiobus_pin_getcaps(device_t dev, device_t child, uint32_t pin, 538 uint32_t *caps) 539{ 540 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); 541 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 542 543 if (pin >= devi->npins) 544 return (EINVAL); 545 546 return GPIO_PIN_GETCAPS(sc->sc_dev, devi->pins[pin], caps); 547} 548 549static int 550gpiobus_pin_set(device_t dev, device_t child, uint32_t pin, 551 unsigned int value) 552{ 553 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); 554 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 555 556 if (pin >= devi->npins) 557 return (EINVAL); 558 559 return GPIO_PIN_SET(sc->sc_dev, devi->pins[pin], value); 560} 561 562static int 563gpiobus_pin_get(device_t dev, device_t child, uint32_t pin, 564 unsigned int *value) 565{ 566 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); 567 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 568 569 if (pin >= devi->npins) 570 return (EINVAL); 571 572 return GPIO_PIN_GET(sc->sc_dev, devi->pins[pin], value); 573} 574 575static int 576gpiobus_pin_toggle(device_t dev, device_t child, uint32_t pin) 577{ 578 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); 579 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 580 581 if (pin >= devi->npins) 582 return (EINVAL); 583 584 return GPIO_PIN_TOGGLE(sc->sc_dev, devi->pins[pin]); 585} 586 587static device_method_t gpiobus_methods[] = { 588 /* Device interface */ 589 DEVMETHOD(device_probe, gpiobus_probe), 590 DEVMETHOD(device_attach, gpiobus_attach), 591 DEVMETHOD(device_detach, gpiobus_detach), 592 DEVMETHOD(device_shutdown, bus_generic_shutdown), 593 DEVMETHOD(device_suspend, gpiobus_suspend), 594 DEVMETHOD(device_resume, gpiobus_resume), 595 596 /* Bus interface */ 597 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 598 DEVMETHOD(bus_config_intr, bus_generic_config_intr), 599 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 600 DEVMETHOD(bus_set_resource, gpiobus_set_resource), 601 DEVMETHOD(bus_alloc_resource, gpiobus_alloc_resource), 602 DEVMETHOD(bus_release_resource, gpiobus_release_resource), 603 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 604 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 605 DEVMETHOD(bus_get_resource_list, gpiobus_get_resource_list), 606 DEVMETHOD(bus_add_child, gpiobus_add_child), 607 DEVMETHOD(bus_print_child, gpiobus_print_child), 608 DEVMETHOD(bus_child_pnpinfo_str, gpiobus_child_pnpinfo_str), 609 DEVMETHOD(bus_child_location_str, gpiobus_child_location_str), 610 DEVMETHOD(bus_hinted_child, gpiobus_hinted_child), 611 612 /* GPIO protocol */ 613 DEVMETHOD(gpiobus_acquire_bus, gpiobus_acquire_bus), 614 DEVMETHOD(gpiobus_release_bus, gpiobus_release_bus), 615 DEVMETHOD(gpiobus_pin_getflags, gpiobus_pin_getflags), 616 DEVMETHOD(gpiobus_pin_getcaps, gpiobus_pin_getcaps), 617 DEVMETHOD(gpiobus_pin_setflags, gpiobus_pin_setflags), 618 DEVMETHOD(gpiobus_pin_get, gpiobus_pin_get), 619 DEVMETHOD(gpiobus_pin_set, gpiobus_pin_set), 620 DEVMETHOD(gpiobus_pin_toggle, gpiobus_pin_toggle), 621 622 DEVMETHOD_END 623}; 624 625driver_t gpiobus_driver = { 626 "gpiobus", 627 gpiobus_methods, 628 sizeof(struct gpiobus_softc) 629}; 630 631devclass_t gpiobus_devclass; 632 633DRIVER_MODULE(gpiobus, gpio, gpiobus_driver, gpiobus_devclass, 0, 0); 634MODULE_VERSION(gpiobus, 1);
| 159gpiobus_init_softc(device_t dev) 160{ 161 struct gpiobus_softc *sc; 162 163 sc = GPIOBUS_SOFTC(dev); 164 sc->sc_busdev = dev; 165 sc->sc_dev = device_get_parent(dev); 166 sc->sc_intr_rman.rm_type = RMAN_ARRAY; 167 sc->sc_intr_rman.rm_descr = "GPIO Interrupts"; 168 if (rman_init(&sc->sc_intr_rman) != 0 || 169 rman_manage_region(&sc->sc_intr_rman, 0, ~0) != 0) 170 panic("%s: failed to set up rman.", __func__); 171 172 if (GPIO_PIN_MAX(sc->sc_dev, &sc->sc_npins) != 0) 173 return (ENXIO); 174 175 KASSERT(sc->sc_npins != 0, ("GPIO device with no pins")); 176 177 /* Pins = GPIO_PIN_MAX() + 1 */ 178 sc->sc_npins++; 179 180 sc->sc_pins_mapped = malloc(sizeof(int) * sc->sc_npins, M_DEVBUF, 181 M_NOWAIT | M_ZERO); 182 if (sc->sc_pins_mapped == NULL) 183 return (ENOMEM); 184 185 /* Initialize the bus lock. */ 186 GPIOBUS_LOCK_INIT(sc); 187 188 return (0); 189} 190 191static int 192gpiobus_parse_pins(struct gpiobus_softc *sc, device_t child, int mask) 193{ 194 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 195 int i, npins; 196 197 npins = 0; 198 for (i = 0; i < 32; i++) { 199 if (mask & (1 << i)) 200 npins++; 201 } 202 203 if (npins == 0) { 204 device_printf(child, "empty pin mask\n"); 205 return (EINVAL); 206 } 207 208 devi->npins = npins; 209 devi->pins = malloc(sizeof(uint32_t) * devi->npins, M_DEVBUF, 210 M_NOWAIT | M_ZERO); 211 212 if (!devi->pins) 213 return (ENOMEM); 214 215 npins = 0; 216 for (i = 0; i < 32; i++) { 217 218 if ((mask & (1 << i)) == 0) 219 continue; 220 221 if (i >= sc->sc_npins) { 222 device_printf(child, 223 "invalid pin %d, max: %d\n", i, sc->sc_npins - 1); 224 free(devi->pins, M_DEVBUF); 225 return (EINVAL); 226 } 227 228 devi->pins[npins++] = i; 229 /* 230 * Mark pin as mapped and give warning if it's already mapped 231 */ 232 if (sc->sc_pins_mapped[i]) { 233 device_printf(child, 234 "warning: pin %d is already mapped\n", i); 235 free(devi->pins, M_DEVBUF); 236 return (EINVAL); 237 } 238 sc->sc_pins_mapped[i] = 1; 239 } 240 241 return (0); 242} 243 244static int 245gpiobus_probe(device_t dev) 246{ 247 device_set_desc(dev, "GPIO bus"); 248 249 return (BUS_PROBE_GENERIC); 250} 251 252static int 253gpiobus_attach(device_t dev) 254{ 255 int err; 256 257 err = gpiobus_init_softc(dev); 258 if (err != 0) 259 return (err); 260 261 /* 262 * Get parent's pins and mark them as unmapped 263 */ 264 bus_generic_probe(dev); 265 bus_enumerate_hinted_children(dev); 266 267 return (bus_generic_attach(dev)); 268} 269 270/* 271 * Since this is not a self-enumerating bus, and since we always add 272 * children in attach, we have to always delete children here. 273 */ 274static int 275gpiobus_detach(device_t dev) 276{ 277 struct gpiobus_softc *sc; 278 struct gpiobus_ivar *devi; 279 device_t *devlist; 280 int i, err, ndevs; 281 282 sc = GPIOBUS_SOFTC(dev); 283 KASSERT(mtx_initialized(&sc->sc_mtx), 284 ("gpiobus mutex not initialized")); 285 GPIOBUS_LOCK_DESTROY(sc); 286 287 if ((err = bus_generic_detach(dev)) != 0) 288 return (err); 289 290 if ((err = device_get_children(dev, &devlist, &ndevs)) != 0) 291 return (err); 292 for (i = 0; i < ndevs; i++) { 293 device_delete_child(dev, devlist[i]); 294 devi = GPIOBUS_IVAR(devlist[i]); 295 if (devi->pins) { 296 free(devi->pins, M_DEVBUF); 297 devi->pins = NULL; 298 } 299 } 300 free(devlist, M_TEMP); 301 302 if (sc->sc_pins_mapped) { 303 free(sc->sc_pins_mapped, M_DEVBUF); 304 sc->sc_pins_mapped = NULL; 305 } 306 307 return (0); 308} 309 310static int 311gpiobus_suspend(device_t dev) 312{ 313 314 return (bus_generic_suspend(dev)); 315} 316 317static int 318gpiobus_resume(device_t dev) 319{ 320 321 return (bus_generic_resume(dev)); 322} 323 324static int 325gpiobus_print_child(device_t dev, device_t child) 326{ 327 char pins[128]; 328 int retval = 0; 329 struct gpiobus_ivar *devi; 330 331 devi = GPIOBUS_IVAR(child); 332 memset(pins, 0, sizeof(pins)); 333 retval += bus_print_child_header(dev, child); 334 retval += printf(" at pin(s) "); 335 gpiobus_print_pins(devi, pins, sizeof(pins)); 336 retval += printf("%s", pins); 337 resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%ld"); 338 retval += bus_print_child_footer(dev, child); 339 340 return (retval); 341} 342 343static int 344gpiobus_child_location_str(device_t bus, device_t child, char *buf, 345 size_t buflen) 346{ 347 struct gpiobus_ivar *devi; 348 349 devi = GPIOBUS_IVAR(child); 350 strlcpy(buf, "pin(s)=", buflen); 351 gpiobus_print_pins(devi, buf, buflen); 352 353 return (0); 354} 355 356static int 357gpiobus_child_pnpinfo_str(device_t bus, device_t child, char *buf, 358 size_t buflen) 359{ 360 361 *buf = '\0'; 362 return (0); 363} 364 365static device_t 366gpiobus_add_child(device_t dev, u_int order, const char *name, int unit) 367{ 368 device_t child; 369 struct gpiobus_ivar *devi; 370 371 child = device_add_child_ordered(dev, order, name, unit); 372 if (child == NULL) 373 return (child); 374 devi = malloc(sizeof(struct gpiobus_ivar), M_DEVBUF, M_NOWAIT | M_ZERO); 375 if (devi == NULL) { 376 device_delete_child(dev, child); 377 return (0); 378 } 379 resource_list_init(&devi->rl); 380 device_set_ivars(child, devi); 381 382 return (child); 383} 384 385static void 386gpiobus_hinted_child(device_t bus, const char *dname, int dunit) 387{ 388 struct gpiobus_softc *sc = GPIOBUS_SOFTC(bus); 389 struct gpiobus_ivar *devi; 390 device_t child; 391 int irq, pins; 392 393 child = BUS_ADD_CHILD(bus, 0, dname, dunit); 394 devi = GPIOBUS_IVAR(child); 395 resource_int_value(dname, dunit, "pins", &pins); 396 if (gpiobus_parse_pins(sc, child, pins)) 397 device_delete_child(bus, child); 398 if (resource_int_value(dname, dunit, "irq", &irq) == 0) { 399 if (bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1) != 0) 400 device_printf(bus, 401 "warning: bus_set_resource() failed\n"); 402 } 403} 404 405static int 406gpiobus_set_resource(device_t dev, device_t child, int type, int rid, 407 u_long start, u_long count) 408{ 409 struct gpiobus_ivar *devi; 410 struct resource_list_entry *rle; 411 412 dprintf("%s: entry (%p, %p, %d, %d, %p, %ld)\n", 413 __func__, dev, child, type, rid, (void *)(intptr_t)start, count); 414 devi = GPIOBUS_IVAR(child); 415 rle = resource_list_add(&devi->rl, type, rid, start, 416 start + count - 1, count); 417 if (rle == NULL) 418 return (ENXIO); 419 420 return (0); 421} 422 423static struct resource * 424gpiobus_alloc_resource(device_t bus, device_t child, int type, int *rid, 425 u_long start, u_long end, u_long count, u_int flags) 426{ 427 struct gpiobus_softc *sc; 428 struct resource *rv; 429 struct resource_list *rl; 430 struct resource_list_entry *rle; 431 int isdefault; 432 433 if (type != SYS_RES_IRQ) 434 return (NULL); 435 isdefault = (start == 0UL && end == ~0UL && count == 1); 436 rle = NULL; 437 if (isdefault) { 438 rl = BUS_GET_RESOURCE_LIST(bus, child); 439 if (rl == NULL) 440 return (NULL); 441 rle = resource_list_find(rl, type, *rid); 442 if (rle == NULL) 443 return (NULL); 444 if (rle->res != NULL) 445 panic("%s: resource entry is busy", __func__); 446 start = rle->start; 447 count = rle->count; 448 end = rle->end; 449 } 450 sc = device_get_softc(bus); 451 rv = rman_reserve_resource(&sc->sc_intr_rman, start, end, count, flags, 452 child); 453 if (rv == NULL) 454 return (NULL); 455 rman_set_rid(rv, *rid); 456 if ((flags & RF_ACTIVE) != 0 && 457 bus_activate_resource(child, type, *rid, rv) != 0) { 458 rman_release_resource(rv); 459 return (NULL); 460 } 461 462 return (rv); 463} 464 465static int 466gpiobus_release_resource(device_t bus __unused, device_t child, int type, 467 int rid, struct resource *r) 468{ 469 int error; 470 471 if (rman_get_flags(r) & RF_ACTIVE) { 472 error = bus_deactivate_resource(child, type, rid, r); 473 if (error) 474 return (error); 475 } 476 477 return (rman_release_resource(r)); 478} 479 480static struct resource_list * 481gpiobus_get_resource_list(device_t bus __unused, device_t child) 482{ 483 struct gpiobus_ivar *ivar; 484 485 ivar = GPIOBUS_IVAR(child); 486 487 return (&ivar->rl); 488} 489 490static int 491gpiobus_acquire_bus(device_t busdev, device_t child, int how) 492{ 493 struct gpiobus_softc *sc; 494 495 sc = device_get_softc(busdev); 496 GPIOBUS_ASSERT_UNLOCKED(sc); 497 GPIOBUS_LOCK(sc); 498 if (sc->sc_owner != NULL) { 499 if (how == GPIOBUS_DONTWAIT) { 500 GPIOBUS_UNLOCK(sc); 501 return (EWOULDBLOCK); 502 } 503 while (sc->sc_owner != NULL) 504 mtx_sleep(sc, &sc->sc_mtx, 0, "gpiobuswait", 0); 505 } 506 sc->sc_owner = child; 507 GPIOBUS_UNLOCK(sc); 508 509 return (0); 510} 511 512static void 513gpiobus_release_bus(device_t busdev, device_t child) 514{ 515 struct gpiobus_softc *sc; 516 517 sc = device_get_softc(busdev); 518 GPIOBUS_ASSERT_UNLOCKED(sc); 519 GPIOBUS_LOCK(sc); 520 if (sc->sc_owner == NULL) 521 panic("gpiobus: releasing unowned bus."); 522 if (sc->sc_owner != child) 523 panic("gpiobus: you don't own the bus. game over."); 524 sc->sc_owner = NULL; 525 wakeup(sc); 526 GPIOBUS_UNLOCK(sc); 527} 528 529static int 530gpiobus_pin_setflags(device_t dev, device_t child, uint32_t pin, 531 uint32_t flags) 532{ 533 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); 534 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 535 uint32_t caps; 536 537 if (pin >= devi->npins) 538 return (EINVAL); 539 if (GPIO_PIN_GETCAPS(sc->sc_dev, devi->pins[pin], &caps) != 0) 540 return (EINVAL); 541 if (gpio_check_flags(caps, flags) != 0) 542 return (EINVAL); 543 544 return (GPIO_PIN_SETFLAGS(sc->sc_dev, devi->pins[pin], flags)); 545} 546 547static int 548gpiobus_pin_getflags(device_t dev, device_t child, uint32_t pin, 549 uint32_t *flags) 550{ 551 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); 552 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 553 554 if (pin >= devi->npins) 555 return (EINVAL); 556 557 return GPIO_PIN_GETFLAGS(sc->sc_dev, devi->pins[pin], flags); 558} 559 560static int 561gpiobus_pin_getcaps(device_t dev, device_t child, uint32_t pin, 562 uint32_t *caps) 563{ 564 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); 565 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 566 567 if (pin >= devi->npins) 568 return (EINVAL); 569 570 return GPIO_PIN_GETCAPS(sc->sc_dev, devi->pins[pin], caps); 571} 572 573static int 574gpiobus_pin_set(device_t dev, device_t child, uint32_t pin, 575 unsigned int value) 576{ 577 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); 578 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 579 580 if (pin >= devi->npins) 581 return (EINVAL); 582 583 return GPIO_PIN_SET(sc->sc_dev, devi->pins[pin], value); 584} 585 586static int 587gpiobus_pin_get(device_t dev, device_t child, uint32_t pin, 588 unsigned int *value) 589{ 590 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); 591 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 592 593 if (pin >= devi->npins) 594 return (EINVAL); 595 596 return GPIO_PIN_GET(sc->sc_dev, devi->pins[pin], value); 597} 598 599static int 600gpiobus_pin_toggle(device_t dev, device_t child, uint32_t pin) 601{ 602 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); 603 struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); 604 605 if (pin >= devi->npins) 606 return (EINVAL); 607 608 return GPIO_PIN_TOGGLE(sc->sc_dev, devi->pins[pin]); 609} 610 611static device_method_t gpiobus_methods[] = { 612 /* Device interface */ 613 DEVMETHOD(device_probe, gpiobus_probe), 614 DEVMETHOD(device_attach, gpiobus_attach), 615 DEVMETHOD(device_detach, gpiobus_detach), 616 DEVMETHOD(device_shutdown, bus_generic_shutdown), 617 DEVMETHOD(device_suspend, gpiobus_suspend), 618 DEVMETHOD(device_resume, gpiobus_resume), 619 620 /* Bus interface */ 621 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 622 DEVMETHOD(bus_config_intr, bus_generic_config_intr), 623 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 624 DEVMETHOD(bus_set_resource, gpiobus_set_resource), 625 DEVMETHOD(bus_alloc_resource, gpiobus_alloc_resource), 626 DEVMETHOD(bus_release_resource, gpiobus_release_resource), 627 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 628 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 629 DEVMETHOD(bus_get_resource_list, gpiobus_get_resource_list), 630 DEVMETHOD(bus_add_child, gpiobus_add_child), 631 DEVMETHOD(bus_print_child, gpiobus_print_child), 632 DEVMETHOD(bus_child_pnpinfo_str, gpiobus_child_pnpinfo_str), 633 DEVMETHOD(bus_child_location_str, gpiobus_child_location_str), 634 DEVMETHOD(bus_hinted_child, gpiobus_hinted_child), 635 636 /* GPIO protocol */ 637 DEVMETHOD(gpiobus_acquire_bus, gpiobus_acquire_bus), 638 DEVMETHOD(gpiobus_release_bus, gpiobus_release_bus), 639 DEVMETHOD(gpiobus_pin_getflags, gpiobus_pin_getflags), 640 DEVMETHOD(gpiobus_pin_getcaps, gpiobus_pin_getcaps), 641 DEVMETHOD(gpiobus_pin_setflags, gpiobus_pin_setflags), 642 DEVMETHOD(gpiobus_pin_get, gpiobus_pin_get), 643 DEVMETHOD(gpiobus_pin_set, gpiobus_pin_set), 644 DEVMETHOD(gpiobus_pin_toggle, gpiobus_pin_toggle), 645 646 DEVMETHOD_END 647}; 648 649driver_t gpiobus_driver = { 650 "gpiobus", 651 gpiobus_methods, 652 sizeof(struct gpiobus_softc) 653}; 654 655devclass_t gpiobus_devclass; 656 657DRIVER_MODULE(gpiobus, gpio, gpiobus_driver, gpiobus_devclass, 0, 0); 658MODULE_VERSION(gpiobus, 1);
|