1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 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/param.h> 30 #include <sys/systm.h> 31 #include <sys/bus.h> 32 #include <sys/conf.h> 33 #include <sys/gpio.h> 34 #include <sys/ioccom.h> 35 #include <sys/filio.h> 36 #include <sys/fcntl.h> 37 #include <sys/sigio.h> 38 #include <sys/signalvar.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/uio.h> 42 #include <sys/poll.h> 43 #include <sys/selinfo.h> 44 #include <sys/module.h> 45 46 #include <dev/gpio/gpiobusvar.h> 47 48 #include "gpiobus_if.h" 49 50 #undef GPIOC_DEBUG 51 #ifdef GPIOC_DEBUG 52 #define dprintf printf 53 #define ddevice_printf device_printf 54 #else 55 #define dprintf(x, arg...) 56 #define ddevice_printf(dev, x, arg...) 57 #endif 58 59 struct gpioc_softc { 60 device_t sc_dev; /* gpiocX dev */ 61 device_t sc_pdev; /* gpiobusX dev */ 62 struct cdev *sc_ctl_dev; /* controller device */ 63 int sc_unit; 64 int sc_npins; 65 struct gpioc_pin_intr *sc_pin_intr; 66 }; 67 68 struct gpioc_pin_intr { 69 struct gpioc_softc *sc; 70 gpio_pin_t pin; 71 uint32_t intr_mode; 72 bool config_locked; 73 int intr_rid; 74 struct resource *intr_res; 75 void *intr_cookie; 76 struct mtx mtx; 77 SLIST_HEAD(gpioc_privs_list, gpioc_privs) privs; 78 }; 79 80 81 struct gpioc_cdevpriv { 82 struct gpioc_softc *sc; 83 struct selinfo selinfo; 84 bool async; 85 uint8_t report_option; 86 struct sigio *sigio; 87 struct mtx mtx; 88 struct gpioc_pin_event *events; 89 int numevents; 90 int evidx_head; 91 int evidx_tail; 92 SLIST_HEAD(gpioc_pins_list, gpioc_pins) pins; 93 }; 94 95 struct gpioc_privs { 96 struct gpioc_cdevpriv *priv; 97 SLIST_ENTRY(gpioc_privs) next; 98 }; 99 100 struct gpioc_pins { 101 struct gpioc_pin_intr *pin; 102 int eventcount; 103 int firstevent; 104 SLIST_ENTRY(gpioc_pins) next; 105 }; 106 107 struct gpioc_pin_event { 108 struct gpioc_pins *privpin; 109 sbintime_t event_time; 110 bool event_pin_state; 111 }; 112 113 static MALLOC_DEFINE(M_GPIOC, "gpioc", "gpioc device data"); 114 115 static int gpioc_allocate_pin_intr(struct gpioc_softc*, 116 struct gpioc_pin_intr*, uint32_t, uint32_t); 117 static int gpioc_release_pin_intr(struct gpioc_softc*, 118 struct gpioc_pin_intr*); 119 static int gpioc_attach_priv_pin(struct gpioc_cdevpriv*, 120 struct gpioc_pin_intr*); 121 static int gpioc_detach_priv_pin(struct gpioc_cdevpriv*, 122 struct gpioc_pin_intr*); 123 static bool gpioc_intr_reconfig_allowed(struct gpioc_cdevpriv*, 124 struct gpioc_pin_intr *intr_conf); 125 static uint32_t gpioc_get_intr_config(struct gpioc_softc*, 126 struct gpioc_cdevpriv*, uint32_t pin); 127 static int gpioc_set_intr_config(struct gpioc_softc*, 128 struct gpioc_cdevpriv*, uint32_t, uint32_t); 129 static void gpioc_interrupt_handler(void*); 130 131 static int gpioc_kqread(struct knote*, long); 132 static void gpioc_kqdetach(struct knote*); 133 134 static int gpioc_probe(device_t dev); 135 static int gpioc_attach(device_t dev); 136 static int gpioc_detach(device_t dev); 137 138 static void gpioc_cdevpriv_dtor(void*); 139 140 static d_open_t gpioc_open; 141 static d_read_t gpioc_read; 142 static d_ioctl_t gpioc_ioctl; 143 static d_poll_t gpioc_poll; 144 static d_kqfilter_t gpioc_kqfilter; 145 146 static struct cdevsw gpioc_cdevsw = { 147 .d_version = D_VERSION, 148 .d_open = gpioc_open, 149 .d_read = gpioc_read, 150 .d_ioctl = gpioc_ioctl, 151 .d_poll = gpioc_poll, 152 .d_kqfilter = gpioc_kqfilter, 153 .d_name = "gpioc", 154 }; 155 156 static const struct filterops gpioc_read_filterops = { 157 .f_isfd = true, 158 .f_attach = NULL, 159 .f_detach = gpioc_kqdetach, 160 .f_event = gpioc_kqread, 161 .f_touch = NULL 162 }; 163 164 static struct gpioc_pin_event * 165 next_head_event(struct gpioc_cdevpriv *priv) 166 { 167 struct gpioc_pin_event *rv; 168 169 rv = &priv->events[priv->evidx_head++]; 170 if (priv->evidx_head == priv->numevents) 171 priv->evidx_head = 0; 172 return (rv); 173 } 174 175 static struct gpioc_pin_event * 176 next_tail_event(struct gpioc_cdevpriv *priv) 177 { 178 struct gpioc_pin_event *rv; 179 180 rv = &priv->events[priv->evidx_tail++]; 181 if (priv->evidx_tail == priv->numevents) 182 priv->evidx_tail = 0; 183 return (rv); 184 } 185 186 static size_t 187 number_of_events(struct gpioc_cdevpriv *priv) 188 { 189 if (priv->evidx_head >= priv->evidx_tail) 190 return (priv->evidx_head - priv->evidx_tail); 191 else 192 return (priv->numevents + priv->evidx_head - priv->evidx_tail); 193 } 194 195 static int 196 gpioc_allocate_pin_intr(struct gpioc_softc *sc, 197 struct gpioc_pin_intr *intr_conf, uint32_t pin, uint32_t flags) 198 { 199 int err; 200 201 intr_conf->config_locked = true; 202 mtx_unlock(&intr_conf->mtx); 203 204 MPASS(intr_conf->pin == NULL); 205 err = gpio_pin_get_by_bus_pinnum(sc->sc_pdev, pin, &intr_conf->pin); 206 if (err != 0) 207 goto error_exit; 208 209 intr_conf->intr_res = gpio_alloc_intr_resource(sc->sc_dev, 210 &intr_conf->intr_rid, RF_ACTIVE, intr_conf->pin, flags); 211 if (intr_conf->intr_res == NULL) { 212 err = ENXIO; 213 goto error_pin; 214 } 215 216 err = bus_setup_intr(sc->sc_dev, intr_conf->intr_res, 217 INTR_TYPE_MISC | INTR_MPSAFE, NULL, gpioc_interrupt_handler, 218 intr_conf, &intr_conf->intr_cookie); 219 if (err != 0) { 220 bus_release_resource(sc->sc_dev, intr_conf->intr_res); 221 intr_conf->intr_res = NULL; 222 goto error_pin; 223 } 224 225 intr_conf->intr_mode = flags; 226 227 error_exit: 228 mtx_lock(&intr_conf->mtx); 229 intr_conf->config_locked = false; 230 wakeup(&intr_conf->config_locked); 231 232 return (err); 233 234 error_pin: 235 gpio_pin_release(intr_conf->pin); 236 intr_conf->pin = NULL; 237 goto error_exit; 238 } 239 240 static int 241 gpioc_release_pin_intr(struct gpioc_softc *sc, struct gpioc_pin_intr *intr_conf) 242 { 243 int err; 244 245 intr_conf->config_locked = true; 246 mtx_unlock(&intr_conf->mtx); 247 248 if (intr_conf->intr_cookie != NULL) { 249 err = bus_teardown_intr(sc->sc_dev, intr_conf->intr_res, 250 intr_conf->intr_cookie); 251 if (err != 0) 252 goto error_exit; 253 else 254 intr_conf->intr_cookie = NULL; 255 } 256 257 if (intr_conf->intr_res != NULL) { 258 err = bus_release_resource(sc->sc_dev, SYS_RES_IRQ, 259 intr_conf->intr_rid, intr_conf->intr_res); 260 if (err != 0) 261 goto error_exit; 262 else { 263 intr_conf->intr_rid = 0; 264 intr_conf->intr_res = NULL; 265 } 266 } 267 268 gpio_pin_release(intr_conf->pin); 269 intr_conf->pin = NULL; 270 271 intr_conf->intr_mode = 0; 272 err = 0; 273 274 error_exit: 275 mtx_lock(&intr_conf->mtx); 276 intr_conf->config_locked = false; 277 wakeup(&intr_conf->config_locked); 278 279 return (err); 280 } 281 282 static int 283 gpioc_attach_priv_pin(struct gpioc_cdevpriv *priv, 284 struct gpioc_pin_intr *intr_conf) 285 { 286 struct gpioc_privs *priv_link; 287 struct gpioc_pins *pin_link; 288 unsigned int consistency_a __diagused; 289 unsigned int consistency_b __diagused; 290 291 consistency_a = 0; 292 consistency_b = 0; 293 mtx_assert(&intr_conf->mtx, MA_OWNED); 294 mtx_lock(&priv->mtx); 295 SLIST_FOREACH(priv_link, &intr_conf->privs, next) { 296 if (priv_link->priv == priv) 297 consistency_a++; 298 } 299 KASSERT(consistency_a <= 1, 300 ("inconsistent links between pin config and cdevpriv")); 301 SLIST_FOREACH(pin_link, &priv->pins, next) { 302 if (pin_link->pin == intr_conf) 303 consistency_b++; 304 } 305 KASSERT(consistency_a == consistency_b, 306 ("inconsistent links between pin config and cdevpriv")); 307 if (consistency_a == 1 && consistency_b == 1) { 308 mtx_unlock(&priv->mtx); 309 return (EEXIST); 310 } 311 priv_link = malloc(sizeof(struct gpioc_privs), M_GPIOC, 312 M_NOWAIT | M_ZERO); 313 if (priv_link == NULL) 314 { 315 mtx_unlock(&priv->mtx); 316 return (ENOMEM); 317 } 318 pin_link = malloc(sizeof(struct gpioc_pins), M_GPIOC, 319 M_NOWAIT | M_ZERO); 320 if (pin_link == NULL) { 321 mtx_unlock(&priv->mtx); 322 return (ENOMEM); 323 } 324 priv_link->priv = priv; 325 pin_link->pin = intr_conf; 326 SLIST_INSERT_HEAD(&intr_conf->privs, priv_link, next); 327 SLIST_INSERT_HEAD(&priv->pins, pin_link, next); 328 mtx_unlock(&priv->mtx); 329 330 return (0); 331 } 332 333 static int 334 gpioc_detach_priv_pin(struct gpioc_cdevpriv *priv, 335 struct gpioc_pin_intr *intr_conf) 336 { 337 struct gpioc_privs *priv_link, *priv_link_temp; 338 struct gpioc_pins *pin_link, *pin_link_temp; 339 unsigned int consistency_a __diagused; 340 unsigned int consistency_b __diagused; 341 342 consistency_a = 0; 343 consistency_b = 0; 344 mtx_assert(&intr_conf->mtx, MA_OWNED); 345 mtx_lock(&priv->mtx); 346 SLIST_FOREACH_SAFE(priv_link, &intr_conf->privs, next, priv_link_temp) { 347 if (priv_link->priv == priv) { 348 SLIST_REMOVE(&intr_conf->privs, priv_link, gpioc_privs, 349 next); 350 free(priv_link, M_GPIOC); 351 consistency_a++; 352 } 353 } 354 KASSERT(consistency_a <= 1, 355 ("inconsistent links between pin config and cdevpriv")); 356 SLIST_FOREACH_SAFE(pin_link, &priv->pins, next, pin_link_temp) { 357 if (pin_link->pin == intr_conf) { 358 /* 359 * If the pin we're removing has events in the priv's 360 * event fifo, we can't leave dangling pointers from 361 * those events to the gpioc_pins struct we're about to 362 * free. We also can't remove random items and leave 363 * holes in the events fifo, so just empty it out. 364 */ 365 if (pin_link->eventcount > 0) { 366 priv->evidx_head = priv->evidx_tail = 0; 367 } 368 SLIST_REMOVE(&priv->pins, pin_link, gpioc_pins, next); 369 free(pin_link, M_GPIOC); 370 consistency_b++; 371 } 372 } 373 KASSERT(consistency_a == consistency_b, 374 ("inconsistent links between pin config and cdevpriv")); 375 mtx_unlock(&priv->mtx); 376 377 return (0); 378 } 379 380 static bool 381 gpioc_intr_reconfig_allowed(struct gpioc_cdevpriv *priv, 382 struct gpioc_pin_intr *intr_conf) 383 { 384 struct gpioc_privs *priv_link; 385 386 mtx_assert(&intr_conf->mtx, MA_OWNED); 387 388 if (SLIST_EMPTY(&intr_conf->privs)) 389 return (true); 390 391 SLIST_FOREACH(priv_link, &intr_conf->privs, next) { 392 if (priv_link->priv != priv) 393 return (false); 394 } 395 396 return (true); 397 } 398 399 400 static uint32_t 401 gpioc_get_intr_config(struct gpioc_softc *sc, struct gpioc_cdevpriv *priv, 402 uint32_t pin) 403 { 404 struct gpioc_pin_intr *intr_conf = &sc->sc_pin_intr[pin]; 405 struct gpioc_privs *priv_link; 406 uint32_t flags; 407 408 flags = intr_conf->intr_mode; 409 410 if (flags == 0) 411 return (0); 412 413 mtx_lock(&intr_conf->mtx); 414 SLIST_FOREACH(priv_link, &intr_conf->privs, next) { 415 if (priv_link->priv == priv) { 416 flags |= GPIO_INTR_ATTACHED; 417 break; 418 } 419 } 420 mtx_unlock(&intr_conf->mtx); 421 422 return (flags); 423 } 424 425 static int 426 gpioc_set_intr_config(struct gpioc_softc *sc, struct gpioc_cdevpriv *priv, 427 uint32_t pin, uint32_t flags) 428 { 429 struct gpioc_pin_intr *intr_conf = &sc->sc_pin_intr[pin]; 430 int res; 431 432 res = 0; 433 if (intr_conf->intr_mode == 0 && flags == 0) { 434 /* No interrupt configured and none requested: Do nothing. */ 435 return (0); 436 } 437 mtx_lock(&intr_conf->mtx); 438 while (intr_conf->config_locked == true) 439 mtx_sleep(&intr_conf->config_locked, &intr_conf->mtx, 0, 440 "gpicfg", 0); 441 if (intr_conf->intr_mode == 0 && flags != 0) { 442 /* 443 * No interrupt is configured, but one is requested: Allocate 444 * and setup interrupt on the according pin. 445 */ 446 res = gpioc_allocate_pin_intr(sc, intr_conf, pin, flags); 447 if (res == 0) 448 res = gpioc_attach_priv_pin(priv, intr_conf); 449 if (res == EEXIST) 450 res = 0; 451 } else if (intr_conf->intr_mode == flags) { 452 /* 453 * Same interrupt requested as already configured: Attach the 454 * cdevpriv to the corresponding pin. 455 */ 456 res = gpioc_attach_priv_pin(priv, intr_conf); 457 if (res == EEXIST) 458 res = 0; 459 } else if (intr_conf->intr_mode != 0 && flags == 0) { 460 /* 461 * Interrupt configured, but none requested: Teardown and 462 * release the pin when no other cdevpriv is attached. Otherwise 463 * just detach pin and cdevpriv from each other. 464 */ 465 if (gpioc_intr_reconfig_allowed(priv, intr_conf)) { 466 res = gpioc_release_pin_intr(sc, intr_conf); 467 } 468 if (res == 0) 469 res = gpioc_detach_priv_pin(priv, intr_conf); 470 } else { 471 /* 472 * Other flag requested than configured: Reconfigure when no 473 * other cdevpriv is are attached to the pin. 474 */ 475 if (!gpioc_intr_reconfig_allowed(priv, intr_conf)) 476 res = EBUSY; 477 else { 478 res = gpioc_release_pin_intr(sc, intr_conf); 479 if (res == 0) 480 res = gpioc_allocate_pin_intr(sc, intr_conf, 481 pin, flags); 482 if (res == 0) 483 res = gpioc_attach_priv_pin(priv, intr_conf); 484 if (res == EEXIST) 485 res = 0; 486 } 487 } 488 mtx_unlock(&intr_conf->mtx); 489 490 return (res); 491 } 492 493 static void 494 gpioc_interrupt_handler(void *arg) 495 { 496 struct gpioc_pin_intr *intr_conf; 497 struct gpioc_privs *privs; 498 sbintime_t evtime; 499 bool pin_state; 500 501 intr_conf = arg; 502 503 /* Capture time and pin state first. */ 504 evtime = sbinuptime(); 505 if (intr_conf->intr_mode & GPIO_INTR_EDGE_BOTH) 506 gpio_pin_is_active(intr_conf->pin, &pin_state); 507 else if (intr_conf->intr_mode & GPIO_INTR_EDGE_RISING) 508 pin_state = true; 509 else 510 pin_state = false; 511 512 mtx_lock(&intr_conf->mtx); 513 514 if (intr_conf->config_locked == true) { 515 ddevice_printf(sc->sc_dev, "Interrupt configuration in " 516 "progress. Discarding interrupt on pin %d.\n", 517 intr_conf->pin->pin); 518 mtx_unlock(&intr_conf->mtx); 519 return; 520 } 521 522 if (SLIST_EMPTY(&intr_conf->privs)) { 523 ddevice_printf(sc->sc_dev, "No file descriptor associated with " 524 "occurred interrupt on pin %d.\n", intr_conf->pin->pin); 525 mtx_unlock(&intr_conf->mtx); 526 return; 527 } 528 529 SLIST_FOREACH(privs, &intr_conf->privs, next) { 530 struct gpioc_cdevpriv *priv = privs->priv; 531 struct gpioc_pins *privpin; 532 struct gpioc_pin_event *event; 533 mtx_lock(&priv->mtx); 534 SLIST_FOREACH(privpin, &priv->pins, next) { 535 if (privpin->pin == intr_conf) 536 break; 537 } 538 if (privpin == NULL) { 539 /* Should be impossible. */ 540 ddevice_printf(sc->sc_dev, "Cannot find privpin\n"); 541 mtx_unlock(&priv->mtx); 542 continue; 543 } 544 545 if (priv->report_option == GPIO_EVENT_REPORT_DETAIL) { 546 event = next_head_event(priv); 547 /* If head is overtaking tail, advance tail. */ 548 if (priv->evidx_head == priv->evidx_tail) 549 next_tail_event(priv); 550 } else { 551 if (privpin->eventcount > 0) 552 event = &priv->events[privpin->firstevent + 1]; 553 else { 554 privpin->firstevent = priv->evidx_head; 555 event = next_head_event(priv); 556 event->privpin = privpin; 557 event->event_time = evtime; 558 event->event_pin_state = pin_state; 559 event = next_head_event(priv); 560 } 561 ++privpin->eventcount; 562 } 563 event->privpin = privpin; 564 event->event_time = evtime; 565 event->event_pin_state = pin_state; 566 wakeup(priv); 567 selwakeup(&priv->selinfo); 568 KNOTE_LOCKED(&priv->selinfo.si_note, 0); 569 if (priv->async == true && priv->sigio != NULL) 570 pgsigio(&priv->sigio, SIGIO, 0); 571 mtx_unlock(&priv->mtx); 572 } 573 574 mtx_unlock(&intr_conf->mtx); 575 } 576 577 static int 578 gpioc_probe(device_t dev) 579 { 580 device_set_desc(dev, "GPIO controller"); 581 return (0); 582 } 583 584 static int 585 gpioc_attach(device_t dev) 586 { 587 int err; 588 struct gpioc_softc *sc; 589 struct make_dev_args devargs; 590 591 sc = device_get_softc(dev); 592 sc->sc_dev = dev; 593 sc->sc_pdev = device_get_parent(dev); 594 sc->sc_unit = device_get_unit(dev); 595 596 sc->sc_npins = gpiobus_get_npins(dev); 597 sc->sc_pin_intr = malloc(sizeof(struct gpioc_pin_intr) * sc->sc_npins, 598 M_GPIOC, M_WAITOK | M_ZERO); 599 for (int i = 0; i < sc->sc_npins; i++) { 600 sc->sc_pin_intr[i].sc = sc; 601 mtx_init(&sc->sc_pin_intr[i].mtx, "gpioc pin", NULL, MTX_DEF); 602 SLIST_INIT(&sc->sc_pin_intr[i].privs); 603 } 604 605 make_dev_args_init(&devargs); 606 devargs.mda_devsw = &gpioc_cdevsw; 607 devargs.mda_uid = UID_ROOT; 608 devargs.mda_gid = GID_WHEEL; 609 devargs.mda_mode = 0600; 610 devargs.mda_si_drv1 = sc; 611 err = make_dev_s(&devargs, &sc->sc_ctl_dev, "gpioc%d", sc->sc_unit); 612 if (err != 0) { 613 device_printf(dev, "Failed to create gpioc%d", sc->sc_unit); 614 return (ENXIO); 615 } 616 617 return (0); 618 } 619 620 static int 621 gpioc_detach(device_t dev) 622 { 623 struct gpioc_softc *sc = device_get_softc(dev); 624 625 if (sc->sc_ctl_dev) 626 destroy_dev(sc->sc_ctl_dev); 627 628 for (int i = 0; i < sc->sc_npins; i++) { 629 mtx_destroy(&sc->sc_pin_intr[i].mtx); 630 MPASS(sc->sc_pin_intr[i].pin == NULL); 631 } 632 free(sc->sc_pin_intr, M_GPIOC); 633 634 return (0); 635 } 636 637 static void 638 gpioc_cdevpriv_dtor(void *data) 639 { 640 struct gpioc_cdevpriv *priv; 641 struct gpioc_privs *priv_link, *priv_link_temp; 642 struct gpioc_pins *pin_link, *pin_link_temp; 643 unsigned int consistency __diagused; 644 645 priv = data; 646 647 SLIST_FOREACH_SAFE(pin_link, &priv->pins, next, pin_link_temp) { 648 consistency = 0; 649 mtx_lock(&pin_link->pin->mtx); 650 while (pin_link->pin->config_locked == true) 651 mtx_sleep(&pin_link->pin->config_locked, 652 &pin_link->pin->mtx, 0, "gpicfg", 0); 653 SLIST_FOREACH_SAFE(priv_link, &pin_link->pin->privs, next, 654 priv_link_temp) { 655 if (priv_link->priv == priv) { 656 SLIST_REMOVE(&pin_link->pin->privs, priv_link, 657 gpioc_privs, next); 658 free(priv_link, M_GPIOC); 659 consistency++; 660 } 661 } 662 KASSERT(consistency == 1, 663 ("inconsistent links between pin config and cdevpriv")); 664 if (gpioc_intr_reconfig_allowed(priv, pin_link->pin)) { 665 gpioc_release_pin_intr(priv->sc, pin_link->pin); 666 } 667 mtx_unlock(&pin_link->pin->mtx); 668 SLIST_REMOVE(&priv->pins, pin_link, gpioc_pins, next); 669 free(pin_link, M_GPIOC); 670 } 671 672 wakeup(&priv); 673 knlist_clear(&priv->selinfo.si_note, 0); 674 seldrain(&priv->selinfo); 675 knlist_destroy(&priv->selinfo.si_note); 676 funsetown(&priv->sigio); 677 678 mtx_destroy(&priv->mtx); 679 free(priv->events, M_GPIOC); 680 free(data, M_GPIOC); 681 } 682 683 static int 684 gpioc_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 685 { 686 struct gpioc_cdevpriv *priv; 687 int err = 0; 688 689 priv = malloc(sizeof(*priv), M_GPIOC, M_WAITOK | M_ZERO); 690 priv->sc = dev->si_drv1; 691 692 mtx_init(&priv->mtx, "gpioc priv", NULL, MTX_DEF); 693 knlist_init_mtx(&priv->selinfo.si_note, &priv->mtx); 694 695 priv->async = false; 696 priv->report_option = GPIO_EVENT_REPORT_DETAIL; 697 priv->sigio = NULL; 698 699 /* 700 * Allocate a circular buffer for events. The scheme we use for summary 701 * reporting assumes there will always be a pair of events available to 702 * record the first/last events on any pin, so we allocate 2 * npins. 703 * Even though we actually default to detailed event reporting, 2 * 704 * npins isn't a horrible fifo size for that either. 705 */ 706 priv->numevents = priv->sc->sc_npins * 2; 707 priv->events = malloc(priv->numevents * sizeof(struct gpio_event_detail), 708 M_GPIOC, M_WAITOK | M_ZERO); 709 710 priv->evidx_head = priv->evidx_tail = 0; 711 SLIST_INIT(&priv->pins); 712 713 err = devfs_set_cdevpriv(priv, gpioc_cdevpriv_dtor); 714 if (err != 0) 715 gpioc_cdevpriv_dtor(priv); 716 return (err); 717 } 718 719 static int 720 gpioc_read(struct cdev *dev, struct uio *uio, int ioflag) 721 { 722 struct gpioc_cdevpriv *priv; 723 struct gpioc_pin_event *event; 724 union { 725 struct gpio_event_summary sum; 726 struct gpio_event_detail evt; 727 uint8_t data[1]; 728 } recbuf; 729 size_t recsize; 730 int err; 731 732 if ((err = devfs_get_cdevpriv((void **)&priv)) != 0) 733 return (err); 734 735 if (priv->report_option == GPIO_EVENT_REPORT_SUMMARY) 736 recsize = sizeof(struct gpio_event_summary); 737 else 738 recsize = sizeof(struct gpio_event_detail); 739 740 if (uio->uio_resid < recsize) 741 return (EINVAL); 742 743 mtx_lock(&priv->mtx); 744 while (priv->evidx_head == priv->evidx_tail) { 745 if (SLIST_EMPTY(&priv->pins)) { 746 err = ENXIO; 747 break; 748 } else if (ioflag & O_NONBLOCK) { 749 err = EWOULDBLOCK; 750 break; 751 } else { 752 err = mtx_sleep(priv, &priv->mtx, PCATCH, "gpintr", 0); 753 if (err != 0) 754 break; 755 } 756 } 757 758 while (err == 0 && uio->uio_resid >= recsize && 759 priv->evidx_tail != priv->evidx_head) { 760 event = next_tail_event(priv); 761 if (priv->report_option == GPIO_EVENT_REPORT_SUMMARY) { 762 recbuf.sum.gp_first_time = event->event_time; 763 recbuf.sum.gp_pin = event->privpin->pin->pin->pin; 764 recbuf.sum.gp_count = event->privpin->eventcount; 765 recbuf.sum.gp_first_state = event->event_pin_state; 766 event = next_tail_event(priv); 767 recbuf.sum.gp_last_time = event->event_time; 768 recbuf.sum.gp_last_state = event->event_pin_state; 769 event->privpin->eventcount = 0; 770 event->privpin->firstevent = 0; 771 } else { 772 recbuf.evt.gp_time = event->event_time; 773 recbuf.evt.gp_pin = event->privpin->pin->pin->pin; 774 recbuf.evt.gp_pinstate = event->event_pin_state; 775 } 776 mtx_unlock(&priv->mtx); 777 err = uiomove(recbuf.data, recsize, uio); 778 mtx_lock(&priv->mtx); 779 } 780 mtx_unlock(&priv->mtx); 781 return (err); 782 } 783 784 static int 785 gpioc_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, 786 struct thread *td) 787 { 788 int max_pin, res; 789 struct gpioc_softc *sc = cdev->si_drv1; 790 struct gpioc_cdevpriv *priv; 791 struct gpio_pin pin; 792 struct gpio_req req; 793 struct gpio_access_32 *a32; 794 struct gpio_config_32 *c32; 795 struct gpio_event_config *evcfg; 796 uint32_t caps, intrflags; 797 798 switch (cmd) { 799 case GPIOMAXPIN: 800 res = 0; 801 max_pin = sc->sc_npins - 1; 802 bcopy(&max_pin, arg, sizeof(max_pin)); 803 break; 804 case GPIOGETCONFIG: 805 bcopy(arg, &pin, sizeof(pin)); 806 dprintf("get config pin %d\n", pin.gp_pin); 807 res = GPIOBUS_PIN_GETFLAGS(sc->sc_pdev, sc->sc_dev, pin.gp_pin, 808 &pin.gp_flags); 809 /* Fail early */ 810 if (res != 0) 811 break; 812 res = devfs_get_cdevpriv((void **)&priv); 813 if (res != 0) 814 break; 815 pin.gp_flags |= gpioc_get_intr_config(sc, priv, 816 pin.gp_pin); 817 res = GPIOBUS_PIN_GETCAPS(sc->sc_pdev, sc->sc_dev, pin.gp_pin, 818 &pin.gp_caps); 819 if (res != 0) 820 break; 821 res = GPIOBUS_PIN_GETNAME(sc->sc_pdev, pin.gp_pin, pin.gp_name); 822 if (res != 0) 823 break; 824 bcopy(&pin, arg, sizeof(pin)); 825 break; 826 case GPIOSETCONFIG: 827 bcopy(arg, &pin, sizeof(pin)); 828 dprintf("set config pin %d\n", pin.gp_pin); 829 res = devfs_get_cdevpriv((void **)&priv); 830 if (res != 0) 831 break; 832 res = GPIOBUS_PIN_GETCAPS(sc->sc_pdev, sc->sc_dev, 833 pin.gp_pin, &caps); 834 if (res != 0) 835 break; 836 res = gpio_check_flags(caps, pin.gp_flags); 837 if (res != 0) 838 break; 839 intrflags = pin.gp_flags & GPIO_INTR_MASK; 840 /* 841 * We can do only edge interrupts, and only if the 842 * hardware supports that interrupt type on that pin. 843 */ 844 switch (intrflags) { 845 case GPIO_INTR_NONE: 846 break; 847 case GPIO_INTR_EDGE_RISING: 848 case GPIO_INTR_EDGE_FALLING: 849 case GPIO_INTR_EDGE_BOTH: 850 if ((intrflags & caps) == 0) 851 res = EOPNOTSUPP; 852 break; 853 default: 854 res = EINVAL; 855 break; 856 } 857 if (res != 0) 858 break; 859 res = GPIOBUS_PIN_SETFLAGS(sc->sc_pdev, sc->sc_dev, pin.gp_pin, 860 pin.gp_flags & ~GPIO_INTR_MASK); 861 if (res != 0) 862 break; 863 res = gpioc_set_intr_config(sc, priv, pin.gp_pin, 864 intrflags); 865 break; 866 case GPIOGET: 867 bcopy(arg, &req, sizeof(req)); 868 res = GPIOBUS_PIN_GET(sc->sc_pdev, sc->sc_dev, req.gp_pin, 869 &req.gp_value); 870 if (res != 0) 871 break; 872 dprintf("read pin %d -> %d\n", 873 req.gp_pin, req.gp_value); 874 bcopy(&req, arg, sizeof(req)); 875 break; 876 case GPIOSET: 877 bcopy(arg, &req, sizeof(req)); 878 res = GPIOBUS_PIN_SET(sc->sc_pdev, sc->sc_dev, req.gp_pin, 879 req.gp_value); 880 dprintf("write pin %d -> %d\n", 881 req.gp_pin, req.gp_value); 882 break; 883 case GPIOTOGGLE: 884 bcopy(arg, &req, sizeof(req)); 885 dprintf("toggle pin %d\n", 886 req.gp_pin); 887 res = GPIOBUS_PIN_TOGGLE(sc->sc_pdev, sc->sc_dev, req.gp_pin); 888 break; 889 case GPIOSETNAME: 890 bcopy(arg, &pin, sizeof(pin)); 891 dprintf("set name on pin %d\n", pin.gp_pin); 892 res = GPIOBUS_PIN_SETNAME(sc->sc_pdev, pin.gp_pin, 893 pin.gp_name); 894 break; 895 case GPIOACCESS32: 896 a32 = (struct gpio_access_32 *)arg; 897 res = GPIOBUS_PIN_ACCESS_32(sc->sc_pdev, sc->sc_dev, 898 a32->first_pin, a32->clear_pins, a32->change_pins, 899 &a32->orig_pins); 900 break; 901 case GPIOCONFIG32: 902 c32 = (struct gpio_config_32 *)arg; 903 res = GPIOBUS_PIN_CONFIG_32(sc->sc_pdev, sc->sc_dev, 904 c32->first_pin, c32->num_pins, c32->pin_flags); 905 break; 906 case GPIOCONFIGEVENTS: 907 evcfg = (struct gpio_event_config *)arg; 908 res = devfs_get_cdevpriv((void **)&priv); 909 if (res != 0) 910 break; 911 /* If any pins have been configured, changes aren't allowed. */ 912 if (!SLIST_EMPTY(&priv->pins)) { 913 res = EINVAL; 914 break; 915 } 916 if (evcfg->gp_report_type != GPIO_EVENT_REPORT_DETAIL && 917 evcfg->gp_report_type != GPIO_EVENT_REPORT_SUMMARY) { 918 res = EINVAL; 919 break; 920 } 921 priv->report_option = evcfg->gp_report_type; 922 /* Reallocate the events buffer if the user wants it bigger. */ 923 if (priv->report_option == GPIO_EVENT_REPORT_DETAIL && 924 priv->numevents < evcfg->gp_fifo_size) { 925 free(priv->events, M_GPIOC); 926 priv->numevents = evcfg->gp_fifo_size; 927 priv->events = malloc(priv->numevents * 928 sizeof(struct gpio_event_detail), M_GPIOC, 929 M_WAITOK | M_ZERO); 930 priv->evidx_head = priv->evidx_tail = 0; 931 } 932 break; 933 case FIONBIO: 934 /* 935 * This dummy handler is necessary to prevent fcntl() 936 * from failing. The actual handling of non-blocking IO 937 * is done using the O_NONBLOCK ioflag passed to the 938 * read() syscall. 939 */ 940 res = 0; 941 break; 942 case FIOASYNC: 943 res = devfs_get_cdevpriv((void **)&priv); 944 if (res == 0) { 945 if (*(int *)arg == FASYNC) 946 priv->async = true; 947 else 948 priv->async = false; 949 } 950 break; 951 case FIOGETOWN: 952 res = devfs_get_cdevpriv((void **)&priv); 953 if (res == 0) 954 *(int *)arg = fgetown(&priv->sigio); 955 break; 956 case FIOSETOWN: 957 res = devfs_get_cdevpriv((void **)&priv); 958 if (res == 0) 959 res = fsetown(*(int *)arg, &priv->sigio); 960 break; 961 default: 962 return (ENOTTY); 963 break; 964 } 965 966 return (res); 967 } 968 969 static int 970 gpioc_poll(struct cdev *dev, int events, struct thread *td) 971 { 972 struct gpioc_cdevpriv *priv; 973 int err; 974 int revents; 975 976 revents = 0; 977 978 err = devfs_get_cdevpriv((void **)&priv); 979 if (err != 0) { 980 revents = POLLERR; 981 return (revents); 982 } 983 984 if (SLIST_EMPTY(&priv->pins)) { 985 revents = POLLHUP; 986 return (revents); 987 } 988 989 if (events & (POLLIN | POLLRDNORM)) { 990 if (priv->evidx_head != priv->evidx_tail) 991 revents |= events & (POLLIN | POLLRDNORM); 992 else 993 selrecord(td, &priv->selinfo); 994 } 995 996 return (revents); 997 } 998 999 static int 1000 gpioc_kqfilter(struct cdev *dev, struct knote *kn) 1001 { 1002 struct gpioc_cdevpriv *priv; 1003 struct knlist *knlist; 1004 int err; 1005 1006 err = devfs_get_cdevpriv((void **)&priv); 1007 if (err != 0) 1008 return err; 1009 1010 if (SLIST_EMPTY(&priv->pins)) 1011 return (ENXIO); 1012 1013 switch(kn->kn_filter) { 1014 case EVFILT_READ: 1015 kn->kn_fop = &gpioc_read_filterops; 1016 kn->kn_hook = (void *)priv; 1017 break; 1018 default: 1019 return (EOPNOTSUPP); 1020 } 1021 1022 knlist = &priv->selinfo.si_note; 1023 knlist_add(knlist, kn, 0); 1024 1025 return (0); 1026 } 1027 1028 static int 1029 gpioc_kqread(struct knote *kn, long hint) 1030 { 1031 struct gpioc_cdevpriv *priv = kn->kn_hook; 1032 size_t recsize; 1033 1034 1035 if (SLIST_EMPTY(&priv->pins)) { 1036 kn->kn_flags |= EV_EOF; 1037 return (1); 1038 } else { 1039 if (priv->evidx_head != priv->evidx_tail) { 1040 if (priv->report_option == GPIO_EVENT_REPORT_SUMMARY) 1041 recsize = sizeof(struct gpio_event_summary); 1042 else 1043 recsize = sizeof(struct gpio_event_detail); 1044 kn->kn_data = recsize * number_of_events(priv); 1045 return (1); 1046 } 1047 } 1048 return (0); 1049 } 1050 1051 static void 1052 gpioc_kqdetach(struct knote *kn) 1053 { 1054 struct gpioc_cdevpriv *priv = kn->kn_hook; 1055 struct knlist *knlist = &priv->selinfo.si_note; 1056 1057 knlist_remove(knlist, kn, 0); 1058 } 1059 1060 static device_method_t gpioc_methods[] = { 1061 /* Device interface */ 1062 DEVMETHOD(device_probe, gpioc_probe), 1063 DEVMETHOD(device_attach, gpioc_attach), 1064 DEVMETHOD(device_detach, gpioc_detach), 1065 1066 DEVMETHOD_END 1067 }; 1068 1069 driver_t gpioc_driver = { 1070 "gpioc", 1071 gpioc_methods, 1072 sizeof(struct gpioc_softc) 1073 }; 1074 1075 DRIVER_MODULE(gpioc, gpiobus, gpioc_driver, 0, 0); 1076 MODULE_VERSION(gpioc, 1); 1077