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