1 /*- 2 * Copyright (c) 2012, 2013 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Oleksandr Rybalko under sponsorship 6 * from the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 /* 31 * Freescale i.MX515 GPIO driver. 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #include "opt_platform.h" 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/bus.h> 42 43 #include <sys/kernel.h> 44 #include <sys/module.h> 45 #include <sys/rman.h> 46 #include <sys/lock.h> 47 #include <sys/mutex.h> 48 #include <sys/gpio.h> 49 #include <sys/proc.h> 50 51 #include <machine/bus.h> 52 #include <machine/intr.h> 53 #include <machine/resource.h> 54 55 #include <dev/fdt/fdt_common.h> 56 #include <dev/gpio/gpiobusvar.h> 57 #include <dev/ofw/openfirm.h> 58 #include <dev/ofw/ofw_bus.h> 59 #include <dev/ofw/ofw_bus_subr.h> 60 61 #include "gpio_if.h" 62 63 #ifdef ARM_INTRNG 64 #include "pic_if.h" 65 #endif 66 67 #define WRITE4(_sc, _r, _v) \ 68 bus_space_write_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r), (_v)) 69 #define READ4(_sc, _r) \ 70 bus_space_read_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r)) 71 #define SET4(_sc, _r, _m) \ 72 WRITE4((_sc), (_r), READ4((_sc), (_r)) | (_m)) 73 #define CLEAR4(_sc, _r, _m) \ 74 WRITE4((_sc), (_r), READ4((_sc), (_r)) & ~(_m)) 75 76 /* Registers definition for Freescale i.MX515 GPIO controller */ 77 78 #define IMX_GPIO_DR_REG 0x000 /* Pin Data */ 79 #define IMX_GPIO_OE_REG 0x004 /* Set Pin Output */ 80 #define IMX_GPIO_PSR_REG 0x008 /* Pad Status */ 81 #define IMX_GPIO_ICR1_REG 0x00C /* Interrupt Configuration */ 82 #define IMX_GPIO_ICR2_REG 0x010 /* Interrupt Configuration */ 83 #define GPIO_ICR_COND_LOW 0 84 #define GPIO_ICR_COND_HIGH 1 85 #define GPIO_ICR_COND_RISE 2 86 #define GPIO_ICR_COND_FALL 3 87 #define IMX_GPIO_IMR_REG 0x014 /* Interrupt Mask Register */ 88 #define IMX_GPIO_ISR_REG 0x018 /* Interrupt Status Register */ 89 #define IMX_GPIO_EDGE_REG 0x01C /* Edge Detect Register */ 90 91 #define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT) 92 #define NGPIO 32 93 94 struct imx51_gpio_softc { 95 device_t dev; 96 device_t sc_busdev; 97 struct mtx sc_mtx; 98 struct resource *sc_res[3]; /* 1 x mem, 2 x IRQ */ 99 void *gpio_ih[2]; 100 bus_space_tag_t sc_iot; 101 bus_space_handle_t sc_ioh; 102 int gpio_npins; 103 struct gpio_pin gpio_pins[NGPIO]; 104 struct arm_irqsrc *gpio_pic_irqsrc[NGPIO]; 105 }; 106 107 static struct ofw_compat_data compat_data[] = { 108 {"fsl,imx6q-gpio", 1}, 109 {"fsl,imx53-gpio", 1}, 110 {"fsl,imx51-gpio", 1}, 111 {NULL, 0} 112 }; 113 114 static struct resource_spec imx_gpio_spec[] = { 115 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 116 { SYS_RES_IRQ, 0, RF_ACTIVE }, 117 { SYS_RES_IRQ, 1, RF_ACTIVE }, 118 { -1, 0 } 119 }; 120 121 /* 122 * Helpers 123 */ 124 static void imx51_gpio_pin_configure(struct imx51_gpio_softc *, 125 struct gpio_pin *, uint32_t); 126 127 /* 128 * Driver stuff 129 */ 130 static int imx51_gpio_probe(device_t); 131 static int imx51_gpio_attach(device_t); 132 static int imx51_gpio_detach(device_t); 133 134 /* 135 * GPIO interface 136 */ 137 static device_t imx51_gpio_get_bus(device_t); 138 static int imx51_gpio_pin_max(device_t, int *); 139 static int imx51_gpio_pin_getcaps(device_t, uint32_t, uint32_t *); 140 static int imx51_gpio_pin_getflags(device_t, uint32_t, uint32_t *); 141 static int imx51_gpio_pin_getname(device_t, uint32_t, char *); 142 static int imx51_gpio_pin_setflags(device_t, uint32_t, uint32_t); 143 static int imx51_gpio_pin_set(device_t, uint32_t, unsigned int); 144 static int imx51_gpio_pin_get(device_t, uint32_t, unsigned int *); 145 static int imx51_gpio_pin_toggle(device_t, uint32_t pin); 146 147 #ifdef ARM_INTRNG 148 /* 149 * this is teardown_intr 150 */ 151 static void 152 gpio_pic_disable_intr(device_t dev, struct arm_irqsrc *isrc) 153 { 154 struct imx51_gpio_softc *sc; 155 u_int irq; 156 157 sc = device_get_softc(dev); 158 irq = isrc->isrc_data; 159 160 // XXX Not sure this is necessary 161 mtx_lock_spin(&sc->sc_mtx); 162 CLEAR4(sc, IMX_GPIO_IMR_REG, (1U << irq)); 163 WRITE4(sc, IMX_GPIO_ISR_REG, (1U << irq)); 164 mtx_unlock_spin(&sc->sc_mtx); 165 } 166 167 /* 168 * this is mask_intr 169 */ 170 static void 171 gpio_pic_disable_source(device_t dev, struct arm_irqsrc *isrc) 172 { 173 struct imx51_gpio_softc *sc; 174 175 sc = device_get_softc(dev); 176 177 mtx_lock_spin(&sc->sc_mtx); 178 CLEAR4(sc, IMX_GPIO_IMR_REG, (1U << isrc->isrc_data)); 179 mtx_unlock_spin(&sc->sc_mtx); 180 } 181 182 /* 183 * this is setup_intr 184 */ 185 static void 186 gpio_pic_enable_intr(device_t dev, struct arm_irqsrc *isrc) 187 { 188 struct imx51_gpio_softc *sc; 189 int icfg; 190 u_int irq, reg, shift, wrk; 191 192 sc = device_get_softc(dev); 193 194 if (isrc->isrc_trig == INTR_TRIGGER_LEVEL) { 195 if (isrc->isrc_pol == INTR_POLARITY_LOW) 196 icfg = GPIO_ICR_COND_LOW; 197 else 198 icfg = GPIO_ICR_COND_HIGH; 199 } else { 200 if (isrc->isrc_pol == INTR_POLARITY_HIGH) 201 icfg = GPIO_ICR_COND_FALL; 202 else 203 icfg = GPIO_ICR_COND_RISE; 204 } 205 206 irq = isrc->isrc_data; 207 if (irq < 16) { 208 reg = IMX_GPIO_ICR1_REG; 209 shift = 2 * irq; 210 } else { 211 reg = IMX_GPIO_ICR2_REG; 212 shift = 2 * (irq - 16); 213 } 214 215 mtx_lock_spin(&sc->sc_mtx); 216 CLEAR4(sc, IMX_GPIO_IMR_REG, (1U << irq)); 217 WRITE4(sc, IMX_GPIO_ISR_REG, (1U << irq)); 218 wrk = READ4(sc, reg); 219 wrk &= ~(0x03 << shift); 220 wrk |= icfg << shift; 221 WRITE4(sc, reg, wrk); 222 mtx_unlock_spin(&sc->sc_mtx); 223 } 224 225 /* 226 * this is unmask_intr 227 */ 228 static void 229 gpio_pic_enable_source(device_t dev, struct arm_irqsrc *isrc) 230 { 231 struct imx51_gpio_softc *sc; 232 233 sc = device_get_softc(dev); 234 235 mtx_lock_spin(&sc->sc_mtx); 236 SET4(sc, IMX_GPIO_IMR_REG, (1U << isrc->isrc_data)); 237 mtx_unlock_spin(&sc->sc_mtx); 238 } 239 240 static void 241 gpio_pic_post_filter(device_t dev, struct arm_irqsrc *isrc) 242 { 243 struct imx51_gpio_softc *sc; 244 245 sc = device_get_softc(dev); 246 247 arm_irq_memory_barrier(0); 248 /* EOI. W1C reg so no r-m-w, no locking needed. */ 249 WRITE4(sc, IMX_GPIO_ISR_REG, (1U << isrc->isrc_data)); 250 } 251 252 static void 253 gpio_pic_post_ithread(device_t dev, struct arm_irqsrc *isrc) 254 { 255 256 arm_irq_memory_barrier(0); 257 gpio_pic_enable_source(dev, isrc); 258 } 259 260 static void 261 gpio_pic_pre_ithread(device_t dev, struct arm_irqsrc *isrc) 262 { 263 264 gpio_pic_disable_source(dev, isrc); 265 } 266 267 /* 268 * intrng calls this to make a new isrc known to us. 269 */ 270 static int 271 gpio_pic_register(device_t dev, struct arm_irqsrc *isrc, boolean_t *is_percpu) 272 { 273 struct imx51_gpio_softc *sc; 274 u_int irq, tripol; 275 276 sc = device_get_softc(dev); 277 278 /* 279 * From devicetree/bindings/gpio/fsl-imx-gpio.txt: 280 * #interrupt-cells: 2. The first cell is the GPIO number. The second 281 * cell bits[3:0] is used to specify trigger type and level flags: 282 * 1 = low-to-high edge triggered. 283 * 2 = high-to-low edge triggered. 284 * 4 = active high level-sensitive. 285 * 8 = active low level-sensitive. 286 * We can do any single one of these modes, but nothing in combo. 287 */ 288 289 if (isrc->isrc_ncells != 2) { 290 device_printf(sc->dev, "Invalid #interrupt-cells"); 291 return (EINVAL); 292 } 293 294 irq = isrc->isrc_cells[0]; 295 tripol = isrc->isrc_cells[1]; 296 if (irq >= sc->gpio_npins) { 297 device_printf(sc->dev, "Invalid interrupt number %d", irq); 298 return (EINVAL); 299 } 300 switch (tripol) 301 { 302 case 1: 303 isrc->isrc_trig = INTR_TRIGGER_EDGE; 304 isrc->isrc_pol = INTR_POLARITY_HIGH; 305 break; 306 case 2: 307 isrc->isrc_trig = INTR_TRIGGER_EDGE; 308 isrc->isrc_pol = INTR_POLARITY_LOW; 309 break; 310 case 4: 311 isrc->isrc_trig = INTR_TRIGGER_LEVEL; 312 isrc->isrc_pol = INTR_POLARITY_HIGH; 313 break; 314 case 8: 315 isrc->isrc_trig = INTR_TRIGGER_LEVEL; 316 isrc->isrc_pol = INTR_POLARITY_LOW; 317 break; 318 default: 319 device_printf(sc->dev, "unsupported trigger/polarity 0x%2x\n", 320 tripol); 321 return (ENOTSUP); 322 } 323 isrc->isrc_nspc_type = ARM_IRQ_NSPC_PLAIN; 324 isrc->isrc_nspc_num = irq; 325 326 /* 327 * 1. The link between ISRC and controller must be set atomically. 328 * 2. Just do things only once in rare case when consumers 329 * of shared interrupt came here at the same moment. 330 */ 331 mtx_lock_spin(&sc->sc_mtx); 332 if (sc->gpio_pic_irqsrc[irq] != NULL) { 333 mtx_unlock_spin(&sc->sc_mtx); 334 return (sc->gpio_pic_irqsrc[irq] == isrc ? 0 : EEXIST); 335 } 336 sc->gpio_pic_irqsrc[irq] = isrc; 337 isrc->isrc_data = irq; 338 mtx_unlock_spin(&sc->sc_mtx); 339 340 arm_irq_set_name(isrc, "%s,%u", device_get_nameunit(sc->dev), irq); 341 return (0); 342 } 343 344 static int 345 gpio_pic_unregister(device_t dev, struct arm_irqsrc *isrc) 346 { 347 struct imx51_gpio_softc *sc; 348 u_int irq; 349 350 sc = device_get_softc(dev); 351 352 mtx_lock_spin(&sc->sc_mtx); 353 irq = isrc->isrc_data; 354 if (sc->gpio_pic_irqsrc[irq] != isrc) { 355 mtx_unlock_spin(&sc->sc_mtx); 356 return (sc->gpio_pic_irqsrc[irq] == NULL ? 0 : EINVAL); 357 } 358 sc->gpio_pic_irqsrc[irq] = NULL; 359 isrc->isrc_data = 0; 360 mtx_unlock_spin(&sc->sc_mtx); 361 362 arm_irq_set_name(isrc, ""); 363 return (0); 364 } 365 366 static int 367 gpio_pic_filter(void *arg) 368 { 369 struct imx51_gpio_softc *sc; 370 uint32_t i, interrupts; 371 372 sc = arg; 373 mtx_lock_spin(&sc->sc_mtx); 374 interrupts = READ4(sc, IMX_GPIO_ISR_REG) & READ4(sc, IMX_GPIO_IMR_REG); 375 mtx_unlock_spin(&sc->sc_mtx); 376 377 for (i = 0; interrupts != 0; i++, interrupts >>= 1) { 378 if ((interrupts & 0x1) == 0) 379 continue; 380 if (sc->gpio_pic_irqsrc[i]) 381 arm_irq_dispatch(sc->gpio_pic_irqsrc[i], curthread->td_intr_frame); 382 else 383 device_printf(sc->dev, "spurious interrupt %d\n", i); 384 } 385 386 return (FILTER_HANDLED); 387 } 388 #endif 389 390 /* 391 * 392 */ 393 static void 394 imx51_gpio_pin_configure(struct imx51_gpio_softc *sc, struct gpio_pin *pin, 395 unsigned int flags) 396 { 397 398 mtx_lock_spin(&sc->sc_mtx); 399 400 /* 401 * Manage input/output 402 */ 403 if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { 404 pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT); 405 if (flags & GPIO_PIN_OUTPUT) { 406 pin->gp_flags |= GPIO_PIN_OUTPUT; 407 SET4(sc, IMX_GPIO_OE_REG, (1U << pin->gp_pin)); 408 } 409 else { 410 pin->gp_flags |= GPIO_PIN_INPUT; 411 CLEAR4(sc, IMX_GPIO_OE_REG, (1U << pin->gp_pin)); 412 } 413 } 414 415 mtx_unlock_spin(&sc->sc_mtx); 416 } 417 418 static device_t 419 imx51_gpio_get_bus(device_t dev) 420 { 421 struct imx51_gpio_softc *sc; 422 423 sc = device_get_softc(dev); 424 425 return (sc->sc_busdev); 426 } 427 428 static int 429 imx51_gpio_pin_max(device_t dev, int *maxpin) 430 { 431 struct imx51_gpio_softc *sc; 432 433 sc = device_get_softc(dev); 434 *maxpin = sc->gpio_npins - 1; 435 436 return (0); 437 } 438 439 static int 440 imx51_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 441 { 442 struct imx51_gpio_softc *sc; 443 int i; 444 445 sc = device_get_softc(dev); 446 for (i = 0; i < sc->gpio_npins; i++) { 447 if (sc->gpio_pins[i].gp_pin == pin) 448 break; 449 } 450 451 if (i >= sc->gpio_npins) 452 return (EINVAL); 453 454 mtx_lock_spin(&sc->sc_mtx); 455 *caps = sc->gpio_pins[i].gp_caps; 456 mtx_unlock_spin(&sc->sc_mtx); 457 458 return (0); 459 } 460 461 static int 462 imx51_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) 463 { 464 struct imx51_gpio_softc *sc; 465 int i; 466 467 sc = device_get_softc(dev); 468 for (i = 0; i < sc->gpio_npins; i++) { 469 if (sc->gpio_pins[i].gp_pin == pin) 470 break; 471 } 472 473 if (i >= sc->gpio_npins) 474 return (EINVAL); 475 476 mtx_lock_spin(&sc->sc_mtx); 477 *flags = sc->gpio_pins[i].gp_flags; 478 mtx_unlock_spin(&sc->sc_mtx); 479 480 return (0); 481 } 482 483 static int 484 imx51_gpio_pin_getname(device_t dev, uint32_t pin, char *name) 485 { 486 struct imx51_gpio_softc *sc; 487 int i; 488 489 sc = device_get_softc(dev); 490 for (i = 0; i < sc->gpio_npins; i++) { 491 if (sc->gpio_pins[i].gp_pin == pin) 492 break; 493 } 494 495 if (i >= sc->gpio_npins) 496 return (EINVAL); 497 498 mtx_lock_spin(&sc->sc_mtx); 499 memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME); 500 mtx_unlock_spin(&sc->sc_mtx); 501 502 return (0); 503 } 504 505 static int 506 imx51_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) 507 { 508 struct imx51_gpio_softc *sc; 509 int i; 510 511 sc = device_get_softc(dev); 512 for (i = 0; i < sc->gpio_npins; i++) { 513 if (sc->gpio_pins[i].gp_pin == pin) 514 break; 515 } 516 517 if (i >= sc->gpio_npins) 518 return (EINVAL); 519 520 imx51_gpio_pin_configure(sc, &sc->gpio_pins[i], flags); 521 522 return (0); 523 } 524 525 static int 526 imx51_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) 527 { 528 struct imx51_gpio_softc *sc; 529 int i; 530 531 sc = device_get_softc(dev); 532 for (i = 0; i < sc->gpio_npins; i++) { 533 if (sc->gpio_pins[i].gp_pin == pin) 534 break; 535 } 536 537 if (i >= sc->gpio_npins) 538 return (EINVAL); 539 540 mtx_lock_spin(&sc->sc_mtx); 541 if (value) 542 SET4(sc, IMX_GPIO_DR_REG, (1U << i)); 543 else 544 CLEAR4(sc, IMX_GPIO_DR_REG, (1U << i)); 545 mtx_unlock_spin(&sc->sc_mtx); 546 547 return (0); 548 } 549 550 static int 551 imx51_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) 552 { 553 struct imx51_gpio_softc *sc; 554 int i; 555 556 sc = device_get_softc(dev); 557 for (i = 0; i < sc->gpio_npins; i++) { 558 if (sc->gpio_pins[i].gp_pin == pin) 559 break; 560 } 561 562 if (i >= sc->gpio_npins) 563 return (EINVAL); 564 565 mtx_lock_spin(&sc->sc_mtx); 566 *val = (READ4(sc, IMX_GPIO_DR_REG) >> i) & 1; 567 mtx_unlock_spin(&sc->sc_mtx); 568 569 return (0); 570 } 571 572 static int 573 imx51_gpio_pin_toggle(device_t dev, uint32_t pin) 574 { 575 struct imx51_gpio_softc *sc; 576 int i; 577 578 sc = device_get_softc(dev); 579 for (i = 0; i < sc->gpio_npins; i++) { 580 if (sc->gpio_pins[i].gp_pin == pin) 581 break; 582 } 583 584 if (i >= sc->gpio_npins) 585 return (EINVAL); 586 587 mtx_lock_spin(&sc->sc_mtx); 588 WRITE4(sc, IMX_GPIO_DR_REG, 589 (READ4(sc, IMX_GPIO_DR_REG) ^ (1U << i))); 590 mtx_unlock_spin(&sc->sc_mtx); 591 592 return (0); 593 } 594 595 static int 596 imx51_gpio_probe(device_t dev) 597 { 598 599 if (!ofw_bus_status_okay(dev)) 600 return (ENXIO); 601 602 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) { 603 device_set_desc(dev, "Freescale i.MX GPIO Controller"); 604 return (BUS_PROBE_DEFAULT); 605 } 606 607 return (ENXIO); 608 } 609 610 static int 611 imx51_gpio_attach(device_t dev) 612 { 613 struct imx51_gpio_softc *sc; 614 int i, irq, unit; 615 616 sc = device_get_softc(dev); 617 sc->dev = dev; 618 sc->gpio_npins = NGPIO; 619 620 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->dev), NULL, MTX_SPIN); 621 622 if (bus_alloc_resources(dev, imx_gpio_spec, sc->sc_res)) { 623 device_printf(dev, "could not allocate resources\n"); 624 bus_release_resources(dev, imx_gpio_spec, sc->sc_res); 625 mtx_destroy(&sc->sc_mtx); 626 return (ENXIO); 627 } 628 629 sc->sc_iot = rman_get_bustag(sc->sc_res[0]); 630 sc->sc_ioh = rman_get_bushandle(sc->sc_res[0]); 631 /* 632 * Mask off all interrupts in hardware, then set up interrupt handling. 633 */ 634 WRITE4(sc, IMX_GPIO_IMR_REG, 0); 635 for (irq = 0; irq < 2; irq++) { 636 #ifdef ARM_INTRNG 637 if ((bus_setup_intr(dev, sc->sc_res[1 + irq], INTR_TYPE_CLK, 638 gpio_pic_filter, NULL, sc, &sc->gpio_ih[irq]))) { 639 device_printf(dev, 640 "WARNING: unable to register interrupt handler\n"); 641 imx51_gpio_detach(dev); 642 return (ENXIO); 643 } 644 #endif 645 } 646 647 unit = device_get_unit(dev); 648 for (i = 0; i < sc->gpio_npins; i++) { 649 sc->gpio_pins[i].gp_pin = i; 650 sc->gpio_pins[i].gp_caps = DEFAULT_CAPS; 651 sc->gpio_pins[i].gp_flags = 652 (READ4(sc, IMX_GPIO_OE_REG) & (1U << i)) ? GPIO_PIN_OUTPUT : 653 GPIO_PIN_INPUT; 654 snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME, 655 "imx_gpio%d.%d", unit, i); 656 } 657 658 #ifdef ARM_INTRNG 659 arm_pic_register(dev, OF_xref_from_node(ofw_bus_get_node(dev))); 660 #endif 661 sc->sc_busdev = gpiobus_attach_bus(dev); 662 663 if (sc->sc_busdev == NULL) { 664 imx51_gpio_detach(dev); 665 return (ENXIO); 666 } 667 668 return (0); 669 } 670 671 static int 672 imx51_gpio_detach(device_t dev) 673 { 674 int irq; 675 struct imx51_gpio_softc *sc; 676 677 sc = device_get_softc(dev); 678 679 gpiobus_detach_bus(dev); 680 for (irq = 1; irq <= 2; irq++) { 681 if (sc->gpio_ih[irq]) 682 bus_teardown_intr(dev, sc->sc_res[irq], sc->gpio_ih[irq]); 683 } 684 bus_release_resources(dev, imx_gpio_spec, sc->sc_res); 685 mtx_destroy(&sc->sc_mtx); 686 687 return(0); 688 } 689 690 static device_method_t imx51_gpio_methods[] = { 691 DEVMETHOD(device_probe, imx51_gpio_probe), 692 DEVMETHOD(device_attach, imx51_gpio_attach), 693 DEVMETHOD(device_detach, imx51_gpio_detach), 694 695 #ifdef ARM_INTRNG 696 /* Interrupt controller interface */ 697 DEVMETHOD(pic_disable_intr, gpio_pic_disable_intr), 698 DEVMETHOD(pic_disable_source, gpio_pic_disable_source), 699 DEVMETHOD(pic_enable_intr, gpio_pic_enable_intr), 700 DEVMETHOD(pic_enable_source, gpio_pic_enable_source), 701 DEVMETHOD(pic_post_filter, gpio_pic_post_filter), 702 DEVMETHOD(pic_post_ithread, gpio_pic_post_ithread), 703 DEVMETHOD(pic_pre_ithread, gpio_pic_pre_ithread), 704 DEVMETHOD(pic_register, gpio_pic_register), 705 DEVMETHOD(pic_unregister, gpio_pic_unregister), 706 #endif 707 708 /* GPIO protocol */ 709 DEVMETHOD(gpio_get_bus, imx51_gpio_get_bus), 710 DEVMETHOD(gpio_pin_max, imx51_gpio_pin_max), 711 DEVMETHOD(gpio_pin_getname, imx51_gpio_pin_getname), 712 DEVMETHOD(gpio_pin_getflags, imx51_gpio_pin_getflags), 713 DEVMETHOD(gpio_pin_getcaps, imx51_gpio_pin_getcaps), 714 DEVMETHOD(gpio_pin_setflags, imx51_gpio_pin_setflags), 715 DEVMETHOD(gpio_pin_get, imx51_gpio_pin_get), 716 DEVMETHOD(gpio_pin_set, imx51_gpio_pin_set), 717 DEVMETHOD(gpio_pin_toggle, imx51_gpio_pin_toggle), 718 {0, 0}, 719 }; 720 721 static driver_t imx51_gpio_driver = { 722 "gpio", 723 imx51_gpio_methods, 724 sizeof(struct imx51_gpio_softc), 725 }; 726 static devclass_t imx51_gpio_devclass; 727 728 DRIVER_MODULE(imx51_gpio, simplebus, imx51_gpio_driver, imx51_gpio_devclass, 729 0, 0); 730