X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fgpio%2Fgpio-omap.c;h=4390dd7d8a763277afe6b9c8efe3c86c5246d80b;hb=d63ff34838f434f99056ab6be25a5b55920283f0;hp=0b0562979171065bb3c454112c985cb74a633728;hpb=5885b9b3f030f9b430f6b1c7fa396c885033f2f8;p=pandora-kernel.git diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 0b0562979171..4390dd7d8a76 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -44,6 +44,7 @@ struct gpio_bank { u32 saved_datain; u32 saved_fallingdetect; u32 saved_risingdetect; + u32 saved_irqstatus; u32 level_mask; u32 toggle_mask; spinlock_t lock; @@ -508,7 +509,10 @@ static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable) { - _enable_gpio_irqbank(bank, GPIO_BIT(bank, gpio)); + if (enable) + _enable_gpio_irqbank(bank, GPIO_BIT(bank, gpio)); + else + _disable_gpio_irqbank(bank, GPIO_BIT(bank, gpio)); } /* @@ -1347,9 +1351,23 @@ void omap2_gpio_prepare_for_idle(int off_mode) for (i = min; i < gpio_bank_count; i++) { struct gpio_bank *bank = &gpio_bank[i]; + void __iomem *reg; u32 l1 = 0, l2 = 0; int j; + /* + * Disable debounce since clock disable below will cause + * problems if GPIO module doesn't go idle for some reason. + */ + if (bank->dbck_enable_mask != 0) { + reg = bank->base + bank->regs->datain; + bank->saved_datain = __raw_readl(reg); + reg = bank->base + bank->regs->irqstatus; + bank->saved_irqstatus = __raw_readl(reg); + reg = bank->base + bank->regs->debounce_en; + __raw_writel(0, reg); + } + for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++) clk_disable(bank->dbck); @@ -1415,12 +1433,28 @@ void omap2_gpio_resume_after_idle(void) min = 1; for (i = min; i < gpio_bank_count; i++) { struct gpio_bank *bank = &gpio_bank[i]; + void __iomem *reg; u32 l = 0, gen, gen0, gen1; int j; for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++) clk_enable(bank->dbck); + if (bank->dbck_enable_mask != 0) { + reg = bank->base + bank->regs->debounce_en; + __raw_writel(bank->dbck_enable_mask, reg); + /* clear irqs that could come from glitches + * because debounce was disabled */ + reg = bank->base + bank->regs->irqstatus; + gen = __raw_readl(reg) & ~bank->saved_irqstatus; + reg = bank->base + bank->regs->datain; + l = __raw_readl(reg) ^ bank->saved_datain; + l = gen & ~l; + l = l & bank->dbck_enable_mask & ~bank->level_mask; + if (l) + _clear_gpio_irqbank(bank, l); + } + if (!workaround_enabled) continue;