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