diff options
Diffstat (limited to 'drivers/gpio/gpio-omap.c')
-rw-r--r-- | drivers/gpio/gpio-omap.c | 129 |
1 files changed, 83 insertions, 46 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index a4fe038d090e..89675f862308 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
@@ -424,6 +424,52 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, | |||
424 | return 0; | 424 | return 0; |
425 | } | 425 | } |
426 | 426 | ||
427 | static void _enable_gpio_module(struct gpio_bank *bank, unsigned offset) | ||
428 | { | ||
429 | if (bank->regs->pinctrl) { | ||
430 | void __iomem *reg = bank->base + bank->regs->pinctrl; | ||
431 | |||
432 | /* Claim the pin for MPU */ | ||
433 | __raw_writel(__raw_readl(reg) | (1 << offset), reg); | ||
434 | } | ||
435 | |||
436 | if (bank->regs->ctrl && !BANK_USED(bank)) { | ||
437 | void __iomem *reg = bank->base + bank->regs->ctrl; | ||
438 | u32 ctrl; | ||
439 | |||
440 | ctrl = __raw_readl(reg); | ||
441 | /* Module is enabled, clocks are not gated */ | ||
442 | ctrl &= ~GPIO_MOD_CTRL_BIT; | ||
443 | __raw_writel(ctrl, reg); | ||
444 | bank->context.ctrl = ctrl; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | static void _disable_gpio_module(struct gpio_bank *bank, unsigned offset) | ||
449 | { | ||
450 | void __iomem *base = bank->base; | ||
451 | |||
452 | if (bank->regs->wkup_en && | ||
453 | !LINE_USED(bank->mod_usage, offset) && | ||
454 | !LINE_USED(bank->irq_usage, offset)) { | ||
455 | /* Disable wake-up during idle for dynamic tick */ | ||
456 | _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0); | ||
457 | bank->context.wake_en = | ||
458 | __raw_readl(bank->base + bank->regs->wkup_en); | ||
459 | } | ||
460 | |||
461 | if (bank->regs->ctrl && !BANK_USED(bank)) { | ||
462 | void __iomem *reg = bank->base + bank->regs->ctrl; | ||
463 | u32 ctrl; | ||
464 | |||
465 | ctrl = __raw_readl(reg); | ||
466 | /* Module is disabled, clocks are gated */ | ||
467 | ctrl |= GPIO_MOD_CTRL_BIT; | ||
468 | __raw_writel(ctrl, reg); | ||
469 | bank->context.ctrl = ctrl; | ||
470 | } | ||
471 | } | ||
472 | |||
427 | static int gpio_is_input(struct gpio_bank *bank, int mask) | 473 | static int gpio_is_input(struct gpio_bank *bank, int mask) |
428 | { | 474 | { |
429 | void __iomem *reg = bank->base + bank->regs->direction; | 475 | void __iomem *reg = bank->base + bank->regs->direction; |
@@ -437,9 +483,10 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) | |||
437 | unsigned gpio = 0; | 483 | unsigned gpio = 0; |
438 | int retval; | 484 | int retval; |
439 | unsigned long flags; | 485 | unsigned long flags; |
486 | unsigned offset; | ||
440 | 487 | ||
441 | if (WARN_ON(!BANK_USED(bank))) | 488 | if (!BANK_USED(bank)) |
442 | return -EINVAL; | 489 | pm_runtime_get_sync(bank->dev); |
443 | 490 | ||
444 | #ifdef CONFIG_ARCH_OMAP1 | 491 | #ifdef CONFIG_ARCH_OMAP1 |
445 | if (d->irq > IH_MPUIO_BASE) | 492 | if (d->irq > IH_MPUIO_BASE) |
@@ -457,7 +504,16 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) | |||
457 | return -EINVAL; | 504 | return -EINVAL; |
458 | 505 | ||
459 | spin_lock_irqsave(&bank->lock, flags); | 506 | spin_lock_irqsave(&bank->lock, flags); |
460 | retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type); | 507 | offset = GPIO_INDEX(bank, gpio); |
508 | retval = _set_gpio_triggering(bank, offset, type); | ||
509 | if (!LINE_USED(bank->mod_usage, offset)) { | ||
510 | _enable_gpio_module(bank, offset); | ||
511 | _set_gpio_direction(bank, offset, 1); | ||
512 | } else if (!gpio_is_input(bank, 1 << offset)) { | ||
513 | spin_unlock_irqrestore(&bank->lock, flags); | ||
514 | return -EINVAL; | ||
515 | } | ||
516 | |||
461 | bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio); | 517 | bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio); |
462 | spin_unlock_irqrestore(&bank->lock, flags); | 518 | spin_unlock_irqrestore(&bank->lock, flags); |
463 | 519 | ||
@@ -620,30 +676,14 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) | |||
620 | 676 | ||
621 | spin_lock_irqsave(&bank->lock, flags); | 677 | spin_lock_irqsave(&bank->lock, flags); |
622 | /* Set trigger to none. You need to enable the desired trigger with | 678 | /* Set trigger to none. You need to enable the desired trigger with |
623 | * request_irq() or set_irq_type(). | 679 | * request_irq() or set_irq_type(). Only do this if the IRQ line has |
680 | * not already been requested. | ||
624 | */ | 681 | */ |
625 | _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); | 682 | if (!LINE_USED(bank->irq_usage, offset)) { |
626 | 683 | _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); | |
627 | if (bank->regs->pinctrl) { | 684 | _enable_gpio_module(bank, offset); |
628 | void __iomem *reg = bank->base + bank->regs->pinctrl; | ||
629 | |||
630 | /* Claim the pin for MPU */ | ||
631 | __raw_writel(__raw_readl(reg) | (1 << offset), reg); | ||
632 | } | 685 | } |
633 | |||
634 | if (bank->regs->ctrl && !BANK_USED(bank)) { | ||
635 | void __iomem *reg = bank->base + bank->regs->ctrl; | ||
636 | u32 ctrl; | ||
637 | |||
638 | ctrl = __raw_readl(reg); | ||
639 | /* Module is enabled, clocks are not gated */ | ||
640 | ctrl &= ~GPIO_MOD_CTRL_BIT; | ||
641 | __raw_writel(ctrl, reg); | ||
642 | bank->context.ctrl = ctrl; | ||
643 | } | ||
644 | |||
645 | bank->mod_usage |= 1 << offset; | 686 | bank->mod_usage |= 1 << offset; |
646 | |||
647 | spin_unlock_irqrestore(&bank->lock, flags); | 687 | spin_unlock_irqrestore(&bank->lock, flags); |
648 | 688 | ||
649 | return 0; | 689 | return 0; |
@@ -652,31 +692,11 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) | |||
652 | static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) | 692 | static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) |
653 | { | 693 | { |
654 | struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); | 694 | struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); |
655 | void __iomem *base = bank->base; | ||
656 | unsigned long flags; | 695 | unsigned long flags; |
657 | 696 | ||
658 | spin_lock_irqsave(&bank->lock, flags); | 697 | spin_lock_irqsave(&bank->lock, flags); |
659 | |||
660 | if (bank->regs->wkup_en) { | ||
661 | /* Disable wake-up during idle for dynamic tick */ | ||
662 | _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0); | ||
663 | bank->context.wake_en = | ||
664 | __raw_readl(bank->base + bank->regs->wkup_en); | ||
665 | } | ||
666 | |||
667 | bank->mod_usage &= ~(1 << offset); | 698 | bank->mod_usage &= ~(1 << offset); |
668 | 699 | _disable_gpio_module(bank, offset); | |
669 | if (bank->regs->ctrl && !BANK_USED(bank)) { | ||
670 | void __iomem *reg = bank->base + bank->regs->ctrl; | ||
671 | u32 ctrl; | ||
672 | |||
673 | ctrl = __raw_readl(reg); | ||
674 | /* Module is disabled, clocks are gated */ | ||
675 | ctrl |= GPIO_MOD_CTRL_BIT; | ||
676 | __raw_writel(ctrl, reg); | ||
677 | bank->context.ctrl = ctrl; | ||
678 | } | ||
679 | |||
680 | _reset_gpio(bank, bank->chip.base + offset); | 700 | _reset_gpio(bank, bank->chip.base + offset); |
681 | spin_unlock_irqrestore(&bank->lock, flags); | 701 | spin_unlock_irqrestore(&bank->lock, flags); |
682 | 702 | ||
@@ -778,8 +798,16 @@ static void gpio_irq_shutdown(struct irq_data *d) | |||
778 | 798 | ||
779 | spin_lock_irqsave(&bank->lock, flags); | 799 | spin_lock_irqsave(&bank->lock, flags); |
780 | bank->irq_usage &= ~(1 << offset); | 800 | bank->irq_usage &= ~(1 << offset); |
801 | _disable_gpio_module(bank, offset); | ||
781 | _reset_gpio(bank, gpio); | 802 | _reset_gpio(bank, gpio); |
782 | spin_unlock_irqrestore(&bank->lock, flags); | 803 | spin_unlock_irqrestore(&bank->lock, flags); |
804 | |||
805 | /* | ||
806 | * If this is the last IRQ to be freed in the bank, | ||
807 | * disable the bank module. | ||
808 | */ | ||
809 | if (!BANK_USED(bank)) | ||
810 | pm_runtime_put(bank->dev); | ||
783 | } | 811 | } |
784 | 812 | ||
785 | static void gpio_ack_irq(struct irq_data *d) | 813 | static void gpio_ack_irq(struct irq_data *d) |
@@ -929,13 +957,22 @@ static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) | |||
929 | { | 957 | { |
930 | struct gpio_bank *bank; | 958 | struct gpio_bank *bank; |
931 | unsigned long flags; | 959 | unsigned long flags; |
960 | int retval = 0; | ||
932 | 961 | ||
933 | bank = container_of(chip, struct gpio_bank, chip); | 962 | bank = container_of(chip, struct gpio_bank, chip); |
934 | spin_lock_irqsave(&bank->lock, flags); | 963 | spin_lock_irqsave(&bank->lock, flags); |
964 | |||
965 | if (LINE_USED(bank->irq_usage, offset)) { | ||
966 | retval = -EINVAL; | ||
967 | goto exit; | ||
968 | } | ||
969 | |||
935 | bank->set_dataout(bank, offset, value); | 970 | bank->set_dataout(bank, offset, value); |
936 | _set_gpio_direction(bank, offset, 0); | 971 | _set_gpio_direction(bank, offset, 0); |
972 | |||
973 | exit: | ||
937 | spin_unlock_irqrestore(&bank->lock, flags); | 974 | spin_unlock_irqrestore(&bank->lock, flags); |
938 | return 0; | 975 | return retval; |
939 | } | 976 | } |
940 | 977 | ||
941 | static int gpio_debounce(struct gpio_chip *chip, unsigned offset, | 978 | static int gpio_debounce(struct gpio_chip *chip, unsigned offset, |