diff options
Diffstat (limited to 'arch/arm')
| -rw-r--r-- | arch/arm/plat-omap/gpio.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 4f81ea35b733..055160e0620e 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
| @@ -195,6 +195,7 @@ struct gpio_bank { | |||
| 195 | spinlock_t lock; | 195 | spinlock_t lock; |
| 196 | struct gpio_chip chip; | 196 | struct gpio_chip chip; |
| 197 | struct clk *dbck; | 197 | struct clk *dbck; |
| 198 | u32 mod_usage; | ||
| 198 | }; | 199 | }; |
| 199 | 200 | ||
| 200 | #define METHOD_MPUIO 0 | 201 | #define METHOD_MPUIO 0 |
| @@ -628,6 +629,10 @@ void omap_set_gpio_debounce(int gpio, int enable) | |||
| 628 | #else | 629 | #else |
| 629 | reg += OMAP24XX_GPIO_DEBOUNCE_EN; | 630 | reg += OMAP24XX_GPIO_DEBOUNCE_EN; |
| 630 | #endif | 631 | #endif |
| 632 | if (!(bank->mod_usage & l)) { | ||
| 633 | printk(KERN_ERR "GPIO %d not requested\n", gpio); | ||
| 634 | return; | ||
| 635 | } | ||
| 631 | 636 | ||
| 632 | spin_lock_irqsave(&bank->lock, flags); | 637 | spin_lock_irqsave(&bank->lock, flags); |
| 633 | val = __raw_readl(reg); | 638 | val = __raw_readl(reg); |
| @@ -663,6 +668,11 @@ void omap_set_gpio_debounce_time(int gpio, int enc_time) | |||
| 663 | bank = get_gpio_bank(gpio); | 668 | bank = get_gpio_bank(gpio); |
| 664 | reg = bank->base; | 669 | reg = bank->base; |
| 665 | 670 | ||
| 671 | if (!bank->mod_usage) { | ||
| 672 | printk(KERN_ERR "GPIO not requested\n"); | ||
| 673 | return; | ||
| 674 | } | ||
| 675 | |||
| 666 | enc_time &= 0xff; | 676 | enc_time &= 0xff; |
| 667 | #ifdef CONFIG_ARCH_OMAP4 | 677 | #ifdef CONFIG_ARCH_OMAP4 |
| 668 | reg += OMAP4_GPIO_DEBOUNCINGTIME; | 678 | reg += OMAP4_GPIO_DEBOUNCINGTIME; |
| @@ -1144,6 +1154,16 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) | |||
| 1144 | __raw_writel(__raw_readl(reg) | (1 << offset), reg); | 1154 | __raw_writel(__raw_readl(reg) | (1 << offset), reg); |
| 1145 | } | 1155 | } |
| 1146 | #endif | 1156 | #endif |
| 1157 | if (!cpu_class_is_omap1()) { | ||
| 1158 | if (!bank->mod_usage) { | ||
| 1159 | u32 ctrl; | ||
| 1160 | ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL); | ||
| 1161 | ctrl &= 0xFFFFFFFE; | ||
| 1162 | /* Module is enabled, clocks are not gated */ | ||
| 1163 | __raw_writel(ctrl, bank->base + OMAP24XX_GPIO_CTRL); | ||
| 1164 | } | ||
| 1165 | bank->mod_usage |= 1 << offset; | ||
| 1166 | } | ||
| 1147 | spin_unlock_irqrestore(&bank->lock, flags); | 1167 | spin_unlock_irqrestore(&bank->lock, flags); |
| 1148 | 1168 | ||
| 1149 | return 0; | 1169 | return 0; |
| @@ -1170,6 +1190,16 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) | |||
| 1170 | __raw_writel(1 << offset, reg); | 1190 | __raw_writel(1 << offset, reg); |
| 1171 | } | 1191 | } |
| 1172 | #endif | 1192 | #endif |
| 1193 | if (!cpu_class_is_omap1()) { | ||
| 1194 | bank->mod_usage &= ~(1 << offset); | ||
| 1195 | if (!bank->mod_usage) { | ||
| 1196 | u32 ctrl; | ||
| 1197 | ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL); | ||
| 1198 | /* Module is disabled, clocks are gated */ | ||
| 1199 | ctrl |= 1; | ||
| 1200 | __raw_writel(ctrl, bank->base + OMAP24XX_GPIO_CTRL); | ||
| 1201 | } | ||
| 1202 | } | ||
| 1173 | _reset_gpio(bank, bank->chip.base + offset); | 1203 | _reset_gpio(bank, bank->chip.base + offset); |
| 1174 | spin_unlock_irqrestore(&bank->lock, flags); | 1204 | spin_unlock_irqrestore(&bank->lock, flags); |
| 1175 | } | 1205 | } |
| @@ -1749,6 +1779,8 @@ static int __init _omap_gpio_init(void) | |||
| 1749 | gpio_count = 32; | 1779 | gpio_count = 32; |
| 1750 | } | 1780 | } |
| 1751 | #endif | 1781 | #endif |
| 1782 | |||
| 1783 | bank->mod_usage = 0; | ||
| 1752 | /* REVISIT eventually switch from OMAP-specific gpio structs | 1784 | /* REVISIT eventually switch from OMAP-specific gpio structs |
| 1753 | * over to the generic ones | 1785 | * over to the generic ones |
| 1754 | */ | 1786 | */ |
