gpio/omap: driver cleanup and fixes
Subsystems (8)
v7 cover gpio/omap: driver cleanup and fixes
This series is continuation of cleanup of OMAP GPIO driver and fixes. The cleanup include getting rid of cpu_is_* checks wherever possible, use of gpio_bank list instead of static array, use of unique platform specific value associated data member to OMAP platforms to avoid cpu_is_* checks. The series also include PM runtime support.*
Baseline: git://gitorious.org/khilman/linux-omap-pm.git
Branch: for_3.2/gpio-cleanup
Commit: 8323374
Test Details:
- Compile tested for omap1_defconfig and omap2plus_defconfig.
- OMAP1710-H3: Bootup test.
- OMAP2430/SDP, OMAP3430/SDP, OMAP4430/SDP: Functional testing.
- PM Testing on OMAP3430-SDP: retention, off_mode, system_wide suspend and gpio wakeup.
v7:
- Use pm_runtime_put() instead of pm_runtime_put_sync_suspend()
- Keep *_runtime_get/put*() outside spinlock
- Remove additional checking of conditions in _restore_context() From:
if (bank->regs->set_dataout && bank->regs->clear_dataout)
...
To:
if (bank->regs->set_dataout)
...
- Use SET_RUNTIME_PM_OPS and SET_SYSTEM_SLEEP_PM_OPS macros
- In [PATCH 19/25] gpio/omap: cleanup prepare_for_idle and resume_after_idle, protect the bank data elements and register access using spinlock in runtime_suspend/resume() callbacks.
This is because these callbacks run with interrupts enabled.
- Add dbclk aliases for all GPIO modules. Without this, GPIO modules were not getting the correct clock handle to enable/disable debounec clock.
- Fix log comments on the following patches:
[PATCH 19/25] gpio/omap: cleanup prepare_for_idle and resume_after_idle [PATCH 20/25] gpio/omap: skip operations in runtime callbacks [PATCH 24/25] gpio/omap: restore OE only after setting the output level
v6:
- Save and restore debounce registers for proper driver operation.
- Restore interrupt enable after all configuration to avoid spurious interrupts.
- Restore dataout register before oe register.
- Restore dataout into dataout_set or dataout based upon the OMAP version.
- Change register name from wkup_status to wkup_en.
- Remove wrapper around omap_pm_get_dev_context_loss_count(). Use it directly. Also, changed the signature of get_context_loss_count in pdata and bank structure from int to u32.
- Use 'context' instead of 'ctx' for clarity wherever it is used.
- Merged two patches into one which are related to bank_is_mpuio() modification.
- Use shift operator instead of following:
+ .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE / 2,
- Remove redundant check from the following
+ if (bank_is_mpuio(bank)) {
+ if (bank->regs->wkup_status) <--- redundant check
+ mpuio_init(bank);
- Change subject of following patch
[PATCH v5 15/22] gpio/omap: use readl in irq_handler for all access into
[PATCH 14/25] gpio/omap: remove unnecessary bit-masking for read access
- Fix multi-line comments in
[PATCH v5 20/22] gpio/omap: cleanup prepare_for_idle and resume_after_idle
v5:
- Reduce runtime callback overhead when *_get/put_sync() called from probe() and *_gpio_request/free().
- Dynamic context save within functions where context is modified instead of saving all context within a common function.
- Removed call to mpuio_init() from omap_gpio_mod_init(). Both the functions are called once during initialization in *_gpio_probe().
Call to omap_gpio_mod_init() has been removed from omap_gpio_request() on the first access to gpio bank. One time initialization looks sufficient.
- In *_gpio_irq_handler() use *_put_sync_suspend() instead of *_put_sync().
- Removed hardcoding of OMAP16xx sysconfig register value and instead defined an associated constant.
- Removed *_get_sync() call from *_gpio_suspend() and *_put_sync() call from *_gpio_resume(). They got wrongly slipped into the code.
- Removed following redundant zero allocated initialization from mach-omap2/gpio.c
+ pdata->regs->irqctrl = 0; + pdata->regs->edgectrl1 = 0; + pdata->regs->edgectrl2 = 0;
- Removed following redundant code in gpio-omap.c -#define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO)
v4:
- since all accesses to registers are 4-byte aligned, removing special checks and handling of 16 and 32-bit wide bank registers and instead use 32-bit read/write access consistently.
- redundant usage of MOD_REG_BIT has been corrected and replaced with _gpio_rmw().
- omap_gpio_mod_init() function has been simplified further using _gpio_rmw().
- sysconfig register offset specific to omap16xx has been removed along with its usage.
- additional logic to skip from suspend/resume:
if (!bank->regs->wkup_status || !bank->suspend_wakeup)
return 0;
if (!bank->regs->wkup_status || !bank->saved_wakeup)
return 0;- separated mpuio related changes into a different patch from the patch where wakeup status register related changes are done.
- Incorrect replacement of !cpu_class_is_omap2() in gpio_irq_type() corrected:
+ if (!bank->regs->leveldetect0 &&
+ (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
return -EINVAL;
v3:
- Avoid use of wkup_set and wkup_clear registers. Instead use wkup_status register for all platforms. This is because on OMAP4 it is recommended not to use them.
- Remove duplicate code in omap_gpio_mod_init() for handling the same for 32-bit and 16-bit GPIO bank widths. This is accomplished by having two functions to handle each case while assiging a common function pointer during initialization.
- Remove OMAP16xx specific one time initialization from omap_gpio_mod_init(). Move it inside omap16xx_gpio_init().
- Avoid usage of USHRT_MAX to indicate undefined values. Use 0 instead.
- In omap_gpio_suspend()/resume() functions remove code that checks if the feature is supported. Instead, assign these functions to struct platform_driver's suspend & resume function pointers for those OMAP platforms whcih support this feature.
- Remove 'suspend_support' flag because it is redundant. Instead use wkup_* registers to decode the same information.
- Restore context also when we don't know if the context is lost.
- Make omap_gpio_save_context() and omap_gpio_restore_context() static.
v2:
- Do special handling of non-wakeup GPIOs only on OMAP2420. Avoid this handling on OMAP3430.
- Isolate cleanups and fixes into separate set of patches. Keep the cleanup first followed by the fixes.
- Avoid calling omap_gpio_get_context_loss() directly and instead call it through function pointer in pdata initialized during init.
- workaround_enabled flag is not longer needed and is removed.
- Call pwrdm_post_transition() before calling omap_gpio_resume_after_idle().
- In omap2_gpio_resume_after_idle() do context restore before handling workaround.
- Use PM runtime framework.
- Modify register offset names to : wkup_status, wkup_clear, wkup_set. Also use 'base + offset' for readibility in all relevant places.
- Remove unwanted messages from commit section like TODO, etc.
Charulatha V (10):
gpio/omap: remove dependency on gpio_bank_count gpio/omap: use flag to identify wakeup domain gpio/omap: make gpio_context part of gpio_bank structure gpio/omap: fix pwrdm_post_transition call sequence gpio/omap: handle save/restore context in GPIO driver gpio/omap: make non-wakeup GPIO part of pdata gpio/omap: avoid cpu checks during module ena/disable gpio/omap: use pinctrl offset instead of macro gpio/omap: remove bank->method & METHOD_* macros gpio/omap: fix bankwidth for OMAP7xx MPUIO
Nishanth Menon (4):
gpio/omap: save and restore debounce registers gpio/omap: enable irq at the end of all configuration in restore gpio/omap: restore OE only after setting the output level gpio/omap: handle set_dataout reg capable IP on restore
Tarun Kanti DebBarma (12):
gpio/omap: further cleanup using wkup_en register gpio/omap: use level/edge detect reg offsets gpio/omap: remove hardcoded offsets in context save/restore gpio/omap: cleanup set_gpio_triggering function gpio/omap: cleanup omap_gpio_mod_init function gpio/omap: remove unnecessary bit-masking for read access gpio/omap: use pm-runtime framework
gpio/omap: optimize suspend and resume functions gpio/omap: cleanup prepare_for_idle and resume_after_idle gpio/omap: skip operations in runtime callbacks gpio/omap: remove omap_gpio_save_context overhead gpio/omap: add dbclk aliases for all gpio modules
arch/arm/mach-omap1/gpio15xx.c | 7 +- arch/arm/mach-omap1/gpio16xx.c | 47 ++- arch/arm/mach-omap1/gpio7xx.c | 14 +- arch/arm/mach-omap2/clock3xxx_data.c | 6 + arch/arm/mach-omap2/clock44xx_data.c | 6 + arch/arm/mach-omap2/gpio.c | 36 +- arch/arm/mach-omap2/pm34xx.c | 21 +- arch/arm/plat-omap/include/plat/gpio.h | 29 +- drivers/gpio/gpio-omap.c | 1051 +++++++++++++------------------- 9 files changed, 524 insertions(+), 693 deletions(-)
PATCH v7 1/26 gpio/omap: remove dependency on gpio_bank_count
From: Charulatha V <[email protected]>
The gpio_bank_count is the count of number of GPIO devices in a SoC. Remove this dependency from the driver by using list. Also remove the dependency on array of pointers to gpio_bank struct of all GPIO devices.
--- arch/arm/mach-omap1/gpio15xx.c | 1 - arch/arm/mach-omap1/gpio16xx.c | 2 - arch/arm/mach-omap1/gpio7xx.c | 2 - arch/arm/mach-omap2/gpio.c | 1 - arch/arm/plat-omap/include/plat/gpio.h | 3 - drivers/gpio/gpio-omap.c | 163 ++++++++++++++++---------------- 6 files changed, 80 insertions(+), 92 deletions(-)
arch/arm/mach-omap1/gpio15xx.c +0 -1
@@ -115,7 +115,6 @@ static int __init omap15xx_gpio_init(void)platform_device_register (&omap15xx_mpu_gpio);platform_device_register (&omap15xx_gpio); - gpio_bank_count =2 ;return 0 ; }postcore_initcall (omap15xx_gpio_init);
arch/arm/mach-omap1/gpio16xx.c +0 -2
@@ -221,8 +221,6 @@ static int __init omap16xx_gpio_init(void)for (i =0 ; i <ARRAY_SIZE (omap16xx_gpio_dev); i++)platform_device_register (omap16xx_gpio_dev[i]); - gpio_bank_count =ARRAY_SIZE (omap16xx_gpio_dev); -return 0 ; }postcore_initcall (omap16xx_gpio_init);
arch/arm/mach-omap1/gpio7xx.c +0 -2
@@ -282,8 +282,6 @@ static int __init omap7xx_gpio_init(void)for (i =0 ; i <ARRAY_SIZE (omap7xx_gpio_dev); i++)platform_device_register (omap7xx_gpio_dev[i]); - gpio_bank_count =ARRAY_SIZE (omap7xx_gpio_dev); -return 0 ; }postcore_initcall (omap7xx_gpio_init);
arch/arm/mach-omap2/gpio.c +0 -1
@@ -121,7 +121,6 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)omap_device_disable_idle_on_suspend (od); - gpio_bank_count++;return 0 ; }
arch/arm/plat-omap/include/plat/gpio.h +0 -3
@@ -202,9 +202,6 @@ struct omap_gpio_platform_data {struct omap_gpio_reg_offs *regs; }; -/* TODO: Analyze removing gpio_bank_count usage from driver code */ -extern int gpio_bank_count; -extern void omap2_gpio_prepare_for_idle (int off_mode);extern void omap2_gpio_resume_after_idle (void );extern void omap_set_gpio_debounce (int gpio,int enable);
drivers/gpio/gpio-omap.c +80 -83
317 lines not on this page · raw message
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 1/26 gpio/omap: remove dependency on gpio_bank_count
Quoted 8 lines · Tarun Kanti DebBarma
From: Charulatha V <[email protected]>
The
gpio_bank_countis the count of number of GPIO devices in a SoC. Remove this dependency from the driver by using list. Also remove the dependency on array of pointers togpio_bankstruct of all GPIO devices.Signed-off-by Charulatha V <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
PATCH v7 2/26 gpio/omap: use flag to identify wakeup domain
In reply to Tarun Kanti DebBarmaFrom: Charulatha V <[email protected]>
In omap3, save/restore context is implemented for GPIO banks 2-6 as GPIO bank1 is in wakeup domain. Instead of identifying bank's power domain by bank id, use 'loses_context' flag which is filled by pwrdm_can_ever_lose_context() during dev_init.
For getting the powerdomain pointer, omap_hwmod_get_pwrdm() is used. omap_device_get_pwrdm() could not be used as the pwrdm information needs to be filled in pdata, whereas omap_device_get_pwrdm() could be used only after omap_device_build() call.
--- arch/arm/mach-omap2/gpio.c | 6 ++++++ arch/arm/plat-omap/include/plat/gpio.h | 1 + drivers/gpio/gpio-omap.c | 13 ++++++------- 3 files changed, 13 insertions(+), 7 deletions(-)
arch/arm/mach-omap2/gpio.c +6 -0
@@ -24,6 +24,8 @@#include <plat/omap_hwmod.h> #include <plat/omap_device.h> +#include "powerdomain.h" +static struct omap_device_pm_latency omap_gpio_latency[] = { [0 ] = { .deactivate_func = omap_device_idle_hwmods,
@@ -39,6 +41,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)struct omap_gpio_dev_attr *dev_attr;char *name ="omap_gpio" ;int id; +struct powerdomain *pwrdm;/* * extract the device id from name field available in the
@@ -107,6 +110,9 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)return -EINVAL ; } + pwrdm =omap_hwmod_get_pwrdm (oh); + pdata->loses_context =pwrdm_can_ever_lose_context (pwrdm); + od = omap_device_build(name, id - 1, oh, pdata, sizeof(*pdata), omap_gpio_latency, ARRAY_SIZE(omap_gpio_latency),
arch/arm/plat-omap/include/plat/gpio.h +1 -0
@@ -198,6 +198,7 @@ struct omap_gpio_platform_data {int bank_width;/* GPIO bank width */ int bank_stride;/* Only needed for omap1 MPUIO */ bool dbck_flag;/* dbck required or not - True for OMAP3&4 */ +bool loses_context;/* whether the bank would ever lose context */ struct omap_gpio_reg_offs *regs; };
drivers/gpio/gpio-omap.c +6 -7
@@ -56,6 +56,7 @@ struct gpio_bank {u32 dbck_enable_mask;struct device *dev;bool dbck_flag; +bool loses_context;int stride;u32 width;u16 id;
@@ -1181,7 +1182,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) bank->dbck_flag = pdata->dbck_flag; bank->stride = pdata->bank_stride; bank->width = pdata->bank_width; - + bank->loses_context = pdata->loses_context; bank->regs = pdata->regs;if (bank->regs->set_dataout && bank->regs->clr_dataout)
@@ -1337,8 +1338,7 @@ void omap2_gpio_prepare_for_idle(int off_mode)u32 l1 =0 , l2 =0 ;int j; -/* TODO: Do not use cpu_is_omap34xx */ -if ((cpu_is_omap34xx ()) && (bank->id ==0 )) +if (!bank->loses_context)continue ;for (j =0 ; j <hweight_long (bank->dbck_enable_mask); j++)
@@ -1405,8 +1405,7 @@ void omap2_gpio_resume_after_idle(void)u32 l =0 , gen, gen0, gen1;int j; -/* TODO: Do not use cpu_is_omap34xx */ -if ((cpu_is_omap34xx ()) && (bank->id ==0 )) +if (!bank->loses_context)continue ;for (j =0 ; j <hweight_long (bank->dbck_enable_mask); j++)
@@ -1505,7 +1504,7 @@ void omap_gpio_save_context(void)list_for_each_entry (bank, &omap_gpio_list, node) { i++; -if (bank->id ==0 ) +if (!bank->loses_context)continue ; gpio_context[i].irqenable1 =
@@ -1539,7 +1538,7 @@ void omap_gpio_restore_context(void)list_for_each_entry (bank, &omap_gpio_list, node) { i++; -if (bank->id ==0 ) +if (!bank->loses_context)continue ; __raw_writel(gpio_context[i].irqenable1,
Signature · 1 line
1.7.0.4
PATCH v7 3/26 gpio/omap: make gpio_context part of gpio_bank structure
In reply to Tarun Kanti DebBarmaFrom: Charulatha V <[email protected]>
Currently gpio_context array used to save gpio bank's context, is used only for OMAP3 architecture. Move gpio_context as part of gpio_bank structure so that it can be specific to each gpio bank and can be used for any OMAP architecture
--- drivers/gpio/gpio-omap.c | 76 ++++++++++++++++++++------------------------- 1 files changed, 34 insertions(+), 42 deletions(-)
drivers/gpio/gpio-omap.c +34 -42
@@ -30,6 +30,19 @@static LIST_HEAD (omap_gpio_list); +struct gpio_regs { +u32 irqenable1; +u32 irqenable2; +u32 wake_en; +u32 ctrl; +u32 oe; +u32 leveldetect0; +u32 leveldetect1; +u32 risingdetect; +u32 fallingdetect; +u32 dataout; +}; +struct gpio_bank {struct list_head node;unsigned long pbase;
@@ -43,7 +56,7 @@ struct gpio_bank {#endif u32 non_wakeup_gpios;u32 enabled_non_wakeup_gpios; - +struct gpio_regs context;u32 saved_datain;u32 saved_fallingdetect;u32 saved_risingdetect;
@@ -66,23 +79,6 @@ struct gpio_bank {struct omap_gpio_reg_offs *regs; }; -#ifdef CONFIG_ARCH_OMAP3 -struct omap3_gpio_regs { -u32 irqenable1; -u32 irqenable2; -u32 wake_en; -u32 ctrl; -u32 oe; -u32 leveldetect0; -u32 leveldetect1; -u32 risingdetect; -u32 fallingdetect; -u32 dataout; -}; - -static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS ]; -#endif -#define GPIO_INDEX (bank, gpio) (gpio % bank->width)#define GPIO_BIT (bank, gpio) (1 << GPIO_INDEX(bank, gpio))
@@ -1499,33 +1495,31 @@ void omap2_gpio_resume_after_idle(void)void omap_gpio_save_context (void ) {struct gpio_bank *bank; -int i =0 ;list_for_each_entry (bank, &omap_gpio_list, node) { - i++;if (!bank->loses_context)continue ; - gpio_context[i].irqenable1 = + bank->context.irqenable1 =__raw_readl (bank->base +OMAP24XX_GPIO_IRQENABLE1 ); - gpio_context[i].irqenable2 = + bank->context.irqenable2 =__raw_readl (bank->base +OMAP24XX_GPIO_IRQENABLE2 ); - gpio_context[i].wake_en = + bank->context.wake_en =__raw_readl (bank->base +OMAP24XX_GPIO_WAKE_EN ); - gpio_context[i].ctrl = + bank->context.ctrl =__raw_readl (bank->base +OMAP24XX_GPIO_CTRL ); - gpio_context[i].oe = + bank->context.oe =__raw_readl (bank->base +OMAP24XX_GPIO_OE ); - gpio_context[i].leveldetect0 = + bank->context.leveldetect0 =__raw_readl (bank->base +OMAP24XX_GPIO_LEVELDETECT0 ); - gpio_context[i].leveldetect1 = + bank->context.leveldetect1 =__raw_readl (bank->base +OMAP24XX_GPIO_LEVELDETECT1 ); - gpio_context[i].risingdetect = + bank->context.risingdetect =__raw_readl (bank->base +OMAP24XX_GPIO_RISINGDETECT ); - gpio_context[i].fallingdetect = + bank->context.fallingdetect =__raw_readl (bank->base +OMAP24XX_GPIO_FALLINGDETECT ); - gpio_context[i].dataout = + bank->context.dataout =__raw_readl (bank->base +OMAP24XX_GPIO_DATAOUT ); } }
@@ -1533,33 +1527,31 @@ void omap_gpio_save_context(void)void omap_gpio_restore_context (void ) {struct gpio_bank *bank; -int i =0 ;list_for_each_entry (bank, &omap_gpio_list, node) { - i++;if (!bank->loses_context)continue ; -__raw_writel (gpio_context[i].irqenable1, +__raw_writel (bank->context.irqenable1, bank->base +OMAP24XX_GPIO_IRQENABLE1 ); -__raw_writel (gpio_context[i].irqenable2, +__raw_writel (bank->context.irqenable2, bank->base +OMAP24XX_GPIO_IRQENABLE2 ); -__raw_writel (gpio_context[i].wake_en, +__raw_writel (bank->context.wake_en, bank->base +OMAP24XX_GPIO_WAKE_EN ); -__raw_writel (gpio_context[i].ctrl, +__raw_writel (bank->context.ctrl, bank->base +OMAP24XX_GPIO_CTRL ); -__raw_writel (gpio_context[i].oe, +__raw_writel (bank->context.oe, bank->base +OMAP24XX_GPIO_OE ); -__raw_writel (gpio_context[i].leveldetect0, +__raw_writel (bank->context.leveldetect0, bank->base +OMAP24XX_GPIO_LEVELDETECT0 ); -__raw_writel (gpio_context[i].leveldetect1, +__raw_writel (bank->context.leveldetect1, bank->base +OMAP24XX_GPIO_LEVELDETECT1 ); -__raw_writel (gpio_context[i].risingdetect, +__raw_writel (bank->context.risingdetect, bank->base +OMAP24XX_GPIO_RISINGDETECT ); -__raw_writel (gpio_context[i].fallingdetect, +__raw_writel (bank->context.fallingdetect, bank->base +OMAP24XX_GPIO_FALLINGDETECT ); -__raw_writel (gpio_context[i].dataout, +__raw_writel (bank->context.dataout, bank->base +OMAP24XX_GPIO_DATAOUT ); } }
Signature · 1 line
1.7.0.4
PATCH v7 4/26 gpio/omap: fix pwrdm_post_transition call sequence
In reply to Tarun Kanti DebBarmaFrom: Charulatha V <[email protected]>
The context lost count is modified in omap_sram_idle() path when pwrdm_post_transition() is called. But pwrdm_post_transition() is called only after omap_gpio_resume_after_idle() is called. Correct this so that context lost count is modified before calling omap_gpio_resume_after_idle().
This would be useful when OMAP GPIO save/restore context is called by the OMAP GPIO driver itself.
--- arch/arm/mach-omap2/pm34xx.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
arch/arm/mach-omap2/pm34xx.c +4 -3
@@ -363,7 +363,6 @@ void omap_sram_idle(void)printk (KERN_ERR "Invalid mpu state in sram_idle\n" );return ; } -pwrdm_pre_transition ();/* NEON control */ if (pwrdm_read_pwrst (neon_pwrdm) ==PWRDM_POWER_ON )
@@ -386,6 +385,8 @@ void omap_sram_idle(void)if (!console_trylock ()) goto console_still_active; +pwrdm_pre_transition (); +/* PER */ if (per_next_state <PWRDM_POWER_ON ) { per_going_off = (per_next_state ==PWRDM_POWER_OFF ) ?1 :0 ;
@@ -455,6 +456,8 @@ void omap_sram_idle(void) }omap3_intc_resume_idle (); +pwrdm_post_transition (); +/* PER */ if (per_next_state <PWRDM_POWER_ON ) { per_prev_state =pwrdm_read_prev_pwrst (per_pwrdm);
@@ -478,8 +481,6 @@ console_still_active:omap3_disable_io_chain (); } -pwrdm_post_transition (); -clkdm_allow_idle (mpu_pwrdm->pwrdm_clkdms[0 ]); }
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 4/26 gpio/omap: fix pwrdm_post_transition call sequence
Quoted 7 lines · Tarun Kanti DebBarma
From: Charulatha V <[email protected]>
The context lost count is modified in
omap_sram_idle()path whenpwrdm_post_transition()is called. Butpwrdm_post_transition()is called only afteromap_gpio_resume_after_idle()is called. Correct this so that context lost count is modified before callingomap_gpio_resume_after_idle().
Quoted 5 lines
This would be useful when OMAP GPIO save/restore context is called by the OMAP GPIO driver itself.
Signed-off-by Charulatha V <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
This should be acked by Kevin, looks OK to me:
PATCH v7 4/26 gpio/omap: fix pwrdm_post_transition call sequence
In reply to Tarun Kanti DebBarmaQuoted 7 lines · Tarun Kanti DebBarma
From: Charulatha V <[email protected]>
The context lost count is modified in
omap_sram_idle()path whenpwrdm_post_transition()is called. Butpwrdm_post_transition()is called only afteromap_gpio_resume_after_idle()is called. Correct this so that context lost count is modified before callingomap_gpio_resume_after_idle().
Quoted 5 lines
This would be useful when OMAP GPIO save/restore context is called by the OMAP GPIO driver itself.
Signed-off-by Charulatha V <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
This one isn't directly related to the GPIO cleanup, so I'll pull it out and add it to my PM cleanup queue for v3.2, adding Tony's ack.
I'll also change the subject prefix to: ARM: OMAP3: PM: ...
Kevin
Quoted 42 lines
--- arch/arm/mach-omap2/pm34xx.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)arch/arm/mach-omap2/pm34xx.c +4
-3@@ -363,7 +363,6 @@ void omap_sram_idle(void)printk (KERN_ERR "Invalid mpu state in sram_idle\n" );return ; } -pwrdm_pre_transition ();/* NEON control */ if (pwrdm_read_pwrst (neon_pwrdm) ==PWRDM_POWER_ON )@@ -386,6 +385,8 @@ void omap_sram_idle(void)if (!console_trylock ()) goto console_still_active; +pwrdm_pre_transition (); +/* PER */ if (per_next_state <PWRDM_POWER_ON ) { per_going_off = (per_next_state ==PWRDM_POWER_OFF ) ?1 :0 ;@@ -455,6 +456,8 @@ void omap_sram_idle(void) }omap3_intc_resume_idle (); +pwrdm_post_transition (); +/* PER */ if (per_next_state <PWRDM_POWER_ON ) { per_prev_state =pwrdm_read_prev_pwrst (per_pwrdm);@@ -478,8 +481,6 @@ console_still_active:omap3_disable_io_chain (); } -pwrdm_post_transition (); -clkdm_allow_idle (mpu_pwrdm->pwrdm_clkdms[0 ]); }
PATCH v7 5/26 gpio/omap: handle save/restore context in GPIO driver
In reply to Tarun Kanti DebBarmaFrom: Charulatha V <[email protected]>
Modify omap_gpio_prepare_for_idle() & omap_gpio_resume_after_idle() functions to handle save context & restore context respectively in the OMAP GPIO driver itself instead of calling these functions from pm specific files. For this, in gpio_prepare_for_idle(), call *_get_context_loss_count() and in gpio_resume_after_idle() call it again. If the count is different, do restore context. The workaround_enabled flag is no more required and is removed.
--- arch/arm/mach-omap2/gpio.c | 5 +- arch/arm/mach-omap2/pm34xx.c | 14 ---- arch/arm/plat-omap/include/plat/gpio.h | 5 +- drivers/gpio/gpio-omap.c | 131 ++++++++++++++------------------ 4 files changed, 65 insertions(+), 90 deletions(-)
arch/arm/mach-omap2/gpio.c +4 -1
@@ -23,6 +23,7 @@#include <plat/omap_hwmod.h> #include <plat/omap_device.h> +#include <plat/omap-pm.h> #include "powerdomain.h"
@@ -63,7 +64,9 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->bank_width = dev_attr->bank_width; pdata->dbck_flag = dev_attr->dbck_flag; pdata->virtual_irq_start =IH_GPIO_BASE +32 * (id -1 ); - +#ifdef CONFIG_PM + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; +#endif pdata->regs =kzalloc (sizeof (struct omap_gpio_reg_offs ),GFP_KERNEL );if (!pdata) {pr_err ("gpio%d: Memory allocation failed\n" , id);
arch/arm/mach-omap2/pm34xx.c +0 -14
@@ -85,16 +85,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm;static struct powerdomain *core_pwrdm, *per_pwrdm;static struct powerdomain *cam_pwrdm; -static inline void omap3_per_save_context (void ) -{ -omap_gpio_save_context (); -} - -static inline void omap3_per_restore_context (void ) -{ -omap_gpio_restore_context (); -} -static void omap3_enable_io_chain (void ) {int timeout =0 ;
@@ -393,8 +383,6 @@ void omap_sram_idle(void)omap_uart_prepare_idle (2 );omap_uart_prepare_idle (3 );omap2_gpio_prepare_for_idle (per_going_off); -if (per_next_state ==PWRDM_POWER_OFF ) -omap3_per_save_context (); }/* CORE */
@@ -462,8 +450,6 @@ void omap_sram_idle(void)if (per_next_state <PWRDM_POWER_ON ) { per_prev_state =pwrdm_read_prev_pwrst (per_pwrdm);omap2_gpio_resume_after_idle (); -if (per_prev_state ==PWRDM_POWER_OFF ) -omap3_per_restore_context ();omap_uart_resume_idle (2 );omap_uart_resume_idle (3 ); }
arch/arm/plat-omap/include/plat/gpio.h +3 -2
@@ -201,14 +201,15 @@ struct omap_gpio_platform_data {bool loses_context;/* whether the bank would ever lose context */ struct omap_gpio_reg_offs *regs; + +/* Return context loss count due to PM states changing */ +u32 (*get_context_loss_count)(struct device *dev); };extern void omap2_gpio_prepare_for_idle (int off_mode);extern void omap2_gpio_resume_after_idle (void );extern void omap_set_gpio_debounce (int gpio,int enable);extern void omap_set_gpio_debounce_time (int gpio,int enable); -extern void omap_gpio_save_context (void ); -extern void omap_gpio_restore_context (void );/*-------------------------------------------------------------------------*/ /* Wrappers for "new style" GPIO calls, using the new infrastructure
drivers/gpio/gpio-omap.c +58 -73
192 lines not on this page · raw message
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 5/26 gpio/omap: handle save/restore context in GPIO driver
Quoted 9 lines · Tarun Kanti DebBarma
From: Charulatha V <[email protected]>
Modify
omap_gpio_prepare_for_idle()&omap_gpio_resume_after_idle()functions to handle save context & restore context respectively in the OMAP GPIO driver itself instead of calling these functions from pm specific files. For this, ingpio_prepare_for_idle(), call*_get_context_loss_count()and ingpio_resume_after_idle()call it again. If the count is different, do restore context. Theworkaround_enabledflag is no more required and is removed.
Quoted 3 lines
Signed-off-by Charulatha V <[email protected]>Signed-off-by Tarun Kanti DebBarma <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
This to should be also acked by Kevin, looks OK to me:
PATCH v7 5/26 gpio/omap: handle save/restore context in GPIO driver
In reply to Tarun Kanti DebBarmaQuoted 12 lines · Tarun Kanti DebBarma
From: Charulatha V <[email protected]>
Modify
omap_gpio_prepare_for_idle()&omap_gpio_resume_after_idle()functions to handle save context & restore context respectively in the OMAP GPIO driver itself instead of calling these functions from pm specific files. For this, ingpio_prepare_for_idle(), call*_get_context_loss_count()and ingpio_resume_after_idle()call it again. If the count is different, do restore context. Theworkaround_enabledflag is no more required and is removed.Signed-off-by Charulatha V <[email protected]>Signed-off-by Tarun Kanti DebBarma <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
[...]
Quoted 13 lines
arch/arm/mach-omap2/gpio.c +1
-0@@ -23,6 +23,7 @@#include <plat/omap_hwmod.h> #include <plat/omap_device.h> +#include <plat/omap-pm.h> #include "powerdomain.h"
arch/arm/mach-omap2/gpio.c static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) · line 69
Quoted 7 lines
arch/arm/mach-omap2/gpio.c +3
-1@@ -63,7 +64,9 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->bank_width = dev_attr->bank_width; pdata->dbck_flag = dev_attr->dbck_flag; pdata->virtual_irq_start =IH_GPIO_BASE +32 * (id -1 ); - +#ifdef CONFIG_PM + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; +#endif
no #ifdef please (c.f. "#ifdefs are ugly" inDocumentation/SubmittingPatches)
In this case, the existence of this API isn't dependent on CONFIG_PM, so the #ifdef isn't right.
Kevin
PATCH v7 6/26 gpio/omap: make non-wakeup GPIO part of pdata
In reply to Tarun Kanti DebBarmaFrom: Charulatha V <[email protected]>
Non-wakeup GPIOs are available only in OMAP2. Avoid cpu_is checks by making non_wakeup_gpios as part of pdata.
--- arch/arm/mach-omap2/gpio.c | 8 ++++++++ arch/arm/plat-omap/include/plat/gpio.h | 1 + drivers/gpio/gpio-omap.c | 8 +------- 3 files changed, 10 insertions(+), 7 deletions(-)
arch/arm/mach-omap2/gpio.c +8 -0
@@ -75,6 +75,14 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)switch (oh->class->rev) {case 0 : +if (id ==1 ) +/* non-wakeup GPIO pins for OMAP2 Bank1 */ + pdata->non_wakeup_gpios =0xe203ffc0 ; +else if (id ==2 ) +/* non-wakeup GPIO pins for OMAP2 Bank2 */ + pdata->non_wakeup_gpios =0x08700040 ; +/* fall through */ +case 1 : pdata->bank_type =METHOD_GPIO_24XX ; pdata->regs->revision =OMAP24XX_GPIO_REVISION ;
arch/arm/plat-omap/include/plat/gpio.h +1 -0
@@ -199,6 +199,7 @@ struct omap_gpio_platform_data {int bank_stride;/* Only needed for omap1 MPUIO */ bool dbck_flag;/* dbck required or not - True for OMAP3&4 */ bool loses_context;/* whether the bank would ever lose context */ +u32 non_wakeup_gpios;struct omap_gpio_reg_offs *regs;
drivers/gpio/gpio-omap.c +1 -7
@@ -1021,13 +1021,6 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)/* Initialize interface clk ungated, module enabled */ __raw_writel (0 , bank->base +OMAP24XX_GPIO_CTRL ); - }else if (cpu_is_omap24xx ()) { -static const u32 non_wakeup_gpios[] = { -0xe203ffc0 ,0x08700040 - }; -if (bank->id <ARRAY_SIZE (non_wakeup_gpios)) - bank->non_wakeup_gpios = - non_wakeup_gpios[bank->id]; } }else if (cpu_class_is_omap1 ()) {if (bank_is_mpuio (bank)) {
@@ -1180,6 +1173,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) bank->dbck_flag = pdata->dbck_flag; bank->stride = pdata->bank_stride; bank->width = pdata->bank_width; + bank->non_wakeup_gpios = pdata->non_wakeup_gpios; bank->loses_context = pdata->loses_context; bank->get_context_loss_count = pdata->get_context_loss_count; bank->regs = pdata->regs;
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 6/26 gpio/omap: make non-wakeup GPIO part of pdata
Quoted 7 lines · Tarun Kanti DebBarma
From: Charulatha V <[email protected]>
Non-wakeup GPIOs are available only in OMAP2. Avoid
cpu_ischecks by makingnon_wakeup_gpiosas part of pdata.Signed-off-by Charulatha V <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
PATCH v7 7/26 gpio/omap: avoid cpu checks during module ena/disable
In reply to Tarun Kanti DebBarmaFrom: Charulatha V <[email protected]>
Remove cpu-is checks while enabling/disabling OMAP GPIO module during a gpio request/free.
--- arch/arm/mach-omap2/gpio.c | 2 + arch/arm/plat-omap/include/plat/gpio.h | 1 + drivers/gpio/gpio-omap.c | 53 ++++++++++++++------------------ 3 files changed, 26 insertions(+), 30 deletions(-)
arch/arm/mach-omap2/gpio.c +2 -0
@@ -98,6 +98,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->regs->clr_irqenable =OMAP24XX_GPIO_CLEARIRQENABLE1 ; pdata->regs->debounce =OMAP24XX_GPIO_DEBOUNCE_VAL ; pdata->regs->debounce_en =OMAP24XX_GPIO_DEBOUNCE_EN ; + pdata->regs->ctrl =OMAP24XX_GPIO_CTRL ;break ;case 2 : pdata->bank_type =METHOD_GPIO_44XX ;
@@ -114,6 +115,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->regs->clr_irqenable =OMAP4_GPIO_IRQSTATUSCLR0 ; pdata->regs->debounce =OMAP4_GPIO_DEBOUNCINGTIME ; pdata->regs->debounce_en =OMAP4_GPIO_DEBOUNCENABLE ; + pdata->regs->ctrl =OMAP4_GPIO_CTRL ;break ;default :WARN (1 ,"Invalid gpio bank_type\n" );
arch/arm/plat-omap/include/plat/gpio.h +1 -0
@@ -188,6 +188,7 @@ struct omap_gpio_reg_offs {u16 clr_irqenable;u16 debounce;u16 debounce_en; +u16 ctrl;bool irqenable_inv; };
drivers/gpio/gpio-omap.c +23 -30
73 lines not on this page · raw message
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 7/26 gpio/omap: avoid cpu checks during module ena/disable
Quoted 7 lines · Tarun Kanti DebBarma
From: Charulatha V <[email protected]>
Remove cpu-is checks while enabling/disabling OMAP GPIO module during a gpio request/free.
Signed-off-by Charulatha V <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
PATCH v7 8/26 gpio/omap: further cleanup using wkup_en register
In reply to Tarun Kanti DebBarmaWakeup enable register offset initialized according to OMAP versions during device registration. Use this to avoid version checks. Starting with OMAP4, legacy registers should not be used in combination with the updated regsiters. Use wkup_en register consistently for all SoCs wherever applicable.
--- arch/arm/mach-omap1/gpio16xx.c | 1 + arch/arm/mach-omap2/gpio.c | 2 + arch/arm/plat-omap/include/plat/gpio.h | 1 + drivers/gpio/gpio-omap.c | 108 ++++++-------------------------- 4 files changed, 23 insertions(+), 89 deletions(-)
arch/arm/mach-omap1/gpio16xx.c +1 -0
@@ -89,6 +89,7 @@ static struct omap_gpio_reg_offs omap16xx_gpio_regs = { .irqenable = OMAP1610_GPIO_IRQENABLE1, .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1, .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1, + .wkup_en = OMAP1610_GPIO_WAKEUPENABLE, };static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
arch/arm/mach-omap2/gpio.c +2 -0
@@ -99,6 +99,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->regs->debounce =OMAP24XX_GPIO_DEBOUNCE_VAL ; pdata->regs->debounce_en =OMAP24XX_GPIO_DEBOUNCE_EN ; pdata->regs->ctrl =OMAP24XX_GPIO_CTRL ; + pdata->regs->wkup_en =OMAP24XX_GPIO_WAKE_EN ;break ;case 2 : pdata->bank_type =METHOD_GPIO_44XX ;
@@ -116,6 +117,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->regs->debounce =OMAP4_GPIO_DEBOUNCINGTIME ; pdata->regs->debounce_en =OMAP4_GPIO_DEBOUNCENABLE ; pdata->regs->ctrl =OMAP4_GPIO_CTRL ; + pdata->regs->wkup_en =OMAP4_GPIO_IRQWAKEN0 ;break ;default :WARN (1 ,"Invalid gpio bank_type\n" );
arch/arm/plat-omap/include/plat/gpio.h +1 -0
@@ -189,6 +189,7 @@ struct omap_gpio_reg_offs {u16 debounce;u16 debounce_en;u16 ctrl; +u16 wkup_en;bool irqenable_inv; };
drivers/gpio/gpio-omap.c +19 -89
172 lines not on this page · raw message
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 8/26 gpio/omap: further cleanup using wkup_en register
Quoted 9 lines · Tarun Kanti DebBarma
Wakeup enable register offset initialized according to OMAP versions during device registration. Use this to avoid version checks. Starting with OMAP4, legacy registers should not be used in combination with the updated regsiters. Use
wkup_enregister consistently for all SoCs wherever applicable.Signed-off-by Tarun Kanti DebBarma <[email protected]>Signed-off-by Charulatha V <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
PATCH v7 9/26 gpio/omap: use level/edge detect reg offsets
In reply to Tarun Kanti DebBarmaBy adding level and edge detection register offsets and then initializing them correctly according to OMAP versions during device registrations we can now remove lot of revision checks in these functions.
--- arch/arm/mach-omap2/gpio.c | 8 ++ arch/arm/plat-omap/include/plat/gpio.h | 4 + drivers/gpio/gpio-omap.c | 118 ++++++++++---------------------- 3 files changed, 48 insertions(+), 82 deletions(-)
arch/arm/mach-omap2/gpio.c +8 -0
@@ -100,6 +100,10 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->regs->debounce_en =OMAP24XX_GPIO_DEBOUNCE_EN ; pdata->regs->ctrl =OMAP24XX_GPIO_CTRL ; pdata->regs->wkup_en =OMAP24XX_GPIO_WAKE_EN ; + pdata->regs->leveldetect0 =OMAP24XX_GPIO_LEVELDETECT0 ; + pdata->regs->leveldetect1 =OMAP24XX_GPIO_LEVELDETECT1 ; + pdata->regs->risingdetect =OMAP24XX_GPIO_RISINGDETECT ; + pdata->regs->fallingdetect =OMAP24XX_GPIO_FALLINGDETECT ;break ;case 2 : pdata->bank_type =METHOD_GPIO_44XX ;
@@ -118,6 +122,10 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->regs->debounce_en =OMAP4_GPIO_DEBOUNCENABLE ; pdata->regs->ctrl =OMAP4_GPIO_CTRL ; pdata->regs->wkup_en =OMAP4_GPIO_IRQWAKEN0 ; + pdata->regs->leveldetect0 =OMAP4_GPIO_LEVELDETECT0 ; + pdata->regs->leveldetect1 =OMAP4_GPIO_LEVELDETECT1 ; + pdata->regs->risingdetect =OMAP4_GPIO_RISINGDETECT ; + pdata->regs->fallingdetect =OMAP4_GPIO_FALLINGDETECT ;break ;default :WARN (1 ,"Invalid gpio bank_type\n" );
arch/arm/plat-omap/include/plat/gpio.h +4 -0
@@ -190,6 +190,10 @@ struct omap_gpio_reg_offs {u16 debounce_en;u16 ctrl;u16 wkup_en; +u16 leveldetect0; +u16 leveldetect1; +u16 risingdetect; +u16 fallingdetect;bool irqenable_inv; };
drivers/gpio/gpio-omap.c +36 -82
168 lines not on this page · raw message
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 9/26 gpio/omap: use level/edge detect reg offsets
Quoted 7 lines · Tarun Kanti DebBarma
By adding level and edge detection register offsets and then initializing them correctly according to OMAP versions during device registrations we can now remove lot of revision checks in these functions.
Signed-off-by Tarun Kanti DebBarma <[email protected]>Signed-off-by Charulatha V <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
PATCH v7 10/26 gpio/omap: remove hardcoded offsets in context save/restore
In reply to Tarun Kanti DebBarmaIt is not required to use hard-coded offsets any more in context save and restore functions and instead use the generic offsets which have been correctly initialized during device registration.
--- arch/arm/mach-omap2/gpio.c | 2 + arch/arm/plat-omap/include/plat/gpio.h | 1 + drivers/gpio/gpio-omap.c | 41 ++++++++++++++----------------- 3 files changed, 22 insertions(+), 22 deletions(-)
arch/arm/mach-omap2/gpio.c +2 -0
@@ -94,6 +94,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->regs->irqstatus =OMAP24XX_GPIO_IRQSTATUS1 ; pdata->regs->irqstatus2 =OMAP24XX_GPIO_IRQSTATUS2 ; pdata->regs->irqenable =OMAP24XX_GPIO_IRQENABLE1 ; + pdata->regs->irqenable2 =OMAP24XX_GPIO_IRQENABLE2 ; pdata->regs->set_irqenable =OMAP24XX_GPIO_SETIRQENABLE1 ; pdata->regs->clr_irqenable =OMAP24XX_GPIO_CLEARIRQENABLE1 ; pdata->regs->debounce =OMAP24XX_GPIO_DEBOUNCE_VAL ;
@@ -116,6 +117,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->regs->irqstatus =OMAP4_GPIO_IRQSTATUS0 ; pdata->regs->irqstatus2 =OMAP4_GPIO_IRQSTATUS1 ; pdata->regs->irqenable =OMAP4_GPIO_IRQSTATUSSET0 ; + pdata->regs->irqenable2 =OMAP4_GPIO_IRQSTATUSSET1 ; pdata->regs->set_irqenable =OMAP4_GPIO_IRQSTATUSSET0 ; pdata->regs->clr_irqenable =OMAP4_GPIO_IRQSTATUSCLR0 ; pdata->regs->debounce =OMAP4_GPIO_DEBOUNCINGTIME ;
arch/arm/plat-omap/include/plat/gpio.h +1 -0
@@ -184,6 +184,7 @@ struct omap_gpio_reg_offs {u16 irqstatus;u16 irqstatus2;u16 irqenable; +u16 irqenable2;u16 set_irqenable;u16 clr_irqenable;u16 debounce;
drivers/gpio/gpio-omap.c +19 -22
64 lines not on this page · raw message
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 10/26 gpio/omap: remove hardcoded offsets in context save/restore
Quoted 7 lines · Tarun Kanti DebBarma
It is not required to use hard-coded offsets any more in context save and restore functions and instead use the generic offsets which have been correctly initialized during device registration.
Signed-off-by Tarun Kanti DebBarma <[email protected]>Signed-off-by Charulatha V <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
PATCH v7 11/26 gpio/omap: cleanup set_gpio_triggering function
In reply to Tarun Kanti DebBarmaGetting rid of ifdefs within the function by adding register offset intctrl and associating OMAPXXXX_GPIO_INT_CONTROL in respective SoC specific files. Also, use wkup_status register consistently instead of referring to wakeup clear and wakeup set register offsets.
--- arch/arm/mach-omap1/gpio15xx.c | 2 + arch/arm/mach-omap1/gpio16xx.c | 3 + arch/arm/mach-omap1/gpio7xx.c | 2 + arch/arm/plat-omap/include/plat/gpio.h | 3 + drivers/gpio/gpio-omap.c | 148 ++++++++------------------------ 5 files changed, 46 insertions(+), 112 deletions(-)
arch/arm/mach-omap1/gpio15xx.c +2 -0
@@ -42,6 +42,7 @@ static struct omap_gpio_reg_offs omap15xx_mpuio_regs = { .irqstatus = OMAP_MPUIO_GPIO_INT, .irqenable = OMAP_MPUIO_GPIO_MASKIT, .irqenable_inv = true, + .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE, };static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = {
@@ -83,6 +84,7 @@ static struct omap_gpio_reg_offs omap15xx_gpio_regs = { .irqstatus = OMAP1510_GPIO_INT_STATUS, .irqenable = OMAP1510_GPIO_INT_MASK, .irqenable_inv = true, + .irqctrl = OMAP1510_GPIO_INT_CONTROL, };static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
arch/arm/mach-omap1/gpio16xx.c +3 -0
@@ -45,6 +45,7 @@ static struct omap_gpio_reg_offs omap16xx_mpuio_regs = { .irqstatus = OMAP_MPUIO_GPIO_INT, .irqenable = OMAP_MPUIO_GPIO_MASKIT, .irqenable_inv = true, + .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE, };static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = {
@@ -90,6 +91,8 @@ static struct omap_gpio_reg_offs omap16xx_gpio_regs = { .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1, .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1, .wkup_en = OMAP1610_GPIO_WAKEUPENABLE, + .edgectrl1 = OMAP1610_GPIO_EDGE_CTRL1, + .edgectrl2 = OMAP1610_GPIO_EDGE_CTRL2, };static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
arch/arm/mach-omap1/gpio7xx.c +2 -0
@@ -47,6 +47,7 @@ static struct omap_gpio_reg_offs omap7xx_mpuio_regs = { .irqstatus = OMAP_MPUIO_GPIO_INT / 2, .irqenable = OMAP_MPUIO_GPIO_MASKIT / 2, .irqenable_inv = true, + .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE >> 1, };static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = {
@@ -88,6 +89,7 @@ static struct omap_gpio_reg_offs omap7xx_gpio_regs = { .irqstatus = OMAP7XX_GPIO_INT_STATUS, .irqenable = OMAP7XX_GPIO_INT_MASK, .irqenable_inv = true, + .irqctrl = OMAP7XX_GPIO_INT_CONTROL, };static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = {
arch/arm/plat-omap/include/plat/gpio.h +3 -0
@@ -195,6 +195,9 @@ struct omap_gpio_reg_offs {u16 leveldetect1;u16 risingdetect;u16 fallingdetect; +u16 irqctrl; +u16 edgectrl1; +u16 edgectrl2;bool irqenable_inv; };
drivers/gpio/gpio-omap.c +36 -112
201 lines not on this page · raw message
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 11/26 gpio/omap: cleanup set_gpio_triggering function
Quoted 8 lines · Tarun Kanti DebBarma
Getting rid of ifdefs within the function by adding register offset intctrl and associating
OMAPXXXX_GPIO_INT_CONTROLin respective SoC specific files. Also, usewkup_statusregister consistently instead of referring to wakeup clear and wakeup set register offsets.Signed-off-by Charulatha V <[email protected]>Signed-off-by Tarun Kanti DebBarma <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
PATCH v7 12/26 gpio/omap: cleanup omap_gpio_mod_init function
In reply to Tarun Kanti DebBarmaWith register offsets now defined for respective OMAP versions we can get rid of cpu_class_* checks. This function now has common initialization code for all OMAP versions. Initialization specific to OMAP16xx has been moved within omap16xx_gpio_init().
--- arch/arm/mach-omap1/gpio16xx.c | 35 +++++++++++++++++++- drivers/gpio/gpio-omap.c | 71 +++++++++------------------------------ 2 files changed, 51 insertions(+), 55 deletions(-)
arch/arm/mach-omap1/gpio16xx.c +34 -1
@@ -24,6 +24,9 @@#define OMAP1610_GPIO4_BASE 0xfffbbc00#define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE +/* smart idle, enable wakeup */ +#define SYSCONFIG_WORD 0x14 +/* mpu gpio */ static struct __initdata resource omap16xx_mpu_gpio_resources[] = { {
@@ -218,12 +221,42 @@ static struct __initdata platform_device * omap16xx_gpio_dev[] = {static int __init omap16xx_gpio_init (void ) {int i; +void __iomem *base; +struct resource *res; +struct platform_device *pdev; +struct omap_gpio_platform_data *pdata;if (!cpu_is_omap16xx ())return -EINVAL ; -for (i =0 ; i <ARRAY_SIZE (omap16xx_gpio_dev); i++) +for (i =0 ; i <ARRAY_SIZE (omap16xx_gpio_dev); i++) { + pdev = omap16xx_gpio_dev[i]; + pdata = pdev->dev.platform_data; + + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (unlikely (!res)) { +dev_err (&pdev->dev,"Invalid mem resource.\n" ); +return -ENODEV ; + } + + base =ioremap (res->start,resource_size (res)); +if (unlikely (!base)) { +dev_err (&pdev->dev,"ioremap failed.\n" ); +return -ENOMEM ; + } + +__raw_writel (SYSCONFIG_WORD , base +OMAP1610_GPIO_SYSCONFIG ); +iounmap (base); + +/* +* Enable system clock for GPIO module. +* The CAM_CLK_CTRL *is* really the right place. +*/ +omap_writel (omap_readl (ULPD_CAM_CLK_CTRL ) |0x04 , +ULPD_CAM_CLK_CTRL ); +platform_device_register (omap16xx_gpio_dev[i]); + }return 0 ; }
drivers/gpio/gpio-omap.c +17 -54
99 lines not on this page · raw message
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 12/26 gpio/omap: cleanup omap_gpio_mod_init function
Quoted 8 lines · Tarun Kanti DebBarma
With register offsets now defined for respective OMAP versions we can get rid of cpu_class_* checks. This function now has common initialization code for all OMAP versions. Initialization specific to OMAP16xx has been moved within
omap16xx_gpio_init().Signed-off-by Tarun Kanti DebBarma <[email protected]>Signed-off-by Charulatha V <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
PATCH v7 13/26 gpio/omap: use pinctrl offset instead of macro
In reply to Tarun Kanti DebBarmaFrom: Charulatha V <[email protected]>
Use regs->pinctrl field instead of using the macro OMAP1510_GPIO_PIN_CONTROL
--- arch/arm/mach-omap1/gpio15xx.c | 1 + arch/arm/plat-omap/include/plat/gpio.h | 1 + drivers/gpio/gpio-omap.c | 8 +++----- 3 files changed, 5 insertions(+), 5 deletions(-)
arch/arm/mach-omap1/gpio15xx.c +1 -0
@@ -85,6 +85,7 @@ static struct omap_gpio_reg_offs omap15xx_gpio_regs = { .irqenable = OMAP1510_GPIO_INT_MASK, .irqenable_inv = true, .irqctrl = OMAP1510_GPIO_INT_CONTROL, + .pinctrl = OMAP1510_GPIO_PIN_CONTROL, };static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
arch/arm/plat-omap/include/plat/gpio.h +1 -0
@@ -198,6 +198,7 @@ struct omap_gpio_reg_offs {u16 irqctrl;u16 edgectrl1;u16 edgectrl2; +u16 pinctrl;bool irqenable_inv; };
drivers/gpio/gpio-omap.c +3 -5
@@ -485,15 +485,13 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)*/ _set_gpio_triggering (bank, offset,IRQ_TYPE_NONE ); -#ifdef CONFIG_ARCH_OMAP15XX -if (bank->method ==METHOD_GPIO_1510 ) { -void __iomem *reg; +if (bank->regs->pinctrl) { +void __iomem *reg = bank->base + bank->regs->pinctrl;/* Claim the pin for MPU */ - reg = bank->base +OMAP1510_GPIO_PIN_CONTROL ;__raw_writel (__raw_readl (reg) | (1 << offset), reg); } -#endif +if (bank->regs->ctrl && !bank->mod_usage) {void __iomem *reg = bank->base + bank->regs->ctrl;u32 ctrl;
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 13/26 gpio/omap: use pinctrl offset instead of macro
Quoted 6 lines · Tarun Kanti DebBarma
From: Charulatha V <[email protected]>
Use
regs->pinctrlfield instead of using the macroOMAP1510_GPIO_PIN_CONTROLSigned-off-by Charulatha V <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
Tony Lindgren
maintainerPATCH v7 13/26 gpio/omap: use pinctrl offset instead of macro
In reply to Tarun Kanti DebBarmaQuoted 6 lines · Tarun Kanti DebBarma
From: Charulatha V <[email protected]>
Use
regs->pinctrlfield instead of using the macroOMAP1510_GPIO_PIN_CONTROLSigned-off-by Charulatha V <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
PATCH v7 14/26 gpio/omap: remove unnecessary bit-masking for read access
In reply to Tarun Kanti DebBarmaRemove un-necessary bit masking. Since the register are 4 byte aligned and readl would work as is. The 'enabled' mask is already taking care to mask for bank width.
--- drivers/gpio/gpio-omap.c | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-)
drivers/gpio/gpio-omap.c +0 -2
@@ -571,8 +571,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) enabled =_get_gpio_irqbank_mask (bank); isr_saved = isr =__raw_readl (isr_reg) & enabled; -if (cpu_is_omap15xx () && (bank->method ==METHOD_MPUIO )) - isr &=0x0000ffff ;if (bank->level_mask) level_mask = bank->level_mask & enabled;
Signature · 1 line
1.7.0.4
PATCH v7 14/26 gpio/omap: remove unnecessary bit-masking for read access
Hello.
Quoted 16 lines · Tarun Kanti DebBarma
Remove un-necessary bit masking. Since the register are 4 byte aligned and readl would work as is. The 'enabled' mask is already taking care to mask for bank width.
Signed-off-by Charulatha V<[email protected]>Signed-off-by Tarun Kanti DebBarma<[email protected]>Reviewed-by Santosh Shilimkar<[email protected]>--- drivers/gpio/gpio-omap.c | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-)drivers/gpio/gpio-omap.c +0
-0
drivers/gpio/gpio-omap.c static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) · line 574
Quoted 6 lines
drivers/gpio/gpio-omap.c +0
-2@@ -571,8 +571,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) enabled =_get_gpio_irqbank_mask (bank); isr_saved = isr =__raw_readl (isr_reg)& enabled; -if (cpu_is_omap15xx ()&& (bank->method ==METHOD_MPUIO )) - isr&=0x0000ffff ;
Should have removed the now unneeded empty line too.
drivers/gpio/gpio-omap.c static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) · line 576
Quoted 2 lines
drivers/gpio/gpio-omap.c +0
-0if (bank->level_mask) level_mask = bank->level_mask& enabled;
WBR, Sergei
PATCH v7 14/26 gpio/omap: remove unnecessary bit-masking for read access
Quoted 24 lines · Sergei Shtylyov
Hello.
Quoted 20 lines · Tarun Kanti DebBarma
Remove un-necessary bit masking. Since the register are 4 byte aligned and readl would work as is. The 'enabled' mask is already taking care to mask for bank width.
Signed-off-by Charulatha V<[email protected]>Signed-off-by Tarun Kanti DebBarma<[email protected]>Reviewed-by Santosh Shilimkar<[email protected]>---
?drivers/gpio/gpio-omap.c | ? ?2 --
?1 files changed, 0 insertions(+), 2 deletions(-)drivers/gpio/gpio-omap.c +0
-0@@ -571,8 +571,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) ? ? ? ? ? ? ? ?enabled = _get_gpio_irqbank_mask(bank); ? ? ? ? ? ? ? ?isr_saved = isr = __raw_readl(isr_reg)& ?enabled;
Quoted 5 lines
drivers/gpio/gpio-omap.c static void gpio_irq_handler(unsigned int irq, struct · line 575
Quoted 3 lines
drivers/gpio/gpio-omap.c +0
-2- ? ? ? ? ? ? ? if (cpu_is_omap15xx()&& ?(bank->method == METHOD_MPUIO)) - ? ? ? ? ? ? ? ? ? ? ? isr&= 0x0000ffff;? Should have removed the now unneeded empty line too.
Sure... I will remove.
--
Tarun
Quoted 6 lines
Quoted 3 lines
drivers/gpio/gpio-omap.c +0
-0? ? ? ? ? ? ? ?if (bank->level_mask)? ? ? ? ? ? ? ? ? ? ? ?level_mask = bank->level_mask& ?enabled;
WBR, Sergei
PATCH v7 15/26 gpio/omap: remove bank->method & METHOD_* macros
In reply to Tarun Kanti DebBarmaFrom: Charulatha V <[email protected]>
The only bank->type (method) used in the OMAP GPIO driver is MPUIO type as they need to be handled separately. Identify the same using a flag and remove all METHOD_* macros.
mpuio_init() function is defined under #ifdefs. It is required only in case of MPUIO bank type and only when PM operations are supported by it. This is applicable only in case of OMAP16xx SoC's MPUIO GPIO bank type. For all the other cases it is a dummy function. Hence clean up the same and remove all the OMAP SoC specific #ifdefs.
--- arch/arm/mach-omap1/gpio15xx.c | 3 +- arch/arm/mach-omap1/gpio16xx.c | 6 +---- arch/arm/mach-omap1/gpio7xx.c | 8 +------ arch/arm/mach-omap2/gpio.c | 2 - arch/arm/plat-omap/include/plat/gpio.h | 8 +------ drivers/gpio/gpio-omap.c | 38 +++++-------------------------- 6 files changed, 10 insertions(+), 55 deletions(-)
arch/arm/mach-omap1/gpio15xx.c +1 -2
@@ -47,7 +47,7 @@ static struct omap_gpio_reg_offs omap15xx_mpuio_regs = {static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = { .virtual_irq_start =IH_MPUIO_BASE , - .bank_type =METHOD_MPUIO , + .is_mpuio = true, .bank_width =16 , .bank_stride =1 , .regs = &omap15xx_mpuio_regs,
@@ -90,7 +90,6 @@ static struct omap_gpio_reg_offs omap15xx_gpio_regs = {static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { .virtual_irq_start =IH_GPIO_BASE , - .bank_type =METHOD_GPIO_1510 , .bank_width =16 , .regs = &omap15xx_gpio_regs, };
arch/arm/mach-omap1/gpio16xx.c +1 -5
@@ -53,7 +53,7 @@ static struct omap_gpio_reg_offs omap16xx_mpuio_regs = {static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { .virtual_irq_start =IH_MPUIO_BASE , - .bank_type =METHOD_MPUIO , + .is_mpuio = true, .bank_width =16 , .bank_stride =1 , .regs = &omap16xx_mpuio_regs,
@@ -100,7 +100,6 @@ static struct omap_gpio_reg_offs omap16xx_gpio_regs = {static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { .virtual_irq_start =IH_GPIO_BASE , - .bank_type =METHOD_GPIO_1610 , .bank_width =16 , .regs = &omap16xx_gpio_regs, };
@@ -130,7 +129,6 @@ static struct __initdata resource omap16xx_gpio2_resources[] = {static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = { .virtual_irq_start =IH_GPIO_BASE +16 , - .bank_type =METHOD_GPIO_1610 , .bank_width =16 , .regs = &omap16xx_gpio_regs, };
@@ -160,7 +158,6 @@ static struct __initdata resource omap16xx_gpio3_resources[] = {static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = { .virtual_irq_start =IH_GPIO_BASE +32 , - .bank_type =METHOD_GPIO_1610 , .bank_width =16 , .regs = &omap16xx_gpio_regs, };
@@ -190,7 +187,6 @@ static struct __initdata resource omap16xx_gpio4_resources[] = {static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = { .virtual_irq_start =IH_GPIO_BASE +48 , - .bank_type =METHOD_GPIO_1610 , .bank_width =16 , .regs = &omap16xx_gpio_regs, };
arch/arm/mach-omap1/gpio7xx.c +1 -7
@@ -52,8 +52,8 @@ static struct omap_gpio_reg_offs omap7xx_mpuio_regs = {static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { .virtual_irq_start =IH_MPUIO_BASE , - .bank_type =METHOD_MPUIO , .bank_width =32 , + .is_mpuio = true, .bank_stride =2 , .regs = &omap7xx_mpuio_regs, };
@@ -94,7 +94,6 @@ static struct omap_gpio_reg_offs omap7xx_gpio_regs = {static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = { .virtual_irq_start =IH_GPIO_BASE , - .bank_type =METHOD_GPIO_7XX , .bank_width =32 , .regs = &omap7xx_gpio_regs, };
@@ -124,7 +123,6 @@ static struct __initdata resource omap7xx_gpio2_resources[] = {static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = { .virtual_irq_start =IH_GPIO_BASE +32 , - .bank_type =METHOD_GPIO_7XX , .bank_width =32 , .regs = &omap7xx_gpio_regs, };
@@ -154,7 +152,6 @@ static struct __initdata resource omap7xx_gpio3_resources[] = {static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = { .virtual_irq_start =IH_GPIO_BASE +64 , - .bank_type =METHOD_GPIO_7XX , .bank_width =32 , .regs = &omap7xx_gpio_regs, };
@@ -184,7 +181,6 @@ static struct __initdata resource omap7xx_gpio4_resources[] = {static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = { .virtual_irq_start =IH_GPIO_BASE +96 , - .bank_type =METHOD_GPIO_7XX , .bank_width =32 , .regs = &omap7xx_gpio_regs, };
@@ -214,7 +210,6 @@ static struct __initdata resource omap7xx_gpio5_resources[] = {static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = { .virtual_irq_start =IH_GPIO_BASE +128 , - .bank_type =METHOD_GPIO_7XX , .bank_width =32 , .regs = &omap7xx_gpio_regs, };
@@ -244,7 +239,6 @@ static struct __initdata resource omap7xx_gpio6_resources[] = {static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = { .virtual_irq_start =IH_GPIO_BASE +160 , - .bank_type =METHOD_GPIO_7XX , .bank_width =32 , .regs = &omap7xx_gpio_regs, };
arch/arm/mach-omap2/gpio.c +0 -2
@@ -84,7 +84,6 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)/* fall through */ case 1 : - pdata->bank_type =METHOD_GPIO_24XX ; pdata->regs->revision =OMAP24XX_GPIO_REVISION ; pdata->regs->direction =OMAP24XX_GPIO_OE ; pdata->regs->datain =OMAP24XX_GPIO_DATAIN ;
@@ -107,7 +106,6 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->regs->fallingdetect =OMAP24XX_GPIO_FALLINGDETECT ;break ;case 2 : - pdata->bank_type =METHOD_GPIO_44XX ; pdata->regs->revision =OMAP4_GPIO_REVISION ; pdata->regs->direction =OMAP4_GPIO_OE ; pdata->regs->datain =OMAP4_GPIO_DATAIN ;
arch/arm/plat-omap/include/plat/gpio.h +1 -7
@@ -162,13 +162,6 @@ IH_MPUIO_BASE + ((nr) & 0x0f) : \ IH_GPIO_BASE + (nr)) -#define METHOD_MPUIO 0 -#define METHOD_GPIO_1510 1 -#define METHOD_GPIO_1610 2 -#define METHOD_GPIO_7XX 3 -#define METHOD_GPIO_24XX 5 -#define METHOD_GPIO_44XX 6 - struct omap_gpio_dev_attr { int bank_width; /* GPIO bank width */ bool dbck_flag; /* dbck required or not - True for OMAP3&4 */
@@ -210,6 +203,7 @@ struct omap_gpio_platform_data {int bank_stride;/* Only needed for omap1 MPUIO */ bool dbck_flag;/* dbck required or not - True for OMAP3&4 */ bool loses_context;/* whether the bank would ever lose context */ +bool is_mpuio;/* whether the bank is of type MPUIO */ u32 non_wakeup_gpios;struct omap_gpio_reg_offs *regs;
drivers/gpio/gpio-omap.c +6 -32
@@ -49,7 +49,6 @@ struct gpio_bank {void __iomem *base;u16 irq;u16 virtual_irq_start; -int method;u32 suspend_wakeup;u32 saved_wakeup;u32 non_wakeup_gpios;
@@ -66,6 +65,7 @@ struct gpio_bank {u32 mod_usage;u32 dbck_enable_mask;struct device *dev; +bool is_mpuio;bool dbck_flag;bool loses_context;int stride;
@@ -689,14 +689,6 @@ static struct irq_chip gpio_irq_chip = {/*---------------------------------------------------------------------*/ -#ifdef CONFIG_ARCH_OMAP1 - -#define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO) - -#ifdef CONFIG_ARCH_OMAP16XX - -#include <linux/platform_device.h> -static int omap_mpuio_suspend_noirq (struct device *dev) {struct platform_device *pdev =to_platform_device (dev);
@@ -758,23 +750,8 @@ static inline void mpuio_init(struct gpio_bank *bank) (void )platform_device_register (&omap_mpuio_device); } -#else -static inline void mpuio_init (struct gpio_bank *bank) {} -#endif /* 16xx */ - -#else - -#define bank_is_mpuio (bank) 0 -static inline void mpuio_init (struct gpio_bank *bank) {} - -#endif -/*---------------------------------------------------------------------*/ -/* REVISIT these are stupid implementations! replace by ones that -* don't switch on METHOD_* and which mostly avoid spinlocks -*/ -static int gpio_input (struct gpio_chip *chip,unsigned offset) {struct gpio_bank *bank;
@@ -895,7 +872,7 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)if (bank->width ==16 ) l =0xffff ; -if (bank_is_mpuio (bank)) { +if (bank->is_mpuio) {__raw_writel (l, bank->base + bank->regs->irqenable);return ; }
@@ -941,7 +918,6 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)int j;static int gpio; - bank->mod_usage =0 ;/* * REVISIT eventually switch from OMAP-specific gpio structs * over to the generic ones
@@ -954,12 +930,10 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) bank->chip.set_debounce = gpio_debounce; bank->chip.set = gpio_set; bank->chip.to_irq = gpio_2irq; -if (bank_is_mpuio (bank)) { +if (bank->is_mpuio) { bank->chip.label ="mpuio" ; -#ifdef CONFIG_ARCH_OMAP16XX if (bank->regs->wkup_en) bank->chip.dev = &omap_mpuio_device.dev; -#endif bank->chip.base =OMAP_MPUIO (0 ); }else { bank->chip.label ="gpio" ;
@@ -974,7 +948,7 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) j < bank->virtual_irq_start + bank->width; j++) {irq_set_lockdep_class (j, &gpio_lock_class);irq_set_chip_data (j, bank); -if (bank_is_mpuio (bank)) { +if (bank->is_mpuio) {omap_mpuio_alloc_gc (bank, j, bank->width); }else {irq_set_chip (j, &gpio_irq_chip);
@@ -1018,11 +992,11 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) pdata = pdev->dev.platform_data; bank->virtual_irq_start = pdata->virtual_irq_start; - bank->method = pdata->bank_type; bank->dev = &pdev->dev; bank->dbck_flag = pdata->dbck_flag; bank->stride = pdata->bank_stride; bank->width = pdata->bank_width; + bank->is_mpuio = pdata->is_mpuio; bank->non_wakeup_gpios = pdata->non_wakeup_gpios; bank->loses_context = pdata->loses_context; bank->get_context_loss_count = pdata->get_context_loss_count;
@@ -1055,7 +1029,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)pm_runtime_enable (bank->dev);pm_runtime_get_sync (bank->dev); -if (bank_is_mpuio (bank)) +if (bank->is_mpuio)mpuio_init (bank);omap_gpio_mod_init (bank);
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 15/26 gpio/omap: remove bank->method & METHOD_* macros
Quoted 12 lines · Tarun Kanti DebBarma
From: Charulatha V <[email protected]>
The only
bank->type(method) used in the OMAP GPIO driver is MPUIO type as they need to be handled separately. Identify the same using a flag and remove all METHOD_* macros.
mpuio_init()function is defined under #ifdefs. It is required only in case of MPUIO bank type and only when PM operations are supported by it. This is applicable only in case of OMAP16xx SoC's MPUIO GPIO bank type. For all the other cases it is a dummy function. Hence clean up the same and remove all the OMAP SoC specific #ifdefs.
Quoted 3 lines
Signed-off-by Charulatha V <[email protected]>Signed-off-by Tarun Kanti DebBarma <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
PATCH v7 16/26 gpio/omap: fix bankwidth for OMAP7xx MPUIO
In reply to Tarun Kanti DebBarmaFrom: Charulatha V <[email protected]>
In all OMAP1 SoCs, the MPUIO bank width is 16 bits. But, in OMAP7xx, it is wrongly initialised to 32. Fix this.
--- arch/arm/mach-omap1/gpio7xx.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
arch/arm/mach-omap1/gpio7xx.c +1 -1
@@ -52,8 +52,8 @@ static struct omap_gpio_reg_offs omap7xx_mpuio_regs = {static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { .virtual_irq_start =IH_MPUIO_BASE , - .bank_width =32 , .is_mpuio = true, + .bank_width =16 , .bank_stride =2 , .regs = &omap7xx_mpuio_regs, };
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 16/26 gpio/omap: fix bankwidth for OMAP7xx MPUIO
Quoted 7 lines · Tarun Kanti DebBarma
From: Charulatha V <[email protected]>
In all OMAP1 SoCs, the MPUIO bank width is 16 bits. But, in OMAP7xx, it is wrongly initialised to 32. Fix this.
Signed-off-by Charulatha V <[email protected]>Reviewed-by Santosh Shilimkar <[email protected]>
PATCH v7 17/26 gpio/omap: use pm-runtime framework
In reply to Tarun Kanti DebBarmaCall runtime pm APIs pm_runtime_get_sync() and pm_runtime_put_sync() for enabling/disabling clocks appropriately. Remove syscore_ops and instead use SET_RUNTIME_PM_OPS macro.
--- drivers/gpio/gpio-omap.c | 65 +++++++++++++++++++++++++++++---------------- 1 files changed, 42 insertions(+), 23 deletions(-)
drivers/gpio/gpio-omap.c +42 -23
@@ -21,6 +21,7 @@#include <linux/io.h> #include <linux/slab.h> #include <linux/pm_runtime.h> +#include <linux/pm.h> #include <mach/hardware.h> #include <asm/irq.h>
@@ -79,6 +80,8 @@ struct gpio_bank {struct omap_gpio_reg_offs *regs; }; +static void omap_gpio_mod_init (struct gpio_bank *bank); +#define GPIO_INDEX (bank, gpio) (gpio % bank->width)#define GPIO_BIT (bank, gpio) (1 << GPIO_INDEX(bank, gpio))#define GPIO_MOD_CTRL_BIT BIT(0)
@@ -478,8 +481,14 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);unsigned long flags; -spin_lock_irqsave (&bank->lock, flags); +/* +* If this is the first gpio_request for the bank, +* enable the bank module. +*/ +if (!bank->mod_usage) +pm_runtime_get_sync (bank->dev); +spin_lock_irqsave (&bank->lock, flags);/* Set trigger to none. You need to enable the desired trigger with * request_irq() or set_irq_type(). */
@@ -535,6 +544,13 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)_reset_gpio (bank, bank->chip.base + offset);spin_unlock_irqrestore (&bank->lock, flags); + +/* +* If this is the last gpio to be freed in the bank, +* disable the bank module. +*/ +if (!bank->mod_usage) +pm_runtime_put_sync (bank->dev); }/*
@@ -560,6 +576,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) bank =irq_get_handler_data (irq); isr_reg = bank->base + bank->regs->irqstatus; +pm_runtime_get_sync (bank->dev);if (WARN_ON (!isr_reg)) goto exit;
@@ -621,6 +638,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) exit:if (!unmasked)chained_irq_exit (chip, desc); +pm_runtime_put (bank->dev); }static void gpio_irq_shutdown (struct irq_data *d)
@@ -1027,6 +1045,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) }pm_runtime_enable (bank->dev); +pm_runtime_irq_safe (bank->dev);pm_runtime_get_sync (bank->dev);if (bank->is_mpuio)
@@ -1036,6 +1055,8 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)omap_gpio_chip_init (bank);omap_gpio_show_rev (bank); +pm_runtime_put_sync (bank->dev); +list_add_tail (&bank->node, &omap_gpio_list);return ret;
@@ -1046,7 +1067,9 @@ err_exit:return ret; } -static int omap_gpio_suspend (void ) +#ifdef CONFIG_ARCH_OMAP2PLUS + +static int omap_gpio_suspend (struct device *dev) {struct gpio_bank *bank;
@@ -1064,12 +1087,13 @@ static int omap_gpio_suspend(void) bank->saved_wakeup =__raw_readl (wake_status);_gpio_rmw (base, bank->regs->wkup_en, bank->suspend_wakeup,1 );spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put_sync (dev); }return 0 ; } -static void omap_gpio_resume (void ) +static int omap_gpio_resume (struct device *dev) {struct gpio_bank *bank;
@@ -1078,20 +1102,17 @@ static void omap_gpio_resume(void)unsigned long flags;if (!bank->regs->wkup_en) -return ; +return 0 ; +pm_runtime_get_sync (dev);spin_lock_irqsave (&bank->lock, flags);_gpio_rmw (base, bank->regs->wkup_en, bank->saved_wakeup,1 );spin_unlock_irqrestore (&bank->lock, flags); } -} -static struct syscore_ops omap_gpio_syscore_ops = { - .suspend = omap_gpio_suspend, - .resume = omap_gpio_resume, -}; +return 0 ; +} -#ifdef CONFIG_ARCH_OMAP2PLUS static void omap_gpio_save_context (struct gpio_bank *bank);static void omap_gpio_restore_context (struct gpio_bank *bank);
@@ -1138,6 +1159,7 @@ save_gpio_context: bank->get_context_loss_count (bank->dev);omap_gpio_save_context (bank); +pm_runtime_put (bank->dev); } }
@@ -1153,6 +1175,8 @@ void omap2_gpio_resume_after_idle(void)if (!bank->loses_context)continue ; +pm_runtime_get_sync (bank->dev); +for (j =0 ; j <hweight_long (bank->dbck_enable_mask); j++)clk_enable (bank->dbck);
@@ -1265,12 +1289,20 @@ static void omap_gpio_restore_context(struct gpio_bank *bank) bank->base + bank->regs->fallingdetect); __raw_writel(bank->context.dataout, bank->base + bank->regs->dataout); } +#else +#define omap_gpio_suspend NULL +#define omap_gpio_resume NULL#endif +static const struct dev_pm_ops gpio_pm_ops = { +SET_SYSTEM_SLEEP_PM_OPS (omap_gpio_suspend, omap_gpio_resume) +}; +static struct platform_driver omap_gpio_driver = { .probe = omap_gpio_probe, .driver = { .name ="omap_gpio" , + .pm = &gpio_pm_ops, }, };
@@ -1284,16 +1316,3 @@ static int __init omap_gpio_drv_reg(void)return platform_driver_register (&omap_gpio_driver); }postcore_initcall (omap_gpio_drv_reg); - -static int __init omap_gpio_sysinit (void ) -{ - -#if defined(CONFIG_ARCH_OMAP16XX ) || defined(CONFIG_ARCH_OMAP2PLUS ) -if (cpu_is_omap16xx () ||cpu_class_is_omap2 ()) -register_syscore_ops (&omap_gpio_syscore_ops); -#endif - -return 0 ; -} - -arch_initcall (omap_gpio_sysinit);
Signature · 1 line
1.7.0.4
PATCH v7 18/26 gpio/omap: optimize suspend and resume functions
In reply to Tarun Kanti DebBarmaThere is no need to operate on all the banks every time the function is called. Just operate on the current bank passed by the framework.
--- drivers/gpio/gpio-omap.c | 53 +++++++++++++++++++++------------------------ 1 files changed, 25 insertions(+), 28 deletions(-)
drivers/gpio/gpio-omap.c +25 -28
@@ -1044,6 +1044,8 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) goto err_free; } +platform_set_drvdata (pdev, bank); +pm_runtime_enable (bank->dev);pm_runtime_irq_safe (bank->dev);pm_runtime_get_sync (bank->dev);
@@ -1071,44 +1073,39 @@ err_exit:static int omap_gpio_suspend (struct device *dev) { -struct gpio_bank *bank; - -list_for_each_entry (bank, &omap_gpio_list, node) { -void __iomem *base = bank->base; -void __iomem *wake_status; -unsigned long flags; - -if (!bank->regs->wkup_en) -return 0 ; +struct platform_device *pdev =to_platform_device (dev); +struct gpio_bank *bank =platform_get_drvdata (pdev); +void __iomem *base = bank->base; +void __iomem *wake_status; +unsigned long flags; - wake_status = bank->base + bank->regs->wkup_en; +if (!bank->regs->wkup_en || !bank->suspend_wakeup) +return 0 ; -spin_lock_irqsave (&bank->lock, flags); - bank->saved_wakeup =__raw_readl (wake_status); -_gpio_rmw (base, bank->regs->wkup_en, bank->suspend_wakeup,1 ); -spin_unlock_irqrestore (&bank->lock, flags); -pm_runtime_put_sync (dev); - } + wake_status = bank->base + bank->regs->wkup_en; +spin_lock_irqsave (&bank->lock, flags); + bank->saved_wakeup =__raw_readl (wake_status); +_gpio_rmw (base, bank->regs->wkup_en, bank->suspend_wakeup,1 ); +spin_unlock_irqrestore (&bank->lock, flags); +pm_runtime_put_sync (dev);return 0 ; }static int omap_gpio_resume (struct device *dev) { -struct gpio_bank *bank; - -list_for_each_entry (bank, &omap_gpio_list, node) { -void __iomem *base = bank->base; -unsigned long flags; +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->regs->wkup_en) -return 0 ; +if (!bank->regs->wkup_en || !bank->saved_wakeup) +return 0 ; -pm_runtime_get_sync (dev); -spin_lock_irqsave (&bank->lock, flags); -_gpio_rmw (base, bank->regs->wkup_en, bank->saved_wakeup,1 ); -spin_unlock_irqrestore (&bank->lock, flags); - } +pm_runtime_get_sync (dev); +spin_lock_irqsave (&bank->lock, flags); +_gpio_rmw (base, bank->regs->wkup_en, bank->saved_wakeup,1 ); +spin_unlock_irqrestore (&bank->lock, flags);return 0 ; }
Signature · 1 line
1.7.0.4
PATCH v7 19/26 gpio/omap: cleanup prepare_for_idle and resume_after_idle
In reply to Tarun Kanti DebBarmaSince *_prepare_for_idle() and *_resume_after_idle() are called with interrupts disabled they should be kept as simple as possible. So, moving most of the stuff to *_runtime_suspend/resume() callbacks.
--- drivers/gpio/gpio-omap.c | 236 +++++++++++++++++++++++++-------------------- 1 files changed, 131 insertions(+), 105 deletions(-)
drivers/gpio/gpio-omap.c +131 -105
@@ -1114,135 +1114,157 @@ static int omap_gpio_resume(struct device *dev)static void omap_gpio_save_context (struct gpio_bank *bank);static void omap_gpio_restore_context (struct gpio_bank *bank); -void omap2_gpio_prepare_for_idle (int off_mode) +static int omap_gpio_runtime_suspend (struct device *dev) { -struct gpio_bank *bank; +struct platform_device *pdev =to_platform_device (dev); +struct gpio_bank *bank =platform_get_drvdata (pdev); +u32 l1 =0 , l2 =0 ; +int j; +unsigned long flags; -list_for_each_entry (bank, &omap_gpio_list, node) { -u32 l1 =0 , l2 =0 ; -int j; +spin_lock_irqsave (&bank->lock, flags); +/* +* If going to OFF, remove triggering for all +* non-wakeup GPIOs. Otherwise spurious IRQs will be +* generated. See OMAP2420 Errata item 1.101. +*/ +if (!(bank->enabled_non_wakeup_gpios)) + goto save_gpio_context; -if (!bank->loses_context) -continue ; + 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); -for (j =0 ; j <hweight_long (bank->dbck_enable_mask); j++) -clk_disable (bank->dbck); + bank->saved_fallingdetect = l1; + bank->saved_risingdetect = l2; + l1 &= ~bank->enabled_non_wakeup_gpios; + l2 &= ~bank->enabled_non_wakeup_gpios; -if (!off_mode) -continue ; +__raw_writel (l1, bank->base + bank->regs->fallingdetect); +__raw_writel (l2, bank->base + bank->regs->risingdetect); -/* If going to OFF, remove triggering for all -* non-wakeup GPIOs. Otherwise spurious IRQs will be -* generated. See OMAP2420 Errata item 1.101. */ -if (!(bank->enabled_non_wakeup_gpios)) - goto save_gpio_context; +save_gpio_context: +if (bank->get_context_loss_count) + bank->context_loss_count = + bank->get_context_loss_count (bank->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); +omap_gpio_save_context (bank); +for (j =0 ; j <hweight_long (bank->dbck_enable_mask); j++) +clk_disable (bank->dbck); + +spin_unlock_irqrestore (&bank->lock, flags); +return 0 ; +} - bank->saved_fallingdetect = l1; - bank->saved_risingdetect = l2; - l1 &= ~bank->enabled_non_wakeup_gpios; - l2 &= ~bank->enabled_non_wakeup_gpios; +static int omap_gpio_runtime_resume (struct device *dev) +{ +struct platform_device *pdev =to_platform_device (dev); +struct gpio_bank *bank =platform_get_drvdata (pdev); +u32 context_lost_cnt_after; +u32 l =0 , gen, gen0, gen1; +int j; +unsigned long flags; -__raw_writel (l1, bank->base + bank->regs->fallingdetect); -__raw_writel (l2, bank->base + bank->regs->risingdetect); +spin_lock_irqsave (&bank->lock, flags); +for (j =0 ; j <hweight_long (bank->dbck_enable_mask); j++) +clk_enable (bank->dbck); -save_gpio_context: -if (bank->get_context_loss_count) - bank->context_loss_count = - bank->get_context_loss_count (bank->dev); +if (bank->get_context_loss_count) { + context_lost_cnt_after = + bank->get_context_loss_count (bank->dev); +if (context_lost_cnt_after != bank->context_loss_count || + !context_lost_cnt_after) { +omap_gpio_restore_context (bank); + }else { +spin_unlock_irqrestore (&bank->lock, flags); +return 0 ; + } + } -omap_gpio_save_context (bank); -pm_runtime_put (bank->dev); +if (!(bank->enabled_non_wakeup_gpios)) { +spin_unlock_irqrestore (&bank->lock, flags); +return 0 ; } + +__raw_writel (bank->saved_fallingdetect, + bank->base + bank->regs->fallingdetect); +__raw_writel (bank->saved_risingdetect, + bank->base + bank->regs->risingdetect); + l =__raw_readl (bank->base + bank->regs->datain); + +/* +* Check if any of the non-wakeup interrupt GPIOs have changed +* state. If so, generate an IRQ by software. This is +* horribly racy, but it's the best we can do to work around +* this silicon bug. +*/ + l ^= bank->saved_datain; + l &= bank->enabled_non_wakeup_gpios; + +/* +* 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 &= bank->saved_datain; + gen1 = l & bank->saved_risingdetect; + gen1 &= ~(bank->saved_datain); + +/* FIXME: Consider GPIO IRQs with level detections properly! */ + gen = l & (~(bank->saved_fallingdetect) & ~(bank->saved_risingdetect)); +/* Consider all GPIO IRQs needed to be updated */ + gen |= gen0 | gen1; + +if (gen) { +u32 old0, old1; + + old0 =__raw_readl (bank->base + bank->regs->leveldetect0); + old1 =__raw_readl (bank->base + bank->regs->leveldetect1); + +__raw_writel (old0, bank->base + bank->regs->leveldetect0); +__raw_writel (old1, bank->base + bank->regs->leveldetect1); +if (cpu_is_omap24xx () ||cpu_is_omap34xx ()) { + old0 |= gen; + old1 |= gen; + } + +if (cpu_is_omap44xx ()) { + old0 |= l; + old1 |= l; + } +__raw_writel (old0, bank->base + bank->regs->leveldetect0); +__raw_writel (old1, bank->base + bank->regs->leveldetect1); + } + +spin_unlock_irqrestore (&bank->lock, flags); +return 0 ; } -void omap2_gpio_resume_after_idle (void ) +void omap2_gpio_prepare_for_idle (int off_mode) {struct gpio_bank *bank; -list_for_each_entry (bank, &omap_gpio_list, node) { -u32 context_lost_cnt_after; -u32 l =0 , gen, gen0, gen1; -int j; +if (!off_mode) +return ; -if (!bank->loses_context) +list_for_each_entry (bank, &omap_gpio_list, node) { +if (!bank->mod_usage || !bank->loses_context)continue ; -pm_runtime_get_sync (bank->dev); - -for (j =0 ; j <hweight_long (bank->dbck_enable_mask); j++) -clk_enable (bank->dbck); +pm_runtime_put (bank->dev); + } +} -if (bank->get_context_loss_count) { - context_lost_cnt_after = - bank->get_context_loss_count (bank->dev); -if (context_lost_cnt_after != bank->context_loss_count - || !context_lost_cnt_after) -omap_gpio_restore_context (bank); - } +void omap2_gpio_resume_after_idle (void ) +{ +struct gpio_bank *bank; -if (!(bank->enabled_non_wakeup_gpios)) +list_for_each_entry (bank, &omap_gpio_list, node) { +if (!bank->mod_usage || !bank->loses_context)continue ; -__raw_writel (bank->saved_fallingdetect, - bank->base + bank->regs->fallingdetect); -__raw_writel (bank->saved_risingdetect, - bank->base + bank->regs->risingdetect); - l =__raw_readl (bank->base + bank->regs->datain); - -/* Check if any of the non-wakeup interrupt GPIOs have changed -* state. If so, generate an IRQ by software. This is -* horribly racy, but it's the best we can do to work around -* this silicon bug. */ - l ^= bank->saved_datain; - l &= bank->enabled_non_wakeup_gpios; - -/* -* 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 &= bank->saved_datain; - - gen1 = l & bank->saved_risingdetect; - gen1 &= ~(bank->saved_datain); - -/* FIXME: Consider GPIO IRQs with level detections properly! */ - gen = l & (~(bank->saved_fallingdetect) & - ~(bank->saved_risingdetect)); -/* Consider all GPIO IRQs needed to be updated */ - gen |= gen0 | gen1; - -if (gen) { -u32 old0, old1; - - old0 =__raw_readl (bank->base + - bank->regs->leveldetect0); - old1 =__raw_readl (bank->base + - bank->regs->leveldetect1); - -__raw_writel (old0, bank->base + - bank->regs->leveldetect0); -__raw_writel (old1, bank->base + - bank->regs->leveldetect1); -if (cpu_is_omap24xx () ||cpu_is_omap34xx ()) { - old0 |= gen; - old1 |= gen; - } - -if (cpu_is_omap44xx ()) { - old0 |= l; - old1 |= l; - } -__raw_writel (old0, bank->base + - bank->regs->leveldetect0); -__raw_writel (old1, bank->base + - bank->regs->leveldetect1); - } +pm_runtime_get_sync (bank->dev); } }
@@ -1289,10 +1311,14 @@ static void omap_gpio_restore_context(struct gpio_bank *bank)#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 ) };static struct platform_driver omap_gpio_driver = {
Signature · 1 line
1.7.0.4
PATCH v7 20/26 gpio/omap: skip operations in runtime callbacks
In reply to Tarun Kanti DebBarmaThe *_runtime_suspend/resume() callbacks perform basic operations necessary before/after turning off/on clocks using *_runtime_put/get*(). This happens when modules are fully initialized and functional. They don't have to be called during initialization. As we need the clocks to be turned on/off using *_runtime_get/put*() in *_probe() make sure we return from these callbacks during this time.
--- drivers/gpio/gpio-omap.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)
drivers/gpio/gpio-omap.c +6 -0
@@ -1122,6 +1122,9 @@ static int omap_gpio_runtime_suspend(struct device *dev)int j;unsigned long flags; +if (!bank->mod_usage) +return 0 ; +spin_lock_irqsave (&bank->lock, flags);/* * If going to OFF, remove triggering for all
@@ -1166,6 +1169,9 @@ static int omap_gpio_runtime_resume(struct device *dev)int j;unsigned long flags; +if (!bank->mod_usage) +return 0 ; +spin_lock_irqsave (&bank->lock, flags);for (j =0 ; j <hweight_long (bank->dbck_enable_mask); j++)clk_enable (bank->dbck);
Signature · 1 line
1.7.0.4
PATCH v7 21/26 gpio/omap: remove omap_gpio_save_context overhead
In reply to Tarun Kanti DebBarmaContext 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.
--- drivers/gpio/gpio-omap.c | 62 ++++++++++++++++++++++++++------------------- 1 files changed, 36 insertions(+), 26 deletions(-)
drivers/gpio/gpio-omap.c +36 -26
@@ -98,6 +98,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; }
@@ -128,6 +129,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)
@@ -217,9 +219,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() ||
@@ -306,6 +319,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 ;
@@ -398,6 +413,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)
@@ -418,6 +434,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)
@@ -509,6 +526,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;
@@ -526,9 +544,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);
@@ -540,6 +561,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);
@@ -900,6 +922,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
@@ -1087,6 +1111,7 @@ static int omap_gpio_suspend(struct device *dev)spin_lock_irqsave (&bank->lock, flags); bank->saved_wakeup =__raw_readl (wake_status);_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);pm_runtime_put_sync (dev);return 0 ;
@@ -1105,13 +1130,13 @@ static int omap_gpio_resume(struct device *dev)pm_runtime_get_sync (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)
@@ -1132,7 +1157,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);
@@ -1146,13 +1171,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);for (j =0 ; j <hweight_long (bank->dbck_enable_mask); j++)clk_disable (bank->dbck);
@@ -1197,6 +1223,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);/*
@@ -1241,6 +1269,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; }spin_unlock_irqrestore (&bank->lock, flags);
@@ -1274,26 +1304,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,
Signature · 1 line
1.7.0.4
PATCH v7 22/26 gpio/omap: save and restore debounce registers
In reply to Tarun Kanti DebBarmaFrom: Nishanth Menon <[email protected]>
GPIO debounce registers need to be saved and restored for proper functioning of driver. To save the registers, we cannot cut the clock before the save, hence move the clk disable after the save.
--- drivers/gpio/gpio-omap.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
drivers/gpio/gpio-omap.c +10 -0
@@ -42,6 +42,8 @@ struct gpio_regs {u32 risingdetect;u32 fallingdetect;u32 dataout; +u32 debounce; +u32 debounce_en; };struct gpio_bank {
@@ -202,6 +204,8 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, bank->dbck_enable_mask = val;__raw_writel (val, reg); + bank->context.debounce = debounce; + bank->context.debounce_en = val; } static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio,
@@ -1323,6 +1327,12 @@ static void omap_gpio_restore_context(struct gpio_bank *bank)__raw_writel (bank->context.fallingdetect, bank->base + bank->regs->fallingdetect);__raw_writel (bank->context.dataout, bank->base + bank->regs->dataout); +if (bank->dbck_enable_mask) { +__raw_writel (bank->context.debounce, bank->base + + bank->regs->debounce); +__raw_writel (bank->context.debounce_en, + bank->base + bank->regs->debounce_en); + } }#else #define omap_gpio_suspend NULL
Signature · 1 line
1.7.0.4
PATCH v7 23/26 gpio/omap: enable irq at the end of all configuration in restore
In reply to Tarun Kanti DebBarmaFrom: Nishanth Menon <[email protected]>
Setup the interrupt enable registers only after we have configured the required edge and required configurations, not before, to prevent spurious events as part of restore routine.
--- drivers/gpio/gpio-omap.c | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-)
drivers/gpio/gpio-omap.c +5 -4
@@ -1310,10 +1310,6 @@ void omap2_gpio_resume_after_idle(void)static void omap_gpio_restore_context (struct gpio_bank *bank) { -__raw_writel (bank->context.irqenable1, - bank->base + bank->regs->irqenable); -__raw_writel (bank->context.irqenable2, - bank->base + bank->regs->irqenable2);__raw_writel (bank->context.wake_en, bank->base + bank->regs->wkup_en);__raw_writel (bank->context.ctrl, bank->base + bank->regs->ctrl);
@@ -1333,6 +1329,11 @@ static void omap_gpio_restore_context(struct gpio_bank *bank)__raw_writel (bank->context.debounce_en, bank->base + bank->regs->debounce_en); } + +__raw_writel (bank->context.irqenable1, + bank->base + bank->regs->irqenable); +__raw_writel (bank->context.irqenable2, + bank->base + bank->regs->irqenable2); }#else #define omap_gpio_suspend NULL
Signature · 1 line
1.7.0.4
PATCH v7 24/26 gpio/omap: restore OE only after setting the output level
In reply to Tarun Kanti DebBarmaFrom: Nishanth Menon <[email protected]>
Setup the dataout register before restoring OE. This is to make sure that we have valid data in dataout register which would be made available in output pins as soon as OE is enabled. Else, there is risk of unknown data getting out into gpio pins.
--- drivers/gpio/gpio-omap.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/gpio/gpio-omap.c +2 -1
@@ -1313,7 +1313,6 @@ static void omap_gpio_restore_context(struct gpio_bank *bank)__raw_writel (bank->context.wake_en, bank->base + bank->regs->wkup_en);__raw_writel (bank->context.ctrl, bank->base + bank->regs->ctrl); -__raw_writel (bank->context.oe, bank->base + bank->regs->direction);__raw_writel (bank->context.leveldetect0, bank->base + bank->regs->leveldetect0); __raw_writel(bank->context.leveldetect1,
@@ -1323,6 +1322,8 @@ static void omap_gpio_restore_context(struct gpio_bank *bank)__raw_writel (bank->context.fallingdetect, bank->base + bank->regs->fallingdetect);__raw_writel (bank->context.dataout, bank->base + bank->regs->dataout); +__raw_writel (bank->context.oe, bank->base + bank->regs->direction); +if (bank->dbck_enable_mask) {__raw_writel (bank->context.debounce, bank->base + bank->regs->debounce);
Signature · 1 line
1.7.0.4
PATCH v7 25/26 gpio/omap: handle set_dataout reg capable IP on restore
In reply to Tarun Kanti DebBarmaFrom: Nishanth Menon <[email protected]>
GPIO IP revisions such as those used in OMAP4 have a set_dataout while the previous revisions used a single dataout register. Depending on what is available restore the dataout settings to the right register.
--- drivers/gpio/gpio-omap.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)
drivers/gpio/gpio-omap.c +7 -2
@@ -1048,7 +1048,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) bank->get_context_loss_count = pdata->get_context_loss_count; bank->regs = pdata->regs; -if (bank->regs->set_dataout && bank->regs->clr_dataout) +if (bank->regs->set_dataout) bank->set_dataout = _set_gpio_dataout_reg;else bank->set_dataout = _set_gpio_dataout_mask;
@@ -1321,7 +1321,12 @@ static void omap_gpio_restore_context(struct gpio_bank *bank) bank->base + bank->regs->risingdetect);__raw_writel (bank->context.fallingdetect, bank->base + bank->regs->fallingdetect); -__raw_writel (bank->context.dataout, bank->base + bank->regs->dataout); +if (bank->regs->set_dataout) +__raw_writel (bank->context.dataout, + bank->base + bank->regs->set_dataout); +else +__raw_writel (bank->context.dataout, + bank->base + bank->regs->dataout);__raw_writel (bank->context.oe, bank->base + bank->regs->direction);if (bank->dbck_enable_mask) {
Signature · 1 line
1.7.0.4
PATCH v7 26/26 gpio/omap: add dbclk aliases for all gpio modules
In reply to Tarun Kanti DebBarmaUnless the dbclk aliases are assigned, clk_get(bank->dev, "dbclk") would not fetch the associated clock handle. As a result, we would not be able to turn on/off the debounce clock. This was preventing the gpio modules going to low power mode whenever dbclk is enabled.
--- arch/arm/mach-omap2/clock3xxx_data.c | 6 ++++++ arch/arm/mach-omap2/clock44xx_data.c | 6 ++++++ 2 files changed, 12 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/clock3xxx_data.c +6 -0
@@ -3462,6 +3462,12 @@ static struct omap_clk omap3xxx_clks[] = {CLK ("musb-am35x" ,"fck" , &hsotgusb_fck_am35xx,CK_AM35XX ),CLK (NULL ,"hecc_ck" , &hecc_ck,CK_AM35XX ),CLK (NULL ,"uart4_ick" , &uart4_ick_am35xx,CK_AM35XX ), +CLK ("omap_gpio.1" ,"dbclk" , &gpio1_dbck,CK_3XXX ), +CLK ("omap_gpio.2" ,"dbclk" , &gpio2_dbck,CK_3XXX ), +CLK ("omap_gpio.3" ,"dbclk" , &gpio3_dbck,CK_3XXX ), +CLK ("omap_gpio.4" ,"dbclk" , &gpio4_dbck,CK_3XXX ), +CLK ("omap_gpio.5" ,"dbclk" , &gpio5_dbck,CK_3XXX ), + CLK("omap_gpio.6", "dbclk", &gpio6_dbck, CK_3XXX), };
arch/arm/mach-omap2/clock44xx_data.c +6 -0
@@ -3363,6 +3363,12 @@ static struct omap_clk omap44xx_clks[] = {CLK ("usbhs-omap.0" ,"usbhost_ick" , &dummy_ck,CK_443X ),CLK ("usbhs-omap.0" ,"usbtll_fck" , &dummy_ck,CK_443X ),CLK ("omap_wdt" ,"ick" , &dummy_ck,CK_443X ), +CLK ("omap_gpio.1" ,"dbclk" , &gpio1_dbclk,CK_443X ), +CLK ("omap_gpio.2" ,"dbclk" , &gpio2_dbclk,CK_443X ), +CLK ("omap_gpio.3" ,"dbclk" , &gpio3_dbclk,CK_443X ), +CLK ("omap_gpio.4" ,"dbclk" , &gpio4_dbclk,CK_443X ), +CLK ("omap_gpio.5" ,"dbclk" , &gpio5_dbclk,CK_443X ), + CLK("omap_gpio.6", "dbclk", &gpio6_dbclk, CK_443X), };int __init omap4xxx_clk_init (void )
Signature · 1 line
1.7.0.4
Tony Lindgren
maintainerPATCH v7 26/26 gpio/omap: add dbclk aliases for all gpio modules
Quoted 6 lines · Tarun Kanti DebBarma
Unless the dbclk aliases are assigned,
clk_get(bank->dev, "dbclk")would not fetch the associated clock handle. As a result, we would not be able to turn on/off the debounce clock. This was preventing the gpio modules going to low power mode whenever dbclk is enabled.Signed-off-by Tarun Kanti DebBarma <[email protected]>
Looks OK to me, Paul should ack this one also:
Quoted 42 lines
--- arch/arm/mach-omap2/clock3xxx_data.c | 6 ++++++ arch/arm/mach-omap2/clock44xx_data.c | 6 ++++++ 2 files changed, 12 insertions(+), 0 deletions(-)arch/arm/mach-omap2/clock3xxx_data.c +6
-0@@ -3462,6 +3462,12 @@ static struct omap_clk omap3xxx_clks[] = {CLK ("musb-am35x" ,"fck" , &hsotgusb_fck_am35xx,CK_AM35XX ),CLK (NULL ,"hecc_ck" , &hecc_ck,CK_AM35XX ),CLK (NULL ,"uart4_ick" , &uart4_ick_am35xx,CK_AM35XX ), +CLK ("omap_gpio.1" ,"dbclk" , &gpio1_dbck,CK_3XXX ), +CLK ("omap_gpio.2" ,"dbclk" , &gpio2_dbck,CK_3XXX ), +CLK ("omap_gpio.3" ,"dbclk" , &gpio3_dbck,CK_3XXX ), +CLK ("omap_gpio.4" ,"dbclk" , &gpio4_dbck,CK_3XXX ), +CLK ("omap_gpio.5" ,"dbclk" , &gpio5_dbck,CK_3XXX ), + CLK("omap_gpio.6", "dbclk", &gpio6_dbck, CK_3XXX), };arch/arm/mach-omap2/clock44xx_data.c +6
-0@@ -3363,6 +3363,12 @@ static struct omap_clk omap44xx_clks[] = {CLK ("usbhs-omap.0" ,"usbhost_ick" , &dummy_ck,CK_443X ),CLK ("usbhs-omap.0" ,"usbtll_fck" , &dummy_ck,CK_443X ),CLK ("omap_wdt" ,"ick" , &dummy_ck,CK_443X ), +CLK ("omap_gpio.1" ,"dbclk" , &gpio1_dbclk,CK_443X ), +CLK ("omap_gpio.2" ,"dbclk" , &gpio2_dbclk,CK_443X ), +CLK ("omap_gpio.3" ,"dbclk" , &gpio3_dbclk,CK_443X ), +CLK ("omap_gpio.4" ,"dbclk" , &gpio4_dbclk,CK_443X ), +CLK ("omap_gpio.5" ,"dbclk" , &gpio5_dbclk,CK_443X ), + CLK("omap_gpio.6", "dbclk", &gpio6_dbclk, CK_443X), };int __init omap4xxx_clk_init (void )Signature · 1 line
1.7.0.4
v7 cover gpio/omap: driver cleanup and fixes
In reply to Tarun Kanti DebBarmaQuoted 9 lines · Tarun Kanti DebBarma
This series is continuation of cleanup of OMAP GPIO driver and fixes. The cleanup include getting rid of cpu_is_* checks wherever possible, use of
gpio_banklist instead of static array, use of unique platform specific value associated data member to OMAP platforms to avoid cpu_is_* checks. The series also include PM runtime support.*Baseline:
git://gitorious.org/khilman/linux-omap-pm.git
Branch: for_3.2/gpio-cleanup
Commit: 8323374
Thanks Tony for ack'ing the patches.
Kevin,
Since Tony's has acked the patches, can you please pull them? Thanks.
--
Tarun
Quoted 211 lines
Test Details:
- Compile tested foromap1_defconfigandomap2plus_defconfig.
- OMAP1710-H3: Bootup test.
- OMAP2430/SDP, OMAP3430/SDP, OMAP4430/SDP: Functional testing.
- PM Testing on OMAP3430-SDP: retention,off_mode,system_wide?suspend and gpio wakeup.v7:
- Usepm_runtime_put()instead ofpm_runtime_put_sync_suspend()- Keep *_runtime_get/put*() ?outside spinlock
- Remove additional checking of conditions in
_restore_context()?From:
?if (bank->regs->set_dataout&&bank->regs->clear_dataout) ?...
?To:
?if (bank->regs->set_dataout)
?...- Use
SET_RUNTIME_PM_OPSandSET_SYSTEM_SLEEP_PM_OPSmacros- In [PATCH 19/25] gpio/omap: cleanup
prepare_for_idleandresume_after_idle, ?protect the bank data elements and register access using spinlock in ?runtime_suspend/resume() callbacks.
?This is because these callbacks run with interrupts enabled.- Add dbclk aliases for all GPIO modules. Without this, GPIO modules were not ?getting the correct clock handle to enable/disable debounec clock.
- Fix log comments on the following patches:
?[PATCH 19/25] gpio/omap: cleanupprepare_for_idleandresume_after_idle?[PATCH 20/25] gpio/omap: skip operations in runtime callbacks ?[PATCH 24/25] gpio/omap: restore OE only after setting the output levelv6:
- Save and restore debounce registers for proper driver operation.
- Restore interrupt enable after all configuration to avoid spurious interrupts.
- Restore dataout register before oe register.
- Restore dataout intodataout_setor dataout based upon the OMAP version.
- Change register name fromwkup_statustowkup_en.
- Remove wrapper aroundomap_pm_get_dev_context_loss_count(). Use it directly. ?Also, changed the signature ofget_context_loss_countin pdata and bank structure ?from int to u32.- Use 'context' instead of 'ctx' for clarity wherever it is used.
- Merged two patches into one which are related tobank_is_mpuio()modification.
- Use shift operator instead of following:
+ ? ? ? .irqctrl ? ? ? ?=OMAP_MPUIO_GPIO_INT_EDGE/ 2,- Remove redundant check from the following
+ ? ? ? if (bank_is_mpuio(bank)) {
+ ? ? ? ? ? ? ? if (bank->regs->wkup_status) <--- redundant check
+ ? ? ? ? ? ? ? ? ? ? ?mpuio_init(bank);- Change subject of following patch
?[PATCH v5 15/22] gpio/omap: use readl inirq_handlerfor all access ?into
?[PATCH 14/25] gpio/omap: remove unnecessary bit-masking for read access- Fix multi-line comments in
?[PATCH v5 20/22] gpio/omap: cleanupprepare_for_idleandresume_after_idlev5:
- Reduce runtime callback overhead when *_get/put_sync() called fromprobe()?and *_gpio_request/free().- Dynamic context save within functions where context is modified instead of ?saving all context within a common function.
- Removed call to
mpuio_init()fromomap_gpio_mod_init(). Both the functions are ?called once during initialization in*_gpio_probe().
?Call toomap_gpio_mod_init()has been removed fromomap_gpio_request()on the ?first access to gpio bank. One time initialization looks sufficient.- In
*_gpio_irq_handler()use*_put_sync_suspend()instead of*_put_sync().- Removed hardcoding of OMAP16xx sysconfig register value and instead defined an ?associated constant.
- Removed
*_get_sync()call from*_gpio_suspend()and*_put_sync()call from ?*_gpio_resume(). They got wrongly slipped into the code.- Removed following redundant zero allocated initialization from
mach-omap2/gpio.c
+ ? ? ?pdata->regs->irqctrl= 0;
+ ? ? ?pdata->regs->edgectrl1= 0;
+ ? ? ?pdata->regs->edgectrl2= 0;- Removed following redundant code in
gpio-omap.c?-#definebank_is_mpuio(bank)?((bank)->method ==METHOD_MPUIO)v4:
- since all accesses to registers are 4-byte aligned, removing special ?checks and handling of 16 and 32-bit wide bank registers and instead ?use 32-bit read/write access consistently.- redundant usage of
MOD_REG_BIThas been corrected and replaced with ?_gpio_rmw().-
omap_gpio_mod_init()function has been simplified further using_gpio_rmw().- sysconfig register offset specific to omap16xx has been removed along ?with its usage.
- additional logic to skip from suspend/resume:
?if (!bank->regs->wkup_status || !bank->suspend_wakeup) ? ? ? ?return 0;
?if (!bank->regs->wkup_status || !bank->saved_wakeup) ? ? ? ?return 0;
- separated mpuio related changes into a different patch from the patch where ?wakeup status register related changes are done.
- Incorrect replacement of !cpu_class_is_omap2() in
gpio_irq_type()?corrected:
+ ? ? ? if (!bank->regs->leveldetect0 &&
+ ? ? ? ? ? ? ? (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))) ? ? ? ? ? ? ? ?return-EINVAL;v3:
- Avoid use ofwkup_setandwkup_clearregisters. Instead usewkup_status?register for all platforms. This is because on OMAP4 it is recommended ?not to use them.- Remove duplicate code in
omap_gpio_mod_init()for handling the same for ?32-bit and 16-bit GPIO bank widths. This is accomplished by having two ?functions to handle each case while assiging a common function pointer ?during initialization.- Remove OMAP16xx specific one time initialization from
omap_gpio_mod_init(). ?Move it insideomap16xx_gpio_init().- Avoid usage of
USHRT_MAXto indicate undefined values. Use 0 instead.- In omap_gpio_suspend()/resume() functions remove code that checks ?if the feature is supported. Instead, assign these functions to ?struct platform_driver's suspend & resume function pointers for those ?OMAP platforms whcih support this feature.
- Remove '
suspend_support' flag because it is redundant. Instead use ?wkup_* registers to decode the same information.- Restore context also when we don't know if the context is lost.
- Make
omap_gpio_save_context()andomap_gpio_restore_context()?static.v2:
- Do special handling of non-wakeup GPIOs only on OMAP2420. Avoid this ?handling on OMAP3430.
- Isolate cleanups and fixes into separate set of patches. Keep the cleanup ?first followed by the fixes.
- Avoid callingomap_gpio_get_context_loss()directly and instead call it ?through function pointer in pdata initialized during init.
-workaround_enabledflag is not longer needed and is removed.
- Callpwrdm_post_transition()before callingomap_gpio_resume_after_idle().
- Inomap2_gpio_resume_after_idle()do context restore before handling ?workaround.
- Use PM runtime framework.
- Modify register offset names to :wkup_status,wkup_clear,wkup_set. ?Also use 'base + offset' for readibility in all relevant places.
- Remove unwanted messages from commit section like TODO, etc.Charulatha V (10):
?gpio/omap: remove dependency ongpio_bank_count?gpio/omap: use flag to identify wakeup domain ?gpio/omap: makegpio_contextpart ofgpio_bankstructure ?gpio/omap: fixpwrdm_post_transitioncall sequence ?gpio/omap: handle save/restore context in GPIO driver ?gpio/omap: make non-wakeup GPIO part of pdata ?gpio/omap: avoid cpu checks during module ena/disable ?gpio/omap: use pinctrl offset instead of macro ?gpio/omap: removebank->method& METHOD_* macros ?gpio/omap: fix bankwidth for OMAP7xx MPUIONishanth Menon (4):
?gpio/omap: save and restore debounce registers ?gpio/omap: enable irq at the end of all configuration in restore ?gpio/omap: restore OE only after setting the output level ?gpio/omap: handleset_dataoutreg capable IP on restoreTarun Kanti DebBarma (12):
?gpio/omap: further cleanup usingwkup_enregister ?gpio/omap: use level/edge detect reg offsets ?gpio/omap: remove hardcoded offsets in context save/restore ?gpio/omap: cleanupset_gpio_triggeringfunction ?gpio/omap: cleanupomap_gpio_mod_initfunction ?gpio/omap: remove unnecessary bit-masking for read access ?gpio/omap: use pm-runtime framework
?gpio/omap: optimize suspend and resume functions ?gpio/omap: cleanupprepare_for_idleandresume_after_idle?gpio/omap: skip operations in runtime callbacks ?gpio/omap: removeomap_gpio_save_contextoverhead ?gpio/omap: add dbclk aliases for all gpio modules?arch/arm/mach-omap1/gpio15xx.c ? ? ? ? | ? ?7 +- ?arch/arm/mach-omap1/gpio16xx.c ? ? ? ? | ? 47 ++- ?arch/arm/mach-omap1/gpio7xx.c ? ? ? ? ?| ? 14 +- ?arch/arm/mach-omap2/clock3xxx_data.c ? | ? ?6 + ?arch/arm/mach-omap2/clock44xx_data.c ? | ? ?6 + ?arch/arm/mach-omap2/gpio.c ? ? ? ? ? ? | ? 36 +- ?arch/arm/mach-omap2/pm34xx.c ? ? ? ? ? | ? 21 +- ?arch/arm/plat-omap/include/plat/gpio.h | ? 29 +- ?drivers/gpio/gpio-omap.c ? ? ? ? ? ? ? | 1051 +++++++++++++-------------------?9 files changed, 524 insertions(+), 693 deletions(-)
v7 cover gpio/omap: driver cleanup and fixes
Hi Tarun,
Quoted 8 lines · Tarun Kanti
Quoted 6 lines · Tarun Kanti DebBarma
This series is continuation of cleanup of OMAP GPIO driver and fixes. The cleanup include getting rid of cpu_is_* checks wherever possible, use of
gpio_banklist instead of static array, use of unique platform specific value associated data member to OMAP platforms to avoid cpu_is_* checks. The series also include PM runtime support.*
Quoted 6 lines
Quoted 3 lines
Baseline:
git://gitorious.org/khilman/linux-omap-pm.git
Branch: for_3.2/gpio-cleanup
Commit: 8323374Thanks Tony for ack'ing the patches.
Kevin,
Since Tony's has acked the patches, can you please pull them?
Before merging, I still need to review and test this version, and I *might* still get to it this week.
Based on the dbclk aliases you added, I assume this has now been tested on platforms using some GPIOs with debounce enabled?
Kevin
v7 cover gpio/omap: driver cleanup and fixes
[...]
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
This series is continuation of cleanup of OMAP GPIO driver and fixes. The cleanup include getting rid of cpu_is_* checks wherever possible, use of
gpio_banklist instead of static array, use of unique platform specific value associated data member to OMAP platforms to avoid cpu_is_* checks. The series also include PM runtime support.*Baseline:
git://gitorious.org/khilman/linux-omap-pm.git
Branch: for_3.2/gpio-cleanup
Commit: 8323374
Quoted 6 lines
Quoted 3 lines
Thanks Tony for ack'ing the patches.
Kevin,
Since Tony's has acked the patches, can you please pull them?Before merging, I still need to review and test this version, and I *might* still get to it this week.
That's fine. Thanks.
Quoted 3 lines
Based on the dbclk aliases you added, I assume this has now been tested on platforms using some GPIOs with debounce enabled?
I have replicated gpio_debounce() code within *_gpio_mod_init() whereby _set_gpio_debounce() is called to enable debounce.
After this, confirmed system going to off-mode through the CPU IDLE path. --
Tarun
Quoted 3 lines
Kevin
v7 cover gpio/omap: driver cleanup and fixes
In reply to Tarun Kanti DebBarmaQuoted 5 lines · Tarun Kanti DebBarma
This series is continuation of cleanup of OMAP GPIO driver and fixes. The cleanup include getting rid of cpu_is_* checks wherever possible, use of
gpio_banklist instead of static array, use of unique platform specific value associated data member to OMAP platforms to avoid cpu_is_* checks. The series also include PM runtime support.*
PER is still not hitting retention for me on 34xx/n900 when GPIOs have debounce enabled. Disabling debounce in the board file makes it work.
[...]
Quoted 2 lines
- Add dbclk aliases for all GPIO modules. Without this, GPIO modules were not getting the correct clock handle to enable/disable debounec clock.
This isn't right. hwmod should already be adding aliases for the optional clocks.
After debugging this myself a bit, here's what I think may be going on. This may not be the only problem but here's at least one of them.
First, debounce clocks are disabled in the runtime_suspend callback.
When a GPIO is freed and it's the last one in the bank, bank->mod_usage goes to zero.
After that, pm_runtime_put_sync() is called, which will trigger the driver's ->runtime_suspend callback. The ->runtime_suspend() callback checks bank->mod_usage as well, and if zero, doesn't do anything (notably, it doesn't disable debounce clocks.)
Kevin
v7 cover gpio/omap: driver cleanup and fixes
[...]
Quoted 5 lines
After debugging this myself a bit, here's what I think may be going on. This may not be the only problem but here's at least one of them.
First, debounce clocks are disabled in the
runtime_suspendcallback.
Quoted 7 lines
When a GPIO is freed and it's the last one in the bank,
bank->mod_usagegoes to zero.After that,
pm_runtime_put_sync()is called, which will trigger the driver's ->runtime_suspend callback. ?The ->runtime_suspend() callback checksbank->mod_usageas well, and if zero, doesn't do anything (notably, it doesn't disable debounce clocks.)
I need some clarification in reproducing/testing the fix on OMAP3430SDP. The first thing I am trying to verify is the code flow of suspend.
1) With no debounce clock enabled, when I enable UART timeouts, I automatically see
system going to retention. That is I don't have to type echo mem > /sys/power/state
echo 5 > /sys/devices/platform/omap/omap_uart.0/sleep_timeout echo 5 > /sys/devices/platform/omap/omap_uart.1/sleep_timeout echo 5 > /sys/devices/platform/omap/omap_uart.2/sleep_timeout
2) I am do not see the print in omap_gpio_suspend/resume(), but I see the print in
*_prepare_for_idle()/*_resume_after_idle().
Folks testing on Tablet2 platform said there is dedicated button to suspend/resume.
Is there something equivalent?
--
Tarun
v7 cover gpio/omap: driver cleanup and fixes
Quoted 24 lines · Tarun Kanti
[...]
Quoted 5 lines
After debugging this myself a bit, here's what I think may be going on. This may not be the only problem but here's at least one of them.
First, debounce clocks are disabled in the
runtime_suspendcallback.Quoted 7 lines
When a GPIO is freed and it's the last one in the bank,
bank->mod_usagegoes to zero.After that,
pm_runtime_put_sync()is called, which will trigger the driver's ->runtime_suspend callback. The ->runtime_suspend() callback checksbank->mod_usageas well, and if zero, doesn't do anything (notably, it doesn't disable debounce clocks.)I need some clarification in reproducing/testing the fix on OMAP3430SDP. The first thing I am trying to verify is the code flow of suspend.
1) With no debounce clock enabled, when I enable UART timeouts, I automatically see
system going to retention. That is I don't have to type echo mem >/sys/power/state
echo 5 >/sys/devices/platform/omap/omap_uart.0/sleep_timeoutecho 5 >/sys/devices/platform/omap/omap_uart.1/sleep_timeoutecho 5 >/sys/devices/platform/omap/omap_uart.2/sleep_timeout
Quoted 4 lines
2) I am do not see the print in omap_gpio_suspend/resume(), but I see the print in
*_prepare_for_idle()/*_resume_after_idle().
Hmmm,
This is mostly happening because you are missing a below fix from Kevin in the branch you are testing with.
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg54927.html {OMAP: omap_device: fix !CONFIG_SUSPEND case in _noirq handlers}
If you rebase, your branch against 3.1-rc6, you should already have this fix. Commit {126caf1376e7}
Regards
Santosh
v7 cover gpio/omap: driver cleanup and fixes
Santosh, Kevin,
[...]
Quoted 21 lines
Quoted 15 lines
Quoted 4 lines
After that,
pm_runtime_put_sync()is called, which will trigger the driver's ->runtime_suspend callback. ?The ->runtime_suspend() callback checksbank->mod_usageas well, and if zero, doesn't do anything (notably, it doesn't disable debounce clocks.)I need some clarification in reproducing/testing the fix on OMAP3430SDP. The first thing I am trying to verify is the code flow of suspend.
1) With no debounce clock enabled, when I enable UART timeouts, I automatically see
system going to retention. That is I don't have to type echo mem >/sys/power/state
echo 5 >/sys/devices/platform/omap/omap_uart.0/sleep_timeoutecho 5 >/sys/devices/platform/omap/omap_uart.1/sleep_timeoutecho 5 >/sys/devices/platform/omap/omap_uart.2/sleep_timeoutQuoted 4 lines
2) I am do not see the print in omap_gpio_suspend/resume(), but I see the print in
*_prepare_for_idle()/*_resume_after_idle().Hmmm,
Quoted 8 lines
This is mostly happening because you are missing a below fix from Kevin in the branch you are testing with.
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg54927.html {OMAP:
omap_device: fix !CONFIG_SUSPEND case in_noirqhandlers}If you rebase, your branch against 3.1-rc6, you should already have this fix. Commit {
126caf1376e7}
Yes, this patch was missing in Kevin's branch and was causing the suspend issue.
As pointed out by Kevin, debounce clock was not getting disabled. In my testing I was somehow grepping CORE power domain instead of PER power domain and hence missed it. The fix for the debounce clock issue is at the end of the email.
- Have re-based the for_3.2/gpio-cleanup branch against 3.1-rc6.
- Dropped [PATCH 26/26] gpio/omap: add dbclk aliases for all gpio modules as suggested by Kevin since it's already taken care by hwmod.
- Added the debounce clock fix in the end.
With above, PER is hitting low power state in Suspend and Idle path.
Have pushed a branch at below URL with mentioned changes.git://gitorious.org/omap-sw-develoment/linux-omap-dev.git
for_3.2/kevin/gpio-cleanup
Regards,
Tarun
v7 cover gpio/omap: driver cleanup and fixes
Quoted 35 lines · Tarun Kanti
Santosh, Kevin,
[...]
Quoted 21 lines
Quoted 15 lines
Quoted 4 lines
After that,
pm_runtime_put_sync()is called, which will trigger the driver's ->runtime_suspend callback. ?The ->runtime_suspend() callback checksbank->mod_usageas well, and if zero, doesn't do anything (notably, it doesn't disable debounce clocks.)I need some clarification in reproducing/testing the fix on OMAP3430SDP. The first thing I am trying to verify is the code flow of suspend.
1) With no debounce clock enabled, when I enable UART timeouts, I automatically see
system going to retention. That is I don't have to type echo mem >/sys/power/state
echo 5 >/sys/devices/platform/omap/omap_uart.0/sleep_timeoutecho 5 >/sys/devices/platform/omap/omap_uart.1/sleep_timeoutecho 5 >/sys/devices/platform/omap/omap_uart.2/sleep_timeoutQuoted 4 lines
2) I am do not see the print in omap_gpio_suspend/resume(), but I see the print in
*_prepare_for_idle()/*_resume_after_idle().Hmmm,
Quoted 8 lines
This is mostly happening because you are missing a below fix from Kevin in the branch you are testing with.
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg54927.html {OMAP:
omap_device: fix !CONFIG_SUSPEND case in_noirqhandlers}If you rebase, your branch against 3.1-rc6, you should already have this fix. Commit {
126caf1376e7}Yes, this patch was missing in Kevin's branch and was causing the suspend issue.
Quoted 6 lines
As pointed out by Kevin, debounce clock was not getting disabled. In my testing I was somehow grepping CORE power domain instead of PER power domain and hence missed it. The fix for the debounce clock issue is at the end of the email.
- Have re-based the for_3.2/gpio-cleanup branch against 3.1-rc6.
Not needed. Just merge with v3.1-rc6 when testing.
Quoted 2 lines
- Dropped [PATCH 26/26] gpio/omap: add dbclk aliases for all gpio modules as suggested by Kevin since it's already taken care by hwmod.
good
Quoted 1 line
- Added the debounce clock fix in the end.
Thanks. Glad you found and fixed it.
Rather than add this patch as a fix at the end, I prefer if the problem is fixed in the original patches that added/created the problem.
Kevin
Quoted 78 lines
With above, PER is hitting low power state in Suspend and Idle path.
Have pushed a branch at below URL with mentioned changes.
git://gitorious.org/omap-sw-develoment/linux-omap-dev.git
for_3.2/kevin/gpio-cleanupRegards,
TarunFrom
5d9a97197ea5426fc79b7a47dd0fd9c6b6ebbbbaMon Sep 17 00:00:00 2001
From: Tarun Kanti DebBarma <[email protected]>
Date: Sat, 24 Sep 2011 13:32:32 +0530
Subject: [PATCH] gpio/omap: fix debounce clock handlingGPIO debounce clock can gate the PER power domain transition and needs to be disabled in GPIO driver suspend.
The debounce clock is not getting disabled in
runtime_suspendcallback because of an un-necessarybank->mod_usagecheck. In omap_gpio_suspend/resume too, there is no need to do any operation if the gpio bank is not used.Remove the un-necessary
bank->mod_usagecheck from suspend callbacks.Thanks to Kevin Hilman for pointing out this issue.
Signed-off-by Tarun Kanti DebBarma <[email protected]>Cc Kevin Hilman <[email protected]>Cc Santosh Shilimkar <[email protected]>--- drivers/gpio/gpio-omap.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-)drivers/gpio/gpio-omap.c +6
-6@@ -1107,6 +1107,9 @@ static int omap_gpio_suspend(struct device *dev)void __iomem *wake_status;unsigned long flags; +if (!bank->mod_usage || !bank->loses_context) +return 0 ; +if (!bank->regs->wkup_en || !bank->suspend_wakeup)return 0 ;@@ -1128,6 +1131,9 @@ static int omap_gpio_resume(struct device *dev)void __iomem *base = bank->base;unsigned long flags; +if (!bank->mod_usage || !bank->loses_context) +return 0 ; +if (!bank->regs->wkup_en || !bank->saved_wakeup)return 0 ;@@ -1151,9 +1157,6 @@ static int omap_gpio_runtime_suspend(struct device *dev)int j;unsigned long flags; -if (!bank->mod_usage) -return 0 ; -spin_lock_irqsave (&bank->lock, flags);/* * If going to OFF, remove triggering for all @@ -1199,9 +1202,6 @@ static int omap_gpio_runtime_resume(struct device *dev)int j;unsigned long flags; -if (!bank->mod_usage) -return 0 ; -spin_lock_irqsave (&bank->lock, flags);for (j =0 ; j <hweight_long (bank->dbck_enable_mask); j++)clk_enable (bank->dbck);
v7 cover gpio/omap: driver cleanup and fixes
[...]
Quoted 6 lines
Quoted 1 line
- Added the debounce clock fix in the end.
Thanks. ?Glad you found and fixed it.
Rather than add this patch as a fix at the end, I prefer if the problem is fixed in the original patches that added/created the problem.
Sure. I will put the changes in respective patches. --
Tarun
[...]
v7 cover gpio/omap: driver cleanup and fixes
Quoted 8 lines · Tarun Kanti
[...]
Quoted 6 lines
Quoted 1 line
- Added the debounce clock fix in the end.
Thanks. ?Glad you found and fixed it.
Rather than add this patch as a fix at the end, I prefer if the problem is fixed in the original patches that added/created the problem.
Sure. I will put the changes in respective patches.
Also, when you rebase, please be sure to add the Acked-by from Tony to the various patches he ack'd.
Thanks,
Kevin
v7 cover gpio/omap: driver cleanup and fixes
In reply to DebBarma, Tarun Kanti"DebBarma, Tarun Kanti" <[email protected]> writes:
[...]
Quoted 9 lines
As pointed out by Kevin, debounce clock was not getting disabled. In my testing I was somehow grepping CORE power domain instead of PER power domain and hence missed it. The fix for the debounce clock issue is at the end of the email.
- Have re-based the for_3.2/gpio-cleanup branch against 3.1-rc6.
- Dropped [PATCH 26/26] gpio/omap: add dbclk aliases for all gpio modules as suggested by Kevin since it's already taken care by hwmod.
- Added the debounce clock fix in the end.
That debounce fix definitely makes things look better, but it's not solving the problem...
Quoted 5 lines
With above, PER is hitting low power state in Suspend and Idle path.
Have pushed a branch at below URL with mentioned changes.
git://gitorious.org/omap-sw-develoment/linux-omap-dev.git
for_3.2/kevin/gpio-cleanup
I tested your branch on my 3430/n900 and PER is still not hitting retention. Setting all debounce values in the board file to zero using the patch below[1] makes PER hit retention again.
Assuming you don't have an n900 to test with, I suggest you just copy the GPIO keys init from board-rx51-peripherals.c (or some of it) into the board file you are testing with.
The problem is most likely be related to having more than one GPIO in a bank with debounce enabled, or more than one bank with GPIOs enabled and your current test is not be catching it.
Kevin
[1]
arch/arm/mach-omap2/board-rx51-peripherals.c +1 -1
@@ -207,7 +207,7 @@ static void __init rx51_charger_init(void)#define RX51_GPIO_LOCK_BUTTON 113#define RX51_GPIO_PROXIMITY 89 -#define RX51_GPIO_DEBOUNCE_TIMEOUT 10 +#define RX51_GPIO_DEBOUNCE_TIMEOUT 0static struct gpio_keys_button rx51_gpio_keys[] = { {
v7 cover gpio/omap: driver cleanup and fixes
Quoted 27 lines · Kevin Hilman
"DebBarma, Tarun Kanti" <[email protected]> writes:
[...]
Quoted 9 lines
As pointed out by Kevin, debounce clock was not getting disabled. In my testing I was somehow grepping CORE power domain instead of PER power domain and hence missed it. The fix for the debounce clock issue is at the end of the email.
- Have re-based the for_3.2/gpio-cleanup branch against 3.1-rc6.
- Dropped [PATCH 26/26] gpio/omap: add dbclk aliases for all gpio modules as suggested by Kevin since it's already taken care by hwmod.
- Added the debounce clock fix in the end.That debounce fix definitely makes things look better, but it's not solving the problem...
Quoted 5 lines
With above, PER is hitting low power state in Suspend and Idle path.
Have pushed a branch at below URL with mentioned changes.
git://gitorious.org/omap-sw-develoment/linux-omap-dev.git
for_3.2/kevin/gpio-cleanupI tested your branch on my 3430/n900 and PER is still not hitting retention. ?Setting all debounce values in the board file to zero using the patch below[1] makes PER hit retention again.
Quoted 8 lines
Assuming you don't have an n900 to test with, I suggest you just copy the GPIO keys init from
board-rx51-peripherals.c(or some of it) into the board file you are testing with.The problem is most likely be related to having more than one GPIO in a bank with debounce enabled, or more than one bank with GPIOs enabled and your current test is not be catching it.
As per commit c8c9fda506945 {OMAP: PM: disable idle on suspend for GPIO and UART}, the gpio code needs to be fixed once GPIO driver is run-time adapted. So I did below change as per the commit and now suspend is working fine even with board files change for debounce functionality. So the last series
+ below one
line change is whats needed for suspend to work. Can you please see if this does help on your board ?
I am not finished my idle testing yet but just reporting the suspend results.
arch/arm/mach-omap2/gpio.c +0 -0
@@ -148,8 +148,6 @@ static int omap2_gpio_dev_init(struct omap_hwmod
*oh, void *unused)
return PTR_ERR(od);
}- omap_device_disable_idle_on_suspend(od);
-
return 0;
}
--
Regards
Tarun
v7 cover gpio/omap: driver cleanup and fixes
Quoted 32 lines · Tarun Kanti
Quoted 31 lines · Kevin Hilman
"DebBarma, Tarun Kanti" <[email protected]> writes:
[...]
Quoted 9 lines
As pointed out by Kevin, debounce clock was not getting disabled. In my testing I was somehow grepping CORE power domain instead of PER power domain and hence missed it. The fix for the debounce clock issue is at the end of the email.
- Have re-based the for_3.2/gpio-cleanup branch against 3.1-rc6.
- Dropped [PATCH 26/26] gpio/omap: add dbclk aliases for all gpio modules as suggested by Kevin since it's already taken care by hwmod.
- Added the debounce clock fix in the end.That debounce fix definitely makes things look better, but it's not solving the problem...
Quoted 5 lines
With above, PER is hitting low power state in Suspend and Idle path.
Have pushed a branch at below URL with mentioned changes.
git://gitorious.org/omap-sw-develoment/linux-omap-dev.git
for_3.2/kevin/gpio-cleanupI tested your branch on my 3430/n900 and PER is still not hitting retention. ?Setting all debounce values in the board file to zero using the patch below[1] makes PER hit retention again.
Assuming you don't have an n900 to test with, I suggest you just copy the GPIO keys init from
board-rx51-peripherals.c(or some of it) into the board file you are testing with.
Quoted 7 lines
Quoted 4 lines
The problem is most likely be related to having more than one GPIO in a bank with debounce enabled, or more than one bank with GPIOs enabled and your current test is not be catching it.
As per commit
c8c9fda506945{OMAP: PM: disable idle on suspend for GPIO and UART}, the gpio code needs to be fixed once GPIO driver is run-time adapted.
Great, good catch.
Quoted 4 lines
So I did below change as per the commit and now suspend is working fine even with board files change for debounce functionality. So the last series + below one line change is whats needed for suspend to work. Can you please see if this does help on your board ?
Yeah, with your patch, PER is hitting retention in suspend on my 3430/n900.
Quoted 2 lines
I am not finished my idle testing yet but just reporting the suspend results.
For me, PER is not hitting retention on idle.
Also, your repost of v7 doesn't included any of the comments I made on it yesterday.
Kevin
v7 cover gpio/omap: driver cleanup and fixes
Quoted 49 lines · Kevin Hilman
Quoted 32 lines · Tarun Kanti
Quoted 31 lines · Kevin Hilman
"DebBarma, Tarun Kanti" <[email protected]> writes:
[...]
Quoted 9 lines
As pointed out by Kevin, debounce clock was not getting disabled. In my testing I was somehow grepping CORE power domain instead of PER power domain and hence missed it. The fix for the debounce clock issue is at the end of the email.
- Have re-based the for_3.2/gpio-cleanup branch against 3.1-rc6.
- Dropped [PATCH 26/26] gpio/omap: add dbclk aliases for all gpio modules as suggested by Kevin since it's already taken care by hwmod.
- Added the debounce clock fix in the end.That debounce fix definitely makes things look better, but it's not solving the problem...
Quoted 5 lines
With above, PER is hitting low power state in Suspend and Idle path.
Have pushed a branch at below URL with mentioned changes.
git://gitorious.org/omap-sw-develoment/linux-omap-dev.git
for_3.2/kevin/gpio-cleanupI tested your branch on my 3430/n900 and PER is still not hitting retention. ?Setting all debounce values in the board file to zero using the patch below[1] makes PER hit retention again.
Assuming you don't have an n900 to test with, I suggest you just copy the GPIO keys init from
board-rx51-peripherals.c(or some of it) into the board file you are testing with.Quoted 7 lines
Quoted 4 lines
The problem is most likely be related to having more than one GPIO in a bank with debounce enabled, or more than one bank with GPIOs enabled and your current test is not be catching it.
As per commit
c8c9fda506945{OMAP: PM: disable idle on suspend for GPIO and UART}, the gpio code needs to be fixed once GPIO driver is run-time adapted.Great, good catch.
Quoted 4 lines
So I did below change as per the commit and now suspend is working fine even with board files change for debounce functionality. So the last series + below one line change is whats needed for suspend to work. Can you please see if this does help on your board ?
Quoted 7 lines
Yeah, with your patch, PER is hitting retention in suspend on my 3430/n900.
Quoted 2 lines
I am not finished my idle testing yet but just reporting the suspend results.
For me, PER is not hitting retention on idle.
I am working on this right now.
Quoted 3 lines
Also, your repost of v7 doesn't included any of the comments I made on it yesterday.
That's right. By the time I received the comments the series was already posted. Anyways, I will include them along with the PER retention issue in the Idle path.
--
Tarun
Quoted 3 lines
Kevin