Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpio: tegra: Convert to gpio_irq_chip

Convert the Tegra GPIO driver to use the gpio_irq_chip infrastructure.
This allows a bit of boiler plate to be removed and while at it enables
support for hierarchical domains, which is useful to support PMC wake
events on Tegra210 and earlier.

Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>

authored by

Thierry Reding and committed by
Bartosz Golaszewski
66fecef5 c988ae37

+147 -73
+147 -73
drivers/gpio/gpio-tegra.c
··· 60 60 61 61 struct tegra_gpio_bank { 62 62 unsigned int bank; 63 - unsigned int irq; 64 63 65 64 /* 66 65 * IRQ-core code uses raw locking, and thus, nested locking also ··· 80 81 u32 dbc_enb[4]; 81 82 #endif 82 83 u32 dbc_cnt[4]; 83 - struct tegra_gpio_info *tgi; 84 84 }; 85 85 86 86 struct tegra_gpio_soc_config { ··· 91 93 struct tegra_gpio_info { 92 94 struct device *dev; 93 95 void __iomem *regs; 94 - struct irq_domain *irq_domain; 95 96 struct tegra_gpio_bank *bank_info; 96 97 const struct tegra_gpio_soc_config *soc; 97 98 struct gpio_chip gc; 98 99 struct irq_chip ic; 99 100 u32 bank_count; 101 + unsigned int *irqs; 100 102 }; 101 103 102 104 static inline void tegra_gpio_writel(struct tegra_gpio_info *tgi, ··· 272 274 return tegra_gpio_set_debounce(chip, offset, debounce); 273 275 } 274 276 275 - static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) 276 - { 277 - struct tegra_gpio_info *tgi = gpiochip_get_data(chip); 278 - 279 - return irq_find_mapping(tgi->irq_domain, offset); 280 - } 281 - 282 277 static void tegra_gpio_irq_ack(struct irq_data *d) 283 278 { 284 - struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); 285 - struct tegra_gpio_info *tgi = bank->tgi; 279 + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 280 + struct tegra_gpio_info *tgi = gpiochip_get_data(chip); 286 281 unsigned int gpio = d->hwirq; 287 282 288 283 tegra_gpio_writel(tgi, 1 << GPIO_BIT(gpio), GPIO_INT_CLR(tgi, gpio)); ··· 283 292 284 293 static void tegra_gpio_irq_mask(struct irq_data *d) 285 294 { 286 - struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); 287 - struct tegra_gpio_info *tgi = bank->tgi; 295 + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 296 + struct tegra_gpio_info *tgi = gpiochip_get_data(chip); 288 297 unsigned int gpio = d->hwirq; 289 298 290 299 tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 0); ··· 292 301 293 302 static void tegra_gpio_irq_unmask(struct irq_data *d) 294 303 { 295 - struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); 296 - struct tegra_gpio_info *tgi = bank->tgi; 304 + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 305 + struct tegra_gpio_info *tgi = gpiochip_get_data(chip); 297 306 unsigned int gpio = d->hwirq; 298 307 299 308 tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 1); ··· 302 311 static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type) 303 312 { 304 313 unsigned int gpio = d->hwirq, port = GPIO_PORT(gpio), lvl_type; 305 - struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); 306 - struct tegra_gpio_info *tgi = bank->tgi; 314 + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 315 + struct tegra_gpio_info *tgi = gpiochip_get_data(chip); 316 + struct tegra_gpio_bank *bank; 307 317 unsigned long flags; 308 - u32 val; 309 318 int ret; 319 + u32 val; 320 + 321 + bank = &tgi->bank_info[GPIO_BANK(d->hwirq)]; 310 322 311 323 switch (type & IRQ_TYPE_SENSE_MASK) { 312 324 case IRQ_TYPE_EDGE_RISING: ··· 361 367 else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) 362 368 irq_set_handler_locked(d, handle_edge_irq); 363 369 364 - return 0; 370 + if (d->parent_data) 371 + ret = irq_chip_set_type_parent(d, type); 372 + 373 + return ret; 365 374 } 366 375 367 376 static void tegra_gpio_irq_shutdown(struct irq_data *d) 368 377 { 369 - struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); 370 - struct tegra_gpio_info *tgi = bank->tgi; 378 + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 379 + struct tegra_gpio_info *tgi = gpiochip_get_data(chip); 371 380 unsigned int gpio = d->hwirq; 372 381 373 382 tegra_gpio_irq_mask(d); ··· 379 382 380 383 static void tegra_gpio_irq_handler(struct irq_desc *desc) 381 384 { 382 - unsigned int port, pin, gpio; 383 - bool unmasked = false; 384 - u32 lvl; 385 - unsigned long sta; 385 + struct tegra_gpio_info *tgi = irq_desc_get_handler_data(desc); 386 386 struct irq_chip *chip = irq_desc_get_chip(desc); 387 - struct tegra_gpio_bank *bank = irq_desc_get_handler_data(desc); 388 - struct tegra_gpio_info *tgi = bank->tgi; 387 + struct irq_domain *domain = tgi->gc.irq.domain; 388 + unsigned int irq = irq_desc_get_irq(desc); 389 + struct tegra_gpio_bank *bank = NULL; 390 + unsigned int port, pin, gpio, i; 391 + bool unmasked = false; 392 + unsigned long sta; 393 + u32 lvl; 394 + 395 + for (i = 0; i < tgi->bank_count; i++) { 396 + if (tgi->irqs[i] == irq) { 397 + bank = &tgi->bank_info[i]; 398 + break; 399 + } 400 + } 401 + 402 + if (WARN_ON(bank == NULL)) 403 + return; 389 404 390 405 chained_irq_enter(chip, desc); 391 406 ··· 420 411 chained_irq_exit(chip, desc); 421 412 } 422 413 423 - generic_handle_irq(irq_find_mapping(tgi->irq_domain, 424 - gpio + pin)); 414 + irq = irq_find_mapping(domain, gpio + pin); 415 + if (WARN_ON(irq == 0)) 416 + continue; 417 + 418 + generic_handle_irq(irq); 425 419 } 426 420 } 427 421 428 422 if (!unmasked) 429 423 chained_irq_exit(chip, desc); 424 + } 430 425 426 + static int tegra_gpio_child_to_parent_hwirq(struct gpio_chip *chip, unsigned int hwirq, 427 + unsigned int type, unsigned int *parent_hwirq, 428 + unsigned int *parent_type) 429 + { 430 + *parent_hwirq = chip->irq.child_offset_to_irq(chip, hwirq); 431 + *parent_type = type; 432 + 433 + return 0; 434 + } 435 + 436 + static void *tegra_gpio_populate_parent_fwspec(struct gpio_chip *chip, unsigned int parent_hwirq, 437 + unsigned int parent_type) 438 + { 439 + struct irq_fwspec *fwspec; 440 + 441 + fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL); 442 + if (!fwspec) 443 + return NULL; 444 + 445 + fwspec->fwnode = chip->irq.parent_domain->fwnode; 446 + fwspec->param_count = 3; 447 + fwspec->param[0] = 0; 448 + fwspec->param[1] = parent_hwirq; 449 + fwspec->param[2] = parent_type; 450 + 451 + return fwspec; 431 452 } 432 453 433 454 #ifdef CONFIG_PM_SLEEP ··· 536 497 537 498 static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable) 538 499 { 539 - struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); 500 + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 501 + struct tegra_gpio_info *tgi = gpiochip_get_data(chip); 502 + struct tegra_gpio_bank *bank; 540 503 unsigned int gpio = d->hwirq; 541 504 u32 port, bit, mask; 542 - int err; 543 505 544 - err = irq_set_irq_wake(bank->irq, enable); 545 - if (err) 546 - return err; 506 + bank = &tgi->bank_info[GPIO_BANK(d->hwirq)]; 547 507 548 508 port = GPIO_PORT(gpio); 549 509 bit = GPIO_BIT(gpio); ··· 553 515 else 554 516 bank->wake_enb[port] &= ~mask; 555 517 518 + if (d->parent_data) 519 + return irq_chip_set_wake_parent(d, enable); 520 + 556 521 return 0; 557 522 } 558 523 #endif 524 + 525 + static int tegra_gpio_irq_set_affinity(struct irq_data *data, const struct cpumask *dest, 526 + bool force) 527 + { 528 + if (data->parent_data) 529 + return irq_chip_set_affinity_parent(data, dest, force); 530 + 531 + return -EINVAL; 532 + } 533 + 534 + static int tegra_gpio_irq_request_resources(struct irq_data *d) 535 + { 536 + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 537 + struct tegra_gpio_info *tgi = gpiochip_get_data(chip); 538 + 539 + tegra_gpio_enable(tgi, d->hwirq); 540 + 541 + return gpiochip_reqres_irq(chip, d->hwirq); 542 + } 543 + 544 + static void tegra_gpio_irq_release_resources(struct irq_data *d) 545 + { 546 + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 547 + struct tegra_gpio_info *tgi = gpiochip_get_data(chip); 548 + 549 + gpiochip_relres_irq(chip, d->hwirq); 550 + tegra_gpio_enable(tgi, d->hwirq); 551 + } 559 552 560 553 #ifdef CONFIG_DEBUG_FS 561 554 ··· 637 568 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(tegra_gpio_suspend, tegra_gpio_resume) 638 569 }; 639 570 640 - static struct lock_class_key gpio_lock_class; 641 - static struct lock_class_key gpio_request_class; 571 + static const struct of_device_id tegra_pmc_of_match[] = { 572 + { .compatible = "nvidia,tegra210-pmc", }, 573 + { /* sentinel */ }, 574 + }; 642 575 643 576 static int tegra_gpio_probe(struct platform_device *pdev) 644 577 { 645 - struct tegra_gpio_info *tgi; 646 578 struct tegra_gpio_bank *bank; 647 - unsigned int gpio, i, j; 579 + struct tegra_gpio_info *tgi; 580 + struct gpio_irq_chip *irq; 581 + struct device_node *np; 582 + unsigned int i, j; 648 583 int ret; 649 584 650 585 tgi = devm_kzalloc(&pdev->dev, sizeof(*tgi), GFP_KERNEL); ··· 677 604 tgi->gc.direction_output = tegra_gpio_direction_output; 678 605 tgi->gc.set = tegra_gpio_set; 679 606 tgi->gc.get_direction = tegra_gpio_get_direction; 680 - tgi->gc.to_irq = tegra_gpio_to_irq; 681 607 tgi->gc.base = 0; 682 608 tgi->gc.ngpio = tgi->bank_count * 32; 683 609 tgi->gc.parent = &pdev->dev; ··· 691 619 #ifdef CONFIG_PM_SLEEP 692 620 tgi->ic.irq_set_wake = tegra_gpio_irq_set_wake; 693 621 #endif 622 + tgi->ic.irq_set_affinity = tegra_gpio_irq_set_affinity; 623 + tgi->ic.irq_request_resources = tegra_gpio_irq_request_resources; 624 + tgi->ic.irq_release_resources = tegra_gpio_irq_release_resources; 694 625 695 626 platform_set_drvdata(pdev, tgi); 696 627 ··· 705 630 if (!tgi->bank_info) 706 631 return -ENOMEM; 707 632 708 - tgi->irq_domain = irq_domain_add_linear(pdev->dev.of_node, 709 - tgi->gc.ngpio, 710 - &irq_domain_simple_ops, NULL); 711 - if (!tgi->irq_domain) 712 - return -ENODEV; 633 + tgi->irqs = devm_kcalloc(&pdev->dev, tgi->bank_count, sizeof(*tgi->irqs), GFP_KERNEL); 634 + if (!tgi->irqs) 635 + return -ENOMEM; 713 636 714 637 for (i = 0; i < tgi->bank_count; i++) { 715 638 ret = platform_get_irq(pdev, i); ··· 716 643 717 644 bank = &tgi->bank_info[i]; 718 645 bank->bank = i; 719 - bank->irq = ret; 720 - bank->tgi = tgi; 646 + 647 + tgi->irqs[i] = ret; 648 + 649 + for (j = 0; j < 4; j++) { 650 + raw_spin_lock_init(&bank->lvl_lock[j]); 651 + spin_lock_init(&bank->dbc_lock[j]); 652 + } 653 + } 654 + 655 + irq = &tgi->gc.irq; 656 + irq->chip = &tgi->ic; 657 + irq->fwnode = of_node_to_fwnode(pdev->dev.of_node); 658 + irq->child_to_parent_hwirq = tegra_gpio_child_to_parent_hwirq; 659 + irq->populate_parent_alloc_arg = tegra_gpio_populate_parent_fwspec; 660 + irq->handler = handle_simple_irq; 661 + irq->default_type = IRQ_TYPE_NONE; 662 + irq->parent_handler = tegra_gpio_irq_handler; 663 + irq->parent_handler_data = tgi; 664 + irq->num_parents = tgi->bank_count; 665 + irq->parents = tgi->irqs; 666 + 667 + np = of_find_matching_node(NULL, tegra_pmc_of_match); 668 + if (np) { 669 + irq->parent_domain = irq_find_host(np); 670 + of_node_put(np); 671 + 672 + if (!irq->parent_domain) 673 + return -EPROBE_DEFER; 721 674 } 722 675 723 676 tgi->regs = devm_platform_ioremap_resource(pdev, 0); ··· 759 660 } 760 661 761 662 ret = devm_gpiochip_add_data(&pdev->dev, &tgi->gc, tgi); 762 - if (ret < 0) { 763 - irq_domain_remove(tgi->irq_domain); 663 + if (ret < 0) 764 664 return ret; 765 - } 766 - 767 - for (gpio = 0; gpio < tgi->gc.ngpio; gpio++) { 768 - int irq = irq_create_mapping(tgi->irq_domain, gpio); 769 - /* No validity check; all Tegra GPIOs are valid IRQs */ 770 - 771 - bank = &tgi->bank_info[GPIO_BANK(gpio)]; 772 - 773 - irq_set_chip_data(irq, bank); 774 - irq_set_lockdep_class(irq, &gpio_lock_class, &gpio_request_class); 775 - irq_set_chip_and_handler(irq, &tgi->ic, handle_simple_irq); 776 - } 777 - 778 - for (i = 0; i < tgi->bank_count; i++) { 779 - bank = &tgi->bank_info[i]; 780 - 781 - irq_set_chained_handler_and_data(bank->irq, 782 - tegra_gpio_irq_handler, bank); 783 - 784 - for (j = 0; j < 4; j++) { 785 - raw_spin_lock_init(&bank->lvl_lock[j]); 786 - spin_lock_init(&bank->dbc_lock[j]); 787 - } 788 - } 789 665 790 666 tegra_gpio_debuginit(tgi); 791 667