aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
authorCharulatha V <charu@ti.com>2009-11-22 13:11:25 -0500
committerTony Lindgren <tony@atomide.com>2009-11-22 13:24:33 -0500
commit058af1ea98675a672ad2aefca035d2e5a228d2cc (patch)
tree623536859832cea0b8e10cf854ebf2cf73d9ec08 /arch/arm/plat-omap
parentedeae658b282f2d076efb3b3f39ccd8eb0c384fa (diff)
omap: GPIO module enable/disable
This patch disables a GPIO module when all pins of a GPIO module are inactive (clock gating forced at module level) and enables the module when any gpio in the module is requested. The module is enabled only when "mod_usage" indicates that no GPIO in that module is currently active and the GPIO being requested is the 1st one to be active in that module. Each module would be disabled in omap_gpio_free() API when all GPIOs in a particular module becomes inactive. The module is re-enabled in omap_gpio_request() API when a GPIO is requested from the module that was previously disabled. Since individual GPIO's bookkeeping is added in this patch via "mod_usage", the same is used in omap_set_gpio_debounce() & omap_set_gpio_debounce_time() APIs to ensure that the gpio being used is actually "requested" prior to being used (Nishant Menon's <nm@ti.comSuggestion) GPIO module level details are specific to hardware and hence introducing this patch in low level layer (plat-omap/gpio.c) Signed-off-by: Charulatha V <charu@ti.com> Acked-by: Nishanth Menon <nm@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/gpio.c32
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 */