diff options
Diffstat (limited to 'arch')
-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 | */ |