From 6edd94db250038c8fdf176f23ca4017d2f312509 Mon Sep 17 00:00:00 2001 From: Tarun Kanti DebBarma Date: Mon, 30 Apr 2012 12:50:12 +0530 Subject: gpio/omap: fix incorrect initialization of omap_gpio_mod_init Initialization of irqenable, irqstatus registers is the common operation done in this function for all OMAP platforms, viz. OMAP1, OMAP2+. The latter _gpio_rmw()'s which supposedly got introduced wrongly to take care of OMAP2+ platforms were overwriting initially programmed OMAP1 value breaking functionality on OMAP1. Somehow incorrect assumption was made that each _gpio_rmw()'s were mutually exclusive. On close observation it is found that the first _gpio_rmw() which is supposedly done to take care of OMAP1 platform is generic enough and takes care of OMAP2+ platform as well. Therefore remove the latter _gpio_rmw() to irqenable as they are redundant now. Writing to ctrl and debounce_en registers for OMAP2+ platforms are modified to match the original(pre-cleanup) code where the registers are initialized with 0. In the cleanup series since we are using _gpio_rmw(reg, 0, 1), instead of __raw_writel(), we are just reading and writing the same values to ctrl and debounce_en. This is not an issue for debounce_en register because it has 0x0 as the default value. But in the case of ctrl register the default value is 0x2 (GATINGRATIO = 0x1) so that we end up writing 0x2 instead of intended 0 value. Therefore changing back to __raw_writel() as this is sufficient for this case besides simpler to understand. Also, change irqstatus initalization logic that avoids comparison with bool, besides making it fit in a single line. Cc: stable@vger.kernel.org Cc: Tony Lindgren Cc: Kevin Hilman Cc: Santosh Shilimkar Cc: Grant Likely Reported-by: Janusz Krzysztofik Tested-by: Janusz Krzysztofik Signed-off-by: Tarun Kanti DebBarma Signed-off-by: Kevin Hilman --- drivers/gpio/gpio-omap.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 1adc2ec1e383..4461540653a8 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -965,18 +965,15 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) } _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv); - _gpio_rmw(base, bank->regs->irqstatus, l, - 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); + _gpio_rmw(base, bank->regs->irqstatus, l, !bank->regs->irqenable_inv); if (bank->regs->debounce_en) - _gpio_rmw(base, bank->regs->debounce_en, 0, 1); + __raw_writel(0, base + bank->regs->debounce_en); /* Save OE default value (0xffffffff) in the context */ bank->context.oe = __raw_readl(bank->base + bank->regs->direction); /* Initialize interface clk ungated, module enabled */ if (bank->regs->ctrl) - _gpio_rmw(base, bank->regs->ctrl, 0, 1); + __raw_writel(0, base + bank->regs->ctrl); } static __devinit void -- cgit v1.2.3 From c6f31c9ec264233cb6a28053a1739425b18fd581 Mon Sep 17 00:00:00 2001 From: Tarun Kanti DebBarma Date: Fri, 27 Apr 2012 19:43:32 +0530 Subject: gpio/omap: remove saved_fallingdetect, saved_risingdetect Since we already have context.fallingdetect and context.risingdetect there is no more need to have these additional fields. Also, getting rid of extra reads associated with them. Cc: Kevin Hilman Cc: Tony Lindgren Cc: Santosh Shilimkar Cc: Cousson, Benoit Cc: Grant Likely Signed-off-by: Tarun Kanti DebBarma Reviewed-by: Santosh Shilimkar Acked-by: Felipe Balbi Tested-by: Govindraj.R Signed-off-by: Kevin Hilman --- drivers/gpio/gpio-omap.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 4461540653a8..7d47c6e76d74 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -63,8 +63,6 @@ struct gpio_bank { u32 enabled_non_wakeup_gpios; struct gpio_regs context; u32 saved_datain; - u32 saved_fallingdetect; - u32 saved_risingdetect; u32 level_mask; u32 toggle_mask; spinlock_t lock; @@ -1244,11 +1242,9 @@ static int omap_gpio_runtime_suspend(struct device *dev) */ bank->saved_datain = __raw_readl(bank->base + bank->regs->datain); - l1 = __raw_readl(bank->base + bank->regs->fallingdetect); - l2 = __raw_readl(bank->base + bank->regs->risingdetect); + l1 = bank->context.fallingdetect; + l2 = bank->context.risingdetect; - bank->saved_fallingdetect = l1; - bank->saved_risingdetect = l2; l1 &= ~bank->enabled_non_wakeup_gpios; l2 &= ~bank->enabled_non_wakeup_gpios; @@ -1307,9 +1303,9 @@ static int omap_gpio_runtime_resume(struct device *dev) } } - __raw_writel(bank->saved_fallingdetect, + __raw_writel(bank->context.fallingdetect, bank->base + bank->regs->fallingdetect); - __raw_writel(bank->saved_risingdetect, + __raw_writel(bank->context.risingdetect, bank->base + bank->regs->risingdetect); l = __raw_readl(bank->base + bank->regs->datain); @@ -1326,14 +1322,15 @@ static int omap_gpio_runtime_resume(struct device *dev) * No need to generate IRQs for the rising edge for gpio IRQs * configured with falling edge only; and vice versa. */ - gen0 = l & bank->saved_fallingdetect; + gen0 = l & bank->context.fallingdetect; gen0 &= bank->saved_datain; - gen1 = l & bank->saved_risingdetect; + gen1 = l & bank->context.risingdetect; gen1 &= ~(bank->saved_datain); /* FIXME: Consider GPIO IRQs with level detections properly! */ - gen = l & (~(bank->saved_fallingdetect) & ~(bank->saved_risingdetect)); + gen = l & (~(bank->context.fallingdetect) & + ~(bank->context.risingdetect)); /* Consider all GPIO IRQs needed to be updated */ gen |= gen0 | gen1; -- cgit v1.2.3 From 0aa2727399c0b78225021413022c164cb99fbc5e Mon Sep 17 00:00:00 2001 From: Tarun Kanti DebBarma Date: Fri, 27 Apr 2012 19:43:33 +0530 Subject: gpio/omap: remove suspend_wakeup field from struct gpio_bank Since we already have bank->context.wake_en to keep track of gpios which are wakeup enabled, there is no need to have this field any more. Cc: Kevin Hilman Cc: Tony Lindgren Cc: Santosh Shilimkar Cc: Cousson, Benoit Cc: Grant Likely Signed-off-by: Tarun Kanti DebBarma Reviewed-by: Santosh Shilimkar Acked-by: Felipe Balbi Tested-by: Govindraj.R Signed-off-by: Kevin Hilman --- drivers/gpio/gpio-omap.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 7d47c6e76d74..c45bc16f0003 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -57,7 +57,6 @@ struct gpio_bank { u16 irq; int irq_base; struct irq_domain *domain; - u32 suspend_wakeup; u32 saved_wakeup; u32 non_wakeup_gpios; u32 enabled_non_wakeup_gpios; @@ -514,11 +513,11 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) spin_lock_irqsave(&bank->lock, flags); if (enable) - bank->suspend_wakeup |= gpio_bit; + bank->context.wake_en |= gpio_bit; else - bank->suspend_wakeup &= ~gpio_bit; + bank->context.wake_en &= ~gpio_bit; - __raw_writel(bank->suspend_wakeup, bank->base + bank->regs->wkup_en); + __raw_writel(bank->context.wake_en, bank->base + bank->regs->wkup_en); spin_unlock_irqrestore(&bank->lock, flags); return 0; @@ -788,7 +787,7 @@ static int omap_mpuio_suspend_noirq(struct device *dev) spin_lock_irqsave(&bank->lock, flags); bank->saved_wakeup = __raw_readl(mask_reg); - __raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg); + __raw_writel(0xffff & ~bank->context.wake_en, mask_reg); spin_unlock_irqrestore(&bank->lock, flags); return 0; @@ -1162,7 +1161,7 @@ static int omap_gpio_suspend(struct device *dev) if (!bank->mod_usage || !bank->loses_context) return 0; - if (!bank->regs->wkup_en || !bank->suspend_wakeup) + if (!bank->regs->wkup_en || !bank->context.wake_en) return 0; wakeup_enable = bank->base + bank->regs->wkup_en; @@ -1170,7 +1169,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, 0xffffffff, 0); - _gpio_rmw(base, bank->regs->wkup_en, bank->suspend_wakeup, 1); + _gpio_rmw(base, bank->regs->wkup_en, bank->context.wake_en, 1); spin_unlock_irqrestore(&bank->lock, flags); return 0; -- cgit v1.2.3 From 499fa2871d95049c12362c27075672e8af988eb6 Mon Sep 17 00:00:00 2001 From: Tarun Kanti DebBarma Date: Fri, 27 Apr 2012 19:43:34 +0530 Subject: gpio/omap: remove saved_wakeup field from struct gpio_bank There is no more need to have saved_wakeup because bank->context.wake_en already holds that value. So getting rid of read/write operation associated with this field. Cc: Kevin Hilman Cc: Tony Lindgren Cc: Santosh Shilimkar Cc: Cousson, Benoit Cc: Grant Likely Signed-off-by: Tarun Kanti DebBarma Reviewed-by: Santosh Shilimkar Acked-by: Felipe Balbi Tested-by: Govindraj.R Signed-off-by: Kevin Hilman --- drivers/gpio/gpio-omap.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index c45bc16f0003..8b6f1b9510eb 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -57,7 +57,6 @@ struct gpio_bank { u16 irq; int irq_base; struct irq_domain *domain; - u32 saved_wakeup; u32 non_wakeup_gpios; u32 enabled_non_wakeup_gpios; struct gpio_regs context; @@ -786,7 +785,6 @@ static int omap_mpuio_suspend_noirq(struct device *dev) unsigned long flags; spin_lock_irqsave(&bank->lock, flags); - bank->saved_wakeup = __raw_readl(mask_reg); __raw_writel(0xffff & ~bank->context.wake_en, mask_reg); spin_unlock_irqrestore(&bank->lock, flags); @@ -802,7 +800,7 @@ static int omap_mpuio_resume_noirq(struct device *dev) unsigned long flags; spin_lock_irqsave(&bank->lock, flags); - __raw_writel(bank->saved_wakeup, mask_reg); + __raw_writel(bank->context.wake_en, mask_reg); spin_unlock_irqrestore(&bank->lock, flags); return 0; @@ -1155,7 +1153,6 @@ static int omap_gpio_suspend(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct gpio_bank *bank = platform_get_drvdata(pdev); void __iomem *base = bank->base; - void __iomem *wakeup_enable; unsigned long flags; if (!bank->mod_usage || !bank->loses_context) @@ -1164,10 +1161,7 @@ static int omap_gpio_suspend(struct device *dev) if (!bank->regs->wkup_en || !bank->context.wake_en) return 0; - wakeup_enable = bank->base + bank->regs->wkup_en; - spin_lock_irqsave(&bank->lock, flags); - bank->saved_wakeup = __raw_readl(wakeup_enable); _gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0); _gpio_rmw(base, bank->regs->wkup_en, bank->context.wake_en, 1); spin_unlock_irqrestore(&bank->lock, flags); @@ -1185,12 +1179,12 @@ static int omap_gpio_resume(struct device *dev) if (!bank->mod_usage || !bank->loses_context) return 0; - if (!bank->regs->wkup_en || !bank->saved_wakeup) + if (!bank->regs->wkup_en || !bank->context.wake_en) return 0; spin_lock_irqsave(&bank->lock, flags); _gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0); - _gpio_rmw(base, bank->regs->wkup_en, bank->saved_wakeup, 1); + _gpio_rmw(base, bank->regs->wkup_en, bank->context.wake_en, 1); spin_unlock_irqrestore(&bank->lock, flags); return 0; -- cgit v1.2.3 From b1a8e3d2d198319e40318563ff80f95605da5a0e Mon Sep 17 00:00:00 2001 From: Tarun Kanti DebBarma Date: Fri, 27 Apr 2012 19:43:35 +0530 Subject: gpio/omap: remove retrigger variable in gpio_irq_handler commit 672e302e3c (ARM: OMAP: use edge/level handlers from generic IRQ framework) removed retrigger support in favor of using generic IRQ framework. This patch cleans up some unused remnants of that removal. Cc: Kevin Hilman Cc: Tony Lindgren Cc: Santosh Shilimkar Cc: Cousson, Benoit Cc: Grant Likely Signed-off-by: Tarun Kanti DebBarma Reviewed-by: Santosh Shilimkar Acked-by: Felipe Balbi Tested-by: Govindraj.R Signed-off-by: Kevin Hilman --- drivers/gpio/gpio-omap.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 8b6f1b9510eb..96d2aef409b9 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -636,7 +636,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) u32 isr; unsigned int gpio_irq, gpio_index; struct gpio_bank *bank; - u32 retrigger = 0; int unmasked = 0; struct irq_chip *chip = irq_desc_get_chip(desc); @@ -673,8 +672,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) chained_irq_exit(chip, desc); } - isr |= retrigger; - retrigger = 0; if (!isr) break; -- cgit v1.2.3 From 9c4ed9e6c01e7a8bd9079da8267e1f03cb4761fc Mon Sep 17 00:00:00 2001 From: Tarun Kanti DebBarma Date: Fri, 27 Apr 2012 19:43:36 +0530 Subject: gpio/omap: remove suspend/resume callbacks Both omap_gpio_suspend() and omap_gpio_resume() does programming of wakeup_en register. _gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0); _gpio_rmw(base, bank->regs->wkup_en, bank->context.wake_en, 1); This is redundant in omap_gpio_suspend() because wakeup_en register automatically gets initialized in _set_gpio_wakeup() and set_gpio_trigger() while being called either from chip.irq_set_wake() or chip.irq_set_type(). This is also redundant in omap_gpio_resume() because wakeup_en register is programmed in omap_gpio_restore_context() called which is called from runtime resume callback. Cc: Kevin Hilman Cc: Tony Lindgren Cc: Santosh Shilimkar Cc: Cousson, Benoit Cc: Grant Likely Signed-off-by: Tarun Kanti DebBarma Reviewed-by: Santosh Shilimkar Tested-by: Govindraj.R Signed-off-by: Kevin Hilman --- drivers/gpio/gpio-omap.c | 47 ----------------------------------------------- 1 file changed, 47 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 96d2aef409b9..c89c38869c0c 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1144,50 +1144,6 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) #ifdef CONFIG_ARCH_OMAP2PLUS -#if defined(CONFIG_PM_SLEEP) -static int omap_gpio_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct gpio_bank *bank = platform_get_drvdata(pdev); - void __iomem *base = bank->base; - unsigned long flags; - - if (!bank->mod_usage || !bank->loses_context) - return 0; - - if (!bank->regs->wkup_en || !bank->context.wake_en) - return 0; - - spin_lock_irqsave(&bank->lock, flags); - _gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0); - _gpio_rmw(base, bank->regs->wkup_en, bank->context.wake_en, 1); - spin_unlock_irqrestore(&bank->lock, flags); - - return 0; -} - -static int omap_gpio_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct gpio_bank *bank = platform_get_drvdata(pdev); - void __iomem *base = bank->base; - unsigned long flags; - - if (!bank->mod_usage || !bank->loses_context) - return 0; - - if (!bank->regs->wkup_en || !bank->context.wake_en) - return 0; - - spin_lock_irqsave(&bank->lock, flags); - _gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0); - _gpio_rmw(base, bank->regs->wkup_en, bank->context.wake_en, 1); - spin_unlock_irqrestore(&bank->lock, flags); - - return 0; -} -#endif /* CONFIG_PM_SLEEP */ - #if defined(CONFIG_PM_RUNTIME) static void omap_gpio_restore_context(struct gpio_bank *bank); @@ -1416,14 +1372,11 @@ static void omap_gpio_restore_context(struct gpio_bank *bank) } #endif /* CONFIG_PM_RUNTIME */ #else -#define omap_gpio_suspend NULL -#define omap_gpio_resume NULL #define omap_gpio_runtime_suspend NULL #define omap_gpio_runtime_resume NULL #endif static const struct dev_pm_ops gpio_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(omap_gpio_suspend, omap_gpio_resume) SET_RUNTIME_PM_OPS(omap_gpio_runtime_suspend, omap_gpio_runtime_resume, NULL) }; -- cgit v1.2.3 From 4e962e8998cc6cb5e58beae5feb6a65cb1a27f26 Mon Sep 17 00:00:00 2001 From: Tarun Kanti DebBarma Date: Fri, 27 Apr 2012 19:43:37 +0530 Subject: gpio/omap: remove cpu_is_omapxxxx() checks from *_runtime_resume() Add register offsets for GPIO_IRQSTATUS_RAW_0, GPIO_IRQSTATUS_RAW_0 which are present on OMAP4+ processors. Now we can distinguish conditions applicable to OMAP4,5 and those specific to OMAP24xx and OMAP3xxx. Cc: Kevin Hilman Cc: Tony Lindgren Cc: Santosh Shilimkar Cc: Cousson, Benoit Cc: Grant Likely Signed-off-by: Tarun Kanti DebBarma Reviewed-by: Santosh Shilimkar Tested-by: Govindraj.R Signed-off-by: Kevin Hilman --- drivers/gpio/gpio-omap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index c89c38869c0c..2c70617e6b45 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1286,14 +1286,14 @@ static int omap_gpio_runtime_resume(struct device *dev) old0 = __raw_readl(bank->base + bank->regs->leveldetect0); old1 = __raw_readl(bank->base + bank->regs->leveldetect1); - if (cpu_is_omap24xx() || cpu_is_omap34xx()) { + if (!bank->regs->irqstatus_raw0) { __raw_writel(old0 | gen, bank->base + bank->regs->leveldetect0); __raw_writel(old1 | gen, bank->base + bank->regs->leveldetect1); } - if (cpu_is_omap44xx()) { + if (bank->regs->irqstatus_raw0) { __raw_writel(old0 | l, bank->base + bank->regs->leveldetect0); __raw_writel(old1 | l, bank->base + -- cgit v1.2.3 From 1b1287032df3a69d3ef9a486b444f4ffcca50d01 Mon Sep 17 00:00:00 2001 From: Tarun Kanti DebBarma Date: Fri, 27 Apr 2012 19:43:38 +0530 Subject: gpio/omap: fix missing check in *_runtime_suspend() We do checking for bank->enabled_non_wakeup_gpios in order to skip redundant operations. Somehow, the check got missed while doing the cleanup series. Just to make sure that we do context restore correctly in *_runtime_resume(), the bank->workaround_enabled check is moved after context restore. Otherwise, it would prevent context restore when bank->enabled_non_wakeup_gpios is 0. Cc: Kevin Hilman Cc: Tony Lindgren Cc: Santosh Shilimkar Cc: Cousson, Benoit Cc: Grant Likely Signed-off-by: Tarun Kanti DebBarma Reviewed-by: Santosh Shilimkar Tested-by: Govindraj.R Signed-off-by: Kevin Hilman --- drivers/gpio/gpio-omap.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 2c70617e6b45..9b71f04538aa 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1157,6 +1157,9 @@ static int omap_gpio_runtime_suspend(struct device *dev) spin_lock_irqsave(&bank->lock, flags); + if (!bank->enabled_non_wakeup_gpios) + goto update_gpio_context_count; + /* * Only edges can generate a wakeup event to the PRCM. * @@ -1232,11 +1235,6 @@ static int omap_gpio_runtime_resume(struct device *dev) __raw_writel(bank->context.risingdetect, bank->base + bank->regs->risingdetect); - if (!bank->workaround_enabled) { - spin_unlock_irqrestore(&bank->lock, flags); - return 0; - } - if (bank->get_context_loss_count) { context_lost_cnt_after = bank->get_context_loss_count(bank->dev); @@ -1249,6 +1247,11 @@ static int omap_gpio_runtime_resume(struct device *dev) } } + if (!bank->workaround_enabled) { + spin_unlock_irqrestore(&bank->lock, flags); + return 0; + } + __raw_writel(bank->context.fallingdetect, bank->base + bank->regs->fallingdetect); __raw_writel(bank->context.risingdetect, -- cgit v1.2.3