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