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 gpioc_pin_event), 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 struct gpioc_pin_event *tmp; 797 uint32_t caps, intrflags; 798 799 switch (cmd) { 800 case GPIOMAXPIN: 801 res = 0; 802 max_pin = sc->sc_npins - 1; 803 bcopy(&max_pin, arg, sizeof(max_pin)); 804 break; 805 case GPIOGETCONFIG: 806 bcopy(arg, &pin, sizeof(pin)); 807 dprintf("get config pin %d\n", pin.gp_pin); 808 res = GPIOBUS_PIN_GETFLAGS(sc->sc_pdev, sc->sc_dev, pin.gp_pin, 809 &pin.gp_flags); 810 /* Fail early */ 811 if (res != 0) 812 break; 813 res = devfs_get_cdevpriv((void **)&priv); 814 if (res != 0) 815 break; 816 pin.gp_flags |= gpioc_get_intr_config(sc, priv, 817 pin.gp_pin); 818 res = GPIOBUS_PIN_GETCAPS(sc->sc_pdev, sc->sc_dev, pin.gp_pin, 819 &pin.gp_caps); 820 if (res != 0) 821 break; 822 res = GPIOBUS_PIN_GETNAME(sc->sc_pdev, pin.gp_pin, pin.gp_name); 823 if (res != 0) 824 break; 825 bcopy(&pin, arg, sizeof(pin)); 826 break; 827 case GPIOSETCONFIG: 828 bcopy(arg, &pin, sizeof(pin)); 829 dprintf("set config pin %d\n", pin.gp_pin); 830 res = devfs_get_cdevpriv((void **)&priv); 831 if (res != 0) 832 break; 833 res = GPIOBUS_PIN_GETCAPS(sc->sc_pdev, sc->sc_dev, 834 pin.gp_pin, &caps); 835 if (res != 0) 836 break; 837 res = gpio_check_flags(caps, pin.gp_flags); 838 if (res != 0) 839 break; 840 intrflags = pin.gp_flags & GPIO_INTR_MASK; 841 /* 842 * We can do only edge interrupts, and only if the 843 * hardware supports that interrupt type on that pin. 844 */ 845 switch (intrflags) { 846 case GPIO_INTR_NONE: 847 break; 848 case GPIO_INTR_EDGE_RISING: 849 case GPIO_INTR_EDGE_FALLING: 850 case GPIO_INTR_EDGE_BOTH: 851 if ((intrflags & caps) == 0) 852 res = EOPNOTSUPP; 853 break; 854 default: 855 res = EINVAL; 856 break; 857 } 858 if (res != 0) 859 break; 860 res = GPIOBUS_PIN_SETFLAGS(sc->sc_pdev, sc->sc_dev, pin.gp_pin, 861 pin.gp_flags & ~GPIO_INTR_MASK); 862 if (res != 0) 863 break; 864 res = gpioc_set_intr_config(sc, priv, pin.gp_pin, 865 intrflags); 866 break; 867 case GPIOGET: 868 bcopy(arg, &req, sizeof(req)); 869 res = GPIOBUS_PIN_GET(sc->sc_pdev, sc->sc_dev, req.gp_pin, 870 &req.gp_value); 871 if (res != 0) 872 break; 873 dprintf("read pin %d -> %d\n", 874 req.gp_pin, req.gp_value); 875 bcopy(&req, arg, sizeof(req)); 876 break; 877 case GPIOSET: 878 bcopy(arg, &req, sizeof(req)); 879 res = GPIOBUS_PIN_SET(sc->sc_pdev, sc->sc_dev, req.gp_pin, 880 req.gp_value); 881 dprintf("write pin %d -> %d\n", 882 req.gp_pin, req.gp_value); 883 break; 884 case GPIOTOGGLE: 885 bcopy(arg, &req, sizeof(req)); 886 dprintf("toggle pin %d\n", 887 req.gp_pin); 888 res = GPIOBUS_PIN_TOGGLE(sc->sc_pdev, sc->sc_dev, req.gp_pin); 889 break; 890 case GPIOSETNAME: 891 bcopy(arg, &pin, sizeof(pin)); 892 dprintf("set name on pin %d\n", pin.gp_pin); 893 res = GPIOBUS_PIN_SETNAME(sc->sc_pdev, pin.gp_pin, 894 pin.gp_name); 895 break; 896 case GPIOACCESS32: 897 a32 = (struct gpio_access_32 *)arg; 898 res = GPIOBUS_PIN_ACCESS_32(sc->sc_pdev, sc->sc_dev, 899 a32->first_pin, a32->clear_pins, a32->change_pins, 900 &a32->orig_pins); 901 break; 902 case GPIOCONFIG32: 903 c32 = (struct gpio_config_32 *)arg; 904 res = GPIOBUS_PIN_CONFIG_32(sc->sc_pdev, sc->sc_dev, 905 c32->first_pin, c32->num_pins, c32->pin_flags); 906 break; 907 case GPIOCONFIGEVENTS: 908 evcfg = (struct gpio_event_config *)arg; 909 res = devfs_get_cdevpriv((void **)&priv); 910 if (res != 0) 911 break; 912 if (evcfg->gp_report_type != GPIO_EVENT_REPORT_DETAIL && 913 evcfg->gp_report_type != GPIO_EVENT_REPORT_SUMMARY) { 914 res = EINVAL; 915 break; 916 } 917 /* Reallocate the events buffer if the user wants it bigger. */ 918 tmp = NULL; 919 if (evcfg->gp_report_type == GPIO_EVENT_REPORT_DETAIL && 920 priv->numevents < evcfg->gp_fifo_size) { 921 tmp = malloc(evcfg->gp_fifo_size * 922 sizeof(struct gpioc_pin_event), M_GPIOC, 923 M_WAITOK | M_ZERO); 924 } 925 mtx_lock(&priv->mtx); 926 /* If any pins have been configured, changes aren't allowed. */ 927 if (!SLIST_EMPTY(&priv->pins)) { 928 mtx_unlock(&priv->mtx); 929 free(tmp, M_GPIOC); 930 res = EINVAL; 931 break; 932 } 933 if (tmp != NULL) { 934 free(priv->events, M_GPIOC); 935 priv->events = tmp; 936 priv->numevents = evcfg->gp_fifo_size; 937 priv->evidx_head = priv->evidx_tail = 0; 938 } 939 priv->report_option = evcfg->gp_report_type; 940 mtx_unlock(&priv->mtx); 941 break; 942 case FIONBIO: 943 /* 944 * This dummy handler is necessary to prevent fcntl() 945 * from failing. The actual handling of non-blocking IO 946 * is done using the O_NONBLOCK ioflag passed to the 947 * read() syscall. 948 */ 949 res = 0; 950 break; 951 case FIOASYNC: 952 res = devfs_get_cdevpriv((void **)&priv); 953 if (res == 0) { 954 if (*(int *)arg == FASYNC) 955 priv->async = true; 956 else 957 priv->async = false; 958 } 959 break; 960 case FIOGETOWN: 961 res = devfs_get_cdevpriv((void **)&priv); 962 if (res == 0) 963 *(int *)arg = fgetown(&priv->sigio); 964 break; 965 case FIOSETOWN: 966 res = devfs_get_cdevpriv((void **)&priv); 967 if (res == 0) 968 res = fsetown(*(int *)arg, &priv->sigio); 969 break; 970 default: 971 return (ENOTTY); 972 break; 973 } 974 975 return (res); 976 } 977 978 static int 979 gpioc_poll(struct cdev *dev, int events, struct thread *td) 980 { 981 struct gpioc_cdevpriv *priv; 982 int err; 983 int revents; 984 985 revents = 0; 986 987 err = devfs_get_cdevpriv((void **)&priv); 988 if (err != 0) { 989 revents = POLLERR; 990 return (revents); 991 } 992 993 if (SLIST_EMPTY(&priv->pins)) { 994 revents = POLLHUP; 995 return (revents); 996 } 997 998 if (events & (POLLIN | POLLRDNORM)) { 999 if (priv->evidx_head != priv->evidx_tail) 1000 revents |= events & (POLLIN | POLLRDNORM); 1001 else 1002 selrecord(td, &priv->selinfo); 1003 } 1004 1005 return (revents); 1006 } 1007 1008 static int 1009 gpioc_kqfilter(struct cdev *dev, struct knote *kn) 1010 { 1011 struct gpioc_cdevpriv *priv; 1012 struct knlist *knlist; 1013 int err; 1014 1015 err = devfs_get_cdevpriv((void **)&priv); 1016 if (err != 0) 1017 return err; 1018 1019 if (SLIST_EMPTY(&priv->pins)) 1020 return (ENXIO); 1021 1022 switch(kn->kn_filter) { 1023 case EVFILT_READ: 1024 kn->kn_fop = &gpioc_read_filterops; 1025 kn->kn_hook = (void *)priv; 1026 break; 1027 default: 1028 return (EOPNOTSUPP); 1029 } 1030 1031 knlist = &priv->selinfo.si_note; 1032 knlist_add(knlist, kn, 0); 1033 1034 return (0); 1035 } 1036 1037 static int 1038 gpioc_kqread(struct knote *kn, long hint) 1039 { 1040 struct gpioc_cdevpriv *priv = kn->kn_hook; 1041 size_t recsize; 1042 1043 1044 if (SLIST_EMPTY(&priv->pins)) { 1045 kn->kn_flags |= EV_EOF; 1046 return (1); 1047 } else { 1048 if (priv->evidx_head != priv->evidx_tail) { 1049 if (priv->report_option == GPIO_EVENT_REPORT_SUMMARY) 1050 recsize = sizeof(struct gpio_event_summary); 1051 else 1052 recsize = sizeof(struct gpio_event_detail); 1053 kn->kn_data = recsize * number_of_events(priv); 1054 return (1); 1055 } 1056 } 1057 return (0); 1058 } 1059 1060 static void 1061 gpioc_kqdetach(struct knote *kn) 1062 { 1063 struct gpioc_cdevpriv *priv = kn->kn_hook; 1064 struct knlist *knlist = &priv->selinfo.si_note; 1065 1066 knlist_remove(knlist, kn, 0); 1067 } 1068 1069 static device_method_t gpioc_methods[] = { 1070 /* Device interface */ 1071 DEVMETHOD(device_probe, gpioc_probe), 1072 DEVMETHOD(device_attach, gpioc_attach), 1073 DEVMETHOD(device_detach, gpioc_detach), 1074 1075 DEVMETHOD_END 1076 }; 1077 1078 driver_t gpioc_driver = { 1079 "gpioc", 1080 gpioc_methods, 1081 sizeof(struct gpioc_softc) 1082 }; 1083 1084 DRIVER_MODULE(gpioc, gpiobus, gpioc_driver, 0, 0); 1085 MODULE_VERSION(gpioc, 1); 1086