diff options
Diffstat (limited to 'drivers/gpio/gpio-omap.c')
-rw-r--r-- | drivers/gpio/gpio-omap.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 0ff43552d472..a4fe038d090e 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
@@ -63,6 +63,7 @@ struct gpio_bank { | |||
63 | struct gpio_chip chip; | 63 | struct gpio_chip chip; |
64 | struct clk *dbck; | 64 | struct clk *dbck; |
65 | u32 mod_usage; | 65 | u32 mod_usage; |
66 | u32 irq_usage; | ||
66 | u32 dbck_enable_mask; | 67 | u32 dbck_enable_mask; |
67 | bool dbck_enabled; | 68 | bool dbck_enabled; |
68 | struct device *dev; | 69 | struct device *dev; |
@@ -86,6 +87,9 @@ struct gpio_bank { | |||
86 | #define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio)) | 87 | #define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio)) |
87 | #define GPIO_MOD_CTRL_BIT BIT(0) | 88 | #define GPIO_MOD_CTRL_BIT BIT(0) |
88 | 89 | ||
90 | #define BANK_USED(bank) (bank->mod_usage || bank->irq_usage) | ||
91 | #define LINE_USED(line, offset) (line & (1 << offset)) | ||
92 | |||
89 | static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq) | 93 | static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq) |
90 | { | 94 | { |
91 | return bank->chip.base + gpio_irq; | 95 | return bank->chip.base + gpio_irq; |
@@ -420,6 +424,13 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, | |||
420 | return 0; | 424 | return 0; |
421 | } | 425 | } |
422 | 426 | ||
427 | static int gpio_is_input(struct gpio_bank *bank, int mask) | ||
428 | { | ||
429 | void __iomem *reg = bank->base + bank->regs->direction; | ||
430 | |||
431 | return __raw_readl(reg) & mask; | ||
432 | } | ||
433 | |||
423 | static int gpio_irq_type(struct irq_data *d, unsigned type) | 434 | static int gpio_irq_type(struct irq_data *d, unsigned type) |
424 | { | 435 | { |
425 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 436 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
@@ -427,7 +438,7 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) | |||
427 | int retval; | 438 | int retval; |
428 | unsigned long flags; | 439 | unsigned long flags; |
429 | 440 | ||
430 | if (WARN_ON(!bank->mod_usage)) | 441 | if (WARN_ON(!BANK_USED(bank))) |
431 | return -EINVAL; | 442 | return -EINVAL; |
432 | 443 | ||
433 | #ifdef CONFIG_ARCH_OMAP1 | 444 | #ifdef CONFIG_ARCH_OMAP1 |
@@ -447,6 +458,7 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) | |||
447 | 458 | ||
448 | spin_lock_irqsave(&bank->lock, flags); | 459 | spin_lock_irqsave(&bank->lock, flags); |
449 | retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type); | 460 | retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type); |
461 | bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio); | ||
450 | spin_unlock_irqrestore(&bank->lock, flags); | 462 | spin_unlock_irqrestore(&bank->lock, flags); |
451 | 463 | ||
452 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | 464 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
@@ -603,7 +615,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) | |||
603 | * If this is the first gpio_request for the bank, | 615 | * If this is the first gpio_request for the bank, |
604 | * enable the bank module. | 616 | * enable the bank module. |
605 | */ | 617 | */ |
606 | if (!bank->mod_usage) | 618 | if (!BANK_USED(bank)) |
607 | pm_runtime_get_sync(bank->dev); | 619 | pm_runtime_get_sync(bank->dev); |
608 | 620 | ||
609 | spin_lock_irqsave(&bank->lock, flags); | 621 | spin_lock_irqsave(&bank->lock, flags); |
@@ -619,7 +631,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) | |||
619 | __raw_writel(__raw_readl(reg) | (1 << offset), reg); | 631 | __raw_writel(__raw_readl(reg) | (1 << offset), reg); |
620 | } | 632 | } |
621 | 633 | ||
622 | if (bank->regs->ctrl && !bank->mod_usage) { | 634 | if (bank->regs->ctrl && !BANK_USED(bank)) { |
623 | void __iomem *reg = bank->base + bank->regs->ctrl; | 635 | void __iomem *reg = bank->base + bank->regs->ctrl; |
624 | u32 ctrl; | 636 | u32 ctrl; |
625 | 637 | ||
@@ -654,7 +666,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) | |||
654 | 666 | ||
655 | bank->mod_usage &= ~(1 << offset); | 667 | bank->mod_usage &= ~(1 << offset); |
656 | 668 | ||
657 | if (bank->regs->ctrl && !bank->mod_usage) { | 669 | if (bank->regs->ctrl && !BANK_USED(bank)) { |
658 | void __iomem *reg = bank->base + bank->regs->ctrl; | 670 | void __iomem *reg = bank->base + bank->regs->ctrl; |
659 | u32 ctrl; | 671 | u32 ctrl; |
660 | 672 | ||
@@ -672,7 +684,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) | |||
672 | * If this is the last gpio to be freed in the bank, | 684 | * If this is the last gpio to be freed in the bank, |
673 | * disable the bank module. | 685 | * disable the bank module. |
674 | */ | 686 | */ |
675 | if (!bank->mod_usage) | 687 | if (!BANK_USED(bank)) |
676 | pm_runtime_put(bank->dev); | 688 | pm_runtime_put(bank->dev); |
677 | } | 689 | } |
678 | 690 | ||
@@ -762,8 +774,10 @@ static void gpio_irq_shutdown(struct irq_data *d) | |||
762 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 774 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
763 | unsigned int gpio = irq_to_gpio(bank, d->hwirq); | 775 | unsigned int gpio = irq_to_gpio(bank, d->hwirq); |
764 | unsigned long flags; | 776 | unsigned long flags; |
777 | unsigned offset = GPIO_INDEX(bank, gpio); | ||
765 | 778 | ||
766 | spin_lock_irqsave(&bank->lock, flags); | 779 | spin_lock_irqsave(&bank->lock, flags); |
780 | bank->irq_usage &= ~(1 << offset); | ||
767 | _reset_gpio(bank, gpio); | 781 | _reset_gpio(bank, gpio); |
768 | spin_unlock_irqrestore(&bank->lock, flags); | 782 | spin_unlock_irqrestore(&bank->lock, flags); |
769 | } | 783 | } |
@@ -897,13 +911,6 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset) | |||
897 | return 0; | 911 | return 0; |
898 | } | 912 | } |
899 | 913 | ||
900 | static int gpio_is_input(struct gpio_bank *bank, int mask) | ||
901 | { | ||
902 | void __iomem *reg = bank->base + bank->regs->direction; | ||
903 | |||
904 | return __raw_readl(reg) & mask; | ||
905 | } | ||
906 | |||
907 | static int gpio_get(struct gpio_chip *chip, unsigned offset) | 914 | static int gpio_get(struct gpio_chip *chip, unsigned offset) |
908 | { | 915 | { |
909 | struct gpio_bank *bank; | 916 | struct gpio_bank *bank; |
@@ -1400,7 +1407,7 @@ void omap2_gpio_prepare_for_idle(int pwr_mode) | |||
1400 | struct gpio_bank *bank; | 1407 | struct gpio_bank *bank; |
1401 | 1408 | ||
1402 | list_for_each_entry(bank, &omap_gpio_list, node) { | 1409 | list_for_each_entry(bank, &omap_gpio_list, node) { |
1403 | if (!bank->mod_usage || !bank->loses_context) | 1410 | if (!BANK_USED(bank) || !bank->loses_context) |
1404 | continue; | 1411 | continue; |
1405 | 1412 | ||
1406 | bank->power_mode = pwr_mode; | 1413 | bank->power_mode = pwr_mode; |
@@ -1414,7 +1421,7 @@ void omap2_gpio_resume_after_idle(void) | |||
1414 | struct gpio_bank *bank; | 1421 | struct gpio_bank *bank; |
1415 | 1422 | ||
1416 | list_for_each_entry(bank, &omap_gpio_list, node) { | 1423 | list_for_each_entry(bank, &omap_gpio_list, node) { |
1417 | if (!bank->mod_usage || !bank->loses_context) | 1424 | if (!BANK_USED(bank) || !bank->loses_context) |
1418 | continue; | 1425 | continue; |
1419 | 1426 | ||
1420 | pm_runtime_get_sync(bank->dev); | 1427 | pm_runtime_get_sync(bank->dev); |