diff options
Diffstat (limited to 'arch/arm/plat-nomadik/gpio.c')
-rw-r--r-- | arch/arm/plat-nomadik/gpio.c | 102 |
1 files changed, 27 insertions, 75 deletions
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 70620426ee55..f49748eca1a3 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c | |||
@@ -54,6 +54,7 @@ struct nmk_gpio_chip { | |||
54 | u32 rwimsc; | 54 | u32 rwimsc; |
55 | u32 fwimsc; | 55 | u32 fwimsc; |
56 | u32 slpm; | 56 | u32 slpm; |
57 | u32 enabled; | ||
57 | }; | 58 | }; |
58 | 59 | ||
59 | static struct nmk_gpio_chip * | 60 | static struct nmk_gpio_chip * |
@@ -318,7 +319,7 @@ static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep) | |||
318 | struct nmk_gpio_chip *nmk_chip; | 319 | struct nmk_gpio_chip *nmk_chip; |
319 | int pin = PIN_NUM(cfgs[i]); | 320 | int pin = PIN_NUM(cfgs[i]); |
320 | 321 | ||
321 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(pin)); | 322 | nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(pin)); |
322 | if (!nmk_chip) { | 323 | if (!nmk_chip) { |
323 | ret = -EINVAL; | 324 | ret = -EINVAL; |
324 | break; | 325 | break; |
@@ -397,7 +398,7 @@ int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode) | |||
397 | struct nmk_gpio_chip *nmk_chip; | 398 | struct nmk_gpio_chip *nmk_chip; |
398 | unsigned long flags; | 399 | unsigned long flags; |
399 | 400 | ||
400 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | 401 | nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); |
401 | if (!nmk_chip) | 402 | if (!nmk_chip) |
402 | return -EINVAL; | 403 | return -EINVAL; |
403 | 404 | ||
@@ -430,7 +431,7 @@ int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull) | |||
430 | struct nmk_gpio_chip *nmk_chip; | 431 | struct nmk_gpio_chip *nmk_chip; |
431 | unsigned long flags; | 432 | unsigned long flags; |
432 | 433 | ||
433 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | 434 | nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); |
434 | if (!nmk_chip) | 435 | if (!nmk_chip) |
435 | return -EINVAL; | 436 | return -EINVAL; |
436 | 437 | ||
@@ -456,7 +457,7 @@ int nmk_gpio_set_mode(int gpio, int gpio_mode) | |||
456 | struct nmk_gpio_chip *nmk_chip; | 457 | struct nmk_gpio_chip *nmk_chip; |
457 | unsigned long flags; | 458 | unsigned long flags; |
458 | 459 | ||
459 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | 460 | nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); |
460 | if (!nmk_chip) | 461 | if (!nmk_chip) |
461 | return -EINVAL; | 462 | return -EINVAL; |
462 | 463 | ||
@@ -473,7 +474,7 @@ int nmk_gpio_get_mode(int gpio) | |||
473 | struct nmk_gpio_chip *nmk_chip; | 474 | struct nmk_gpio_chip *nmk_chip; |
474 | u32 afunc, bfunc, bit; | 475 | u32 afunc, bfunc, bit; |
475 | 476 | ||
476 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | 477 | nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); |
477 | if (!nmk_chip) | 478 | if (!nmk_chip) |
478 | return -EINVAL; | 479 | return -EINVAL; |
479 | 480 | ||
@@ -541,13 +542,6 @@ static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, | |||
541 | static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip, | 542 | static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip, |
542 | int gpio, bool on) | 543 | int gpio, bool on) |
543 | { | 544 | { |
544 | #ifdef CONFIG_ARCH_U8500 | ||
545 | if (cpu_is_u8500v2()) { | ||
546 | __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, | ||
547 | on ? NMK_GPIO_SLPM_WAKEUP_ENABLE | ||
548 | : NMK_GPIO_SLPM_WAKEUP_DISABLE); | ||
549 | } | ||
550 | #endif | ||
551 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on); | 545 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on); |
552 | } | 546 | } |
553 | 547 | ||
@@ -564,6 +558,11 @@ static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable) | |||
564 | if (!nmk_chip) | 558 | if (!nmk_chip) |
565 | return -EINVAL; | 559 | return -EINVAL; |
566 | 560 | ||
561 | if (enable) | ||
562 | nmk_chip->enabled |= bitmask; | ||
563 | else | ||
564 | nmk_chip->enabled &= ~bitmask; | ||
565 | |||
567 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); | 566 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); |
568 | spin_lock(&nmk_chip->lock); | 567 | spin_lock(&nmk_chip->lock); |
569 | 568 | ||
@@ -590,8 +589,6 @@ static void nmk_gpio_irq_unmask(struct irq_data *d) | |||
590 | 589 | ||
591 | static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) | 590 | static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) |
592 | { | 591 | { |
593 | struct irq_desc *desc = irq_to_desc(d->irq); | ||
594 | bool enabled = !(desc->status & IRQ_DISABLED); | ||
595 | struct nmk_gpio_chip *nmk_chip; | 592 | struct nmk_gpio_chip *nmk_chip; |
596 | unsigned long flags; | 593 | unsigned long flags; |
597 | u32 bitmask; | 594 | u32 bitmask; |
@@ -606,7 +603,7 @@ static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) | |||
606 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); | 603 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); |
607 | spin_lock(&nmk_chip->lock); | 604 | spin_lock(&nmk_chip->lock); |
608 | 605 | ||
609 | if (!enabled) | 606 | if (!(nmk_chip->enabled & bitmask)) |
610 | __nmk_gpio_set_wake(nmk_chip, gpio, on); | 607 | __nmk_gpio_set_wake(nmk_chip, gpio, on); |
611 | 608 | ||
612 | if (on) | 609 | if (on) |
@@ -622,9 +619,7 @@ static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) | |||
622 | 619 | ||
623 | static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) | 620 | static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
624 | { | 621 | { |
625 | struct irq_desc *desc = irq_to_desc(d->irq); | 622 | bool enabled, wake = irqd_is_wakeup_set(d); |
626 | bool enabled = !(desc->status & IRQ_DISABLED); | ||
627 | bool wake = desc->wake_depth; | ||
628 | int gpio; | 623 | int gpio; |
629 | struct nmk_gpio_chip *nmk_chip; | 624 | struct nmk_gpio_chip *nmk_chip; |
630 | unsigned long flags; | 625 | unsigned long flags; |
@@ -641,6 +636,8 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
641 | if (type & IRQ_TYPE_LEVEL_LOW) | 636 | if (type & IRQ_TYPE_LEVEL_LOW) |
642 | return -EINVAL; | 637 | return -EINVAL; |
643 | 638 | ||
639 | enabled = nmk_chip->enabled & bitmask; | ||
640 | |||
644 | spin_lock_irqsave(&nmk_chip->lock, flags); | 641 | spin_lock_irqsave(&nmk_chip->lock, flags); |
645 | 642 | ||
646 | if (enabled) | 643 | if (enabled) |
@@ -681,7 +678,7 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, | |||
681 | u32 status) | 678 | u32 status) |
682 | { | 679 | { |
683 | struct nmk_gpio_chip *nmk_chip; | 680 | struct nmk_gpio_chip *nmk_chip; |
684 | struct irq_chip *host_chip = get_irq_chip(irq); | 681 | struct irq_chip *host_chip = irq_get_chip(irq); |
685 | unsigned int first_irq; | 682 | unsigned int first_irq; |
686 | 683 | ||
687 | if (host_chip->irq_mask_ack) | 684 | if (host_chip->irq_mask_ack) |
@@ -692,7 +689,7 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, | |||
692 | host_chip->irq_ack(&desc->irq_data); | 689 | host_chip->irq_ack(&desc->irq_data); |
693 | } | 690 | } |
694 | 691 | ||
695 | nmk_chip = get_irq_data(irq); | 692 | nmk_chip = irq_get_handler_data(irq); |
696 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); | 693 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); |
697 | while (status) { | 694 | while (status) { |
698 | int bit = __ffs(status); | 695 | int bit = __ffs(status); |
@@ -706,7 +703,7 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, | |||
706 | 703 | ||
707 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 704 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) |
708 | { | 705 | { |
709 | struct nmk_gpio_chip *nmk_chip = get_irq_data(irq); | 706 | struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq); |
710 | u32 status = readl(nmk_chip->addr + NMK_GPIO_IS); | 707 | u32 status = readl(nmk_chip->addr + NMK_GPIO_IS); |
711 | 708 | ||
712 | __nmk_gpio_irq_handler(irq, desc, status); | 709 | __nmk_gpio_irq_handler(irq, desc, status); |
@@ -715,7 +712,7 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
715 | static void nmk_gpio_secondary_irq_handler(unsigned int irq, | 712 | static void nmk_gpio_secondary_irq_handler(unsigned int irq, |
716 | struct irq_desc *desc) | 713 | struct irq_desc *desc) |
717 | { | 714 | { |
718 | struct nmk_gpio_chip *nmk_chip = get_irq_data(irq); | 715 | struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq); |
719 | u32 status = nmk_chip->get_secondary_status(nmk_chip->bank); | 716 | u32 status = nmk_chip->get_secondary_status(nmk_chip->bank); |
720 | 717 | ||
721 | __nmk_gpio_irq_handler(irq, desc, status); | 718 | __nmk_gpio_irq_handler(irq, desc, status); |
@@ -728,20 +725,20 @@ static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) | |||
728 | 725 | ||
729 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); | 726 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); |
730 | for (i = first_irq; i < first_irq + nmk_chip->chip.ngpio; i++) { | 727 | for (i = first_irq; i < first_irq + nmk_chip->chip.ngpio; i++) { |
731 | set_irq_chip(i, &nmk_gpio_irq_chip); | 728 | irq_set_chip_and_handler(i, &nmk_gpio_irq_chip, |
732 | set_irq_handler(i, handle_edge_irq); | 729 | handle_edge_irq); |
733 | set_irq_flags(i, IRQF_VALID); | 730 | set_irq_flags(i, IRQF_VALID); |
734 | set_irq_chip_data(i, nmk_chip); | 731 | irq_set_chip_data(i, nmk_chip); |
735 | set_irq_type(i, IRQ_TYPE_EDGE_FALLING); | 732 | irq_set_irq_type(i, IRQ_TYPE_EDGE_FALLING); |
736 | } | 733 | } |
737 | 734 | ||
738 | set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler); | 735 | irq_set_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler); |
739 | set_irq_data(nmk_chip->parent_irq, nmk_chip); | 736 | irq_set_handler_data(nmk_chip->parent_irq, nmk_chip); |
740 | 737 | ||
741 | if (nmk_chip->secondary_parent_irq >= 0) { | 738 | if (nmk_chip->secondary_parent_irq >= 0) { |
742 | set_irq_chained_handler(nmk_chip->secondary_parent_irq, | 739 | irq_set_chained_handler(nmk_chip->secondary_parent_irq, |
743 | nmk_gpio_secondary_irq_handler); | 740 | nmk_gpio_secondary_irq_handler); |
744 | set_irq_data(nmk_chip->secondary_parent_irq, nmk_chip); | 741 | irq_set_handler_data(nmk_chip->secondary_parent_irq, nmk_chip); |
745 | } | 742 | } |
746 | 743 | ||
747 | return 0; | 744 | return 0; |
@@ -832,51 +829,6 @@ static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
832 | : "? ", | 829 | : "? ", |
833 | (mode < 0) ? "unknown" : modes[mode], | 830 | (mode < 0) ? "unknown" : modes[mode], |
834 | pull ? "pull" : "none"); | 831 | pull ? "pull" : "none"); |
835 | |||
836 | if (!is_out) { | ||
837 | int irq = gpio_to_irq(gpio); | ||
838 | struct irq_desc *desc = irq_to_desc(irq); | ||
839 | |||
840 | /* This races with request_irq(), set_irq_type(), | ||
841 | * and set_irq_wake() ... but those are "rare". | ||
842 | * | ||
843 | * More significantly, trigger type flags aren't | ||
844 | * currently maintained by genirq. | ||
845 | */ | ||
846 | if (irq >= 0 && desc->action) { | ||
847 | char *trigger; | ||
848 | |||
849 | switch (desc->status & IRQ_TYPE_SENSE_MASK) { | ||
850 | case IRQ_TYPE_NONE: | ||
851 | trigger = "(default)"; | ||
852 | break; | ||
853 | case IRQ_TYPE_EDGE_FALLING: | ||
854 | trigger = "edge-falling"; | ||
855 | break; | ||
856 | case IRQ_TYPE_EDGE_RISING: | ||
857 | trigger = "edge-rising"; | ||
858 | break; | ||
859 | case IRQ_TYPE_EDGE_BOTH: | ||
860 | trigger = "edge-both"; | ||
861 | break; | ||
862 | case IRQ_TYPE_LEVEL_HIGH: | ||
863 | trigger = "level-high"; | ||
864 | break; | ||
865 | case IRQ_TYPE_LEVEL_LOW: | ||
866 | trigger = "level-low"; | ||
867 | break; | ||
868 | default: | ||
869 | trigger = "?trigger?"; | ||
870 | break; | ||
871 | } | ||
872 | |||
873 | seq_printf(s, " irq-%d %s%s", | ||
874 | irq, trigger, | ||
875 | (desc->status & IRQ_WAKEUP) | ||
876 | ? " wakeup" : ""); | ||
877 | } | ||
878 | } | ||
879 | |||
880 | seq_printf(s, "\n"); | 832 | seq_printf(s, "\n"); |
881 | } | 833 | } |
882 | } | 834 | } |