Context is now saved dynamically in respective functions whenever and whichever registers are modified. This avoid overhead of saving all registers context in the runtime suspend callback. Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@xxxxxx> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@xxxxxx> --- drivers/gpio/gpio-omap.c | 62 ++++++++++++++++++++++++++------------------- 1 files changed, 36 insertions(+), 26 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 4339815..7fc57a4 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -99,6 +99,7 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) else l &= ~(1 << gpio); __raw_writel(l, reg); + bank->context.oe = l; } @@ -129,6 +130,7 @@ static void _set_gpio_dataout_mask(struct gpio_bank *bank, int gpio, int enable) else l &= ~gpio_bit; __raw_writel(l, reg); + bank->context.dataout = l; } static int _get_gpio_datain(struct gpio_bank *bank, int gpio) @@ -238,9 +240,20 @@ static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio, _gpio_rmw(base, bank->regs->fallingdetect, gpio_bit, trigger & IRQ_TYPE_EDGE_FALLING); - if (likely(!(bank->non_wakeup_gpios & gpio_bit))) + bank->context.leveldetect0 = + __raw_readl(bank->base + bank->regs->leveldetect0); + bank->context.leveldetect1 = + __raw_readl(bank->base + bank->regs->leveldetect1); + bank->context.risingdetect = + __raw_readl(bank->base + bank->regs->risingdetect); + bank->context.fallingdetect = + __raw_readl(bank->base + bank->regs->fallingdetect); + if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { _gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0); + bank->context.wake_en = + __raw_readl(bank->base + bank->regs->wkup_en); + } /* This part needs to be executed always for OMAP{34xx, 44xx} */ if (cpu_is_omap34xx() || cpu_is_omap44xx() || @@ -327,6 +340,8 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) /* Enable wake-up during idle for dynamic tick */ _gpio_rmw(base, bank->regs->wkup_en, 1 << gpio, trigger); + bank->context.wake_en = + __raw_readl(bank->base + bank->regs->wkup_en); __raw_writel(l, reg); } return 0; @@ -419,6 +434,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) } __raw_writel(l, reg); + bank->context.irqenable1 = l; } static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) @@ -439,6 +455,7 @@ static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) } __raw_writel(l, reg); + bank->context.irqenable1 = l; } static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable) @@ -532,6 +549,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) /* Module is enabled, clocks are not gated */ ctrl &= ~GPIO_MOD_CTRL_BIT; __raw_writel(ctrl, reg); + bank->context.ctrl = ctrl; } bank->mod_usage |= 1 << offset; @@ -549,9 +567,12 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) spin_lock_irqsave(&bank->lock, flags); - if (bank->regs->wkup_en) + if (bank->regs->wkup_en) { /* Disable wake-up during idle for dynamic tick */ _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0); + bank->context.wake_en = + __raw_readl(bank->base + bank->regs->wkup_en); + } bank->mod_usage &= ~(1 << offset); @@ -563,6 +584,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) /* Module is disabled, clocks are gated */ ctrl |= GPIO_MOD_CTRL_BIT; __raw_writel(ctrl, reg); + bank->context.ctrl = ctrl; } _reset_gpio(bank, bank->chip.base + offset); @@ -924,6 +946,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) bank->regs->irqenable_inv == false); _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0); _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0); + bank->context.irqenable1 = + __raw_readl(bank->base + bank->regs->irqenable); } static __init void @@ -1114,6 +1138,7 @@ static int omap_gpio_suspend(struct device *dev) spin_lock_irqsave(&bank->lock, flags); bank->saved_wakeup = __raw_readl(wakeup_enable); _gpio_rmw(base, bank->regs->wkup_en, bank->suspend_wakeup, 1); + bank->context.wake_en = __raw_readl(bank->base + bank->regs->wkup_en); spin_unlock_irqrestore(&bank->lock, flags); _gpio_dbck_disable(bank); @@ -1138,13 +1163,13 @@ static int omap_gpio_resume(struct device *dev) spin_lock_irqsave(&bank->lock, flags); _gpio_rmw(base, bank->regs->wkup_en, bank->saved_wakeup, 1); + bank->context.wake_en = __raw_readl(bank->base + bank->regs->wkup_en); spin_unlock_irqrestore(&bank->lock, flags); return 0; } -static void omap_gpio_save_context(struct gpio_bank *bank); static void omap_gpio_restore_context(struct gpio_bank *bank); static int omap_gpio_runtime_suspend(struct device *dev) @@ -1164,7 +1189,7 @@ static int omap_gpio_runtime_suspend(struct device *dev) * generated. See OMAP2420 Errata item 1.101. */ if (!(bank->enabled_non_wakeup_gpios)) - goto save_gpio_context; + goto update_gpio_context_count; bank->saved_datain = __raw_readl(bank->base + bank->regs->datain); @@ -1178,13 +1203,14 @@ static int omap_gpio_runtime_suspend(struct device *dev) __raw_writel(l1, bank->base + bank->regs->fallingdetect); __raw_writel(l2, bank->base + bank->regs->risingdetect); + bank->context.fallingdetect = l1; + bank->context.risingdetect = l2; -save_gpio_context: +update_gpio_context_count: if (bank->get_context_loss_count) bank->context_loss_count = bank->get_context_loss_count(bank->dev); - omap_gpio_save_context(bank); spin_unlock_irqrestore(&bank->lock, flags); return 0; @@ -1223,6 +1249,8 @@ static int omap_gpio_runtime_resume(struct device *dev) bank->base + bank->regs->fallingdetect); __raw_writel(bank->saved_risingdetect, bank->base + bank->regs->risingdetect); + bank->context.fallingdetect = bank->saved_fallingdetect; + bank->context.risingdetect = bank->saved_risingdetect; l = __raw_readl(bank->base + bank->regs->datain); /* @@ -1267,6 +1295,8 @@ static int omap_gpio_runtime_resume(struct device *dev) } __raw_writel(old0, bank->base + bank->regs->leveldetect0); __raw_writel(old1, bank->base + bank->regs->leveldetect1); + bank->context.leveldetect0 = old0; + bank->context.leveldetect1 = old1; } save_gpio_context: @@ -1303,26 +1333,6 @@ void omap2_gpio_resume_after_idle(void) } } -static void omap_gpio_save_context(struct gpio_bank *bank) -{ - bank->context.irqenable1 = - __raw_readl(bank->base + bank->regs->irqenable); - bank->context.irqenable2 = - __raw_readl(bank->base + bank->regs->irqenable2); - bank->context.wake_en = - __raw_readl(bank->base + bank->regs->wkup_en); - bank->context.ctrl = __raw_readl(bank->base + bank->regs->ctrl); - bank->context.oe = __raw_readl(bank->base + bank->regs->direction); - bank->context.leveldetect0 = - __raw_readl(bank->base + bank->regs->leveldetect0); - bank->context.leveldetect1 = - __raw_readl(bank->base + bank->regs->leveldetect1); - bank->context.risingdetect = - __raw_readl(bank->base + bank->regs->risingdetect); - bank->context.fallingdetect = - bank->context.dataout = __raw_readl(bank->base + bank->regs->dataout); -} - static void omap_gpio_restore_context(struct gpio_bank *bank) { __raw_writel(bank->context.irqenable1, -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html