linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v9 00/25] gpio/omap: driver cleanup and fixes
@ 2012-02-02 17:30 Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count Tarun Kanti DebBarma
                   ` (28 more replies)
  0 siblings, 29 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma

The following changes since commit 62aa2b537c6f5957afd98e29f96897419ed5ebab:
  Linus Torvalds (1):
        Linux 3.3-rc2

are available in the git repository at:
http://gitorious.org/~tarunkanti/omap-sw-develoment/tarunkantis-linux-omap-dev
Branch: for_3.4/gpio_cleanup_fixes_v9

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.

Power Tests
a) OMAP3430SDP
- Modify board-3430sdp.c file to have multiple GPIO modules active
  with debounce timeout enabled.
- Enable CPU-Idle
- Enable UART timeouts
- Enable offmode
- echo mem > /sys/power/state
- Verify retention and offmode count increment

  Used following patches to avoid exception during system suspend:-
  [PATCH RFC 1/2] mtd : Prevent the NULL pointer access
  [PATCH RFC 2/2] mtd : Make the mtd_suspend return 0 if the suspend is not implemented

# echo mem > /sys/power/state
[   47.128021] PM: Syncing filesystems ... done.
[   47.144104] Freezing user space processes ... (elapsed 0.01 seconds) done.
[   47.168243] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) don                                                                                                 e.
[   47.205139] Unable to handle kernel NULL pointer dereference at virtual addre                                                                                                 ss 000000a0
[   47.213317] pgd = deaac000
[   47.216033] [000000a0] *pgd=9e932831, *pte=00000000, *ppte=00000000
[   47.222381] Internal error: Oops: 17 [#1] SMP
[   47.226745] Modules linked in:
[   47.229827] CPU: 0    Not tainted  (3.3.0-rc2-00031-g12c5c5c #235)
[   47.236022] PC is at mtd_cls_suspend+0x8/0x20
[   47.240386] LR is at mtd_cls_suspend+0x8/0x20
[   47.244750] pc : [<c02e78f8>]    lr : [<c02e78f8>]    psr: a0000013
[   47.244750] sp : dea1fe60  ip : 22222222  fp : c0ee7d40
[   47.256256] r10: c0ee7cf0  r9 : 00000000  r8 : c02e78f0
[   47.261474] r7 : 00000000  r6 : 00000000  r5 : 00000002  r4 : dea45800
[   47.268005] r3 : deb4cac0  r2 : 00000000  r1 : 00000002  r0 : 00000000
[   47.274536] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[   47.281677] Control: 10c5387d  Table: 9eaac019  DAC: 00000015
[   47.287445] Process sh (pid: 1177, stack limit = 0xdea1e2f8)
[   47.293090] Stack: (0xdea1fe60 to 0xdea20000)
[...]

b) ZOOM3
- Enable CPU-Idle
- Enable UART timeout
- echo mem > /sys/power/state
- Wakeup system using serial keyboard
- Verify retention count increment

Functional Tests
- Done on OMAP2430, OMAP3430SDP, ZOOM3, OMAP4430

Bootup Test
- Done on OMAP1710
  Used following patch to fix OMAP1 build error:-
  [PATCH] i2c: OMAP: Fix OMAP1 build error

v9:
- Summary of Comments/Issues fixed
  * GPIO wakeup does not work

  * Call debounce clock enable/disable functions from PM runtime callbacks.
    This will avoid calling the functions from multiple places.

  * Modify description of following patch to match latest changes.
    gpio/omap: save and restore debounce registers.

  * Use (bank->regs->set_dataout && bank->regs->clr_dataout) together instead
    of using only one of them.

  * Remove cpu_is_omapxxxx() checks from set_gpio_trigger().

  * _gpio_dbck_enable() in runtime callback triggered from omap_gpio_request
    does not enable dbck because dbck_enable_mask is not set at this point.

  * Workaround associated with an errata got missed in v8. This has been
    included.

v8:
- Remove PM_CONFIG macro around following assignment.
  pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;

- Once pm_runtime is enabled there is no more need for calling the
  omap_device_disable_idle_on_suspend(od).

- With pm_runtime, handling of clocks in Suspend is  taken care of by
  powerdomain hooks. So remove usage of *_runtime_put/get* from
  suspend/resume hooks and Idle path.

- Add handling of debounce clocks along the Suspend and Idle paths.

- Remove [PATCH 04/24] gpio/omap: fix pwrdm_post_transition call sequence
  from this series. This will be merged as part of power cleanup series.

- Remove [PATCH v7 20/26] gpio/omap: skip operations in runtime callbacks
  The bank->mod_usage check in this patch is not needed any more because
  they are now already being taken care in suspend/resume and Idle paths.

- Remove [PATCH v7 26/26] gpio/omap: add dbclk aliases for all gpio modules
  This is already taken care in hwmod.

- Remove redundant blank line in
  [PATCH v7 14/26] gpio/omap: remove unnecessary bit-masking for read access

-               if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
-                       isr &= 0x0000ffff;

               if (bank->level_mask)
                       level_mask = bank->level_mask & enabled;

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 (8):
  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: 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 (13):
  gpio/omap: handle save/restore context in GPIO driver
  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: fix debounce clock handling
  gpio/omap: fix incorrect access of debounce module
  gpio/omap: remove omap_gpio_save_context overhead

 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/gpio.c             |   36 +-
 arch/arm/mach-omap2/pm34xx.c           |   14 -
 arch/arm/plat-omap/include/plat/gpio.h |   29 +-
 drivers/gpio/gpio-omap.c               | 1099 +++++++++++++-------------------
 7 files changed, 549 insertions(+), 697 deletions(-)


^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 18:41   ` Felipe Balbi
  2012-02-02 17:30 ` [PATCH v9 02/25] gpio/omap: use flag to identify wakeup domain Tarun Kanti DebBarma
                   ` (27 subsequent siblings)
  28 siblings, 1 reply; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Charulatha V

From: Charulatha V <charu@ti.com>

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.

Signed-off-by: Charulatha V <charu@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 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(-)

diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
index 399da4c..f8c15ea 100644
--- a/arch/arm/mach-omap1/gpio15xx.c
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -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);
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index 0f399bd..df4bb44 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -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);
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
index 5ab63ea..923eaa1 100644
--- a/arch/arm/mach-omap1/gpio7xx.c
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -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);
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 8cbfbc2..07ac648 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -111,7 +111,6 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 
 	omap_device_disable_idle_on_suspend(pdev);
 
-	gpio_bank_count++;
 	return 0;
 }
 
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 9e86ee0..acf1c77 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -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);
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 0b05629..6ea7390 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -28,7 +28,10 @@
 #include <asm/gpio.h>
 #include <asm/mach/irq.h>
 
+static LIST_HEAD(omap_gpio_list);
+
 struct gpio_bank {
+	struct list_head node;
 	unsigned long pbase;
 	void __iomem *base;
 	u16 irq;
@@ -55,6 +58,7 @@ struct gpio_bank {
 	bool dbck_flag;
 	int stride;
 	u32 width;
+	u16 id;
 
 	void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable);
 
@@ -78,15 +82,6 @@ struct omap3_gpio_regs {
 static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
 #endif
 
-/*
- * TODO: Cleanup gpio_bank usage as it is having information
- * related to all instances of the device
- */
-static struct gpio_bank *gpio_bank;
-
-/* TODO: Analyze removing gpio_bank_count usage from driver code */
-int gpio_bank_count;
-
 #define GPIO_INDEX(bank, gpio) (gpio % bank->width)
 #define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio))
 
@@ -869,9 +864,8 @@ static struct platform_device omap_mpuio_device = {
 	/* could list the /proc/iomem resources */
 };
 
-static inline void mpuio_init(void)
+static inline void mpuio_init(struct gpio_bank *bank)
 {
-	struct gpio_bank *bank = &gpio_bank[0];
 	platform_set_drvdata(&omap_mpuio_device, bank);
 
 	if (platform_driver_register(&omap_mpuio_driver) == 0)
@@ -879,13 +873,13 @@ static inline void mpuio_init(void)
 }
 
 #else
-static inline void mpuio_init(void) {}
+static inline void mpuio_init(struct gpio_bank *bank) {}
 #endif	/* 16xx */
 
 #else
 
 #define bank_is_mpuio(bank)	0
-static inline void mpuio_init(void) {}
+static inline void mpuio_init(struct gpio_bank *bank) {}
 
 #endif
 
@@ -1007,20 +1001,8 @@ static void __init omap_gpio_show_rev(struct gpio_bank *bank)
  */
 static struct lock_class_key gpio_lock_class;
 
-static inline int init_gpio_info(struct platform_device *pdev)
-{
-	/* TODO: Analyze removing gpio_bank_count usage from driver code */
-	gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank),
-				GFP_KERNEL);
-	if (!gpio_bank) {
-		dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n");
-		return -ENOMEM;
-	}
-	return 0;
-}
-
 /* TODO: Cleanup cpu_is_* checks */
-static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
+static void omap_gpio_mod_init(struct gpio_bank *bank)
 {
 	if (cpu_class_is_omap2()) {
 		if (cpu_is_omap44xx()) {
@@ -1044,13 +1026,16 @@ static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
 			static const u32 non_wakeup_gpios[] = {
 				0xe203ffc0, 0x08700040
 			};
-			if (id < ARRAY_SIZE(non_wakeup_gpios))
-				bank->non_wakeup_gpios = non_wakeup_gpios[id];
+			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))
+		if (bank_is_mpuio(bank)) {
 			__raw_writew(0xffff, bank->base +
 				OMAP_MPUIO_GPIO_MASKIT / bank->stride);
+			mpuio_init(bank);
+		}
 		if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
 			__raw_writew(0xffff, bank->base
 						+ OMAP1510_GPIO_INT_MASK);
@@ -1161,35 +1146,35 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
 
 static int __devinit omap_gpio_probe(struct platform_device *pdev)
 {
-	static int gpio_init_done;
 	struct omap_gpio_platform_data *pdata;
 	struct resource *res;
-	int id;
 	struct gpio_bank *bank;
+	int ret = 0;
 
-	if (!pdev->dev.platform_data)
-		return -EINVAL;
-
-	pdata = pdev->dev.platform_data;
-
-	if (!gpio_init_done) {
-		int ret;
-
-		ret = init_gpio_info(pdev);
-		if (ret)
-			return ret;
+	if (!pdev->dev.platform_data) {
+		ret = -EINVAL;
+		goto err_exit;
 	}
 
-	id = pdev->id;
-	bank = &gpio_bank[id];
+	bank = kzalloc(sizeof(struct gpio_bank), GFP_KERNEL);
+	if (!bank) {
+		dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n");
+		ret = -ENOMEM;
+		goto err_exit;
+	}
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (unlikely(!res)) {
-		dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n", id);
-		return -ENODEV;
+		dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n",
+				pdev->id);
+		ret = -ENODEV;
+		goto err_free;
 	}
 
 	bank->irq = res->start;
+	bank->id = pdev->id;
+
+	pdata = pdev->dev.platform_data;
 	bank->virtual_irq_start = pdata->virtual_irq_start;
 	bank->method = pdata->bank_type;
 	bank->dev = &pdev->dev;
@@ -1209,39 +1194,46 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 	/* Static mapping, never released */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (unlikely(!res)) {
-		dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n", id);
-		return -ENODEV;
+		dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n",
+				pdev->id);
+		ret = -ENODEV;
+		goto err_free;
 	}
 
 	bank->base = ioremap(res->start, resource_size(res));
 	if (!bank->base) {
-		dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n", id);
-		return -ENOMEM;
+		dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n",
+				pdev->id);
+		ret = -ENOMEM;
+		goto err_free;
 	}
 
 	pm_runtime_enable(bank->dev);
 	pm_runtime_get_sync(bank->dev);
 
-	omap_gpio_mod_init(bank, id);
+	omap_gpio_mod_init(bank);
 	omap_gpio_chip_init(bank);
 	omap_gpio_show_rev(bank);
 
-	if (!gpio_init_done)
-		gpio_init_done = 1;
+	list_add_tail(&bank->node, &omap_gpio_list);
 
-	return 0;
+	return ret;
+
+err_free:
+	kfree(bank);
+err_exit:
+	return ret;
 }
 
 #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
 static int omap_gpio_suspend(void)
 {
-	int i;
+	struct gpio_bank *bank;
 
 	if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
 		return 0;
 
-	for (i = 0; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
+	list_for_each_entry(bank, &omap_gpio_list, node) {
 		void __iomem *wake_status;
 		void __iomem *wake_clear;
 		void __iomem *wake_set;
@@ -1285,13 +1277,12 @@ static int omap_gpio_suspend(void)
 
 static void omap_gpio_resume(void)
 {
-	int i;
+	struct gpio_bank *bank;
 
 	if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
 		return;
 
-	for (i = 0; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
+	list_for_each_entry(bank, &omap_gpio_list, node) {
 		void __iomem *wake_clear;
 		void __iomem *wake_set;
 		unsigned long flags;
@@ -1339,17 +1330,17 @@ static int workaround_enabled;
 
 void omap2_gpio_prepare_for_idle(int off_mode)
 {
-	int i, c = 0;
-	int min = 0;
-
-	if (cpu_is_omap34xx())
-		min = 1;
+	int c = 0;
+	struct gpio_bank *bank;
 
-	for (i = min; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
+	list_for_each_entry(bank, &omap_gpio_list, node) {
 		u32 l1 = 0, l2 = 0;
 		int j;
 
+		/* TODO: Do not use cpu_is_omap34xx */
+		if ((cpu_is_omap34xx()) && (bank->id == 0))
+			continue;
+
 		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
 			clk_disable(bank->dbck);
 
@@ -1408,16 +1399,16 @@ void omap2_gpio_prepare_for_idle(int off_mode)
 
 void omap2_gpio_resume_after_idle(void)
 {
-	int i;
-	int min = 0;
+	struct gpio_bank *bank;
 
-	if (cpu_is_omap34xx())
-		min = 1;
-	for (i = min; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
+	list_for_each_entry(bank, &omap_gpio_list, node) {
 		u32 l = 0, gen, gen0, gen1;
 		int j;
 
+		/* TODO: Do not use cpu_is_omap34xx */
+		if ((cpu_is_omap34xx()) && (bank->id == 0))
+			continue;
+
 		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
 			clk_enable(bank->dbck);
 
@@ -1506,14 +1497,17 @@ void omap2_gpio_resume_after_idle(void)
 #endif
 
 #ifdef CONFIG_ARCH_OMAP3
-/* save the registers of bank 2-6 */
 void omap_gpio_save_context(void)
 {
-	int i;
+	struct gpio_bank *bank;
+	int i = 0;
+
+	list_for_each_entry(bank, &omap_gpio_list, node) {
+		i++;
+
+		if (bank->id == 0)
+			continue;
 
-	/* saving banks from 2-6 only since GPIO1 is in WKUP */
-	for (i = 1; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
 		gpio_context[i].irqenable1 =
 			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
 		gpio_context[i].irqenable2 =
@@ -1537,13 +1531,17 @@ void omap_gpio_save_context(void)
 	}
 }
 
-/* restore the required registers of bank 2-6 */
 void omap_gpio_restore_context(void)
 {
-	int i;
+	struct gpio_bank *bank;
+	int i = 0;
+
+	list_for_each_entry(bank, &omap_gpio_list, node) {
+		i++;
+
+		if (bank->id == 0)
+			continue;
 
-	for (i = 1; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
 		__raw_writel(gpio_context[i].irqenable1,
 				bank->base + OMAP24XX_GPIO_IRQENABLE1);
 		__raw_writel(gpio_context[i].irqenable2,
@@ -1588,7 +1586,6 @@ postcore_initcall(omap_gpio_drv_reg);
 
 static int __init omap_gpio_sysinit(void)
 {
-	mpuio_init();
 
 #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
 	if (cpu_is_omap16xx() || cpu_class_is_omap2())
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 02/25] gpio/omap: use flag to identify wakeup domain
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 03/25] gpio/omap: make gpio_context part of gpio_bank structure Tarun Kanti DebBarma
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Charulatha V

From: Charulatha V <charu@ti.com>

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.

Signed-off-by: Charulatha V <charu@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 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(-)

diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 07ac648..076be34 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -24,6 +24,8 @@
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
+#include "powerdomain.h"
+
 static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 {
 	struct platform_device *pdev;
@@ -31,6 +33,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
@@ -99,6 +102,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);
+
 	pdev = omap_device_build(name, id - 1, oh, pdata,
 				sizeof(*pdata),	NULL, 0, false);
 	kfree(pdata);
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index acf1c77..6eb035c 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -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;
 };
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 6ea7390..07efa15 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -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,
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 03/25] gpio/omap: make gpio_context part of gpio_bank structure
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 02/25] gpio/omap: use flag to identify wakeup domain Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 04/25] gpio/omap: handle save/restore context in GPIO driver Tarun Kanti DebBarma
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Charulatha V

From: Charulatha V <charu@ti.com>

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

Signed-off-by: Charulatha V <charu@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 drivers/gpio/gpio-omap.c |   76 ++++++++++++++++++++-------------------------
 1 files changed, 34 insertions(+), 42 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 07efa15..6788c8a 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -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);
 	}
 }
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 04/25] gpio/omap: handle save/restore context in GPIO driver
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (2 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 03/25] gpio/omap: make gpio_context part of gpio_bank structure Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 05/25] gpio/omap: make non-wakeup GPIO part of pdata Tarun Kanti DebBarma
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma, Charulatha V

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.

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/gpio.c             |    3 +-
 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, 63 insertions(+), 90 deletions(-)

diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 076be34..f84db8f 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -23,6 +23,7 @@
 
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
+#include <plat/omap-pm.h>
 
 #include "powerdomain.h"
 
@@ -55,7 +56,7 @@ 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);
-
+	pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
 	pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL);
 	if (!pdata) {
 		pr_err("gpio%d: Memory allocation failed\n", id);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index fc69875..59c6dc1 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -75,16 +75,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;
@@ -332,8 +322,6 @@ void omap_sram_idle(void)
 	if (per_next_state < PWRDM_POWER_ON) {
 		per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
 		omap2_gpio_prepare_for_idle(per_going_off);
-		if (per_next_state == PWRDM_POWER_OFF)
-				omap3_per_save_context();
 	}
 
 	/* CORE */
@@ -399,8 +387,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();
 	}
 
 	/* Disable IO-PAD and IO-CHAIN wakeup */
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 6eb035c..c1ddc5a 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -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 */
+	int (*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
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 6788c8a..a1a3b9d 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -72,9 +72,11 @@ struct gpio_bank {
 	bool loses_context;
 	int stride;
 	u32 width;
+	int context_loss_count;
 	u16 id;
 
 	void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable);
+	int (*get_context_loss_count)(struct device *dev);
 
 	struct omap_gpio_reg_offs *regs;
 };
@@ -1179,6 +1181,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 	bank->stride = pdata->bank_stride;
 	bank->width = pdata->bank_width;
 	bank->loses_context = pdata->loses_context;
+	bank->get_context_loss_count = pdata->get_context_loss_count;
 	bank->regs = pdata->regs;
 
 	if (bank->regs->set_dataout && bank->regs->clr_dataout)
@@ -1323,11 +1326,11 @@ static struct syscore_ops omap_gpio_syscore_ops = {
 
 #ifdef CONFIG_ARCH_OMAP2PLUS
 
-static int workaround_enabled;
+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)
 {
-	int c = 0;
 	struct gpio_bank *bank;
 
 	list_for_each_entry(bank, &omap_gpio_list, node) {
@@ -1347,7 +1350,7 @@ void omap2_gpio_prepare_for_idle(int off_mode)
 		 * non-wakeup GPIOs.  Otherwise spurious IRQs will be
 		 * generated.  See OMAP2420 Errata item 1.101. */
 		if (!(bank->enabled_non_wakeup_gpios))
-			continue;
+			goto save_gpio_context;
 
 		if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
 			bank->saved_datain = __raw_readl(bank->base +
@@ -1384,13 +1387,13 @@ void omap2_gpio_prepare_for_idle(int off_mode)
 			__raw_writel(l2, bank->base + OMAP4_GPIO_RISINGDETECT);
 		}
 
-		c++;
-	}
-	if (!c) {
-		workaround_enabled = 0;
-		return;
+save_gpio_context:
+		if (bank->get_context_loss_count)
+			bank->context_loss_count =
+				bank->get_context_loss_count(bank->dev);
+
+		omap_gpio_save_context(bank);
 	}
-	workaround_enabled = 1;
 }
 
 void omap2_gpio_resume_after_idle(void)
@@ -1398,6 +1401,7 @@ void omap2_gpio_resume_after_idle(void)
 	struct gpio_bank *bank;
 
 	list_for_each_entry(bank, &omap_gpio_list, node) {
+		int context_lost_cnt_after;
 		u32 l = 0, gen, gen0, gen1;
 		int j;
 
@@ -1407,8 +1411,13 @@ void omap2_gpio_resume_after_idle(void)
 		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
 			clk_enable(bank->dbck);
 
-		if (!workaround_enabled)
-			continue;
+		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);
+		}
 
 		if (!(bank->enabled_non_wakeup_gpios))
 			continue;
@@ -1486,74 +1495,50 @@ void omap2_gpio_resume_after_idle(void)
 			}
 		}
 	}
-
 }
 
-#endif
-
-#ifdef CONFIG_ARCH_OMAP3
-void omap_gpio_save_context(void)
+static void omap_gpio_save_context(struct gpio_bank *bank)
 {
-	struct gpio_bank *bank;
-
-	list_for_each_entry(bank, &omap_gpio_list, node) {
-
-		if (!bank->loses_context)
-			continue;
-
-		bank->context.irqenable1 =
-			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
-		bank->context.irqenable2 =
-			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2);
-		bank->context.wake_en =
-			__raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN);
-		bank->context.ctrl =
-			__raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
-		bank->context.oe =
-			__raw_readl(bank->base + OMAP24XX_GPIO_OE);
-		bank->context.leveldetect0 =
-			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-		bank->context.leveldetect1 =
-			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-		bank->context.risingdetect =
-			__raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
-		bank->context.fallingdetect =
-			__raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-		bank->context.dataout =
-			__raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
-	}
+	bank->context.irqenable1 =
+		__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
+	bank->context.irqenable2 =
+		__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2);
+	bank->context.wake_en =
+		__raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN);
+	bank->context.ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
+	bank->context.oe = __raw_readl(bank->base + OMAP24XX_GPIO_OE);
+	bank->context.leveldetect0 =
+		__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+	bank->context.leveldetect1 =
+		__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+	bank->context.risingdetect =
+		__raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
+	bank->context.fallingdetect =
+		__raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+	bank->context.dataout =
+		__raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
 }
 
-void omap_gpio_restore_context(void)
+static void omap_gpio_restore_context(struct gpio_bank *bank)
 {
-	struct gpio_bank *bank;
-
-	list_for_each_entry(bank, &omap_gpio_list, node) {
-
-		if (!bank->loses_context)
-			continue;
-
-		__raw_writel(bank->context.irqenable1,
-				bank->base + OMAP24XX_GPIO_IRQENABLE1);
-		__raw_writel(bank->context.irqenable2,
-				bank->base + OMAP24XX_GPIO_IRQENABLE2);
-		__raw_writel(bank->context.wake_en,
-				bank->base + OMAP24XX_GPIO_WAKE_EN);
-		__raw_writel(bank->context.ctrl,
-				bank->base + OMAP24XX_GPIO_CTRL);
-		__raw_writel(bank->context.oe,
-				bank->base + OMAP24XX_GPIO_OE);
-		__raw_writel(bank->context.leveldetect0,
-				bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-		__raw_writel(bank->context.leveldetect1,
-				bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-		__raw_writel(bank->context.risingdetect,
-				bank->base + OMAP24XX_GPIO_RISINGDETECT);
-		__raw_writel(bank->context.fallingdetect,
-				bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-		__raw_writel(bank->context.dataout,
-				bank->base + OMAP24XX_GPIO_DATAOUT);
-	}
+	__raw_writel(bank->context.irqenable1,
+			bank->base + OMAP24XX_GPIO_IRQENABLE1);
+	__raw_writel(bank->context.irqenable2,
+			bank->base + OMAP24XX_GPIO_IRQENABLE2);
+	__raw_writel(bank->context.wake_en,
+			bank->base + OMAP24XX_GPIO_WAKE_EN);
+	__raw_writel(bank->context.ctrl, bank->base + OMAP24XX_GPIO_CTRL);
+	__raw_writel(bank->context.oe, bank->base + OMAP24XX_GPIO_OE);
+	__raw_writel(bank->context.leveldetect0,
+			bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+	__raw_writel(bank->context.leveldetect1,
+			bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+	__raw_writel(bank->context.risingdetect,
+			bank->base + OMAP24XX_GPIO_RISINGDETECT);
+	__raw_writel(bank->context.fallingdetect,
+			bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+	__raw_writel(bank->context.dataout,
+			bank->base + OMAP24XX_GPIO_DATAOUT);
 }
 #endif
 
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 05/25] gpio/omap: make non-wakeup GPIO part of pdata
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (3 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 04/25] gpio/omap: handle save/restore context in GPIO driver Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 06/25] gpio/omap: avoid cpu checks during module ena/disable Tarun Kanti DebBarma
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Charulatha V

From: Charulatha V <charu@ti.com>

Non-wakeup GPIOs are available only in OMAP2. Avoid cpu_is checks by making
non_wakeup_gpios as part of pdata.

Signed-off-by: Charulatha V <charu@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 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(-)

diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index f84db8f..1d60fff 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -65,6 +65,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;
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index c1ddc5a..49ec751 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -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;
 
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index a1a3b9d..2eed159 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -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;
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 06/25] gpio/omap: avoid cpu checks during module ena/disable
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (4 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 05/25] gpio/omap: make non-wakeup GPIO part of pdata Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 07/25] gpio/omap: further cleanup using wkup_en register Tarun Kanti DebBarma
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Charulatha V

From: Charulatha V <charu@ti.com>

Remove cpu-is checks while enabling/disabling OMAP GPIO module during a gpio
request/free.

Signed-off-by: Charulatha V <charu@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 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(-)

diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 1d60fff..bc9271a 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -88,6 +88,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;
@@ -104,6 +105,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");
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 49ec751..db94bd1 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -188,6 +188,7 @@ struct omap_gpio_reg_offs {
 	u16 clr_irqenable;
 	u16 debounce;
 	u16 debounce_en;
+	u16 ctrl;
 
 	bool irqenable_inv;
 };
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 2eed159..5cc2c04 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -83,6 +83,7 @@ struct gpio_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)
 
 static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
 {
@@ -577,22 +578,18 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
 		__raw_writel(__raw_readl(reg) | (1 << offset), reg);
 	}
 #endif
-	if (!cpu_class_is_omap1()) {
-		if (!bank->mod_usage) {
-			void __iomem *reg = bank->base;
-			u32 ctrl;
-
-			if (cpu_is_omap24xx() || cpu_is_omap34xx())
-				reg += OMAP24XX_GPIO_CTRL;
-			else if (cpu_is_omap44xx())
-				reg += OMAP4_GPIO_CTRL;
-			ctrl = __raw_readl(reg);
-			/* Module is enabled, clocks are not gated */
-			ctrl &= 0xFFFFFFFE;
-			__raw_writel(ctrl, reg);
-		}
-		bank->mod_usage |= 1 << offset;
+	if (bank->regs->ctrl && !bank->mod_usage) {
+		void __iomem *reg = bank->base + bank->regs->ctrl;
+		u32 ctrl;
+
+		ctrl = __raw_readl(reg);
+		/* Module is enabled, clocks are not gated */
+		ctrl &= ~GPIO_MOD_CTRL_BIT;
+		__raw_writel(ctrl, reg);
 	}
+
+	bank->mod_usage |= 1 << offset;
+
 	spin_unlock_irqrestore(&bank->lock, flags);
 
 	return 0;
@@ -625,22 +622,18 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
 		__raw_writel(1 << offset, reg);
 	}
 #endif
-	if (!cpu_class_is_omap1()) {
-		bank->mod_usage &= ~(1 << offset);
-		if (!bank->mod_usage) {
-			void __iomem *reg = bank->base;
-			u32 ctrl;
-
-			if (cpu_is_omap24xx() || cpu_is_omap34xx())
-				reg += OMAP24XX_GPIO_CTRL;
-			else if (cpu_is_omap44xx())
-				reg += OMAP4_GPIO_CTRL;
-			ctrl = __raw_readl(reg);
-			/* Module is disabled, clocks are gated */
-			ctrl |= 1;
-			__raw_writel(ctrl, reg);
-		}
+	bank->mod_usage &= ~(1 << offset);
+
+	if (bank->regs->ctrl && !bank->mod_usage) {
+		void __iomem *reg = bank->base + bank->regs->ctrl;
+		u32 ctrl;
+
+		ctrl = __raw_readl(reg);
+		/* Module is disabled, clocks are gated */
+		ctrl |= GPIO_MOD_CTRL_BIT;
+		__raw_writel(ctrl, reg);
 	}
+
 	_reset_gpio(bank, bank->chip.base + offset);
 	spin_unlock_irqrestore(&bank->lock, flags);
 }
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 07/25] gpio/omap: further cleanup using wkup_en register
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (5 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 06/25] gpio/omap: avoid cpu checks during module ena/disable Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 08/25] gpio/omap: use level/edge detect reg offsets Tarun Kanti DebBarma
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma, Charulatha V

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_en register consistently for
all SoCs wherever applicable.

Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Signed-off-by: Charulatha V <charu@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 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               |  110 ++++++--------------------------
 4 files changed, 25 insertions(+), 89 deletions(-)

diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index df4bb44..1eb47e2 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -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 = {
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index bc9271a..4877b52 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -89,6 +89,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;
@@ -106,6 +107,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");
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index db94bd1..2b54bca 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -189,6 +189,7 @@ struct omap_gpio_reg_offs {
 	u16 debounce;
 	u16 debounce_en;
 	u16 ctrl;
+	u16 wkup_en;
 
 	bool irqenable_inv;
 };
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 5cc2c04..3daedff 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -51,9 +51,7 @@ struct gpio_bank {
 	u16 virtual_irq_start;
 	int method;
 	u32 suspend_wakeup;
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
 	u32 saved_wakeup;
-#endif
 	u32 non_wakeup_gpios;
 	u32 enabled_non_wakeup_gpios;
 	struct gpio_regs context;
@@ -598,30 +596,15 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
 static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
 {
 	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
+	void __iomem *base = bank->base;
 	unsigned long flags;
 
 	spin_lock_irqsave(&bank->lock, flags);
-#ifdef CONFIG_ARCH_OMAP16XX
-	if (bank->method == METHOD_GPIO_1610) {
-		/* Disable wake-up during idle for dynamic tick */
-		void __iomem *reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
-		__raw_writel(1 << offset, reg);
-	}
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	if (bank->method == METHOD_GPIO_24XX) {
-		/* Disable wake-up during idle for dynamic tick */
-		void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
-		__raw_writel(1 << offset, reg);
-	}
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-	if (bank->method == METHOD_GPIO_44XX) {
+
+	if (bank->regs->wkup_en)
 		/* Disable wake-up during idle for dynamic tick */
-		void __iomem *reg = bank->base + OMAP4_GPIO_IRQWAKEN0;
-		__raw_writel(1 << offset, reg);
-	}
-#endif
+		_gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0);
+
 	bank->mod_usage &= ~(1 << offset);
 
 	if (bank->regs->ctrl && !bank->mod_usage) {
@@ -1071,8 +1054,8 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
 	ct->chip.irq_mask = irq_gc_mask_set_bit;
 	ct->chip.irq_unmask = irq_gc_mask_clr_bit;
 	ct->chip.irq_set_type = gpio_irq_type;
-	/* REVISIT: assuming only 16xx supports MPUIO wake events */
-	if (cpu_is_omap16xx())
+
+	if (bank->regs->wkup_en)
 		ct->chip.irq_set_wake = gpio_wake_enable,
 
 	ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride;
@@ -1101,7 +1084,8 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
 	if (bank_is_mpuio(bank)) {
 		bank->chip.label = "mpuio";
 #ifdef CONFIG_ARCH_OMAP16XX
-		bank->chip.dev = &omap_mpuio_device.dev;
+		if (bank->regs->wkup_en)
+			bank->chip.dev = &omap_mpuio_device.dev;
 #endif
 		bank->chip.base = OMAP_MPUIO(0);
 	} else {
@@ -1212,50 +1196,24 @@ err_exit:
 	return ret;
 }
 
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
 static int omap_gpio_suspend(void)
 {
 	struct gpio_bank *bank;
 
-	if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
-		return 0;
-
 	list_for_each_entry(bank, &omap_gpio_list, node) {
+		void __iomem *base = bank->base;
 		void __iomem *wake_status;
-		void __iomem *wake_clear;
-		void __iomem *wake_set;
 		unsigned long flags;
 
-		switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP16XX
-		case METHOD_GPIO_1610:
-			wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE;
-			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
-			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
-			break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-		case METHOD_GPIO_24XX:
-			wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN;
-			wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
-			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
-			break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-		case METHOD_GPIO_44XX:
-			wake_status = bank->base + OMAP4_GPIO_IRQWAKEN0;
-			wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
-			wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
-			break;
-#endif
-		default:
-			continue;
-		}
+		if (!bank->regs->wkup_en)
+			return 0;
+
+		wake_status = bank->base + bank->regs->wkup_en;
 
 		spin_lock_irqsave(&bank->lock, flags);
 		bank->saved_wakeup = __raw_readl(wake_status);
-		__raw_writel(0xffffffff, wake_clear);
-		__raw_writel(bank->suspend_wakeup, wake_set);
+		_gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0);
+		_gpio_rmw(base, bank->regs->wkup_en, bank->suspend_wakeup, 1);
 		spin_unlock_irqrestore(&bank->lock, flags);
 	}
 
@@ -1266,40 +1224,16 @@ static void omap_gpio_resume(void)
 {
 	struct gpio_bank *bank;
 
-	if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
-		return;
-
 	list_for_each_entry(bank, &omap_gpio_list, node) {
-		void __iomem *wake_clear;
-		void __iomem *wake_set;
+		void __iomem *base = bank->base;
 		unsigned long flags;
 
-		switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP16XX
-		case METHOD_GPIO_1610:
-			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
-			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
-			break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-		case METHOD_GPIO_24XX:
-			wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
-			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
-			break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-		case METHOD_GPIO_44XX:
-			wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
-			wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
-			break;
-#endif
-		default:
-			continue;
-		}
+		if (!bank->regs->wkup_en)
+			return;
 
 		spin_lock_irqsave(&bank->lock, flags);
-		__raw_writel(0xffffffff, wake_clear);
-		__raw_writel(bank->saved_wakeup, wake_set);
+		_gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0);
+		_gpio_rmw(base, bank->regs->wkup_en, bank->saved_wakeup, 1);
 		spin_unlock_irqrestore(&bank->lock, flags);
 	}
 }
@@ -1309,8 +1243,6 @@ static struct syscore_ops omap_gpio_syscore_ops = {
 	.resume		= omap_gpio_resume,
 };
 
-#endif
-
 #ifdef CONFIG_ARCH_OMAP2PLUS
 
 static void omap_gpio_save_context(struct gpio_bank *bank);
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 08/25] gpio/omap: use level/edge detect reg offsets
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (6 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 07/25] gpio/omap: further cleanup using wkup_en register Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 09/25] gpio/omap: remove hardcoded offsets in context save/restore Tarun Kanti DebBarma
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma, Charulatha V

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 <tarun.kanti@ti.com>
Signed-off-by: Charulatha V <charu@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/gpio.c             |    8 ++
 arch/arm/plat-omap/include/plat/gpio.h |    4 +
 drivers/gpio/gpio-omap.c               |  114 +++++++++-----------------------
 3 files changed, 44 insertions(+), 82 deletions(-)

diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 4877b52..ae5043e 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -90,6 +90,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;
@@ -108,6 +112,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");
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 2b54bca..395b3c1 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -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;
 };
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 3daedff..991dd39 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -257,15 +257,9 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
 			bank->enabled_non_wakeup_gpios &= ~gpio_bit;
 	}
 
-	if (cpu_is_omap44xx()) {
-		bank->level_mask =
-			__raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT0) |
-			__raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT1);
-	} else {
-		bank->level_mask =
-			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) |
-			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-	}
+	bank->level_mask =
+		__raw_readl(bank->base + bank->regs->leveldetect0) |
+		__raw_readl(bank->base + bank->regs->leveldetect1);
 }
 #endif
 
@@ -405,12 +399,12 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
 	if (type & ~IRQ_TYPE_SENSE_MASK)
 		return -EINVAL;
 
-	/* OMAP1 allows only only edge triggering */
-	if (!cpu_class_is_omap2()
-			&& (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
+	bank = irq_data_get_irq_chip_data(d);
+
+	if (!bank->regs->leveldetect0 &&
+		(type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
 		return -EINVAL;
 
-	bank = irq_data_get_irq_chip_data(d);
 	spin_lock_irqsave(&bank->lock, flags);
 	retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type);
 	spin_unlock_irqrestore(&bank->lock, flags);
@@ -658,9 +652,8 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 		if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
 			isr &= 0x0000ffff;
 
-		if (cpu_class_is_omap2()) {
+		if (bank->level_mask)
 			level_mask = bank->level_mask & enabled;
-		}
 
 		/* clear edge sensitive interrupts before handler(s) are
 		called so that we don't miss any interrupt occurred while
@@ -1271,40 +1264,18 @@ void omap2_gpio_prepare_for_idle(int off_mode)
 		if (!(bank->enabled_non_wakeup_gpios))
 			goto save_gpio_context;
 
-		if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-			bank->saved_datain = __raw_readl(bank->base +
-					OMAP24XX_GPIO_DATAIN);
-			l1 = __raw_readl(bank->base +
-					OMAP24XX_GPIO_FALLINGDETECT);
-			l2 = __raw_readl(bank->base +
-					OMAP24XX_GPIO_RISINGDETECT);
-		}
-
-		if (cpu_is_omap44xx()) {
-			bank->saved_datain = __raw_readl(bank->base +
-						OMAP4_GPIO_DATAIN);
-			l1 = __raw_readl(bank->base +
-						OMAP4_GPIO_FALLINGDETECT);
-			l2 = __raw_readl(bank->base +
-						OMAP4_GPIO_RISINGDETECT);
-		}
+		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);
 
 		bank->saved_fallingdetect = l1;
 		bank->saved_risingdetect = l2;
 		l1 &= ~bank->enabled_non_wakeup_gpios;
 		l2 &= ~bank->enabled_non_wakeup_gpios;
 
-		if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-			__raw_writel(l1, bank->base +
-					OMAP24XX_GPIO_FALLINGDETECT);
-			__raw_writel(l2, bank->base +
-					OMAP24XX_GPIO_RISINGDETECT);
-		}
-
-		if (cpu_is_omap44xx()) {
-			__raw_writel(l1, bank->base + OMAP4_GPIO_FALLINGDETECT);
-			__raw_writel(l2, bank->base + OMAP4_GPIO_RISINGDETECT);
-		}
+		__raw_writel(l1, bank->base + bank->regs->fallingdetect);
+		__raw_writel(l2, bank->base + bank->regs->risingdetect);
 
 save_gpio_context:
 		if (bank->get_context_loss_count)
@@ -1341,21 +1312,11 @@ void omap2_gpio_resume_after_idle(void)
 		if (!(bank->enabled_non_wakeup_gpios))
 			continue;
 
-		if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-			__raw_writel(bank->saved_fallingdetect,
-				 bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-			__raw_writel(bank->saved_risingdetect,
-				 bank->base + OMAP24XX_GPIO_RISINGDETECT);
-			l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
-		}
-
-		if (cpu_is_omap44xx()) {
-			__raw_writel(bank->saved_fallingdetect,
-				 bank->base + OMAP4_GPIO_FALLINGDETECT);
-			__raw_writel(bank->saved_risingdetect,
-				 bank->base + OMAP4_GPIO_RISINGDETECT);
-			l = __raw_readl(bank->base + OMAP4_GPIO_DATAIN);
-		}
+		__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
@@ -1383,35 +1344,24 @@ void omap2_gpio_resume_after_idle(void)
 		if (gen) {
 			u32 old0, old1;
 
+			old0 = __raw_readl(bank->base +
+						bank->regs->leveldetect0);
+			old1 = __raw_readl(bank->base +
+						bank->regs->leveldetect1);
+
 			if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-				old0 = __raw_readl(bank->base +
-					OMAP24XX_GPIO_LEVELDETECT0);
-				old1 = __raw_readl(bank->base +
-					OMAP24XX_GPIO_LEVELDETECT1);
-				__raw_writel(old0 | gen, bank->base +
-					OMAP24XX_GPIO_LEVELDETECT0);
-				__raw_writel(old1 | gen, bank->base +
-					OMAP24XX_GPIO_LEVELDETECT1);
-				__raw_writel(old0, bank->base +
-					OMAP24XX_GPIO_LEVELDETECT0);
-				__raw_writel(old1, bank->base +
-					OMAP24XX_GPIO_LEVELDETECT1);
+				old0 |= gen;
+				old1 |= gen;
 			}
 
 			if (cpu_is_omap44xx()) {
-				old0 = __raw_readl(bank->base +
-						OMAP4_GPIO_LEVELDETECT0);
-				old1 = __raw_readl(bank->base +
-						OMAP4_GPIO_LEVELDETECT1);
-				__raw_writel(old0 | l, bank->base +
-						OMAP4_GPIO_LEVELDETECT0);
-				__raw_writel(old1 | l, bank->base +
-						OMAP4_GPIO_LEVELDETECT1);
-				__raw_writel(old0, bank->base +
-						OMAP4_GPIO_LEVELDETECT0);
-				__raw_writel(old1, bank->base +
-						OMAP4_GPIO_LEVELDETECT1);
+				old0 |= l;
+				old1 |= l;
 			}
+			__raw_writel(old0, bank->base +
+						bank->regs->leveldetect0);
+			__raw_writel(old1, bank->base +
+						bank->regs->leveldetect1);
 		}
 	}
 }
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 09/25] gpio/omap: remove hardcoded offsets in context save/restore
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (7 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 08/25] gpio/omap: use level/edge detect reg offsets Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 10/25] gpio/omap: cleanup set_gpio_triggering function Tarun Kanti DebBarma
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma, Charulatha V

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 <tarun.kanti@ti.com>
Signed-off-by: Charulatha V <charu@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/gpio.c             |    2 +
 arch/arm/plat-omap/include/plat/gpio.h |    1 +
 drivers/gpio/gpio-omap.c               |   42 +++++++++++++++----------------
 3 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index ae5043e..f4c45ca 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -84,6 +84,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;
@@ -106,6 +107,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;
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 395b3c1..914c976 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -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;
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 991dd39..ceb9edf 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1369,45 +1369,43 @@ void omap2_gpio_resume_after_idle(void)
 static void omap_gpio_save_context(struct gpio_bank *bank)
 {
 	bank->context.irqenable1 =
-		__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
+			__raw_readl(bank->base + bank->regs->irqenable);
 	bank->context.irqenable2 =
-		__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2);
+			__raw_readl(bank->base + bank->regs->irqenable2);
 	bank->context.wake_en =
-		__raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN);
-	bank->context.ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
-	bank->context.oe = __raw_readl(bank->base + OMAP24XX_GPIO_OE);
+			__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 + OMAP24XX_GPIO_LEVELDETECT0);
+			__raw_readl(bank->base + bank->regs->leveldetect0);
 	bank->context.leveldetect1 =
-		__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+			__raw_readl(bank->base + bank->regs->leveldetect1);
 	bank->context.risingdetect =
-		__raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
+			__raw_readl(bank->base + bank->regs->risingdetect);
 	bank->context.fallingdetect =
-		__raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-	bank->context.dataout =
-		__raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
+			__raw_readl(bank->base + bank->regs->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,
-			bank->base + OMAP24XX_GPIO_IRQENABLE1);
+				bank->base + bank->regs->irqenable);
 	__raw_writel(bank->context.irqenable2,
-			bank->base + OMAP24XX_GPIO_IRQENABLE2);
+				bank->base + bank->regs->irqenable2);
 	__raw_writel(bank->context.wake_en,
-			bank->base + OMAP24XX_GPIO_WAKE_EN);
-	__raw_writel(bank->context.ctrl, bank->base + OMAP24XX_GPIO_CTRL);
-	__raw_writel(bank->context.oe, bank->base + OMAP24XX_GPIO_OE);
+				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 + OMAP24XX_GPIO_LEVELDETECT0);
+				bank->base + bank->regs->leveldetect0);
 	__raw_writel(bank->context.leveldetect1,
-			bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+				bank->base + bank->regs->leveldetect1);
 	__raw_writel(bank->context.risingdetect,
-			bank->base + OMAP24XX_GPIO_RISINGDETECT);
+				bank->base + bank->regs->risingdetect);
 	__raw_writel(bank->context.fallingdetect,
-			bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-	__raw_writel(bank->context.dataout,
-			bank->base + OMAP24XX_GPIO_DATAOUT);
+				bank->base + bank->regs->fallingdetect);
+	__raw_writel(bank->context.dataout, bank->base + bank->regs->dataout);
 }
 #endif
 
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 10/25] gpio/omap: cleanup set_gpio_triggering function
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (8 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 09/25] gpio/omap: remove hardcoded offsets in context save/restore Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function Tarun Kanti DebBarma
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma, Charulatha V

Getting 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. Get rid of cpu_is_xxxx checks in
set_gpio_trigger() using irqctrl.

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 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               |  157 +++++++++-----------------------
 5 files changed, 53 insertions(+), 114 deletions(-)

diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
index f8c15ea..2adfece 100644
--- a/arch/arm/mach-omap1/gpio15xx.c
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -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 = {
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index 1eb47e2..46bb57a 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -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 = {
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
index 923eaa1..207a23c 100644
--- a/arch/arm/mach-omap1/gpio7xx.c
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -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 = {
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 914c976..9e403e5 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -195,6 +195,9 @@ struct omap_gpio_reg_offs {
 	u16 leveldetect1;
 	u16 risingdetect;
 	u16 fallingdetect;
+	u16 irqctrl;
+	u16 edgectrl1;
+	u16 edgectrl2;
 
 	bool irqenable_inv;
 };
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index ceb9edf..f39d9e4 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -199,52 +199,32 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
 	__raw_writel(val, reg);
 }
 
-#ifdef CONFIG_ARCH_OMAP2PLUS
-static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
+static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio,
 						int trigger)
 {
 	void __iomem *base = bank->base;
 	u32 gpio_bit = 1 << gpio;
 
-	if (cpu_is_omap44xx()) {
-		_gpio_rmw(base, OMAP4_GPIO_LEVELDETECT0, gpio_bit,
-			  trigger & IRQ_TYPE_LEVEL_LOW);
-		_gpio_rmw(base, OMAP4_GPIO_LEVELDETECT1, gpio_bit,
-			  trigger & IRQ_TYPE_LEVEL_HIGH);
-		_gpio_rmw(base, OMAP4_GPIO_RISINGDETECT, gpio_bit,
-			  trigger & IRQ_TYPE_EDGE_RISING);
-		_gpio_rmw(base, OMAP4_GPIO_FALLINGDETECT, gpio_bit,
-			  trigger & IRQ_TYPE_EDGE_FALLING);
-	} else {
-		_gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
-			  trigger & IRQ_TYPE_LEVEL_LOW);
-		_gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
-			  trigger & IRQ_TYPE_LEVEL_HIGH);
-		_gpio_rmw(base, OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
-			  trigger & IRQ_TYPE_EDGE_RISING);
-		_gpio_rmw(base, OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
-			  trigger & IRQ_TYPE_EDGE_FALLING);
-	}
-	if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
-		if (cpu_is_omap44xx()) {
-			_gpio_rmw(base, OMAP4_GPIO_IRQWAKEN0, gpio_bit,
-				  trigger != 0);
-		} else {
-			/*
-			 * GPIO wakeup request can only be generated on edge
-			 * transitions
-			 */
-			if (trigger & IRQ_TYPE_EDGE_BOTH)
-				__raw_writel(1 << gpio, bank->base
-					+ OMAP24XX_GPIO_SETWKUENA);
-			else
-				__raw_writel(1 << gpio, bank->base
-					+ OMAP24XX_GPIO_CLEARWKUENA);
-		}
-	}
+	_gpio_rmw(base, bank->regs->leveldetect0, gpio_bit,
+		  trigger & IRQ_TYPE_LEVEL_LOW);
+	_gpio_rmw(base, bank->regs->leveldetect1, gpio_bit,
+		  trigger & IRQ_TYPE_LEVEL_HIGH);
+	_gpio_rmw(base, bank->regs->risingdetect, gpio_bit,
+		  trigger & IRQ_TYPE_EDGE_RISING);
+	_gpio_rmw(base, bank->regs->fallingdetect, gpio_bit,
+		  trigger & IRQ_TYPE_EDGE_FALLING);
+
+	if (likely(!(bank->non_wakeup_gpios & gpio_bit)))
+		_gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0);
+
 	/* This part needs to be executed always for OMAP{34xx, 44xx} */
-	if (cpu_is_omap34xx() || cpu_is_omap44xx() ||
-			(bank->non_wakeup_gpios & gpio_bit)) {
+	if (!bank->regs->irqctrl) {
+		/* On omap24xx proceed only when valid GPIO bit is set */
+		if (bank->non_wakeup_gpios) {
+			if (!(bank->non_wakeup_gpios & gpio_bit))
+				goto exit;
+		}
+
 		/*
 		 * Log the edge gpio and manually trigger the IRQ
 		 * after resume if the input level changes
@@ -257,11 +237,11 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
 			bank->enabled_non_wakeup_gpios &= ~gpio_bit;
 	}
 
+exit:
 	bank->level_mask =
 		__raw_readl(bank->base + bank->regs->leveldetect0) |
 		__raw_readl(bank->base + bank->regs->leveldetect1);
 }
-#endif
 
 #ifdef CONFIG_ARCH_OMAP1
 /*
@@ -273,23 +253,10 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
 	void __iomem *reg = bank->base;
 	u32 l = 0;
 
-	switch (bank->method) {
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
-		break;
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_CONTROL;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_INT_CONTROL;
-		break;
-#endif
-	default:
+	if (!bank->regs->irqctrl)
 		return;
-	}
+
+	reg += bank->regs->irqctrl;
 
 	l = __raw_readl(reg);
 	if ((l >> gpio) & 1)
@@ -299,31 +266,21 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
 
 	__raw_writel(l, reg);
 }
+#else
+static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) {}
 #endif
 
 static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 {
 	void __iomem *reg = bank->base;
+	void __iomem *base = bank->base;
 	u32 l = 0;
 
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
-		l = __raw_readl(reg);
-		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
-			bank->toggle_mask |= 1 << gpio;
-		if (trigger & IRQ_TYPE_EDGE_RISING)
-			l |= 1 << gpio;
-		else if (trigger & IRQ_TYPE_EDGE_FALLING)
-			l &= ~(1 << gpio);
-		else
-			goto bad;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_CONTROL;
+	if (bank->regs->leveldetect0 && bank->regs->wkup_en) {
+		set_gpio_trigger(bank, gpio, trigger);
+	} else if (bank->regs->irqctrl) {
+		reg += bank->regs->irqctrl;
+
 		l = __raw_readl(reg);
 		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
 			bank->toggle_mask |= 1 << gpio;
@@ -332,15 +289,15 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 		else if (trigger & IRQ_TYPE_EDGE_FALLING)
 			l &= ~(1 << gpio);
 		else
-			goto bad;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
+			return -EINVAL;
+
+		__raw_writel(l, reg);
+	} else if (bank->regs->edgectrl1) {
 		if (gpio & 0x08)
-			reg += OMAP1610_GPIO_EDGE_CTRL2;
+			reg += bank->regs->edgectrl2;
 		else
-			reg += OMAP1610_GPIO_EDGE_CTRL1;
+			reg += bank->regs->edgectrl1;
+
 		gpio &= 0x07;
 		l = __raw_readl(reg);
 		l &= ~(3 << (gpio << 1));
@@ -348,40 +305,12 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 			l |= 2 << (gpio << 1);
 		if (trigger & IRQ_TYPE_EDGE_FALLING)
 			l |= 1 << (gpio << 1);
-		if (trigger)
-			/* Enable wake-up during idle for dynamic tick */
-			__raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_SET_WAKEUPENA);
-		else
-			__raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA);
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_INT_CONTROL;
-		l = __raw_readl(reg);
-		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
-			bank->toggle_mask |= 1 << gpio;
-		if (trigger & IRQ_TYPE_EDGE_RISING)
-			l |= 1 << gpio;
-		else if (trigger & IRQ_TYPE_EDGE_FALLING)
-			l &= ~(1 << gpio);
-		else
-			goto bad;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP2PLUS
-	case METHOD_GPIO_24XX:
-	case METHOD_GPIO_44XX:
-		set_24xx_gpio_triggering(bank, gpio, trigger);
-		return 0;
-#endif
-	default:
-		goto bad;
+
+		/* Enable wake-up during idle for dynamic tick */
+		_gpio_rmw(base, bank->regs->wkup_en, 1 << gpio, trigger);
+		__raw_writel(l, reg);
 	}
-	__raw_writel(l, reg);
 	return 0;
-bad:
-	return -EINVAL;
 }
 
 static int gpio_irq_type(struct irq_data *d, unsigned type)
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (9 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 10/25] gpio/omap: cleanup set_gpio_triggering function Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-04-21 14:03   ` Janusz Krzysztofik
  2012-02-02 17:30 ` [PATCH v9 12/25] gpio/omap: use pinctrl offset instead of macro Tarun Kanti DebBarma
                   ` (17 subsequent siblings)
  28 siblings, 1 reply; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma, Charulatha V

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 <tarun.kanti@ti.com>
Signed-off-by: Charulatha V <charu@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap1/gpio16xx.c |   35 +++++++++++++++++-
 drivers/gpio/gpio-omap.c       |   77 ++++++++++++----------------------------
 2 files changed, 57 insertions(+), 55 deletions(-)

diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index 46bb57a..86ac415 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -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;
 }
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index f39d9e4..a948351 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -610,7 +610,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 			if (!(isr & 1))
 				continue;
 
-#ifdef CONFIG_ARCH_OMAP1
 			/*
 			 * Some chips can't respond to both rising and falling
 			 * at the same time.  If this irq was requested with
@@ -620,7 +619,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 			 */
 			if (bank->toggle_mask & (1 << gpio_index))
 				_toggle_gpio_edge_triggering(bank, gpio_index);
-#endif
 
 			generic_handle_irq(gpio_irq);
 		}
@@ -898,62 +896,30 @@ static void __init omap_gpio_show_rev(struct gpio_bank *bank)
  */
 static struct lock_class_key gpio_lock_class;
 
-/* TODO: Cleanup cpu_is_* checks */
 static void omap_gpio_mod_init(struct gpio_bank *bank)
 {
-	if (cpu_class_is_omap2()) {
-		if (cpu_is_omap44xx()) {
-			__raw_writel(0xffffffff, bank->base +
-					OMAP4_GPIO_IRQSTATUSCLR0);
-			__raw_writel(0x00000000, bank->base +
-					 OMAP4_GPIO_DEBOUNCENABLE);
-			/* Initialize interface clk ungated, module enabled */
-			__raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
-		} else if (cpu_is_omap34xx()) {
-			__raw_writel(0x00000000, bank->base +
-					OMAP24XX_GPIO_IRQENABLE1);
-			__raw_writel(0xffffffff, bank->base +
-					OMAP24XX_GPIO_IRQSTATUS1);
-			__raw_writel(0x00000000, bank->base +
-					OMAP24XX_GPIO_DEBOUNCE_EN);
-
-			/* Initialize interface clk ungated, module enabled */
-			__raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
-		}
-	} else if (cpu_class_is_omap1()) {
-		if (bank_is_mpuio(bank)) {
-			__raw_writew(0xffff, bank->base +
-				OMAP_MPUIO_GPIO_MASKIT / bank->stride);
-			mpuio_init(bank);
-		}
-		if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
-			__raw_writew(0xffff, bank->base
-						+ OMAP1510_GPIO_INT_MASK);
-			__raw_writew(0x0000, bank->base
-						+ OMAP1510_GPIO_INT_STATUS);
-		}
-		if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) {
-			__raw_writew(0x0000, bank->base
-						+ OMAP1610_GPIO_IRQENABLE1);
-			__raw_writew(0xffff, bank->base
-						+ OMAP1610_GPIO_IRQSTATUS1);
-			__raw_writew(0x0014, bank->base
-						+ OMAP1610_GPIO_SYSCONFIG);
+	void __iomem *base = bank->base;
+	u32 l = 0xffffffff;
 
-			/*
-			 * 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);
-		}
-		if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) {
-			__raw_writel(0xffffffff, bank->base
-						+ OMAP7XX_GPIO_INT_MASK);
-			__raw_writel(0x00000000, bank->base
-						+ OMAP7XX_GPIO_INT_STATUS);
-		}
+	if (bank->width == 16)
+		l = 0xffff;
+
+	if (bank_is_mpuio(bank)) {
+		__raw_writel(l, bank->base + bank->regs->irqenable);
+		return;
 	}
+
+	_gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv);
+	_gpio_rmw(base, bank->regs->irqstatus, l,
+					bank->regs->irqenable_inv == false);
+	_gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0);
+	_gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0);
+	if (bank->regs->debounce_en)
+		_gpio_rmw(base, bank->regs->debounce_en, 0, 1);
+
+	 /* Initialize interface clk ungated, module enabled */
+	if (bank->regs->ctrl)
+		_gpio_rmw(base, bank->regs->ctrl, 0, 1);
 }
 
 static __init void
@@ -1104,6 +1070,9 @@ 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))
+		mpuio_init(bank);
+
 	omap_gpio_mod_init(bank);
 	omap_gpio_chip_init(bank);
 	omap_gpio_show_rev(bank);
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 12/25] gpio/omap: use pinctrl offset instead of macro
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (10 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 13/25] gpio/omap: remove unnecessary bit-masking for read access Tarun Kanti DebBarma
                   ` (16 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Charulatha V

From: Charulatha V <charu@ti.com>

Use regs->pinctrl field instead of using the macro OMAP1510_GPIO_PIN_CONTROL

Signed-off-by: Charulatha V <charu@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 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(-)

diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
index 2adfece..950e467 100644
--- a/arch/arm/mach-omap1/gpio15xx.c
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -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 = {
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 9e403e5..8be1651 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -198,6 +198,7 @@ struct omap_gpio_reg_offs {
 	u16 irqctrl;
 	u16 edgectrl1;
 	u16 edgectrl2;
+	u16 pinctrl;
 
 	bool irqenable_inv;
 };
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index a948351..485b6b2 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -490,15 +490,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;
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 13/25] gpio/omap: remove unnecessary bit-masking for read access
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (11 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 12/25] gpio/omap: use pinctrl offset instead of macro Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 14/25] gpio/omap: remove bank->method & METHOD_* macros Tarun Kanti DebBarma
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma, Charulatha V

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 <charu@ti.com>
Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 drivers/gpio/gpio-omap.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 485b6b2..38beccc 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -576,9 +576,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;
 
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 14/25] gpio/omap: remove bank->method & METHOD_* macros
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (12 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 13/25] gpio/omap: remove unnecessary bit-masking for read access Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 15/25] gpio/omap: fix bankwidth for OMAP7xx MPUIO Tarun Kanti DebBarma
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Charulatha V, Tarun Kanti DebBarma

From: Charulatha V <charu@ti.com>

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.

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 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(-)

diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
index 950e467..634903e 100644
--- a/arch/arm/mach-omap1/gpio15xx.c
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -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,
 };
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
index 86ac415..1c5f90e 100644
--- a/arch/arm/mach-omap1/gpio16xx.c
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -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,
 };
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
index 207a23c..433491c 100644
--- a/arch/arm/mach-omap1/gpio7xx.c
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -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,
 };
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index f4c45ca..dfda6b3 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -74,7 +74,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;
@@ -97,7 +96,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;
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index 8be1651..cb75b65 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -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;
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 38beccc..951d784 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -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;
@@ -693,14 +693,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);
@@ -762,23 +754,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;
@@ -899,7 +876,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;
 	}
@@ -951,7 +928,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
@@ -964,12 +940,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";
@@ -984,7 +958,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);
@@ -1028,11 +1002,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;
@@ -1065,7 +1039,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);
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 15/25] gpio/omap: fix bankwidth for OMAP7xx MPUIO
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (13 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 14/25] gpio/omap: remove bank->method & METHOD_* macros Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 16/25] gpio/omap: use pm-runtime framework Tarun Kanti DebBarma
                   ` (13 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Charulatha V

From: Charulatha V <charu@ti.com>

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 <charu@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap1/gpio7xx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
index 433491c..4771d6b 100644
--- a/arch/arm/mach-omap1/gpio7xx.c
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -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,
 };
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 16/25] gpio/omap: use pm-runtime framework
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (14 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 15/25] gpio/omap: fix bankwidth for OMAP7xx MPUIO Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 17/25] gpio/omap: optimize suspend and resume functions Tarun Kanti DebBarma
                   ` (12 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma, Charulatha V

Call runtime pm APIs pm_runtime_get_sync() and pm_runtime_put()
for enabling/disabling clocks appropriately. Remove syscore_ops and
instead use SET_RUNTIME_PM_OPS macro.

There is no more need to call omap_device_disable_idle_on_suspend
since driver is PM runtime adapted now.

Signed-off-by: Charulatha V <charu@ti.com>
Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/gpio.c |    2 -
 drivers/gpio/gpio-omap.c   |   65 ++++++++++++++++++++++++++++---------------
 2 files changed, 42 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index dfda6b3..1e0b750 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -136,8 +136,6 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 		return PTR_ERR(pdev);
 	}
 
-	omap_device_disable_idle_on_suspend(pdev);
-
 	return 0;
 }
 
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 951d784..b92a23f 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -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>
@@ -483,8 +484,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().
 	 */
@@ -540,6 +547,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(bank->dev);
 }
 
 /*
@@ -565,6 +579,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;
@@ -625,6 +640,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)
@@ -1037,6 +1053,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)
@@ -1046,6 +1063,8 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 	omap_gpio_chip_init(bank);
 	omap_gpio_show_rev(bank);
 
+	pm_runtime_put(bank->dev);
+
 	list_add_tail(&bank->node, &omap_gpio_list);
 
 	return ret;
@@ -1056,7 +1075,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;
 
@@ -1080,7 +1101,7 @@ static int omap_gpio_suspend(void)
 	return 0;
 }
 
-static void omap_gpio_resume(void)
+static int omap_gpio_resume(struct device *dev)
 {
 	struct gpio_bank *bank;
 
@@ -1089,21 +1110,17 @@ static void omap_gpio_resume(void)
 		unsigned long flags;
 
 		if (!bank->regs->wkup_en)
-			return;
+			return 0;
 
 		spin_lock_irqsave(&bank->lock, flags);
 		_gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0);
 		_gpio_rmw(base, bank->regs->wkup_en, bank->saved_wakeup, 1);
 		spin_unlock_irqrestore(&bank->lock, flags);
 	}
+
+	return 0;
 }
 
-static struct syscore_ops omap_gpio_syscore_ops = {
-	.suspend	= omap_gpio_suspend,
-	.resume		= omap_gpio_resume,
-};
-
-#ifdef CONFIG_ARCH_OMAP2PLUS
 
 static void omap_gpio_save_context(struct gpio_bank *bank);
 static void omap_gpio_restore_context(struct gpio_bank *bank);
@@ -1145,11 +1162,15 @@ void omap2_gpio_prepare_for_idle(int off_mode)
 		__raw_writel(l2, bank->base + bank->regs->risingdetect);
 
 save_gpio_context:
+
 		if (bank->get_context_loss_count)
 			bank->context_loss_count =
 				bank->get_context_loss_count(bank->dev);
 
 		omap_gpio_save_context(bank);
+
+		if (!pm_runtime_suspended(bank->dev))
+			pm_runtime_put(bank->dev);
 	}
 }
 
@@ -1168,6 +1189,9 @@ void omap2_gpio_resume_after_idle(void)
 		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
 			clk_enable(bank->dbck);
 
+		if (pm_runtime_suspended(bank->dev))
+			pm_runtime_get_sync(bank->dev);
+
 		if (bank->get_context_loss_count) {
 			context_lost_cnt_after =
 				bank->get_context_loss_count(bank->dev);
@@ -1274,12 +1298,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,
 	},
 };
 
@@ -1293,16 +1325,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);
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 17/25] gpio/omap: optimize suspend and resume functions
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (15 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 16/25] gpio/omap: use pm-runtime framework Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 18/25] gpio/omap: cleanup prepare_for_idle and resume_after_idle Tarun Kanti DebBarma
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma

There 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.

Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 drivers/gpio/gpio-omap.c |   54 ++++++++++++++++++++++++---------------------
 1 files changed, 29 insertions(+), 25 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index b92a23f..9db892c 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1052,6 +1052,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);
@@ -1079,44 +1081,46 @@ err_exit:
 
 static int omap_gpio_suspend(struct device *dev)
 {
-	struct gpio_bank *bank;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_bank *bank = platform_get_drvdata(pdev);
+	void __iomem *base = bank->base;
+	void __iomem *wakeup_enable;
+	unsigned long flags;
 
-	list_for_each_entry(bank, &omap_gpio_list, node) {
-		void __iomem *base = bank->base;
-		void __iomem *wake_status;
-		unsigned long flags;
+	if (!bank->mod_usage || !bank->loses_context)
+		return 0;
 
-		if (!bank->regs->wkup_en)
-			return 0;
+	if (!bank->regs->wkup_en || !bank->suspend_wakeup)
+		return 0;
 
-		wake_status = bank->base + bank->regs->wkup_en;
+	wakeup_enable = 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, 0xffffffff, 0);
-		_gpio_rmw(base, bank->regs->wkup_en, bank->suspend_wakeup, 1);
-		spin_unlock_irqrestore(&bank->lock, flags);
-	}
+	spin_lock_irqsave(&bank->lock, flags);
+	bank->saved_wakeup = __raw_readl(wakeup_enable);
+	_gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0);
+	_gpio_rmw(base, bank->regs->wkup_en, bank->suspend_wakeup, 1);
+	spin_unlock_irqrestore(&bank->lock, flags);
 
 	return 0;
 }
 
 static int omap_gpio_resume(struct device *dev)
 {
-	struct gpio_bank *bank;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_bank *bank = platform_get_drvdata(pdev);
+	void __iomem *base = bank->base;
+	unsigned long flags;
 
-	list_for_each_entry(bank, &omap_gpio_list, node) {
-		void __iomem *base = bank->base;
-		unsigned long flags;
+	if (!bank->mod_usage || !bank->loses_context)
+		return 0;
 
-		if (!bank->regs->wkup_en)
-			return 0;
+	if (!bank->regs->wkup_en || !bank->saved_wakeup)
+		return 0;
 
-		spin_lock_irqsave(&bank->lock, flags);
-		_gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0);
-		_gpio_rmw(base, bank->regs->wkup_en, bank->saved_wakeup, 1);
-		spin_unlock_irqrestore(&bank->lock, flags);
-	}
+	spin_lock_irqsave(&bank->lock, flags);
+	_gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0);
+	_gpio_rmw(base, bank->regs->wkup_en, bank->saved_wakeup, 1);
+	spin_unlock_irqrestore(&bank->lock, flags);
 
 	return 0;
 }
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 18/25] gpio/omap: cleanup prepare_for_idle and resume_after_idle
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (16 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 17/25] gpio/omap: optimize suspend and resume functions Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 19/25] gpio/omap: fix debounce clock handling Tarun Kanti DebBarma
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma, Charulatha V

Since *_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.

To avoid invalid context restore happening in *_runtime_resume()
callback as a result of *_get_sync() call in *_gpio_probe(), update
bank->context_loss_count. This would make context restore condition
check false in the callback and skip restore until further
initialization take place. The workaround_enabled static variable
is now a member of struct gpio_bank.

Unlike most GPIO registers the OE has 0xffffffff as the default value.
To make sure invalid context is not restored, updating the OE context
with default value.

Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Signed-off-by: Charulatha V <charu@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 drivers/gpio/gpio-omap.c |  241 +++++++++++++++++++++++++++-------------------
 1 files changed, 143 insertions(+), 98 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 9db892c..8b619fd 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -29,6 +29,8 @@
 #include <asm/gpio.h>
 #include <asm/mach/irq.h>
 
+#define OFF_MODE	1
+
 static LIST_HEAD(omap_gpio_list);
 
 struct gpio_regs {
@@ -73,6 +75,8 @@ struct gpio_bank {
 	u32 width;
 	int context_loss_count;
 	u16 id;
+	int power_mode;
+	bool workaround_enabled;
 
 	void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable);
 	int (*get_context_loss_count)(struct device *dev);
@@ -905,6 +909,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
 	if (bank->regs->debounce_en)
 		_gpio_rmw(base, bank->regs->debounce_en, 0, 1);
 
+	/* Save OE default value (0xffffffff) in the context */
+	bank->context.oe = __raw_readl(bank->base + bank->regs->direction);
 	 /* Initialize interface clk ungated, module enabled */
 	if (bank->regs->ctrl)
 		_gpio_rmw(base, bank->regs->ctrl, 0, 1);
@@ -1129,135 +1135,170 @@ 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;
-
-	list_for_each_entry(bank, &omap_gpio_list, node) {
-		u32 l1 = 0, l2 = 0;
-		int j;
-
-		if (!bank->loses_context)
-			continue;
-
-		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
-			clk_disable(bank->dbck);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_bank *bank = platform_get_drvdata(pdev);
+	u32 l1 = 0, l2 = 0;
+	unsigned long flags;
 
-		if (!off_mode)
-			continue;
+	spin_lock_irqsave(&bank->lock, flags);
+	if (bank->power_mode != OFF_MODE) {
+		bank->power_mode = 0;
+		goto save_gpio_context;
+	}
+	/*
+	 * 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 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;
+	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);
 
-		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);
+	bank->saved_fallingdetect = l1;
+	bank->saved_risingdetect = l2;
+	l1 &= ~bank->enabled_non_wakeup_gpios;
+	l2 &= ~bank->enabled_non_wakeup_gpios;
 
-		bank->saved_fallingdetect = l1;
-		bank->saved_risingdetect = l2;
-		l1 &= ~bank->enabled_non_wakeup_gpios;
-		l2 &= ~bank->enabled_non_wakeup_gpios;
+	__raw_writel(l1, bank->base + bank->regs->fallingdetect);
+	__raw_writel(l2, bank->base + bank->regs->risingdetect);
 
-		__raw_writel(l1, bank->base + bank->regs->fallingdetect);
-		__raw_writel(l2, bank->base + bank->regs->risingdetect);
+	bank->workaround_enabled = true;
 
 save_gpio_context:
-
-		if (bank->get_context_loss_count)
-			bank->context_loss_count =
+	if (bank->get_context_loss_count)
+		bank->context_loss_count =
 				bank->get_context_loss_count(bank->dev);
 
-		omap_gpio_save_context(bank);
+	omap_gpio_save_context(bank);
+	spin_unlock_irqrestore(&bank->lock, flags);
 
-		if (!pm_runtime_suspended(bank->dev))
-			pm_runtime_put(bank->dev);
-	}
+	return 0;
 }
 
-void omap2_gpio_resume_after_idle(void)
+static int omap_gpio_runtime_resume(struct device *dev)
 {
-	struct gpio_bank *bank;
-
-	list_for_each_entry(bank, &omap_gpio_list, node) {
-		int context_lost_cnt_after;
-		u32 l = 0, gen, gen0, gen1;
-		int j;
-
-		if (!bank->loses_context)
-			continue;
-
-		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
-			clk_enable(bank->dbck);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_bank *bank = platform_get_drvdata(pdev);
+	int context_lost_cnt_after;
+	u32 l = 0, gen, gen0, gen1;
+	unsigned long flags;
 
-		if (pm_runtime_suspended(bank->dev))
-			pm_runtime_get_sync(bank->dev);
+	spin_lock_irqsave(&bank->lock, flags);
+	if (!bank->enabled_non_wakeup_gpios || !bank->workaround_enabled) {
+		spin_unlock_irqrestore(&bank->lock, flags);
+		return 0;
+	}
 
-		if (bank->get_context_loss_count) {
-			context_lost_cnt_after =
-				bank->get_context_loss_count(bank->dev);
-			if (context_lost_cnt_after != bank->context_loss_count
-				|| !context_lost_cnt_after)
-				omap_gpio_restore_context(bank);
+	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;
 		}
+	}
 
-		if (!(bank->enabled_non_wakeup_gpios))
-			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);
 
-		__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;
 
-		/* 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;
 
-		/*
-		 * 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);
 
-		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;
 
-		/* 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;
 
-		if (gen) {
-			u32 old0, old1;
+		old0 = __raw_readl(bank->base + bank->regs->leveldetect0);
+		old1 = __raw_readl(bank->base + bank->regs->leveldetect1);
 
-			old0 = __raw_readl(bank->base +
+		if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+			__raw_writel(old0 | gen, bank->base +
 						bank->regs->leveldetect0);
-			old1 = __raw_readl(bank->base +
+			__raw_writel(old1 | gen, 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 +
+		if (cpu_is_omap44xx()) {
+			__raw_writel(old0 | l, bank->base +
 						bank->regs->leveldetect0);
-			__raw_writel(old1, bank->base +
+			__raw_writel(old1 | l, bank->base +
 						bank->regs->leveldetect1);
 		}
+		__raw_writel(old0, bank->base + bank->regs->leveldetect0);
+		__raw_writel(old1, bank->base + bank->regs->leveldetect1);
+	}
+
+	bank->workaround_enabled = false;
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	return 0;
+}
+
+void omap2_gpio_prepare_for_idle(int pwr_mode)
+{
+	struct gpio_bank *bank;
+
+	list_for_each_entry(bank, &omap_gpio_list, node) {
+		int j;
+
+		if (!bank->mod_usage || !bank->loses_context)
+			continue;
+
+		bank->power_mode = pwr_mode;
+
+		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
+			clk_disable(bank->dbck);
+
+		pm_runtime_put_sync_suspend(bank->dev);
+	}
+}
+
+void omap2_gpio_resume_after_idle(void)
+{
+	struct gpio_bank *bank;
+
+	list_for_each_entry(bank, &omap_gpio_list, node) {
+		int j;
+
+		if (!bank->mod_usage || !bank->loses_context)
+			continue;
+
+		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
+			clk_enable(bank->dbck);
+
+		pm_runtime_get_sync(bank->dev);
 	}
 }
 
@@ -1305,10 +1346,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 = {
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 19/25] gpio/omap: fix debounce clock handling
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (17 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 18/25] gpio/omap: cleanup prepare_for_idle and resume_after_idle Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 20/25] gpio/omap: fix incorrect access of debounce module Tarun Kanti DebBarma
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma

The dbck_enable_mask indicates which all GPIOs within a bank have debounce
enabled and dbck is enabled/disabled based upon this. But there is no
mechanism to track the dbck state. In order to manage the dbck state we need
additional flag and logic so that turning off/on dbck is synchronized with
pm_runtime_put/get_sync calls.

Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 drivers/gpio/gpio-omap.c |   29 +++++++++++++++++++----------
 1 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 8b619fd..0ea3dc9 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -67,6 +67,7 @@ struct gpio_bank {
 	struct clk *dbck;
 	u32 mod_usage;
 	u32 dbck_enable_mask;
+	bool dbck_enabled;
 	struct device *dev;
 	bool is_mpuio;
 	bool dbck_flag;
@@ -158,6 +159,22 @@ static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
 	__raw_writel(l, base + reg);
 }
 
+static inline void _gpio_dbck_enable(struct gpio_bank *bank)
+{
+	if (bank->dbck_enable_mask && !bank->dbck_enabled) {
+		clk_enable(bank->dbck);
+		bank->dbck_enabled = true;
+	}
+}
+
+static inline void _gpio_dbck_disable(struct gpio_bank *bank)
+{
+	if (bank->dbck_enable_mask && bank->dbck_enabled) {
+		clk_disable(bank->dbck);
+		bank->dbck_enabled = false;
+	}
+}
+
 /**
  * _set_gpio_debounce - low level gpio debounce time
  * @bank: the gpio bank we're acting upon
@@ -1176,6 +1193,7 @@ save_gpio_context:
 				bank->get_context_loss_count(bank->dev);
 
 	omap_gpio_save_context(bank);
+	_gpio_dbck_disable(bank);
 	spin_unlock_irqrestore(&bank->lock, flags);
 
 	return 0;
@@ -1190,6 +1208,7 @@ static int omap_gpio_runtime_resume(struct device *dev)
 	unsigned long flags;
 
 	spin_lock_irqsave(&bank->lock, flags);
+	_gpio_dbck_enable(bank);
 	if (!bank->enabled_non_wakeup_gpios || !bank->workaround_enabled) {
 		spin_unlock_irqrestore(&bank->lock, flags);
 		return 0;
@@ -1271,16 +1290,11 @@ void omap2_gpio_prepare_for_idle(int pwr_mode)
 	struct gpio_bank *bank;
 
 	list_for_each_entry(bank, &omap_gpio_list, node) {
-		int j;
-
 		if (!bank->mod_usage || !bank->loses_context)
 			continue;
 
 		bank->power_mode = pwr_mode;
 
-		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
-			clk_disable(bank->dbck);
-
 		pm_runtime_put_sync_suspend(bank->dev);
 	}
 }
@@ -1290,14 +1304,9 @@ void omap2_gpio_resume_after_idle(void)
 	struct gpio_bank *bank;
 
 	list_for_each_entry(bank, &omap_gpio_list, node) {
-		int j;
-
 		if (!bank->mod_usage || !bank->loses_context)
 			continue;
 
-		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
-			clk_enable(bank->dbck);
-
 		pm_runtime_get_sync(bank->dev);
 	}
 }
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 20/25] gpio/omap: fix incorrect access of debounce module
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (18 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 19/25] gpio/omap: fix debounce clock handling Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 21/25] gpio/omap: remove omap_gpio_save_context overhead Tarun Kanti DebBarma
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma

Enable debounce clock before writing/reading debounce registers.
Disable the clock at the end so that it is synchronized with the
pm_runtime_get/put_sync calls.

Enable debounce clock per module. This call is mandatory because
in omap_gpio_request() when *_runtime_get_sync() is called,
_gpio_dbck_enable() within runtime callbck fails to turn on dbck
 because dbck_enable_mask used within _gpio_dbck_enable() is still
not initialized at that point. Therefore we have to enable dbck here.

Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 drivers/gpio/gpio-omap.c |   18 +++++++++++++-----
 1 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 0ea3dc9..7515382 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -203,22 +203,30 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
 
 	l = GPIO_BIT(bank, gpio);
 
+	clk_enable(bank->dbck);
 	reg = bank->base + bank->regs->debounce;
 	__raw_writel(debounce, reg);
 
 	reg = bank->base + bank->regs->debounce_en;
 	val = __raw_readl(reg);
 
-	if (debounce) {
+	if (debounce)
 		val |= l;
-		clk_enable(bank->dbck);
-	} else {
+	else
 		val &= ~l;
-		clk_disable(bank->dbck);
-	}
 	bank->dbck_enable_mask = val;
 
 	__raw_writel(val, reg);
+	clk_disable(bank->dbck);
+	/*
+	 * Enable debounce clock per module.
+	 * This call is mandatory because in omap_gpio_request() when
+	 * *_runtime_get_sync() is called,  _gpio_dbck_enable() within
+	 * runtime callbck fails to turn on dbck because dbck_enable_mask
+	 * used within _gpio_dbck_enable() is still not initialized at
+	 * that point. Therefore we have to enable dbck here.
+	 */
+	_gpio_dbck_enable(bank);
 }
 
 static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio,
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 21/25] gpio/omap: remove omap_gpio_save_context overhead
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (19 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 20/25] gpio/omap: fix incorrect access of debounce module Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 22/25] gpio/omap: save and restore debounce registers Tarun Kanti DebBarma
                   ` (7 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Tarun Kanti DebBarma

Context is now saved dynamically in respective functions whenever and
whichever registers are modified. This avoid overhead of saving all
registers context in the runtime suspend callback.

Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 drivers/gpio/gpio-omap.c |   56 +++++++++++++++++++++++-----------------------
 1 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 7515382..4056d78 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -101,6 +101,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;
 }
 
 
@@ -131,6 +132,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)
@@ -244,8 +246,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 (!bank->regs->irqctrl) {
@@ -338,6 +352,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;
@@ -430,6 +446,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)
@@ -450,6 +467,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)
@@ -541,6 +559,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;
@@ -558,9 +577,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);
 
@@ -572,6 +594,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);
@@ -1157,7 +1180,6 @@ 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);
 
 static int omap_gpio_runtime_suspend(struct device *dev)
@@ -1170,7 +1192,7 @@ static int omap_gpio_runtime_suspend(struct device *dev)
 	spin_lock_irqsave(&bank->lock, flags);
 	if (bank->power_mode != OFF_MODE) {
 		bank->power_mode = 0;
-		goto save_gpio_context;
+		goto update_gpio_context_count;
 	}
 	/*
 	 * If going to OFF, remove triggering for all
@@ -1178,7 +1200,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);
@@ -1195,12 +1217,11 @@ static int omap_gpio_runtime_suspend(struct device *dev)
 
 	bank->workaround_enabled = true;
 
-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);
 	_gpio_dbck_disable(bank);
 	spin_unlock_irqrestore(&bank->lock, flags);
 
@@ -1319,27 +1340,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 =
-			__raw_readl(bank->base + bank->regs->fallingdetect);
-	bank->context.dataout = __raw_readl(bank->base + bank->regs->dataout);
-}
-
 static void omap_gpio_restore_context(struct gpio_bank *bank)
 {
 	__raw_writel(bank->context.irqenable1,
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 22/25] gpio/omap: save and restore debounce registers
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (20 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 21/25] gpio/omap: remove omap_gpio_save_context overhead Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 23/25] gpio/omap: enable irq at the end of all configuration in restore Tarun Kanti DebBarma
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Nishanth Menon, Tarun Kanti DebBarma

From: Nishanth Menon <nm@ti.com>

GPIO debounce registers need to be saved and restored for proper functioning
of driver.

Signed-off-by: Nishanth Menon <nm@ti.com>
tarun.kanti@ti.com: Debounce context save is moved to _set_gpio_debounce()
as part of dynamic context save to remove overhead.
Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 drivers/gpio/gpio-omap.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 4056d78..560567d 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -44,6 +44,8 @@ struct gpio_regs {
 	u32 risingdetect;
 	u32 fallingdetect;
 	u32 dataout;
+	u32 debounce;
+	u32 debounce_en;
 };
 
 struct gpio_bank {
@@ -229,6 +231,10 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
 	 * that point. Therefore we have to enable dbck here.
 	 */
 	_gpio_dbck_enable(bank);
+	if (bank->dbck_enable_mask) {
+		bank->context.debounce = debounce;
+		bank->context.debounce_en = val;
+	}
 }
 
 static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio,
@@ -1359,6 +1365,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
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 23/25] gpio/omap: enable irq at the end of all configuration in restore
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (21 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 22/25] gpio/omap: save and restore debounce registers Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 24/25] gpio/omap: restore OE only after setting the output level Tarun Kanti DebBarma
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Nishanth Menon, Tarun Kanti DebBarma

From: Nishanth Menon <nm@ti.com>

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.

Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 drivers/gpio/gpio-omap.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 560567d..36aaea7 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1348,10 +1348,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);
@@ -1371,6 +1367,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
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 24/25] gpio/omap: restore OE only after setting the output level
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (22 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 23/25] gpio/omap: enable irq at the end of all configuration in restore Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 17:30 ` [PATCH v9 25/25] gpio/omap: handle set_dataout reg capable IP on restore Tarun Kanti DebBarma
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Nishanth Menon, Tarun Kanti DebBarma

From: Nishanth Menon <nm@ti.com>

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.

Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 drivers/gpio/gpio-omap.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 36aaea7..81fdbcf 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1351,7 +1351,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,
@@ -1361,6 +1360,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);
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v9 25/25] gpio/omap: handle set_dataout reg capable IP on restore
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (23 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 24/25] gpio/omap: restore OE only after setting the output level Tarun Kanti DebBarma
@ 2012-02-02 17:30 ` Tarun Kanti DebBarma
  2012-02-02 19:42 ` [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Grant Likely
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 64+ messages in thread
From: Tarun Kanti DebBarma @ 2012-02-02 17:30 UTC (permalink / raw)
  To: linux-omap
  Cc: grant.likely, khilman, tony, linux-kernel, linux-arm-kernel,
	Nishanth Menon, Tarun Kanti DebBarma

From: Nishanth Menon <nm@ti.com>

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.

Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 drivers/gpio/gpio-omap.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 81fdbcf..4273401 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1359,7 +1359,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 && bank->regs->clr_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) {
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-02 17:30 ` [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count Tarun Kanti DebBarma
@ 2012-02-02 18:41   ` Felipe Balbi
  2012-02-02 19:16     ` Grant Likely
  0 siblings, 1 reply; 64+ messages in thread
From: Felipe Balbi @ 2012-02-02 18:41 UTC (permalink / raw)
  To: Tarun Kanti DebBarma
  Cc: linux-omap, grant.likely, khilman, tony, linux-kernel,
	linux-arm-kernel, Charulatha V

[-- Attachment #1: Type: text/plain, Size: 628 bytes --]

Hi,

On Thu, Feb 02, 2012 at 11:00:27PM +0530, Tarun Kanti DebBarma wrote:
> diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
> index 0b05629..6ea7390 100644
> --- a/drivers/gpio/gpio-omap.c
> +++ b/drivers/gpio/gpio-omap.c
> @@ -28,7 +28,10 @@
>  #include <asm/gpio.h>
>  #include <asm/mach/irq.h>
>  
> +static LIST_HEAD(omap_gpio_list);

I guess it's now too late because patch is acked and everything, but I
think if you make the driver handle one bank alone and just instantiate
it multiple times (omap_gpio.0, omap_gpio.1, omap_gpio.3, etc) driver
would be faaaaaar simpler.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-02 18:41   ` Felipe Balbi
@ 2012-02-02 19:16     ` Grant Likely
  2012-02-02 19:45       ` Felipe Balbi
  0 siblings, 1 reply; 64+ messages in thread
From: Grant Likely @ 2012-02-02 19:16 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Tarun Kanti DebBarma, linux-omap, khilman, tony, linux-kernel,
	linux-arm-kernel, Charulatha V

On Thu, Feb 02, 2012 at 08:41:07PM +0200, Felipe Balbi wrote:
> Hi,
> 
> On Thu, Feb 02, 2012 at 11:00:27PM +0530, Tarun Kanti DebBarma wrote:
> > diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
> > index 0b05629..6ea7390 100644
> > --- a/drivers/gpio/gpio-omap.c
> > +++ b/drivers/gpio/gpio-omap.c
> > @@ -28,7 +28,10 @@
> >  #include <asm/gpio.h>
> >  #include <asm/mach/irq.h>
> >  
> > +static LIST_HEAD(omap_gpio_list);
> 
> I guess it's now too late because patch is acked and everything, but I
> think if you make the driver handle one bank alone and just instantiate
> it multiple times (omap_gpio.0, omap_gpio.1, omap_gpio.3, etc) driver
> would be faaaaaar simpler.

Is there any shared state between the banks?  On my very cursory glance it
looked like banks still have some interaction between them.  If not, then
yes I agree that multiple instances would be better.

g.



^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 00/25] gpio/omap: driver cleanup and fixes
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (24 preceding siblings ...)
  2012-02-02 17:30 ` [PATCH v9 25/25] gpio/omap: handle set_dataout reg capable IP on restore Tarun Kanti DebBarma
@ 2012-02-02 19:42 ` Grant Likely
  2012-02-03 17:51   ` Kevin Hilman
  2012-02-03  9:21 ` Hebbar, Gururaja
                   ` (2 subsequent siblings)
  28 siblings, 1 reply; 64+ messages in thread
From: Grant Likely @ 2012-02-02 19:42 UTC (permalink / raw)
  To: Tarun Kanti DebBarma
  Cc: linux-omap, khilman, tony, linux-kernel, linux-arm-kernel

On Thu, Feb 02, 2012 at 11:00:26PM +0530, Tarun Kanti DebBarma wrote:
> The following changes since commit 62aa2b537c6f5957afd98e29f96897419ed5ebab:
>   Linus Torvalds (1):
>         Linux 3.3-rc2
> 
> are available in the git repository at:
> http://gitorious.org/~tarunkanti/omap-sw-develoment/tarunkantis-linux-omap-dev
> Branch: for_3.4/gpio_cleanup_fixes_v9

Bad git url.  I had to replace 'http:' with 'git:'.

I've merged this series into my gpio/next branch.  It should show up in
linux-next in a couple of days.

g.

> 
> 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.
> 
> Power Tests
> a) OMAP3430SDP
> - Modify board-3430sdp.c file to have multiple GPIO modules active
>   with debounce timeout enabled.
> - Enable CPU-Idle
> - Enable UART timeouts
> - Enable offmode
> - echo mem > /sys/power/state
> - Verify retention and offmode count increment
> 
>   Used following patches to avoid exception during system suspend:-
>   [PATCH RFC 1/2] mtd : Prevent the NULL pointer access
>   [PATCH RFC 2/2] mtd : Make the mtd_suspend return 0 if the suspend is not implemented
> 
> # echo mem > /sys/power/state
> [   47.128021] PM: Syncing filesystems ... done.
> [   47.144104] Freezing user space processes ... (elapsed 0.01 seconds) done.
> [   47.168243] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) don                                                                                                 e.
> [   47.205139] Unable to handle kernel NULL pointer dereference at virtual addre                                                                                                 ss 000000a0
> [   47.213317] pgd = deaac000
> [   47.216033] [000000a0] *pgd=9e932831, *pte=00000000, *ppte=00000000
> [   47.222381] Internal error: Oops: 17 [#1] SMP
> [   47.226745] Modules linked in:
> [   47.229827] CPU: 0    Not tainted  (3.3.0-rc2-00031-g12c5c5c #235)
> [   47.236022] PC is at mtd_cls_suspend+0x8/0x20
> [   47.240386] LR is at mtd_cls_suspend+0x8/0x20
> [   47.244750] pc : [<c02e78f8>]    lr : [<c02e78f8>]    psr: a0000013
> [   47.244750] sp : dea1fe60  ip : 22222222  fp : c0ee7d40
> [   47.256256] r10: c0ee7cf0  r9 : 00000000  r8 : c02e78f0
> [   47.261474] r7 : 00000000  r6 : 00000000  r5 : 00000002  r4 : dea45800
> [   47.268005] r3 : deb4cac0  r2 : 00000000  r1 : 00000002  r0 : 00000000
> [   47.274536] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
> [   47.281677] Control: 10c5387d  Table: 9eaac019  DAC: 00000015
> [   47.287445] Process sh (pid: 1177, stack limit = 0xdea1e2f8)
> [   47.293090] Stack: (0xdea1fe60 to 0xdea20000)
> [...]
> 
> b) ZOOM3
> - Enable CPU-Idle
> - Enable UART timeout
> - echo mem > /sys/power/state
> - Wakeup system using serial keyboard
> - Verify retention count increment
> 
> Functional Tests
> - Done on OMAP2430, OMAP3430SDP, ZOOM3, OMAP4430
> 
> Bootup Test
> - Done on OMAP1710
>   Used following patch to fix OMAP1 build error:-
>   [PATCH] i2c: OMAP: Fix OMAP1 build error
> 
> v9:
> - Summary of Comments/Issues fixed
>   * GPIO wakeup does not work
> 
>   * Call debounce clock enable/disable functions from PM runtime callbacks.
>     This will avoid calling the functions from multiple places.
> 
>   * Modify description of following patch to match latest changes.
>     gpio/omap: save and restore debounce registers.
> 
>   * Use (bank->regs->set_dataout && bank->regs->clr_dataout) together instead
>     of using only one of them.
> 
>   * Remove cpu_is_omapxxxx() checks from set_gpio_trigger().
> 
>   * _gpio_dbck_enable() in runtime callback triggered from omap_gpio_request
>     does not enable dbck because dbck_enable_mask is not set at this point.
> 
>   * Workaround associated with an errata got missed in v8. This has been
>     included.
> 
> v8:
> - Remove PM_CONFIG macro around following assignment.
>   pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
> 
> - Once pm_runtime is enabled there is no more need for calling the
>   omap_device_disable_idle_on_suspend(od).
> 
> - With pm_runtime, handling of clocks in Suspend is  taken care of by
>   powerdomain hooks. So remove usage of *_runtime_put/get* from
>   suspend/resume hooks and Idle path.
> 
> - Add handling of debounce clocks along the Suspend and Idle paths.
> 
> - Remove [PATCH 04/24] gpio/omap: fix pwrdm_post_transition call sequence
>   from this series. This will be merged as part of power cleanup series.
> 
> - Remove [PATCH v7 20/26] gpio/omap: skip operations in runtime callbacks
>   The bank->mod_usage check in this patch is not needed any more because
>   they are now already being taken care in suspend/resume and Idle paths.
> 
> - Remove [PATCH v7 26/26] gpio/omap: add dbclk aliases for all gpio modules
>   This is already taken care in hwmod.
> 
> - Remove redundant blank line in
>   [PATCH v7 14/26] gpio/omap: remove unnecessary bit-masking for read access
> 
> -               if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
> -                       isr &= 0x0000ffff;
> 
>                if (bank->level_mask)
>                        level_mask = bank->level_mask & enabled;
> 
> 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 (8):
>   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: 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 (13):
>   gpio/omap: handle save/restore context in GPIO driver
>   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: fix debounce clock handling
>   gpio/omap: fix incorrect access of debounce module
>   gpio/omap: remove omap_gpio_save_context overhead
> 
>  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/gpio.c             |   36 +-
>  arch/arm/mach-omap2/pm34xx.c           |   14 -
>  arch/arm/plat-omap/include/plat/gpio.h |   29 +-
>  drivers/gpio/gpio-omap.c               | 1099 +++++++++++++-------------------
>  7 files changed, 549 insertions(+), 697 deletions(-)
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-02 19:16     ` Grant Likely
@ 2012-02-02 19:45       ` Felipe Balbi
  2012-02-02 20:48         ` Cousson, Benoit
  0 siblings, 1 reply; 64+ messages in thread
From: Felipe Balbi @ 2012-02-02 19:45 UTC (permalink / raw)
  To: Grant Likely
  Cc: Felipe Balbi, Tarun Kanti DebBarma, linux-omap, khilman, tony,
	linux-kernel, linux-arm-kernel, Charulatha V

[-- Attachment #1: Type: text/plain, Size: 1307 bytes --]

On Thu, Feb 02, 2012 at 12:16:30PM -0700, Grant Likely wrote:
> On Thu, Feb 02, 2012 at 08:41:07PM +0200, Felipe Balbi wrote:
> > Hi,
> > 
> > On Thu, Feb 02, 2012 at 11:00:27PM +0530, Tarun Kanti DebBarma wrote:
> > > diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
> > > index 0b05629..6ea7390 100644
> > > --- a/drivers/gpio/gpio-omap.c
> > > +++ b/drivers/gpio/gpio-omap.c
> > > @@ -28,7 +28,10 @@
> > >  #include <asm/gpio.h>
> > >  #include <asm/mach/irq.h>
> > >  
> > > +static LIST_HEAD(omap_gpio_list);
> > 
> > I guess it's now too late because patch is acked and everything, but I
> > think if you make the driver handle one bank alone and just instantiate
> > it multiple times (omap_gpio.0, omap_gpio.1, omap_gpio.3, etc) driver
> > would be faaaaaar simpler.
> 
> Is there any shared state between the banks?  On my very cursory glance it
> looked like banks still have some interaction between them.  If not, then
> yes I agree that multiple instances would be better.

A quick glance at the TRM shows that banks have separate address spaces
and IRQ lines. I think it's done this way because we can handoff one (or
more) bank to other cores on the SoC, so they need to be pretty
independent.

I could be missing something though.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-02 19:45       ` Felipe Balbi
@ 2012-02-02 20:48         ` Cousson, Benoit
  2012-02-02 21:49           ` Felipe Balbi
  0 siblings, 1 reply; 64+ messages in thread
From: Cousson, Benoit @ 2012-02-02 20:48 UTC (permalink / raw)
  To: balbi, khilman
  Cc: Grant Likely, Tarun Kanti DebBarma, linux-omap, tony,
	linux-kernel, linux-arm-kernel, Charulatha V

On 2/2/2012 8:45 PM, Felipe Balbi wrote:
> On Thu, Feb 02, 2012 at 12:16:30PM -0700, Grant Likely wrote:
>> On Thu, Feb 02, 2012 at 08:41:07PM +0200, Felipe Balbi wrote:
>>> Hi,
>>>
>>> On Thu, Feb 02, 2012 at 11:00:27PM +0530, Tarun Kanti DebBarma wrote:
>>>> diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
>>>> index 0b05629..6ea7390 100644
>>>> --- a/drivers/gpio/gpio-omap.c
>>>> +++ b/drivers/gpio/gpio-omap.c
>>>> @@ -28,7 +28,10 @@
>>>>   #include<asm/gpio.h>
>>>>   #include<asm/mach/irq.h>
>>>>
>>>> +static LIST_HEAD(omap_gpio_list);
>>>
>>> I guess it's now too late because patch is acked and everything, but I
>>> think if you make the driver handle one bank alone and just instantiate
>>> it multiple times (omap_gpio.0, omap_gpio.1, omap_gpio.3, etc) driver
>>> would be faaaaaar simpler.
>>
>> Is there any shared state between the banks?  On my very cursory glance it
>> looked like banks still have some interaction between them.  If not, then
>> yes I agree that multiple instances would be better.
>
> A quick glance at the TRM shows that banks have separate address spaces
> and IRQ lines. I think it's done this way because we can handoff one (or
> more) bank to other cores on the SoC, so they need to be pretty
> independent.
>
> I could be missing something though.

In fact the driver already handled the 6 GPIOS banks as individual devices:

[    0.185638] gpiochip_add: registered GPIOs 0 to 31 on device: gpio
[    0.185882] OMAP GPIO hardware version 0.1
[    0.186767] gpiochip_add: registered GPIOs 32 to 63 on device: gpio
[    0.187744] gpiochip_add: registered GPIOs 64 to 95 on device: gpio
[    0.188751] gpiochip_add: registered GPIOs 96 to 127 on device: gpio
[    0.189819] gpiochip_add: registered GPIOs 128 to 159 on device: gpio
[    0.190917] gpiochip_add: registered GPIOs 160 to 191 on device: gpio

That list is only used to iterate over all the instances during CPU idle:

void omap2_gpio_prepare_for_idle(int pwr_mode)
{
	struct gpio_bank *bank;

	list_for_each_entry(bank, &omap_gpio_list, node) {
		if (!bank->mod_usage || !bank->loses_context)
			continue;

		bank->power_mode = pwr_mode;

		pm_runtime_put_sync_suspend(bank->dev);
	}
}

void omap2_gpio_resume_after_idle(void)
{
	struct gpio_bank *bank;

	list_for_each_entry(bank, &omap_gpio_list, node) {
		if (!bank->mod_usage || !bank->loses_context)
			continue;

		pm_runtime_get_sync(bank->dev);
	}
}


I don't know if there is some reason to not use driver_for_each_device.


Kevin,

Do we have any constraint inside omap_sram_idle to not use the device 
iterator?


Regards,
Benoit

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-02 20:48         ` Cousson, Benoit
@ 2012-02-02 21:49           ` Felipe Balbi
  2012-02-02 21:53             ` Felipe Balbi
  0 siblings, 1 reply; 64+ messages in thread
From: Felipe Balbi @ 2012-02-02 21:49 UTC (permalink / raw)
  To: Cousson, Benoit
  Cc: balbi, khilman, Grant Likely, Tarun Kanti DebBarma, linux-omap,
	tony, linux-kernel, linux-arm-kernel, Charulatha V

[-- Attachment #1: Type: text/plain, Size: 3818 bytes --]

Hi,

On Thu, Feb 02, 2012 at 09:48:13PM +0100, Cousson, Benoit wrote:
> On 2/2/2012 8:45 PM, Felipe Balbi wrote:
> >On Thu, Feb 02, 2012 at 12:16:30PM -0700, Grant Likely wrote:
> >>On Thu, Feb 02, 2012 at 08:41:07PM +0200, Felipe Balbi wrote:
> >>>Hi,
> >>>
> >>>On Thu, Feb 02, 2012 at 11:00:27PM +0530, Tarun Kanti DebBarma wrote:
> >>>>diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
> >>>>index 0b05629..6ea7390 100644
> >>>>--- a/drivers/gpio/gpio-omap.c
> >>>>+++ b/drivers/gpio/gpio-omap.c
> >>>>@@ -28,7 +28,10 @@
> >>>>  #include<asm/gpio.h>
> >>>>  #include<asm/mach/irq.h>
> >>>>
> >>>>+static LIST_HEAD(omap_gpio_list);
> >>>
> >>>I guess it's now too late because patch is acked and everything, but I
> >>>think if you make the driver handle one bank alone and just instantiate
> >>>it multiple times (omap_gpio.0, omap_gpio.1, omap_gpio.3, etc) driver
> >>>would be faaaaaar simpler.
> >>
> >>Is there any shared state between the banks?  On my very cursory glance it
> >>looked like banks still have some interaction between them.  If not, then
> >>yes I agree that multiple instances would be better.
> >
> >A quick glance at the TRM shows that banks have separate address spaces
> >and IRQ lines. I think it's done this way because we can handoff one (or
> >more) bank to other cores on the SoC, so they need to be pretty
> >independent.
> >
> >I could be missing something though.
> 
> In fact the driver already handled the 6 GPIOS banks as individual devices:
> 
> [    0.185638] gpiochip_add: registered GPIOs 0 to 31 on device: gpio
> [    0.185882] OMAP GPIO hardware version 0.1
> [    0.186767] gpiochip_add: registered GPIOs 32 to 63 on device: gpio
> [    0.187744] gpiochip_add: registered GPIOs 64 to 95 on device: gpio
> [    0.188751] gpiochip_add: registered GPIOs 96 to 127 on device: gpio
> [    0.189819] gpiochip_add: registered GPIOs 128 to 159 on device: gpio
> [    0.190917] gpiochip_add: registered GPIOs 160 to 191 on device: gpio

yeah, but you can get all of that for free from driver core. Just add
one platform_device for each bank and make the omap-gpio.c only
understand one bank. No tricks.

What I'm trying to say is to remove the Bank array or list_head and make
probe() get called 6 times by creating 6 omap_gpio platform_devices.

From probe you cann gpiochip_add() once and only once.

> That list is only used to iterate over all the instances during CPU idle:
> 
> void omap2_gpio_prepare_for_idle(int pwr_mode)
> {
> 	struct gpio_bank *bank;
> 
> 	list_for_each_entry(bank, &omap_gpio_list, node) {
> 		if (!bank->mod_usage || !bank->loses_context)
> 			continue;
> 
> 		bank->power_mode = pwr_mode;
> 
> 		pm_runtime_put_sync_suspend(bank->dev);
> 	}
> }
> 
> void omap2_gpio_resume_after_idle(void)
> {
> 	struct gpio_bank *bank;
> 
> 	list_for_each_entry(bank, &omap_gpio_list, node) {
> 		if (!bank->mod_usage || !bank->loses_context)
> 			continue;
> 
> 		pm_runtime_get_sync(bank->dev);
> 	}
> }

that's the thing which is unnecessary, actually :-)

Why do we even have this omap2_gpio_resume_after_idle() ? Can't the gpio
driver handle its own PM or listen to cpuidle notificaitons for that ?

I would like to understand why do we need this hack for pm runtime.
Can't you just use ->prepare() and ->complete() from dev_pm_ops ?

> I don't know if there is some reason to not use driver_for_each_device.

driver_for_each_device() is already handled by driver core. So your
omap_device_build() would have a loop creating N omap_devices, one for
each gpio bank. Each bank would receive one IRQ line and one address
base. And they would only understand that. Every instance of the driver
handles the GPIOs connected on one bank.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-02 21:49           ` Felipe Balbi
@ 2012-02-02 21:53             ` Felipe Balbi
  2012-02-02 22:00               ` Cousson, Benoit
  0 siblings, 1 reply; 64+ messages in thread
From: Felipe Balbi @ 2012-02-02 21:53 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Cousson, Benoit, khilman, Grant Likely, Tarun Kanti DebBarma,
	linux-omap, tony, linux-kernel, linux-arm-kernel, Charulatha V

[-- Attachment #1: Type: text/plain, Size: 2362 bytes --]

Hi again,

On Thu, Feb 02, 2012 at 11:49:08PM +0200, Felipe Balbi wrote:
> > In fact the driver already handled the 6 GPIOS banks as individual devices:
> > 
> > [    0.185638] gpiochip_add: registered GPIOs 0 to 31 on device: gpio
> > [    0.185882] OMAP GPIO hardware version 0.1
> > [    0.186767] gpiochip_add: registered GPIOs 32 to 63 on device: gpio
> > [    0.187744] gpiochip_add: registered GPIOs 64 to 95 on device: gpio
> > [    0.188751] gpiochip_add: registered GPIOs 96 to 127 on device: gpio
> > [    0.189819] gpiochip_add: registered GPIOs 128 to 159 on device: gpio
> > [    0.190917] gpiochip_add: registered GPIOs 160 to 191 on device: gpio
> 
> yeah, but you can get all of that for free from driver core. Just add
> one platform_device for each bank and make the omap-gpio.c only
> understand one bank. No tricks.
> 
> What I'm trying to say is to remove the Bank array or list_head and make
> probe() get called 6 times by creating 6 omap_gpio platform_devices.
> 
> From probe you cann gpiochip_add() once and only once.
		 ^^^^
		 call

I actually just took the time to go over the driver and that's what it
does. So the list_head is only there fo the nasty cpuidle stuff below:

> > That list is only used to iterate over all the instances during CPU idle:
> > 
> > void omap2_gpio_prepare_for_idle(int pwr_mode)
> > {
> > 	struct gpio_bank *bank;
> > 
> > 	list_for_each_entry(bank, &omap_gpio_list, node) {
> > 		if (!bank->mod_usage || !bank->loses_context)
> > 			continue;
> > 
> > 		bank->power_mode = pwr_mode;
> > 
> > 		pm_runtime_put_sync_suspend(bank->dev);
> > 	}
> > }
> > 
> > void omap2_gpio_resume_after_idle(void)
> > {
> > 	struct gpio_bank *bank;
> > 
> > 	list_for_each_entry(bank, &omap_gpio_list, node) {
> > 		if (!bank->mod_usage || !bank->loses_context)
> > 			continue;
> > 
> > 		pm_runtime_get_sync(bank->dev);
> > 	}
> > }
> 
> that's the thing which is unnecessary, actually :-)
> 
> Why do we even have this omap2_gpio_resume_after_idle() ? Can't the gpio
> driver handle its own PM or listen to cpuidle notificaitons for that ?
> 
> I would like to understand why do we need this hack for pm runtime.
> Can't you just use ->prepare() and ->complete() from dev_pm_ops ?

This question remains. Why do we need those funtions ?

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-02 21:53             ` Felipe Balbi
@ 2012-02-02 22:00               ` Cousson, Benoit
  2012-02-02 22:07                 ` Felipe Balbi
  0 siblings, 1 reply; 64+ messages in thread
From: Cousson, Benoit @ 2012-02-02 22:00 UTC (permalink / raw)
  To: balbi
  Cc: khilman, Grant Likely, Tarun Kanti DebBarma, linux-omap, tony,
	linux-kernel, linux-arm-kernel, Charulatha V

On 2/2/2012 10:53 PM, Felipe Balbi wrote:
> Hi again,
>
> On Thu, Feb 02, 2012 at 11:49:08PM +0200, Felipe Balbi wrote:
>>> In fact the driver already handled the 6 GPIOS banks as individual devices:
>>>
>>> [    0.185638] gpiochip_add: registered GPIOs 0 to 31 on device: gpio
>>> [    0.185882] OMAP GPIO hardware version 0.1
>>> [    0.186767] gpiochip_add: registered GPIOs 32 to 63 on device: gpio
>>> [    0.187744] gpiochip_add: registered GPIOs 64 to 95 on device: gpio
>>> [    0.188751] gpiochip_add: registered GPIOs 96 to 127 on device: gpio
>>> [    0.189819] gpiochip_add: registered GPIOs 128 to 159 on device: gpio
>>> [    0.190917] gpiochip_add: registered GPIOs 160 to 191 on device: gpio
>>
>> yeah, but you can get all of that for free from driver core. Just add
>> one platform_device for each bank and make the omap-gpio.c only
>> understand one bank. No tricks.
>>
>> What I'm trying to say is to remove the Bank array or list_head and make
>> probe() get called 6 times by creating 6 omap_gpio platform_devices.
>>
>>  From probe you cann gpiochip_add() once and only once.
> 		^^^^
> 		 call
>
> I actually just took the time to go over the driver and that's what it
> does. So the list_head is only there fo the nasty cpuidle stuff below:

Yes, that was my point :-)

>>> That list is only used to iterate over all the instances during CPU idle:
>>>
>>> void omap2_gpio_prepare_for_idle(int pwr_mode)
>>> {
>>> 	struct gpio_bank *bank;
>>>
>>> 	list_for_each_entry(bank,&omap_gpio_list, node) {
>>> 		if (!bank->mod_usage || !bank->loses_context)
>>> 			continue;
>>>
>>> 		bank->power_mode = pwr_mode;
>>>
>>> 		pm_runtime_put_sync_suspend(bank->dev);
>>> 	}
>>> }
>>>
>>> void omap2_gpio_resume_after_idle(void)
>>> {
>>> 	struct gpio_bank *bank;
>>>
>>> 	list_for_each_entry(bank,&omap_gpio_list, node) {
>>> 		if (!bank->mod_usage || !bank->loses_context)
>>> 			continue;
>>>
>>> 		pm_runtime_get_sync(bank->dev);
>>> 	}
>>> }
>>
>> that's the thing which is unnecessary, actually :-)
>>
>> Why do we even have this omap2_gpio_resume_after_idle() ? Can't the gpio
>> driver handle its own PM or listen to cpuidle notificaitons for that ?
>>
>> I would like to understand why do we need this hack for pm runtime.
>> Can't you just use ->prepare() and ->complete() from dev_pm_ops ?
>
> This question remains. Why do we need those funtions ?

These functions are called from the CPUIdle path so outside the scope of 
the GPIO driver. These are part of a bunch of nasty PM hacks we are 
doing in the CPU idle loop. We are in the process of getting rid of most 
of them, but it looks like some are still needed.

Regards,
Benoit


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-02 22:00               ` Cousson, Benoit
@ 2012-02-02 22:07                 ` Felipe Balbi
  2012-02-03 17:50                   ` Kevin Hilman
  0 siblings, 1 reply; 64+ messages in thread
From: Felipe Balbi @ 2012-02-02 22:07 UTC (permalink / raw)
  To: Cousson, Benoit
  Cc: balbi, khilman, Grant Likely, Tarun Kanti DebBarma, linux-omap,
	tony, linux-kernel, linux-arm-kernel, Charulatha V

[-- Attachment #1: Type: text/plain, Size: 3902 bytes --]

Hi,

On Thu, Feb 02, 2012 at 11:00:43PM +0100, Cousson, Benoit wrote:
> On 2/2/2012 10:53 PM, Felipe Balbi wrote:
> >Hi again,
> >
> >On Thu, Feb 02, 2012 at 11:49:08PM +0200, Felipe Balbi wrote:
> >>>In fact the driver already handled the 6 GPIOS banks as individual devices:
> >>>
> >>>[    0.185638] gpiochip_add: registered GPIOs 0 to 31 on device: gpio
> >>>[    0.185882] OMAP GPIO hardware version 0.1
> >>>[    0.186767] gpiochip_add: registered GPIOs 32 to 63 on device: gpio
> >>>[    0.187744] gpiochip_add: registered GPIOs 64 to 95 on device: gpio
> >>>[    0.188751] gpiochip_add: registered GPIOs 96 to 127 on device: gpio
> >>>[    0.189819] gpiochip_add: registered GPIOs 128 to 159 on device: gpio
> >>>[    0.190917] gpiochip_add: registered GPIOs 160 to 191 on device: gpio
> >>
> >>yeah, but you can get all of that for free from driver core. Just add
> >>one platform_device for each bank and make the omap-gpio.c only
> >>understand one bank. No tricks.
> >>
> >>What I'm trying to say is to remove the Bank array or list_head and make
> >>probe() get called 6 times by creating 6 omap_gpio platform_devices.
> >>
> >> From probe you cann gpiochip_add() once and only once.
> >		^^^^
> >		 call
> >
> >I actually just took the time to go over the driver and that's what it
> >does. So the list_head is only there fo the nasty cpuidle stuff below:
> 
> Yes, that was my point :-)

:-) my bad

> >>>That list is only used to iterate over all the instances during CPU idle:
> >>>
> >>>void omap2_gpio_prepare_for_idle(int pwr_mode)
> >>>{
> >>>	struct gpio_bank *bank;
> >>>
> >>>	list_for_each_entry(bank,&omap_gpio_list, node) {
> >>>		if (!bank->mod_usage || !bank->loses_context)
> >>>			continue;
> >>>
> >>>		bank->power_mode = pwr_mode;
> >>>
> >>>		pm_runtime_put_sync_suspend(bank->dev);
> >>>	}
> >>>}
> >>>
> >>>void omap2_gpio_resume_after_idle(void)
> >>>{
> >>>	struct gpio_bank *bank;
> >>>
> >>>	list_for_each_entry(bank,&omap_gpio_list, node) {
> >>>		if (!bank->mod_usage || !bank->loses_context)
> >>>			continue;
> >>>
> >>>		pm_runtime_get_sync(bank->dev);
> >>>	}
> >>>}
> >>
> >>that's the thing which is unnecessary, actually :-)
> >>
> >>Why do we even have this omap2_gpio_resume_after_idle() ? Can't the gpio
> >>driver handle its own PM or listen to cpuidle notificaitons for that ?
> >>
> >>I would like to understand why do we need this hack for pm runtime.
> >>Can't you just use ->prepare() and ->complete() from dev_pm_ops ?
> >
> >This question remains. Why do we need those funtions ?
> 
> These functions are called from the CPUIdle path so outside the scope
> of the GPIO driver. These are part of a bunch of nasty PM hacks we
> are doing in the CPU idle loop. We are in the process of getting rid
> of most of them, but it looks like some are still needed.

Too bad. I can see that the gpio pm implementation seems a bit
"peculiar". I mean, pm does reference counting and yet the driver has
checks to prevent multiple gets and puts on a single bank (meaning that
pm counter will be either 0 or 1 at any point in time).

To me it looks like those functions are there in order to forcefully put
PER power domain in OFF because drivers are always holding a reference
to their gpios (drivers generally gpio_request() on probe() and
gpio_free() on remove()).

Looks like the entire pm implementation on OMAP gpio driver has always
considered only the fact that gpios can be requested and freed, but
never that we want the system to go to OFF even while gpios are
requested, because we have I/O PAD wakeups. At some point that has to be
sorted out because that HACK is quite ugly :-)

I'll see if I find some time to go over the interactions between
gpio-omap.c and pm24x.c and pm34xx.c any of these days, but I can't
promise anything ;-)

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 64+ messages in thread

* RE: [PATCH v9 00/25] gpio/omap: driver cleanup and fixes
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (25 preceding siblings ...)
  2012-02-02 19:42 ` [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Grant Likely
@ 2012-02-03  9:21 ` Hebbar, Gururaja
       [not found]   ` <CAC83ZvLoYVofH9oKXw92i-=DbP2i3NfZjLGSJwk1j0JvXcFZVQ@mail.gmail.com>
  2012-02-03 21:01 ` Kevin Hilman
  2012-02-10 19:24 ` Tony Lindgren
  28 siblings, 1 reply; 64+ messages in thread
From: Hebbar, Gururaja @ 2012-02-03  9:21 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti, linux-omap
  Cc: Hilman, Kevin, tony, linux-kernel, grant.likely, linux-arm-kernel

Tarun,

I am interested in testing these patches on AM335x. Do you have a tree with these 
patches applied so that I can pull. 

On Thu, Feb 02, 2012 at 23:00:26, DebBarma, Tarun Kanti wrote:
> The following changes since commit 62aa2b537c6f5957afd98e29f96897419ed5ebab:
>   Linus Torvalds (1):
>         Linux 3.3-rc2
> 
> are available in the git repository at:
> http://gitorious.org/~tarunkanti/omap-sw-develoment/tarunkantis-linux-omap-dev
> Branch: for_3.4/gpio_cleanup_fixes_v9
> 
> 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.
> 
> Power Tests
> a) OMAP3430SDP
> - Modify board-3430sdp.c file to have multiple GPIO modules active
>   with debounce timeout enabled.
> - Enable CPU-Idle
> - Enable UART timeouts
> - Enable offmode
> - echo mem > /sys/power/state
> - Verify retention and offmode count increment
> 
>   Used following patches to avoid exception during system suspend:-
>   [PATCH RFC 1/2] mtd : Prevent the NULL pointer access
>   [PATCH RFC 2/2] mtd : Make the mtd_suspend return 0 if the suspend is not implemented
> 
> # echo mem > /sys/power/state
> [   47.128021] PM: Syncing filesystems ... done.
> [   47.144104] Freezing user space processes ... (elapsed 0.01 seconds) done.
> [   47.168243] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) don                                                                                                 e.
> [   47.205139] Unable to handle kernel NULL pointer dereference at virtual addre                                                                                                 ss 000000a0
> [   47.213317] pgd = deaac000
> [   47.216033] [000000a0] *pgd=9e932831, *pte=00000000, *ppte=00000000
> [   47.222381] Internal error: Oops: 17 [#1] SMP
> [   47.226745] Modules linked in:
> [   47.229827] CPU: 0    Not tainted  (3.3.0-rc2-00031-g12c5c5c #235)
> [   47.236022] PC is at mtd_cls_suspend+0x8/0x20
> [   47.240386] LR is at mtd_cls_suspend+0x8/0x20
> [   47.244750] pc : [<c02e78f8>]    lr : [<c02e78f8>]    psr: a0000013
> [   47.244750] sp : dea1fe60  ip : 22222222  fp : c0ee7d40
> [   47.256256] r10: c0ee7cf0  r9 : 00000000  r8 : c02e78f0
> [   47.261474] r7 : 00000000  r6 : 00000000  r5 : 00000002  r4 : dea45800
> [   47.268005] r3 : deb4cac0  r2 : 00000000  r1 : 00000002  r0 : 00000000
> [   47.274536] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
> [   47.281677] Control: 10c5387d  Table: 9eaac019  DAC: 00000015
> [   47.287445] Process sh (pid: 1177, stack limit = 0xdea1e2f8)
> [   47.293090] Stack: (0xdea1fe60 to 0xdea20000)
> [...]
> 
> b) ZOOM3
> - Enable CPU-Idle
> - Enable UART timeout
> - echo mem > /sys/power/state
> - Wakeup system using serial keyboard
> - Verify retention count increment
> 
> Functional Tests
> - Done on OMAP2430, OMAP3430SDP, ZOOM3, OMAP4430
> 
> Bootup Test
> - Done on OMAP1710
>   Used following patch to fix OMAP1 build error:-
>   [PATCH] i2c: OMAP: Fix OMAP1 build error
> 

[..]
[..]

> Charulatha V (8):
>   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: 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 (13):
>   gpio/omap: handle save/restore context in GPIO driver
>   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: fix debounce clock handling
>   gpio/omap: fix incorrect access of debounce module
>   gpio/omap: remove omap_gpio_save_context overhead
> 
>  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/gpio.c             |   36 +-
>  arch/arm/mach-omap2/pm34xx.c           |   14 -
>  arch/arm/plat-omap/include/plat/gpio.h |   29 +-
>  drivers/gpio/gpio-omap.c               | 1099 +++++++++++++-------------------
>  7 files changed, 549 insertions(+), 697 deletions(-)
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


Regards, 
Gururaja

^ permalink raw reply	[flat|nested] 64+ messages in thread

* RE: [PATCH v9 00/25] gpio/omap: driver cleanup and fixes
       [not found]   ` <CAC83ZvLoYVofH9oKXw92i-=DbP2i3NfZjLGSJwk1j0JvXcFZVQ@mail.gmail.com>
@ 2012-02-03 12:09     ` Hebbar, Gururaja
  0 siblings, 0 replies; 64+ messages in thread
From: Hebbar, Gururaja @ 2012-02-03 12:09 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti
  Cc: linux-omap, Hilman, Kevin, tony, linux-kernel, grant.likely,
	linux-arm-kernel

Hi,

On Fri, Feb 03, 2012 at 15:29:49, DebBarma, Tarun Kanti wrote:
> On Fri, Feb 3, 2012 at 2:51 PM, Hebbar, Gururaja
> <gururaja.hebbar@ti.com> wrote:
> 
> 
> 	Tarun,
> 	
> 	I am interested in testing these patches on AM335x. Do you have
> a tree with these
> 	patches applied so that I can pull.
> 	
> 
> You can find the series here:-
> git://gitorious.org/~tarunkanti/omap-sw-develoment/tarunkantis-linux-oma
> p-dev for_3.4/gpio_cleanup_fixes_v9

I am unable to download from this repo. The Gitorious web page fails to show
the tree and gives 500 error

downloading using https protocol fails with below error.

ghebbar@linux-psp-server:~/projects/linux-gits/gitorious-omap$ git remote add omap-gpio2 https://git.gitorious.org/omap-sw-develoment/linux-omap-dev.git

ghebbar@linux-psp-server:~/projects/linux-gits/gitorious-omap$ git fetch omap-gpio2

error: Unable to get pack index https://git.gitorious.org/omap-sw-develoment/linux-omap-dev.git/objects/pack/pack-a461f67f3067aa122c09f38cf55346152c9fafb8.idx

error: Unable to get pack index https://git.gitorious.org/omap-sw-develoment/linux-omap-dev.git/objects/pack/pack-a66a5d34b6388e1b0c6b49fe4a029cbf755b17c7.idx

error: Unable to get pack index https://git.gitorious.org/omap-sw-develoment/linux-omap-dev.git/objects/pack/pack-952401733bd66c72bc947b54ad5a04ca8edfff2a.idx

error: Unable to get pack index https://git.gitorious.org/omap-sw-develoment/linux-omap-dev.git/objects/pack/pack-1f38918dfb5427f9b79b88d7c6cda15e85c2ad92.idx

error: Unable to get pack file https://git.gitorious.org/omap-sw-develoment/linux-omap-dev.git/objects/pack/pack-2e39094e5e34e6ce642fc2513727a2025b23f8c7.pack
GnuTLS recv error (-9): A TLS packet with unexpected length was received.
error: Unable to find f5af8c1f05d8a1e27ca910285da3fee28eb5acce under https://git.gitorious.org/omap-sw-develoment/linux-omap-dev.git
Cannot obtain needed object f5af8c1f05d8a1e27ca910285da3fee28eb5acce
while processing commit 7e0e6be8759e6423a4f97b4bbc5e9fec0e5cfde3.
error: Fetch failed.
ghebbar@linux-psp-server:~/projects/linux-gits/gitorious-omap$ git fetch omap-gpio2
error: Unable to get pack index https://git.gitorious.org/omap-sw-develoment/linux-omap-dev.git/objects/pack/pack-a461f67f3067aa122c09f38cf55346152c9fafb8.idx

error: wrong index v2 file size in .git/objects/pack/pack-952401733bd66c72bc947b54ad5a04ca8edfff2a.idx
error: .git/objects/pack/pack-2e39094e5e34e6ce642fc2513727a2025b23f8c7.pack SHA1 checksum mismatch
error: inflate: data stream error (invalid distance too far back)


is there any issue with the repo.

> --
> Tarun
>  
> 
> 
> 
> 	On Thu, Feb 02, 2012 at 23:00:26, DebBarma, Tarun Kanti wrote:
> 	> The following changes since commit
> 62aa2b537c6f5957afd98e29f96897419ed5ebab:
> 	>   Linus Torvalds (1):
> 	>         Linux 3.3-rc2
> 	>
> 	> are available in the git repository at:
> 	>
> http://gitorious.org/~tarunkanti/omap-sw-develoment/tarunkantis-linux-om
> ap-dev
> <http://gitorious.org/%7Etarunkanti/omap-sw-develoment/tarunkantis-linux
> -omap-dev> 
> 	> Branch: for_3.4/gpio_cleanup_fixes_v9
> 	>
> 	> 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.
> 	>
> 	> Power Tests
> 	> a) OMAP3430SDP
> 	> - Modify board-3430sdp.c file to have multiple GPIO modules
> active
> 	>   with debounce timeout enabled.
> 	> - Enable CPU-Idle
> 	> - Enable UART timeouts
> 	> - Enable offmode
> 	> - echo mem > /sys/power/state
> 	> - Verify retention and offmode count increment
> 	>
> 	>   Used following patches to avoid exception during system
> suspend:-
> 	>   [PATCH RFC 1/2] mtd : Prevent the NULL pointer access
> 	>   [PATCH RFC 2/2] mtd : Make the mtd_suspend return 0 if the
> suspend is not implemented
> 	>
> 	> # echo mem > /sys/power/state
> 	> [   47.128021] PM: Syncing filesystems ... done.
> 	> [   47.144104] Freezing user space processes ... (elapsed 0.01
> seconds) done.
> 	> [   47.168243] Freezing remaining freezable tasks ... (elapsed
> 0.02 seconds) don
> e.
> 	> [   47.205139] Unable to handle kernel NULL pointer
> dereference at virtual addre
> ss 000000a0
> 	> [   47.213317] pgd = deaac000
> 	> [   47.216033] [000000a0] *pgd=9e932831, *pte=00000000,
> *ppte=00000000
> 	> [   47.222381] Internal error: Oops: 17 [#1] SMP
> 	> [   47.226745] Modules linked in:
> 	> [   47.229827] CPU: 0    Not tainted
> (3.3.0-rc2-00031-g12c5c5c #235)
> 	> [   47.236022] PC is at mtd_cls_suspend+0x8/0x20
> 	> [   47.240386] LR is at mtd_cls_suspend+0x8/0x20
> 	> [   47.244750] pc : [<c02e78f8>]    lr : [<c02e78f8>]    psr:
> a0000013
> 	> [   47.244750] sp : dea1fe60  ip : 22222222  fp : c0ee7d40
> 	> [   47.256256] r10: c0ee7cf0  r9 : 00000000  r8 : c02e78f0
> 	> [   47.261474] r7 : 00000000  r6 : 00000000  r5 : 00000002  r4
> : dea45800
> 	> [   47.268005] r3 : deb4cac0  r2 : 00000000  r1 : 00000002  r0
> : 00000000
> 	> [   47.274536] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA
> ARM  Segment user
> 	> [   47.281677] Control: 10c5387d  Table: 9eaac019  DAC:
> 00000015
> 	> [   47.287445] Process sh (pid: 1177, stack limit =
> 0xdea1e2f8)
> 	> [   47.293090] Stack: (0xdea1fe60 to 0xdea20000)
> 	> [...]
> 	>
> 	> b) ZOOM3
> 	> - Enable CPU-Idle
> 	> - Enable UART timeout
> 	> - echo mem > /sys/power/state
> 	> - Wakeup system using serial keyboard
> 	> - Verify retention count increment
> 	>
> 	> Functional Tests
> 	> - Done on OMAP2430, OMAP3430SDP, ZOOM3, OMAP4430
> 	>
> 	> Bootup Test
> 	> - Done on OMAP1710
> 	>   Used following patch to fix OMAP1 build error:-
> 	>   [PATCH] i2c: OMAP: Fix OMAP1 build error
> 	>
> 	
> 	
> 	[..]
> 	[..]
> 	
> 
> 	> Charulatha V (8):
> 	>   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: 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 (13):
> 	>   gpio/omap: handle save/restore context in GPIO driver
> 	>   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: fix debounce clock handling
> 	>   gpio/omap: fix incorrect access of debounce module
> 	>   gpio/omap: remove omap_gpio_save_context overhead
> 	>
> 	>  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/gpio.c             |   36 +-
> 	>  arch/arm/mach-omap2/pm34xx.c           |   14 -
> 	>  arch/arm/plat-omap/include/plat/gpio.h |   29 +-
> 	>  drivers/gpio/gpio-omap.c               | 1099
> +++++++++++++-------------------
> 	>  7 files changed, 549 insertions(+), 697 deletions(-)
> 	>
> 	>
> 	
> 	> _______________________________________________
> 	> linux-arm-kernel mailing list
> 	> linux-arm-kernel@lists.infradead.org
> 	> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 	>
> 	
> 	
> 	Regards,
> 	Gururaja
> 	
> 
> 
> 


Regards, 
Gururaja

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-02 22:07                 ` Felipe Balbi
@ 2012-02-03 17:50                   ` Kevin Hilman
  2012-02-04 16:08                     ` Felipe Balbi
  0 siblings, 1 reply; 64+ messages in thread
From: Kevin Hilman @ 2012-02-03 17:50 UTC (permalink / raw)
  To: balbi
  Cc: Cousson, Benoit, Grant Likely, Tarun Kanti DebBarma, linux-omap,
	tony, linux-kernel, linux-arm-kernel, Charulatha V

Felipe Balbi <balbi@ti.com> writes:

[...]

>> >This question remains. Why do we need those funtions ?
>> 
>> These functions are called from the CPUIdle path so outside the scope
>> of the GPIO driver. These are part of a bunch of nasty PM hacks we
>> are doing in the CPU idle loop. We are in the process of getting rid
>> of most of them, but it looks like some are still needed.
>
> Too bad. I can see that the gpio pm implementation seems a bit
> "peculiar". I mean, pm does reference counting and yet the driver has
> checks to prevent multiple gets and puts on a single bank (meaning that
> pm counter will be either 0 or 1 at any point in time).
>
> To me it looks like those functions are there in order to forcefully put
> PER power domain in OFF because drivers are always holding a reference
> to their gpios (drivers generally gpio_request() on probe() and
> gpio_free() on remove()).
>
> Looks like the entire pm implementation on OMAP gpio driver has always
> considered only the fact that gpios can be requested and freed, but
> never that we want the system to go to OFF even while gpios are
> requested, because we have I/O PAD wakeups. At some point that has to be
> sorted out because that HACK is quite ugly :-)
>
> I'll see if I find some time to go over the interactions between
> gpio-omap.c and pm24x.c and pm34xx.c any of these days, but I can't
> promise anything ;-)

If you look at the state of these prepare/resume hacks at the end of
this series, you'll see that they are significantly cleaner and do
nothing but call the runtime PM hooks.

We have explored several ways to get rid of them completely in the idle
path but have not yet come up with a clean way, but this series gets us
a long ways towards that goal.

Kevin




^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 00/25] gpio/omap: driver cleanup and fixes
  2012-02-02 19:42 ` [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Grant Likely
@ 2012-02-03 17:51   ` Kevin Hilman
  2012-02-03 21:16     ` Grant Likely
  0 siblings, 1 reply; 64+ messages in thread
From: Kevin Hilman @ 2012-02-03 17:51 UTC (permalink / raw)
  To: Grant Likely
  Cc: Tarun Kanti DebBarma, linux-omap, tony, linux-kernel, linux-arm-kernel

Grant Likely <grant.likely@secretlab.ca> writes:

> On Thu, Feb 02, 2012 at 11:00:26PM +0530, Tarun Kanti DebBarma wrote:
>> The following changes since commit 62aa2b537c6f5957afd98e29f96897419ed5ebab:
>>   Linus Torvalds (1):
>>         Linux 3.3-rc2
>> 
>> are available in the git repository at:
>> http://gitorious.org/~tarunkanti/omap-sw-develoment/tarunkantis-linux-omap-dev
>> Branch: for_3.4/gpio_cleanup_fixes_v9
>
> Bad git url.  I had to replace 'http:' with 'git:'.
>
> I've merged this series into my gpio/next branch.  It should show up in
> linux-next in a couple of days.

Grant, this series isn't quite ready for merge, and shouldn't be
considered a pull request.

I still need to give it a once over and some final testing.

Kevin


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 00/25] gpio/omap: driver cleanup and fixes
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (26 preceding siblings ...)
  2012-02-03  9:21 ` Hebbar, Gururaja
@ 2012-02-03 21:01 ` Kevin Hilman
  2012-02-06 11:53   ` DebBarma, Tarun Kanti
  2012-02-10 19:24 ` Tony Lindgren
  28 siblings, 1 reply; 64+ messages in thread
From: Kevin Hilman @ 2012-02-03 21:01 UTC (permalink / raw)
  To: Tarun Kanti DebBarma
  Cc: linux-omap, tony, linux-kernel, grant.likely, linux-arm-kernel

Hi Tarun,

Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:

> The following changes since commit 62aa2b537c6f5957afd98e29f96897419ed5ebab:
>   Linus Torvalds (1):
>         Linux 3.3-rc2
>
> are available in the git repository at:
> http://gitorious.org/~tarunkanti/omap-sw-develoment/tarunkantis-linux-omap-dev
> Branch: for_3.4/gpio_cleanup_fixes_v9
>
> 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.

This version is looking pretty good, and I'm almost ready to queue it up
for Grant.

However, one more minor nit.  Please fix up the compile warnings when
built without CONFIG_PM_SLEEP or CONFIG_PM_RUNTIME.

The definitons of the dev_pm_ops callbacks need to be conditional when
using the SET_*_PM_OPS() macros, otherwise you get these warnings:

  CC      drivers/gpio/gpio-omap.o
/work/kernel/omap/pm/drivers/gpio/gpio-omap.c:1142:12: warning: 'omap_gpio_suspend' defined but not used [-Wunused-function]
/work/kernel/omap/pm/drivers/gpio/gpio-omap.c:1167:12: warning: 'omap_gpio_resume' defined but not used [-Wunused-function]
/work/kernel/omap/pm/drivers/gpio/gpio-omap.c:1191:12: warning: 'omap_gpio_runtime_suspend' defined but not used [-Wunused-function]
/work/kernel/omap/pm/drivers/gpio/gpio-omap.c:1237:12: warning: 'omap_gpio_runtime_resume' defined but not used [-Wunused-function]


Thanks,

Kevin

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 00/25] gpio/omap: driver cleanup and fixes
  2012-02-03 17:51   ` Kevin Hilman
@ 2012-02-03 21:16     ` Grant Likely
  0 siblings, 0 replies; 64+ messages in thread
From: Grant Likely @ 2012-02-03 21:16 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Tarun Kanti DebBarma, linux-omap, tony, linux-kernel, linux-arm-kernel

On Fri, Feb 3, 2012 at 10:51 AM, Kevin Hilman <khilman@ti.com> wrote:
> Grant Likely <grant.likely@secretlab.ca> writes:
>
>> On Thu, Feb 02, 2012 at 11:00:26PM +0530, Tarun Kanti DebBarma wrote:
>>> The following changes since commit 62aa2b537c6f5957afd98e29f96897419ed5ebab:
>>>   Linus Torvalds (1):
>>>         Linux 3.3-rc2
>>>
>>> are available in the git repository at:
>>> http://gitorious.org/~tarunkanti/omap-sw-develoment/tarunkantis-linux-omap-dev
>>> Branch: for_3.4/gpio_cleanup_fixes_v9
>>
>> Bad git url.  I had to replace 'http:' with 'git:'.
>>
>> I've merged this series into my gpio/next branch.  It should show up in
>> linux-next in a couple of days.
>
> Grant, this series isn't quite ready for merge, and shouldn't be
> considered a pull request.

No problem.  I'll drop it from my tree.

g.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-03 17:50                   ` Kevin Hilman
@ 2012-02-04 16:08                     ` Felipe Balbi
  2012-02-05  7:07                       ` Varadarajan, Charulatha
  0 siblings, 1 reply; 64+ messages in thread
From: Felipe Balbi @ 2012-02-04 16:08 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: balbi, Cousson, Benoit, Grant Likely, Tarun Kanti DebBarma,
	linux-omap, tony, linux-kernel, linux-arm-kernel, Charulatha V

[-- Attachment #1: Type: text/plain, Size: 8820 bytes --]

Hi,

On Fri, Feb 03, 2012 at 09:50:19AM -0800, Kevin Hilman wrote:
> Felipe Balbi <balbi@ti.com> writes:
> 
> [...]
> 
> >> >This question remains. Why do we need those funtions ?
> >> 
> >> These functions are called from the CPUIdle path so outside the scope
> >> of the GPIO driver. These are part of a bunch of nasty PM hacks we
> >> are doing in the CPU idle loop. We are in the process of getting rid
> >> of most of them, but it looks like some are still needed.
> >
> > Too bad. I can see that the gpio pm implementation seems a bit
> > "peculiar". I mean, pm does reference counting and yet the driver has
> > checks to prevent multiple gets and puts on a single bank (meaning that
> > pm counter will be either 0 or 1 at any point in time).
> >
> > To me it looks like those functions are there in order to forcefully put
> > PER power domain in OFF because drivers are always holding a reference
> > to their gpios (drivers generally gpio_request() on probe() and
> > gpio_free() on remove()).
> >
> > Looks like the entire pm implementation on OMAP gpio driver has always
> > considered only the fact that gpios can be requested and freed, but
> > never that we want the system to go to OFF even while gpios are
> > requested, because we have I/O PAD wakeups. At some point that has to be
> > sorted out because that HACK is quite ugly :-)
> >
> > I'll see if I find some time to go over the interactions between
> > gpio-omap.c and pm24x.c and pm34xx.c any of these days, but I can't
> > promise anything ;-)
> 
> If you look at the state of these prepare/resume hacks at the end of
> this series, you'll see that they are significantly cleaner and do
> nothing but call the runtime PM hooks.

sure, definitely.

> We have explored several ways to get rid of them completely in the idle
> path but have not yet come up with a clean way, but this series gets us
> a long ways towards that goal.

have you thought about being a bit more aggressive at when to
runtime_get and runtime_put ?

I didn't test below (will do probably on monday), but I think this will
help keeping GPIO block always suspended, and only wake it up when truly
needed. That way, you could, at some point, remove that list_head
because by the time you reach CPUIdle path, GPIO module is already
suspended. That's the theory at least, gotta run it first on silicon to
be sure

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 4273401..2dd9ced 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -537,12 +537,7 @@ 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;
 
-	/*
-	 * If this is the first gpio_request for the bank,
-	 * enable the bank module.
-	 */
-	if (!bank->mod_usage)
-		pm_runtime_get_sync(bank->dev);
+	pm_runtime_get_sync(bank->dev);
 
 	spin_lock_irqsave(&bank->lock, flags);
 	/* Set trigger to none. You need to enable the desired trigger with
@@ -572,6 +567,8 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
 
 	spin_unlock_irqrestore(&bank->lock, flags);
 
+	pm_runtime_put(bank->dev);
+
 	return 0;
 }
 
@@ -581,6 +578,8 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
 	void __iomem *base = bank->base;
 	unsigned long flags;
 
+	pm_runtime_get_sync(bank->dev);
+
 	spin_lock_irqsave(&bank->lock, flags);
 
 	if (bank->regs->wkup_en) {
@@ -606,12 +605,7 @@ 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(bank->dev);
+	pm_runtime_put(bank->dev);
 }
 
 /*
@@ -707,9 +701,11 @@ static void gpio_irq_shutdown(struct irq_data *d)
 	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
 	unsigned long flags;
 
+	pm_runtime_get_sync(bank->dev);
 	spin_lock_irqsave(&bank->lock, flags);
 	_reset_gpio(bank, gpio);
 	spin_unlock_irqrestore(&bank->lock, flags);
+	pm_runtime_put(bank->dev);
 }
 
 static void gpio_ack_irq(struct irq_data *d)
@@ -717,7 +713,9 @@ static void gpio_ack_irq(struct irq_data *d)
 	unsigned int gpio = d->irq - IH_GPIO_BASE;
 	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
 
+	pm_runtime_get_sync(bank->dev);
 	_clear_gpio_irqstatus(bank, gpio);
+	pm_runtime_put(bank->dev);
 }
 
 static void gpio_mask_irq(struct irq_data *d)
@@ -726,10 +724,12 @@ static void gpio_mask_irq(struct irq_data *d)
 	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
 	unsigned long flags;
 
+	pm_runtime_get_sync(bank->dev);
 	spin_lock_irqsave(&bank->lock, flags);
 	_set_gpio_irqenable(bank, gpio, 0);
 	_set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE);
 	spin_unlock_irqrestore(&bank->lock, flags);
+	pm_runtime_put(bank->dev);
 }
 
 static void gpio_unmask_irq(struct irq_data *d)
@@ -740,6 +740,7 @@ static void gpio_unmask_irq(struct irq_data *d)
 	u32 trigger = irqd_get_trigger_type(d);
 	unsigned long flags;
 
+	pm_runtime_get_sync(bank->dev);
 	spin_lock_irqsave(&bank->lock, flags);
 	if (trigger)
 		_set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), trigger);
@@ -753,6 +754,7 @@ static void gpio_unmask_irq(struct irq_data *d)
 
 	_set_gpio_irqenable(bank, gpio, 1);
 	spin_unlock_irqrestore(&bank->lock, flags);
+	pm_runtime_put(bank->dev);
 }
 
 static struct irq_chip gpio_irq_chip = {
@@ -836,17 +838,26 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset)
 	unsigned long flags;
 
 	bank = container_of(chip, struct gpio_bank, chip);
+	pm_runtime_get_sync(bank->dev);
+
 	spin_lock_irqsave(&bank->lock, flags);
 	_set_gpio_direction(bank, offset, 1);
 	spin_unlock_irqrestore(&bank->lock, flags);
+	pm_runtime_put(bank->dev);
+
 	return 0;
 }
 
 static int gpio_is_input(struct gpio_bank *bank, int mask)
 {
 	void __iomem *reg = bank->base + bank->regs->direction;
+	u32 val;
 
-	return __raw_readl(reg) & mask;
+	pm_runtime_get_sync(bank->dev);
+	val = __raw_readl(reg) & mask;
+	pm_runtime_put(bank->dev);
+
+	return val;
 }
 
 static int gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -856,15 +867,20 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset)
 	int gpio;
 	u32 mask;
 
+	int val;
 	gpio = chip->base + offset;
 	bank = container_of(chip, struct gpio_bank, chip);
 	reg = bank->base;
 	mask = GPIO_BIT(bank, gpio);
 
+	pm_runtime_get_sync(bank->dev);
 	if (gpio_is_input(bank, mask))
-		return _get_gpio_datain(bank, gpio);
+		val = _get_gpio_datain(bank, gpio);
 	else
-		return _get_gpio_dataout(bank, gpio);
+		val = _get_gpio_dataout(bank, gpio);
+	pm_runtime_put(bank->dev);
+
+	return val;
 }
 
 static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)
@@ -873,10 +889,14 @@ static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)
 	unsigned long flags;
 
 	bank = container_of(chip, struct gpio_bank, chip);
+
+	pm_runtime_get_sync(bank->dev);
 	spin_lock_irqsave(&bank->lock, flags);
 	bank->set_dataout(bank, offset, value);
 	_set_gpio_direction(bank, offset, 0);
 	spin_unlock_irqrestore(&bank->lock, flags);
+	pm_runtime_put(bank->dev);
+
 	return 0;
 }
 
@@ -894,9 +914,11 @@ static int gpio_debounce(struct gpio_chip *chip, unsigned offset,
 			dev_err(bank->dev, "Could not get gpio dbck\n");
 	}
 
+	pm_runtime_get_sync(bank->dev);
 	spin_lock_irqsave(&bank->lock, flags);
 	_set_gpio_debounce(bank, offset, debounce);
 	spin_unlock_irqrestore(&bank->lock, flags);
+	pm_runtime_put(bank->dev);
 
 	return 0;
 }
@@ -907,9 +929,12 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 	unsigned long flags;
 
 	bank = container_of(chip, struct gpio_bank, chip);
+
+	pm_runtime_get_sync(bank->dev);
 	spin_lock_irqsave(&bank->lock, flags);
 	bank->set_dataout(bank, offset, value);
 	spin_unlock_irqrestore(&bank->lock, flags);
+	pm_runtime_put(bank->dev);
 }
 
 static int gpio_2irq(struct gpio_chip *chip, unsigned offset)
@@ -1330,7 +1355,8 @@ void omap2_gpio_prepare_for_idle(int pwr_mode)
 
 		bank->power_mode = pwr_mode;
 
-		pm_runtime_put_sync_suspend(bank->dev);
+		if (!pm_runtime_suspended(bank->dev))
+			pm_runtime_suspend(bank->dev);
 	}
 }
 
@@ -1342,7 +1368,8 @@ void omap2_gpio_resume_after_idle(void)
 		if (!bank->mod_usage || !bank->loses_context)
 			continue;
 
-		pm_runtime_get_sync(bank->dev);
+		if (pm_runtime_suspended(bank->dev))
+			pm_runtime_resume(bank->dev);
 	}
 }
 

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-04 16:08                     ` Felipe Balbi
@ 2012-02-05  7:07                       ` Varadarajan, Charulatha
  2012-02-05  9:08                         ` Felipe Balbi
  0 siblings, 1 reply; 64+ messages in thread
From: Varadarajan, Charulatha @ 2012-02-05  7:07 UTC (permalink / raw)
  To: balbi
  Cc: Kevin Hilman, Cousson, Benoit, Grant Likely,
	Tarun Kanti DebBarma, linux-omap, tony, linux-kernel,
	linux-arm-kernel

Felipe,

On Sat, Feb 4, 2012 at 21:38, Felipe Balbi <balbi@ti.com> wrote:
>
> Hi,
>
> On Fri, Feb 03, 2012 at 09:50:19AM -0800, Kevin Hilman wrote:
> > Felipe Balbi <balbi@ti.com> writes:
> >
> > [...]
> >
> > >> >This question remains. Why do we need those funtions ?
> > >>
> > >> These functions are called from the CPUIdle path so outside the scope
> > >> of the GPIO driver. These are part of a bunch of nasty PM hacks we
> > >> are doing in the CPU idle loop. We are in the process of getting rid
> > >> of most of them, but it looks like some are still needed.
> > >
> > > Too bad. I can see that the gpio pm implementation seems a bit
> > > "peculiar". I mean, pm does reference counting and yet the driver has
> > > checks to prevent multiple gets and puts on a single bank (meaning that
> > > pm counter will be either 0 or 1 at any point in time).
> > >
> > > To me it looks like those functions are there in order to forcefully put
> > > PER power domain in OFF because drivers are always holding a reference
> > > to their gpios (drivers generally gpio_request() on probe() and
> > > gpio_free() on remove()).
> > >
> > > Looks like the entire pm implementation on OMAP gpio driver has always
> > > considered only the fact that gpios can be requested and freed, but
> > > never that we want the system to go to OFF even while gpios are
> > > requested, because we have I/O PAD wakeups. At some point that has to be
> > > sorted out because that HACK is quite ugly :-)
> > >
> > > I'll see if I find some time to go over the interactions between
> > > gpio-omap.c and pm24x.c and pm34xx.c any of these days, but I can't
> > > promise anything ;-)
> >
> > If you look at the state of these prepare/resume hacks at the end of
> > this series, you'll see that they are significantly cleaner and do
> > nothing but call the runtime PM hooks.
>
> sure, definitely.
>
> > We have explored several ways to get rid of them completely in the idle
> > path but have not yet come up with a clean way, but this series gets us
> > a long ways towards that goal.
>
> have you thought about being a bit more aggressive at when to
> runtime_get and runtime_put ?
>
> I didn't test below (will do probably on monday), but I think this will
> help keeping GPIO block always suspended, and only wake it up when truly
> needed. That way, you could, at some point, remove that list_head
> because by the time you reach CPUIdle path, GPIO module is already
> suspended. That's the theory at least, gotta run it first on silicon to
> be sure
>
> diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
> index 4273401..2dd9ced 100644
> --- a/drivers/gpio/gpio-omap.c
> +++ b/drivers/gpio/gpio-omap.c
> @@ -537,12 +537,7 @@ 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;
>
> -       /*
> -        * If this is the first gpio_request for the bank,
> -        * enable the bank module.
> -        */
> -       if (!bank->mod_usage)
> -               pm_runtime_get_sync(bank->dev);
> +       pm_runtime_get_sync(bank->dev);

bank->mod_usage check is used to take care of doing pm_runtime_get*/put* only
if all the GPIOs in a particular bank are enabled or disabled respectively.

With the above change, pm_runtime_put*/get* would be called for every
gpio_request()
/_free() (that is, for upto 32 pins in OMAP3/4) in a bank irrespective
of whether other
GPIO pins are enabled or disabled in the same bank. Hence it is
required to have a
check based on mod_usage.

I agree with your approach of aggressively doing pm_runtime* calls and this
was discussed internally sometime ago.

-V Charulatha

>
>        spin_lock_irqsave(&bank->lock, flags);
>        /* Set trigger to none. You need to enable the desired trigger with
> @@ -572,6 +567,8 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
>
>        spin_unlock_irqrestore(&bank->lock, flags);
>
> +       pm_runtime_put(bank->dev);
> +
>        return 0;
>  }
>
> @@ -581,6 +578,8 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
>        void __iomem *base = bank->base;
>        unsigned long flags;
>
> +       pm_runtime_get_sync(bank->dev);
> +
>        spin_lock_irqsave(&bank->lock, flags);
>
>        if (bank->regs->wkup_en) {
> @@ -606,12 +605,7 @@ 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(bank->dev);
> +       pm_runtime_put(bank->dev);
>  }
>
>  /*
> @@ -707,9 +701,11 @@ static void gpio_irq_shutdown(struct irq_data *d)
>        struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
>        unsigned long flags;
>
> +       pm_runtime_get_sync(bank->dev);
>        spin_lock_irqsave(&bank->lock, flags);
>        _reset_gpio(bank, gpio);
>        spin_unlock_irqrestore(&bank->lock, flags);
> +       pm_runtime_put(bank->dev);
>  }
>
>  static void gpio_ack_irq(struct irq_data *d)
> @@ -717,7 +713,9 @@ static void gpio_ack_irq(struct irq_data *d)
>        unsigned int gpio = d->irq - IH_GPIO_BASE;
>        struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
>
> +       pm_runtime_get_sync(bank->dev);
>        _clear_gpio_irqstatus(bank, gpio);
> +       pm_runtime_put(bank->dev);
>  }
>
>  static void gpio_mask_irq(struct irq_data *d)
> @@ -726,10 +724,12 @@ static void gpio_mask_irq(struct irq_data *d)
>        struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
>        unsigned long flags;
>
> +       pm_runtime_get_sync(bank->dev);
>        spin_lock_irqsave(&bank->lock, flags);
>        _set_gpio_irqenable(bank, gpio, 0);
>        _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE);
>        spin_unlock_irqrestore(&bank->lock, flags);
> +       pm_runtime_put(bank->dev);
>  }
>
>  static void gpio_unmask_irq(struct irq_data *d)
> @@ -740,6 +740,7 @@ static void gpio_unmask_irq(struct irq_data *d)
>        u32 trigger = irqd_get_trigger_type(d);
>        unsigned long flags;
>
> +       pm_runtime_get_sync(bank->dev);
>        spin_lock_irqsave(&bank->lock, flags);
>        if (trigger)
>                _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), trigger);
> @@ -753,6 +754,7 @@ static void gpio_unmask_irq(struct irq_data *d)
>
>        _set_gpio_irqenable(bank, gpio, 1);
>        spin_unlock_irqrestore(&bank->lock, flags);
> +       pm_runtime_put(bank->dev);
>  }
>
>  static struct irq_chip gpio_irq_chip = {
> @@ -836,17 +838,26 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset)
>        unsigned long flags;
>
>        bank = container_of(chip, struct gpio_bank, chip);
> +       pm_runtime_get_sync(bank->dev);
> +
>        spin_lock_irqsave(&bank->lock, flags);
>        _set_gpio_direction(bank, offset, 1);
>        spin_unlock_irqrestore(&bank->lock, flags);
> +       pm_runtime_put(bank->dev);
> +
>        return 0;
>  }
>
>  static int gpio_is_input(struct gpio_bank *bank, int mask)
>  {
>        void __iomem *reg = bank->base + bank->regs->direction;
> +       u32 val;
>
> -       return __raw_readl(reg) & mask;
> +       pm_runtime_get_sync(bank->dev);
> +       val = __raw_readl(reg) & mask;
> +       pm_runtime_put(bank->dev);
> +
> +       return val;
>  }
>
>  static int gpio_get(struct gpio_chip *chip, unsigned offset)
> @@ -856,15 +867,20 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset)
>        int gpio;
>        u32 mask;
>
> +       int val;
>        gpio = chip->base + offset;
>        bank = container_of(chip, struct gpio_bank, chip);
>        reg = bank->base;
>        mask = GPIO_BIT(bank, gpio);
>
> +       pm_runtime_get_sync(bank->dev);
>        if (gpio_is_input(bank, mask))
> -               return _get_gpio_datain(bank, gpio);
> +               val = _get_gpio_datain(bank, gpio);
>        else
> -               return _get_gpio_dataout(bank, gpio);
> +               val = _get_gpio_dataout(bank, gpio);
> +       pm_runtime_put(bank->dev);
> +
> +       return val;
>  }
>
>  static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)
> @@ -873,10 +889,14 @@ static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)
>        unsigned long flags;
>
>        bank = container_of(chip, struct gpio_bank, chip);
> +
> +       pm_runtime_get_sync(bank->dev);
>        spin_lock_irqsave(&bank->lock, flags);
>        bank->set_dataout(bank, offset, value);
>        _set_gpio_direction(bank, offset, 0);
>        spin_unlock_irqrestore(&bank->lock, flags);
> +       pm_runtime_put(bank->dev);
> +
>        return 0;
>  }
>
> @@ -894,9 +914,11 @@ static int gpio_debounce(struct gpio_chip *chip, unsigned offset,
>                        dev_err(bank->dev, "Could not get gpio dbck\n");
>        }
>
> +       pm_runtime_get_sync(bank->dev);
>        spin_lock_irqsave(&bank->lock, flags);
>        _set_gpio_debounce(bank, offset, debounce);
>        spin_unlock_irqrestore(&bank->lock, flags);
> +       pm_runtime_put(bank->dev);
>
>        return 0;
>  }
> @@ -907,9 +929,12 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)
>        unsigned long flags;
>
>        bank = container_of(chip, struct gpio_bank, chip);
> +
> +       pm_runtime_get_sync(bank->dev);
>        spin_lock_irqsave(&bank->lock, flags);
>        bank->set_dataout(bank, offset, value);
>        spin_unlock_irqrestore(&bank->lock, flags);
> +       pm_runtime_put(bank->dev);
>  }
>
>  static int gpio_2irq(struct gpio_chip *chip, unsigned offset)
> @@ -1330,7 +1355,8 @@ void omap2_gpio_prepare_for_idle(int pwr_mode)
>
>                bank->power_mode = pwr_mode;
>
> -               pm_runtime_put_sync_suspend(bank->dev);
> +               if (!pm_runtime_suspended(bank->dev))
> +                       pm_runtime_suspend(bank->dev);
>        }
>  }
>
> @@ -1342,7 +1368,8 @@ void omap2_gpio_resume_after_idle(void)
>                if (!bank->mod_usage || !bank->loses_context)
>                        continue;
>
> -               pm_runtime_get_sync(bank->dev);
> +               if (pm_runtime_suspended(bank->dev))
> +                       pm_runtime_resume(bank->dev);
>        }
>  }
>
>
> --
> balbi

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-05  7:07                       ` Varadarajan, Charulatha
@ 2012-02-05  9:08                         ` Felipe Balbi
  2012-02-05  9:16                           ` Shilimkar, Santosh
  2012-02-06  5:18                           ` Varadarajan, Charulatha
  0 siblings, 2 replies; 64+ messages in thread
From: Felipe Balbi @ 2012-02-05  9:08 UTC (permalink / raw)
  To: Varadarajan, Charulatha
  Cc: balbi, Kevin Hilman, Cousson, Benoit, Grant Likely,
	Tarun Kanti DebBarma, linux-omap, tony, linux-kernel,
	linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 4183 bytes --]

Hi,

On Sun, Feb 05, 2012 at 12:37:55PM +0530, Varadarajan, Charulatha wrote:
> Felipe,
> 
> On Sat, Feb 4, 2012 at 21:38, Felipe Balbi <balbi@ti.com> wrote:
> >
> > Hi,
> >
> > On Fri, Feb 03, 2012 at 09:50:19AM -0800, Kevin Hilman wrote:
> > > Felipe Balbi <balbi@ti.com> writes:
> > >
> > > [...]
> > >
> > > >> >This question remains. Why do we need those funtions ?
> > > >>
> > > >> These functions are called from the CPUIdle path so outside the scope
> > > >> of the GPIO driver. These are part of a bunch of nasty PM hacks we
> > > >> are doing in the CPU idle loop. We are in the process of getting rid
> > > >> of most of them, but it looks like some are still needed.
> > > >
> > > > Too bad. I can see that the gpio pm implementation seems a bit
> > > > "peculiar". I mean, pm does reference counting and yet the driver has
> > > > checks to prevent multiple gets and puts on a single bank (meaning that
> > > > pm counter will be either 0 or 1 at any point in time).
> > > >
> > > > To me it looks like those functions are there in order to forcefully put
> > > > PER power domain in OFF because drivers are always holding a reference
> > > > to their gpios (drivers generally gpio_request() on probe() and
> > > > gpio_free() on remove()).
> > > >
> > > > Looks like the entire pm implementation on OMAP gpio driver has always
> > > > considered only the fact that gpios can be requested and freed, but
> > > > never that we want the system to go to OFF even while gpios are
> > > > requested, because we have I/O PAD wakeups. At some point that has to be
> > > > sorted out because that HACK is quite ugly :-)
> > > >
> > > > I'll see if I find some time to go over the interactions between
> > > > gpio-omap.c and pm24x.c and pm34xx.c any of these days, but I can't
> > > > promise anything ;-)
> > >
> > > If you look at the state of these prepare/resume hacks at the end of
> > > this series, you'll see that they are significantly cleaner and do
> > > nothing but call the runtime PM hooks.
> >
> > sure, definitely.
> >
> > > We have explored several ways to get rid of them completely in the idle
> > > path but have not yet come up with a clean way, but this series gets us
> > > a long ways towards that goal.
> >
> > have you thought about being a bit more aggressive at when to
> > runtime_get and runtime_put ?
> >
> > I didn't test below (will do probably on monday), but I think this will
> > help keeping GPIO block always suspended, and only wake it up when truly
> > needed. That way, you could, at some point, remove that list_head
> > because by the time you reach CPUIdle path, GPIO module is already
> > suspended. That's the theory at least, gotta run it first on silicon to
> > be sure
> >
> > diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
> > index 4273401..2dd9ced 100644
> > --- a/drivers/gpio/gpio-omap.c
> > +++ b/drivers/gpio/gpio-omap.c
> > @@ -537,12 +537,7 @@ 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;
> >
> > -       /*
> > -        * If this is the first gpio_request for the bank,
> > -        * enable the bank module.
> > -        */
> > -       if (!bank->mod_usage)
> > -               pm_runtime_get_sync(bank->dev);
> > +       pm_runtime_get_sync(bank->dev);
> 
> bank->mod_usage check is used to take care of doing pm_runtime_get*/put* only
> if all the GPIOs in a particular bank are enabled or disabled respectively.

and why should you care about that ? The first get will enable the
resources you need, the second get will just increase a counter and so
on. So if you have 32 gets, you will disable the module when you have 32
puts.

> With the above change, pm_runtime_put*/get* would be called for every
> gpio_request()
> /_free() (that is, for upto 32 pins in OMAP3/4) in a bank irrespective
> of whether other

so ?

> GPIO pins are enabled or disabled in the same bank. Hence it is
> required to have a
> check based on mod_usage.

unnecessary.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-05  9:08                         ` Felipe Balbi
@ 2012-02-05  9:16                           ` Shilimkar, Santosh
  2012-02-05 11:35                             ` Felipe Balbi
  2012-02-06  5:18                           ` Varadarajan, Charulatha
  1 sibling, 1 reply; 64+ messages in thread
From: Shilimkar, Santosh @ 2012-02-05  9:16 UTC (permalink / raw)
  To: balbi
  Cc: Varadarajan, Charulatha, Kevin Hilman, Cousson, Benoit,
	Grant Likely, Tarun Kanti DebBarma, linux-omap, tony,
	linux-kernel, linux-arm-kernel

On Sun, Feb 5, 2012 at 2:38 PM, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Sun, Feb 05, 2012 at 12:37:55PM +0530, Varadarajan, Charulatha wrote:
>> Felipe,
>>
>> On Sat, Feb 4, 2012 at 21:38, Felipe Balbi <balbi@ti.com> wrote:

[....]

>> bank->mod_usage check is used to take care of doing pm_runtime_get*/put* only
>> if all the GPIOs in a particular bank are enabled or disabled respectively.
>
> and why should you care about that ? The first get will enable the
> resources you need, the second get will just increase a counter and so
> on. So if you have 32 gets, you will disable the module when you have 32
> puts.
>
Am not sure if it is clear to you that the GPIO resources like clock,
debounce clk are per bank wise and not per GPIO line. So doing 32
get/put per bank is stupid. runtime pm is for managing pm
resources and if the pm resource is per bank, it has to be
handled per bank.

>> With the above change, pm_runtime_put*/get* would be called for every
>> gpio_request()
>> /_free() (that is, for upto 32 pins in OMAP3/4) in a bank irrespective
>> of whether other
>
> so ?
It's useless.

>
>> GPIO pins are enabled or disabled in the same bank. Hence it is
>> required to have a
>> check based on mod_usage.
>
> unnecessary.
>
I don't think so.

Regards
Santosh

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-05  9:16                           ` Shilimkar, Santosh
@ 2012-02-05 11:35                             ` Felipe Balbi
  2012-02-05 12:35                               ` Shilimkar, Santosh
  0 siblings, 1 reply; 64+ messages in thread
From: Felipe Balbi @ 2012-02-05 11:35 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: balbi, Varadarajan, Charulatha, Kevin Hilman, Cousson, Benoit,
	Grant Likely, Tarun Kanti DebBarma, linux-omap, tony,
	linux-kernel, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 2613 bytes --]

Hi,

On Sun, Feb 05, 2012 at 02:46:19PM +0530, Shilimkar, Santosh wrote:
> >> bank->mod_usage check is used to take care of doing pm_runtime_get*/put* only
> >> if all the GPIOs in a particular bank are enabled or disabled respectively.
> >
> > and why should you care about that ? The first get will enable the
> > resources you need, the second get will just increase a counter and so
> > on. So if you have 32 gets, you will disable the module when you have 32
> > puts.
> >
> Am not sure if it is clear to you that the GPIO resources like clock,
> debounce clk are per bank wise and not per GPIO line. So doing 32

this is just one more reason to have usage counters.

> get/put per bank is stupid. runtime pm is for managing pm

what's stupid is trying to use the pm usage counters as a binary flag,
see below.

> resources and if the pm resource is per bank, it has to be
> handled per bank.

hehe, what are you talking about Santosh ? That's the whole point of
reference counting. If there are 32 users for 1 resource, you want to
make sure that you only free the resources (clocks, or whatever resource
you want) after all 32 users are done with it.

Trying to use the pm usage counter as a binary flag, that's the stupid
part of the OMAP GPIO driver.

Instead of adding checks such as:

if (module_isnt_used())
	enable_clocks();

on get and:

if (module_isnt_needed_anymore())
	disable_clcoks()

on put is the most useless piece of code on that driver. Because such
checks are already available on PM core through usage counters. The way
that part of the code works is as follow:

get() {
	if (pm_counter_is_zero(dev)) {
		atomic_inc();

		rpm_resume();
	}
}

put() {
	atomic_dec();

	if (pm_counter_is_zero(dev)) {
		rpm_suspend();
	}
}

Do you not see that you're duplicating functionality by trying to use
the pm counter a binary flag ?

> >> With the above change, pm_runtime_put*/get* would be called for every
> >> gpio_request()
> >> /_free() (that is, for upto 32 pins in OMAP3/4) in a bank irrespective
> >> of whether other
> >
> > so ?
> It's useless.

no, it's not.

> >> GPIO pins are enabled or disabled in the same bank. Hence it is
> >> required to have a
> >> check based on mod_usage.
> >
> > unnecessary.
> >
> I don't think so.

then show that to me with code. Looking at the usage counters on pm
runtime, you're duplicating functionality with it and trying to use it
as a binary flag.

Preventing multiple gets/puts breaks the whole idea of _having_ usage
counters to start with.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-05 11:35                             ` Felipe Balbi
@ 2012-02-05 12:35                               ` Shilimkar, Santosh
  2012-02-06  6:40                                 ` Felipe Balbi
  0 siblings, 1 reply; 64+ messages in thread
From: Shilimkar, Santosh @ 2012-02-05 12:35 UTC (permalink / raw)
  To: balbi
  Cc: Varadarajan, Charulatha, Kevin Hilman, Cousson, Benoit,
	Grant Likely, Tarun Kanti DebBarma, linux-omap, tony,
	linux-kernel, linux-arm-kernel

On Sun, Feb 5, 2012 at 5:05 PM, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Sun, Feb 05, 2012 at 02:46:19PM +0530, Shilimkar, Santosh wrote:
>> >> bank->mod_usage check is used to take care of doing pm_runtime_get*/put* only
>> >> if all the GPIOs in a particular bank are enabled or disabled respectively.
>> >
>> > and why should you care about that ? The first get will enable the
>> > resources you need, the second get will just increase a counter and so
>> > on. So if you have 32 gets, you will disable the module when you have 32
>> > puts.
>> >
>> Am not sure if it is clear to you that the GPIO resources like clock,
>> debounce clk are per bank wise and not per GPIO line. So doing 32
>
> this is just one more reason to have usage counters.
>
>> get/put per bank is stupid. runtime pm is for managing pm
>
> what's stupid is trying to use the pm usage counters as a binary flag,
> see below.
>
>> resources and if the pm resource is per bank, it has to be
>> handled per bank.
>
> hehe, what are you talking about Santosh ? That's the whole point of
> reference counting. If there are 32 users for 1 resource, you want to
> make sure that you only free the resources (clocks, or whatever resource
> you want) after all 32 users are done with it.
>
> Trying to use the pm usage counter as a binary flag, that's the stupid
> part of the OMAP GPIO driver.
>
> Instead of adding checks such as:
>
> if (module_isnt_used())
>        enable_clocks();
>
> on get and:
>
> if (module_isnt_needed_anymore())
>        disable_clcoks()
>
> on put is the most useless piece of code on that driver. Because such
> checks are already available on PM core through usage counters. The way
> that part of the code works is as follow:
>
> get() {
>        if (pm_counter_is_zero(dev)) {
>                atomic_inc();
>
>                rpm_resume();
>        }
> }
>
> put() {
>        atomic_dec();
>
>        if (pm_counter_is_zero(dev)) {
>                rpm_suspend();
>        }
> }
>
> Do you not see that you're duplicating functionality by trying to use
> the pm counter a binary flag ?
>
Ahh.. Now I see your point. I miss-understood the point first time
and thought that we have disconnect on the pm resources from
number of GPIO perspective.

What you are saying is to use pm runtime reference counters rather
than creating local ones for GPIO which seems to be right thing to
do. Sorry for the noise.

The agressive clock cutting was tried initially without much success
and may be we can revisit this one more time.

As per as this series is concerned, we would like to fix
the build error pointed by Kevin and queue it for 3.4.

There are few more fixes getting cooked up for GPIO and
as part of that series we will have a look at your suggestion.

Thanks for review.

Regards
santosh




Regards
Santosh

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-05  9:08                         ` Felipe Balbi
  2012-02-05  9:16                           ` Shilimkar, Santosh
@ 2012-02-06  5:18                           ` Varadarajan, Charulatha
  1 sibling, 0 replies; 64+ messages in thread
From: Varadarajan, Charulatha @ 2012-02-06  5:18 UTC (permalink / raw)
  To: balbi
  Cc: Kevin Hilman, Cousson, Benoit, Grant Likely,
	Tarun Kanti DebBarma, linux-omap, tony, linux-kernel,
	linux-arm-kernel

Felipe,

On Sun, Feb 5, 2012 at 14:38, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Sun, Feb 05, 2012 at 12:37:55PM +0530, Varadarajan, Charulatha wrote:
>> Felipe,
>>
>> On Sat, Feb 4, 2012 at 21:38, Felipe Balbi <balbi@ti.com> wrote:
>> >
>> > Hi,
>> >
>> > On Fri, Feb 03, 2012 at 09:50:19AM -0800, Kevin Hilman wrote:
>> > > Felipe Balbi <balbi@ti.com> writes:
>> > >
>> > > [...]
>> > >
>> > > >> >This question remains. Why do we need those funtions ?
>> > > >>
>> > > >> These functions are called from the CPUIdle path so outside the scope
>> > > >> of the GPIO driver. These are part of a bunch of nasty PM hacks we
>> > > >> are doing in the CPU idle loop. We are in the process of getting rid
>> > > >> of most of them, but it looks like some are still needed.
>> > > >
>> > > > Too bad. I can see that the gpio pm implementation seems a bit
>> > > > "peculiar". I mean, pm does reference counting and yet the driver has
>> > > > checks to prevent multiple gets and puts on a single bank (meaning that
>> > > > pm counter will be either 0 or 1 at any point in time).
>> > > >
>> > > > To me it looks like those functions are there in order to forcefully put
>> > > > PER power domain in OFF because drivers are always holding a reference
>> > > > to their gpios (drivers generally gpio_request() on probe() and
>> > > > gpio_free() on remove()).
>> > > >
>> > > > Looks like the entire pm implementation on OMAP gpio driver has always
>> > > > considered only the fact that gpios can be requested and freed, but
>> > > > never that we want the system to go to OFF even while gpios are
>> > > > requested, because we have I/O PAD wakeups. At some point that has to be
>> > > > sorted out because that HACK is quite ugly :-)
>> > > >
>> > > > I'll see if I find some time to go over the interactions between
>> > > > gpio-omap.c and pm24x.c and pm34xx.c any of these days, but I can't
>> > > > promise anything ;-)
>> > >
>> > > If you look at the state of these prepare/resume hacks at the end of
>> > > this series, you'll see that they are significantly cleaner and do
>> > > nothing but call the runtime PM hooks.
>> >
>> > sure, definitely.
>> >
>> > > We have explored several ways to get rid of them completely in the idle
>> > > path but have not yet come up with a clean way, but this series gets us
>> > > a long ways towards that goal.
>> >
>> > have you thought about being a bit more aggressive at when to
>> > runtime_get and runtime_put ?
>> >
>> > I didn't test below (will do probably on monday), but I think this will
>> > help keeping GPIO block always suspended, and only wake it up when truly
>> > needed. That way, you could, at some point, remove that list_head
>> > because by the time you reach CPUIdle path, GPIO module is already
>> > suspended. That's the theory at least, gotta run it first on silicon to
>> > be sure
>> >
>> > diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
>> > index 4273401..2dd9ced 100644
>> > --- a/drivers/gpio/gpio-omap.c
>> > +++ b/drivers/gpio/gpio-omap.c
>> > @@ -537,12 +537,7 @@ 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;
>> >
>> > -       /*
>> > -        * If this is the first gpio_request for the bank,
>> > -        * enable the bank module.
>> > -        */
>> > -       if (!bank->mod_usage)
>> > -               pm_runtime_get_sync(bank->dev);
>> > +       pm_runtime_get_sync(bank->dev);
>>
>> bank->mod_usage check is used to take care of doing pm_runtime_get*/put* only
>> if all the GPIOs in a particular bank are enabled or disabled respectively.
>
> and why should you care about that ? The first get will enable the
> resources you need, the second get will just increase a counter and so
> on. So if you have 32 gets, you will disable the module when you have 32
> puts.

Agreed!

-V Charulatha

>
>> With the above change, pm_runtime_put*/get* would be called for every
>> gpio_request()
>> /_free() (that is, for upto 32 pins in OMAP3/4) in a bank irrespective
>> of whether other
>
> so ?
>
>> GPIO pins are enabled or disabled in the same bank. Hence it is
>> required to have a
>> check based on mod_usage.
>
> unnecessary.
>
> --
> balbi

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count
  2012-02-05 12:35                               ` Shilimkar, Santosh
@ 2012-02-06  6:40                                 ` Felipe Balbi
  0 siblings, 0 replies; 64+ messages in thread
From: Felipe Balbi @ 2012-02-06  6:40 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: balbi, Varadarajan, Charulatha, Kevin Hilman, Cousson, Benoit,
	Grant Likely, Tarun Kanti DebBarma, linux-omap, tony,
	linux-kernel, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 3225 bytes --]

On Sun, Feb 05, 2012 at 06:05:37PM +0530, Shilimkar, Santosh wrote:
> On Sun, Feb 5, 2012 at 5:05 PM, Felipe Balbi <balbi@ti.com> wrote:
> > Hi,
> >
> > On Sun, Feb 05, 2012 at 02:46:19PM +0530, Shilimkar, Santosh wrote:
> >> >> bank->mod_usage check is used to take care of doing pm_runtime_get*/put* only
> >> >> if all the GPIOs in a particular bank are enabled or disabled respectively.
> >> >
> >> > and why should you care about that ? The first get will enable the
> >> > resources you need, the second get will just increase a counter and so
> >> > on. So if you have 32 gets, you will disable the module when you have 32
> >> > puts.
> >> >
> >> Am not sure if it is clear to you that the GPIO resources like clock,
> >> debounce clk are per bank wise and not per GPIO line. So doing 32
> >
> > this is just one more reason to have usage counters.
> >
> >> get/put per bank is stupid. runtime pm is for managing pm
> >
> > what's stupid is trying to use the pm usage counters as a binary flag,
> > see below.
> >
> >> resources and if the pm resource is per bank, it has to be
> >> handled per bank.
> >
> > hehe, what are you talking about Santosh ? That's the whole point of
> > reference counting. If there are 32 users for 1 resource, you want to
> > make sure that you only free the resources (clocks, or whatever resource
> > you want) after all 32 users are done with it.
> >
> > Trying to use the pm usage counter as a binary flag, that's the stupid
> > part of the OMAP GPIO driver.
> >
> > Instead of adding checks such as:
> >
> > if (module_isnt_used())
> >        enable_clocks();
> >
> > on get and:
> >
> > if (module_isnt_needed_anymore())
> >        disable_clcoks()
> >
> > on put is the most useless piece of code on that driver. Because such
> > checks are already available on PM core through usage counters. The way
> > that part of the code works is as follow:
> >
> > get() {
> >        if (pm_counter_is_zero(dev)) {
> >                atomic_inc();
> >
> >                rpm_resume();
> >        }
> > }
> >
> > put() {
> >        atomic_dec();
> >
> >        if (pm_counter_is_zero(dev)) {
> >                rpm_suspend();
> >        }
> > }
> >
> > Do you not see that you're duplicating functionality by trying to use
> > the pm counter a binary flag ?
> >
> Ahh.. Now I see your point. I miss-understood the point first time
> and thought that we have disconnect on the pm resources from
> number of GPIO perspective.
> 
> What you are saying is to use pm runtime reference counters rather
> than creating local ones for GPIO which seems to be right thing to
> do. Sorry for the noise.

no problem.

> The agressive clock cutting was tried initially without much success
> and may be we can revisit this one more time.

I think one issue will be wrt to IRQ handling. If you want pm_runtime_*
calls to be irq_safe, they will keep the parent always on, so we need to
find a way to make that part work properly, I guess.

> As per as this series is concerned, we would like to fix
> the build error pointed by Kevin and queue it for 3.4.

sure, go ahead. No problems with that at all.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 00/25] gpio/omap: driver cleanup and fixes
  2012-02-03 21:01 ` Kevin Hilman
@ 2012-02-06 11:53   ` DebBarma, Tarun Kanti
  0 siblings, 0 replies; 64+ messages in thread
From: DebBarma, Tarun Kanti @ 2012-02-06 11:53 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, tony, linux-kernel, grant.likely, linux-arm-kernel

Kevin,

On Sat, Feb 4, 2012 at 2:31 AM, Kevin Hilman <khilman@ti.com> wrote:
>
> Hi Tarun,
>
> Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
>
> > The following changes since commit 62aa2b537c6f5957afd98e29f96897419ed5ebab:
> >   Linus Torvalds (1):
> >         Linux 3.3-rc2
> >
> > are available in the git repository at:
> > http://gitorious.org/~tarunkanti/omap-sw-develoment/tarunkantis-linux-omap-dev
> > Branch: for_3.4/gpio_cleanup_fixes_v9
> >
> > 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.
>
> This version is looking pretty good, and I'm almost ready to queue it up
> for Grant.
>
> However, one more minor nit.  Please fix up the compile warnings when
> built without CONFIG_PM_SLEEP or CONFIG_PM_RUNTIME.
>
> The definitons of the dev_pm_ops callbacks need to be conditional when
> using the SET_*_PM_OPS() macros, otherwise you get these warnings:

I have updated the branch with the required changes.
--
Tarun
>
>
>
>  CC      drivers/gpio/gpio-omap.o
> /work/kernel/omap/pm/drivers/gpio/gpio-omap.c:1142:12: warning: 'omap_gpio_suspend' defined but not used [-Wunused-function]
> /work/kernel/omap/pm/drivers/gpio/gpio-omap.c:1167:12: warning: 'omap_gpio_resume' defined but not used [-Wunused-function]
> /work/kernel/omap/pm/drivers/gpio/gpio-omap.c:1191:12: warning: 'omap_gpio_runtime_suspend' defined but not used [-Wunused-function]
> /work/kernel/omap/pm/drivers/gpio/gpio-omap.c:1237:12: warning: 'omap_gpio_runtime_resume' defined but not used [-Wunused-function]
>
>
> Thanks,
>
> Kevin

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 00/25] gpio/omap: driver cleanup and fixes
  2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
                   ` (27 preceding siblings ...)
  2012-02-03 21:01 ` Kevin Hilman
@ 2012-02-10 19:24 ` Tony Lindgren
  2012-02-10 19:55   ` Kevin Hilman
  28 siblings, 1 reply; 64+ messages in thread
From: Tony Lindgren @ 2012-02-10 19:24 UTC (permalink / raw)
  To: Tarun Kanti DebBarma
  Cc: linux-omap, grant.likely, khilman, linux-kernel, linux-arm-kernel

Hi Tarun,

* Tarun Kanti DebBarma <tarun.kanti@ti.com> [120202 09:00]:
> 
>   Used following patches to avoid exception during system suspend:-
>   [PATCH RFC 1/2] mtd : Prevent the NULL pointer access
>   [PATCH RFC 2/2] mtd : Make the mtd_suspend return 0 if the suspend is not implemented

OK so MTD fixes those are supposedly going in during the -rc cycle..
 
> # echo mem > /sys/power/state
> [   47.128021] PM: Syncing filesystems ... done.
> [   47.144104] Freezing user space processes ... (elapsed 0.01 seconds) done.
> [   47.168243] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) don                                                                                                 e.
> [   47.205139] Unable to handle kernel NULL pointer dereference at virtual addre                                                                                                 ss 000000a0
> [   47.213317] pgd = deaac000
> [   47.216033] [000000a0] *pgd=9e932831, *pte=00000000, *ppte=00000000
> [   47.222381] Internal error: Oops: 17 [#1] SMP
> [   47.226745] Modules linked in:
> [   47.229827] CPU: 0    Not tainted  (3.3.0-rc2-00031-g12c5c5c #235)
> [   47.236022] PC is at mtd_cls_suspend+0x8/0x20
> [   47.240386] LR is at mtd_cls_suspend+0x8/0x20
> [   47.244750] pc : [<c02e78f8>]    lr : [<c02e78f8>]    psr: a0000013
> [   47.244750] sp : dea1fe60  ip : 22222222  fp : c0ee7d40
> [   47.256256] r10: c0ee7cf0  r9 : 00000000  r8 : c02e78f0
> [   47.261474] r7 : 00000000  r6 : 00000000  r5 : 00000002  r4 : dea45800
> [   47.268005] r3 : deb4cac0  r2 : 00000000  r1 : 00000002  r0 : 00000000
> [   47.274536] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
> [   47.281677] Control: 10c5387d  Table: 9eaac019  DAC: 00000015
> [   47.287445] Process sh (pid: 1177, stack limit = 0xdea1e2f8)
> [   47.293090] Stack: (0xdea1fe60 to 0xdea20000)
> [...]

..but are there also some patches in your series that should also be
applied separately as fixes for the -rc cycle?

Regards,

Tony

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 00/25] gpio/omap: driver cleanup and fixes
  2012-02-10 19:24 ` Tony Lindgren
@ 2012-02-10 19:55   ` Kevin Hilman
  2012-02-13  5:33     ` DebBarma, Tarun Kanti
  0 siblings, 1 reply; 64+ messages in thread
From: Kevin Hilman @ 2012-02-10 19:55 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Tarun Kanti DebBarma, linux-omap, grant.likely, linux-kernel,
	linux-arm-kernel

Tony Lindgren <tony@atomide.com> writes:

[...]

> ..but are there also some patches in your series that should also be
> applied separately as fixes for the -rc cycle?

IMO, there aren't any things in this series that fall into the
regression category.

After I get to a final review and test of this (early next week), I'm
planning to sent a pull request to Grant.

Kevin

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 00/25] gpio/omap: driver cleanup and fixes
  2012-02-10 19:55   ` Kevin Hilman
@ 2012-02-13  5:33     ` DebBarma, Tarun Kanti
  0 siblings, 0 replies; 64+ messages in thread
From: DebBarma, Tarun Kanti @ 2012-02-13  5:33 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Tony Lindgren, linux-omap, grant.likely, linux-kernel, linux-arm-kernel

On Sat, Feb 11, 2012 at 1:25 AM, Kevin Hilman <khilman@ti.com> wrote:
> Tony Lindgren <tony@atomide.com> writes:
>
> [...]
>
>> ..but are there also some patches in your series that should also be
>> applied separately as fixes for the -rc cycle?
>
> IMO, there aren't any things in this series that fall into the
> regression category.
That's right.
--
Tarun
>
> After I get to a final review and test of this (early next week), I'm
> planning to sent a pull request to Grant.
>
> Kevin

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function
  2012-02-02 17:30 ` [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function Tarun Kanti DebBarma
@ 2012-04-21 14:03   ` Janusz Krzysztofik
  2012-04-23 18:54     ` DebBarma, Tarun Kanti
  0 siblings, 1 reply; 64+ messages in thread
From: Janusz Krzysztofik @ 2012-04-21 14:03 UTC (permalink / raw)
  To: Tarun Kanti DebBarma
  Cc: linux-omap, grant.likely, khilman, tony, linux-kernel,
	linux-arm-kernel, Charulatha V

On Thursday 02 of February 2012 23:00:37 Tarun Kanti DebBarma wrote:
> 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...
> 
> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> Signed-off-by: Charulatha V <charu@ti.com>
> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Acked-by: Tony Lindgren <tony@atomide.com>

Sorry for being so late with my comment for chanes already present in 
mainline, but this patch breaks GPIO on Amstrad Delta at least, and I 
have neither enough spare time nor enough experience with non OMAP1 
machines to provide a solution myself.

> ---
>  arch/arm/mach-omap1/gpio16xx.c |   35 +++++++++++++++++-
>  drivers/gpio/gpio-omap.c       |   77 ++++++++++++----------------------------
>  2 files changed, 57 insertions(+), 55 deletions(-)
...
> diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
> index f39d9e4..a948351 100644
> --- a/drivers/gpio/gpio-omap.c
> +++ b/drivers/gpio/gpio-omap.c
...
> @@ -898,62 +896,30 @@ static void __init omap_gpio_show_rev(struct gpio_bank *bank)
>   */
>  static struct lock_class_key gpio_lock_class;
>  
> -/* TODO: Cleanup cpu_is_* checks */
>  static void omap_gpio_mod_init(struct gpio_bank *bank)
>  {
> -	if (cpu_class_is_omap2()) {
> -		if (cpu_is_omap44xx()) {
> -			__raw_writel(0xffffffff, bank->base +
> -					OMAP4_GPIO_IRQSTATUSCLR0);
> -			__raw_writel(0x00000000, bank->base +
> -					 OMAP4_GPIO_DEBOUNCENABLE);
> -			/* Initialize interface clk ungated, module enabled */
> -			__raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
> -		} else if (cpu_is_omap34xx()) {
> -			__raw_writel(0x00000000, bank->base +
> -					OMAP24XX_GPIO_IRQENABLE1);
> -			__raw_writel(0xffffffff, bank->base +
> -					OMAP24XX_GPIO_IRQSTATUS1);
> -			__raw_writel(0x00000000, bank->base +
> -					OMAP24XX_GPIO_DEBOUNCE_EN);
> -
> -			/* Initialize interface clk ungated, module enabled */
> -			__raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
> -		}
> -	} else if (cpu_class_is_omap1()) {
> -		if (bank_is_mpuio(bank)) {
> -			__raw_writew(0xffff, bank->base +
> -				OMAP_MPUIO_GPIO_MASKIT / bank->stride);
> -			mpuio_init(bank);
> -		}
> -		if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
> -			__raw_writew(0xffff, bank->base
> -						+ OMAP1510_GPIO_INT_MASK);
> -			__raw_writew(0x0000, bank->base
> -						+ OMAP1510_GPIO_INT_STATUS);
> -		}
> -		if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) {
> -			__raw_writew(0x0000, bank->base
> -						+ OMAP1610_GPIO_IRQENABLE1);
> -			__raw_writew(0xffff, bank->base
> -						+ OMAP1610_GPIO_IRQSTATUS1);
> -			__raw_writew(0x0014, bank->base
> -						+ OMAP1610_GPIO_SYSCONFIG);
> +	void __iomem *base = bank->base;
> +	u32 l = 0xffffffff;
>  
> -			/*
> -			 * 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);
> -		}
> -		if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) {
> -			__raw_writel(0xffffffff, bank->base
> -						+ OMAP7XX_GPIO_INT_MASK);
> -			__raw_writel(0x00000000, bank->base
> -						+ OMAP7XX_GPIO_INT_STATUS);
> -		}
> +	if (bank->width == 16)
> +		l = 0xffff;
> +
> +	if (bank_is_mpuio(bank)) {
> +		__raw_writel(l, bank->base + bank->regs->irqenable);
> +		return;
>  	}
> +
> +	_gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv);
> +	_gpio_rmw(base, bank->regs->irqstatus, l,
> +					bank->regs->irqenable_inv == false);
> +	_gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0);
> +	_gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0);

bank->regs->irqenable trgister is manipulated 3 times in a row, each 
time based on different criteria. This breaks GPIO on Amstrad Delta at 
least, and generally looks wrong. I was only able to verify that 
commenting out the above two lines fixes the issue with Amstrad Delta for 
me.

> +	if (bank->regs->debounce_en)
> +		_gpio_rmw(base, bank->regs->debounce_en, 0, 1);

This also looks suspicious, I guess the second line should rather be:

		_gpio_rmw(base, bank->regs->debounce, 0, 1);

> +
> +	 /* Initialize interface clk ungated, module enabled */
> +	if (bank->regs->ctrl)
> +		_gpio_rmw(base, bank->regs->ctrl, 0, 1);

Is bank->regs->ctrl a flag, or a register offset? If the latter, is that 
offset guaranteed to never take a valid value of 0?

Thanks,
Janusz

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function
  2012-04-21 14:03   ` Janusz Krzysztofik
@ 2012-04-23 18:54     ` DebBarma, Tarun Kanti
  2012-04-24 15:36       ` DebBarma, Tarun Kanti
  0 siblings, 1 reply; 64+ messages in thread
From: DebBarma, Tarun Kanti @ 2012-04-23 18:54 UTC (permalink / raw)
  To: Janusz Krzysztofik
  Cc: linux-omap, grant.likely, khilman, tony, linux-kernel,
	linux-arm-kernel, Charulatha V

On Sat, Apr 21, 2012 at 7:33 PM, Janusz Krzysztofik
<jkrzyszt@tis.icnet.pl> wrote:
> On Thursday 02 of February 2012 23:00:37 Tarun Kanti DebBarma wrote:
>> 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...
>>
>> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
>> Signed-off-by: Charulatha V <charu@ti.com>
>> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> Acked-by: Tony Lindgren <tony@atomide.com>
>
> Sorry for being so late with my comment for chanes already present in
> mainline, but this patch breaks GPIO on Amstrad Delta at least, and I
> have neither enough spare time nor enough experience with non OMAP1
> machines to provide a solution myself.
Yes, I looked at the omap_gpio_mod_init() and OMAP1 configurations are
overwritten.
Also looks like there is issue in making distinction between omap15xx
and omap16xx.
I will post a patch and you can help me testing it in OMAP1 platform.
Thanks for pointing this out.
--
Tarun
>
>> ---
>>  arch/arm/mach-omap1/gpio16xx.c |   35 +++++++++++++++++-
>>  drivers/gpio/gpio-omap.c       |   77 ++++++++++++----------------------------
>>  2 files changed, 57 insertions(+), 55 deletions(-)
> ...
>> diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
>> index f39d9e4..a948351 100644
>> --- a/drivers/gpio/gpio-omap.c
>> +++ b/drivers/gpio/gpio-omap.c
> ...
>> @@ -898,62 +896,30 @@ static void __init omap_gpio_show_rev(struct gpio_bank *bank)
>>   */
>>  static struct lock_class_key gpio_lock_class;
>>
>> -/* TODO: Cleanup cpu_is_* checks */
>>  static void omap_gpio_mod_init(struct gpio_bank *bank)
>>  {
>> -     if (cpu_class_is_omap2()) {
>> -             if (cpu_is_omap44xx()) {
>> -                     __raw_writel(0xffffffff, bank->base +
>> -                                     OMAP4_GPIO_IRQSTATUSCLR0);
>> -                     __raw_writel(0x00000000, bank->base +
>> -                                      OMAP4_GPIO_DEBOUNCENABLE);
>> -                     /* Initialize interface clk ungated, module enabled */
>> -                     __raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
>> -             } else if (cpu_is_omap34xx()) {
>> -                     __raw_writel(0x00000000, bank->base +
>> -                                     OMAP24XX_GPIO_IRQENABLE1);
>> -                     __raw_writel(0xffffffff, bank->base +
>> -                                     OMAP24XX_GPIO_IRQSTATUS1);
>> -                     __raw_writel(0x00000000, bank->base +
>> -                                     OMAP24XX_GPIO_DEBOUNCE_EN);
>> -
>> -                     /* Initialize interface clk ungated, module enabled */
>> -                     __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
>> -             }
>> -     } else if (cpu_class_is_omap1()) {
>> -             if (bank_is_mpuio(bank)) {
>> -                     __raw_writew(0xffff, bank->base +
>> -                             OMAP_MPUIO_GPIO_MASKIT / bank->stride);
>> -                     mpuio_init(bank);
>> -             }
>> -             if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
>> -                     __raw_writew(0xffff, bank->base
>> -                                             + OMAP1510_GPIO_INT_MASK);
>> -                     __raw_writew(0x0000, bank->base
>> -                                             + OMAP1510_GPIO_INT_STATUS);
>> -             }
>> -             if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) {
>> -                     __raw_writew(0x0000, bank->base
>> -                                             + OMAP1610_GPIO_IRQENABLE1);
>> -                     __raw_writew(0xffff, bank->base
>> -                                             + OMAP1610_GPIO_IRQSTATUS1);
>> -                     __raw_writew(0x0014, bank->base
>> -                                             + OMAP1610_GPIO_SYSCONFIG);
>> +     void __iomem *base = bank->base;
>> +     u32 l = 0xffffffff;
>>
>> -                     /*
>> -                      * 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);
>> -             }
>> -             if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) {
>> -                     __raw_writel(0xffffffff, bank->base
>> -                                             + OMAP7XX_GPIO_INT_MASK);
>> -                     __raw_writel(0x00000000, bank->base
>> -                                             + OMAP7XX_GPIO_INT_STATUS);
>> -             }
>> +     if (bank->width == 16)
>> +             l = 0xffff;
>> +
>> +     if (bank_is_mpuio(bank)) {
>> +             __raw_writel(l, bank->base + bank->regs->irqenable);
>> +             return;
>>       }
>> +
>> +     _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv);
>> +     _gpio_rmw(base, bank->regs->irqstatus, l,
>> +                                     bank->regs->irqenable_inv == false);
>> +     _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0);
>> +     _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0);
>
> bank->regs->irqenable trgister is manipulated 3 times in a row, each
> time based on different criteria. This breaks GPIO on Amstrad Delta at
> least, and generally looks wrong. I was only able to verify that
> commenting out the above two lines fixes the issue with Amstrad Delta for
> me.
>
>> +     if (bank->regs->debounce_en)
>> +             _gpio_rmw(base, bank->regs->debounce_en, 0, 1);
>
> This also looks suspicious, I guess the second line should rather be:
>
>                _gpio_rmw(base, bank->regs->debounce, 0, 1);
>
>> +
>> +      /* Initialize interface clk ungated, module enabled */
>> +     if (bank->regs->ctrl)
>> +             _gpio_rmw(base, bank->regs->ctrl, 0, 1);
>
> Is bank->regs->ctrl a flag, or a register offset? If the latter, is that
> offset guaranteed to never take a valid value of 0?
>
> Thanks,
> Janusz

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function
  2012-04-23 18:54     ` DebBarma, Tarun Kanti
@ 2012-04-24 15:36       ` DebBarma, Tarun Kanti
  2012-04-24 16:04         ` Tony Lindgren
  2012-04-24 22:37         ` Janusz Krzysztofik
  0 siblings, 2 replies; 64+ messages in thread
From: DebBarma, Tarun Kanti @ 2012-04-24 15:36 UTC (permalink / raw)
  To: Janusz Krzysztofik
  Cc: linux-omap, grant.likely, khilman, tony, linux-kernel,
	linux-arm-kernel, Charulatha V

[-- Attachment #1: Type: text/plain, Size: 8670 bytes --]

Hi Janusz,

On Tue, Apr 24, 2012 at 12:24 AM, DebBarma, Tarun Kanti
<tarun.kanti@ti.com> wrote:
> On Sat, Apr 21, 2012 at 7:33 PM, Janusz Krzysztofik
> <jkrzyszt@tis.icnet.pl> wrote:
>> On Thursday 02 of February 2012 23:00:37 Tarun Kanti DebBarma wrote:
>>> 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...
>>>
>>> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
>>> Signed-off-by: Charulatha V <charu@ti.com>
>>> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>> Acked-by: Tony Lindgren <tony@atomide.com>
>>
>> Sorry for being so late with my comment for chanes already present in
>> mainline, but this patch breaks GPIO on Amstrad Delta at least, and I
>> have neither enough spare time nor enough experience with non OMAP1
>> machines to provide a solution myself.
> Yes, I looked at the omap_gpio_mod_init() and OMAP1 configurations are
> overwritten.
> Also looks like there is issue in making distinction between omap15xx
> and omap16xx.
> I will post a patch and you can help me testing it in OMAP1 platform.
> Thanks for pointing this out.
> --
> Tarun
>>
>>> ---
>>>  arch/arm/mach-omap1/gpio16xx.c |   35 +++++++++++++++++-
>>>  drivers/gpio/gpio-omap.c       |   77 ++++++++++++----------------------------
>>>  2 files changed, 57 insertions(+), 55 deletions(-)
>> ...
>>> diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
>>> index f39d9e4..a948351 100644
>>> --- a/drivers/gpio/gpio-omap.c
>>> +++ b/drivers/gpio/gpio-omap.c
>> ...
>>> @@ -898,62 +896,30 @@ static void __init omap_gpio_show_rev(struct gpio_bank *bank)
>>>   */
>>>  static struct lock_class_key gpio_lock_class;
>>>
>>> -/* TODO: Cleanup cpu_is_* checks */
>>>  static void omap_gpio_mod_init(struct gpio_bank *bank)
>>>  {
>>> -     if (cpu_class_is_omap2()) {
>>> -             if (cpu_is_omap44xx()) {
>>> -                     __raw_writel(0xffffffff, bank->base +
>>> -                                     OMAP4_GPIO_IRQSTATUSCLR0);
>>> -                     __raw_writel(0x00000000, bank->base +
>>> -                                      OMAP4_GPIO_DEBOUNCENABLE);
>>> -                     /* Initialize interface clk ungated, module enabled */
>>> -                     __raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
>>> -             } else if (cpu_is_omap34xx()) {
>>> -                     __raw_writel(0x00000000, bank->base +
>>> -                                     OMAP24XX_GPIO_IRQENABLE1);
>>> -                     __raw_writel(0xffffffff, bank->base +
>>> -                                     OMAP24XX_GPIO_IRQSTATUS1);
>>> -                     __raw_writel(0x00000000, bank->base +
>>> -                                     OMAP24XX_GPIO_DEBOUNCE_EN);
>>> -
>>> -                     /* Initialize interface clk ungated, module enabled */
>>> -                     __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
>>> -             }
>>> -     } else if (cpu_class_is_omap1()) {
>>> -             if (bank_is_mpuio(bank)) {
>>> -                     __raw_writew(0xffff, bank->base +
>>> -                             OMAP_MPUIO_GPIO_MASKIT / bank->stride);
>>> -                     mpuio_init(bank);
>>> -             }
>>> -             if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
>>> -                     __raw_writew(0xffff, bank->base
>>> -                                             + OMAP1510_GPIO_INT_MASK);
>>> -                     __raw_writew(0x0000, bank->base
>>> -                                             + OMAP1510_GPIO_INT_STATUS);
>>> -             }
>>> -             if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) {
>>> -                     __raw_writew(0x0000, bank->base
>>> -                                             + OMAP1610_GPIO_IRQENABLE1);
>>> -                     __raw_writew(0xffff, bank->base
>>> -                                             + OMAP1610_GPIO_IRQSTATUS1);
>>> -                     __raw_writew(0x0014, bank->base
>>> -                                             + OMAP1610_GPIO_SYSCONFIG);
>>> +     void __iomem *base = bank->base;
>>> +     u32 l = 0xffffffff;
>>>
>>> -                     /*
>>> -                      * 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);
>>> -             }
>>> -             if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) {
>>> -                     __raw_writel(0xffffffff, bank->base
>>> -                                             + OMAP7XX_GPIO_INT_MASK);
>>> -                     __raw_writel(0x00000000, bank->base
>>> -                                             + OMAP7XX_GPIO_INT_STATUS);
>>> -             }
>>> +     if (bank->width == 16)
>>> +             l = 0xffff;
>>> +
>>> +     if (bank_is_mpuio(bank)) {
>>> +             __raw_writel(l, bank->base + bank->regs->irqenable);
>>> +             return;
>>>       }
>>> +
>>> +     _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv);
>>> +     _gpio_rmw(base, bank->regs->irqstatus, l,
>>> +                                     bank->regs->irqenable_inv == false);
>>> +     _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0);
>>> +     _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0);
>>
>> bank->regs->irqenable trgister is manipulated 3 times in a row, each
>> time based on different criteria. This breaks GPIO on Amstrad Delta at
>> least, and generally looks wrong. I was only able to verify that
>> commenting out the above two lines fixes the issue with Amstrad Delta for
>> me.
>>
>>> +     if (bank->regs->debounce_en)
>>> +             _gpio_rmw(base, bank->regs->debounce_en, 0, 1);
>>
>> This also looks suspicious, I guess the second line should rather be:
>>
>>                _gpio_rmw(base, bank->regs->debounce, 0, 1);
>>
>>> +
>>> +      /* Initialize interface clk ungated, module enabled */
>>> +     if (bank->regs->ctrl)
>>> +             _gpio_rmw(base, bank->regs->ctrl, 0, 1);
>>
>> Is bank->regs->ctrl a flag, or a register offset? If the latter, is that
>> offset guaranteed to never take a valid value of 0?
>>
>> Thanks,
>> Janusz

Here is the patch, with attachment as well. I have just tested on
OMAP4 platform.
Testing on other OMAP2+ platforms is pending. In the meantime can you please
validate on OMAP1 platform and confirm? Thanks.
--
Tarun

From: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Date: Tue, 24 Apr 2012 20:34:32 +0530
Subject: [PATCH] gpio/omap: fix omap1 register overwrite in omap_gpio_mod_init

Initialization of irqenable, irqstatus registers is the common
operation done in this function for all OMAP platforms, viz.
OMAP1, OMAP2+. The latter _gpio_rmw()'s to irqenable register
was overwriting the correctly programmed OMAP1 value at the
beginning. As a result, even though it worked on OMAP2+
platforms it was breaking OMAP1 functionality.

On closer observation it is found that the first _gpio_rmw()
which is supposedly done to take care of OMAP1 platform is
generic enough and takes care of OMAP2+ platform as well.
Therefore remove the latter _gpio_rmw() to irqenable as they
are redundant.

Also, changing the sequence and logic of initializing the
irqstatus.

Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
---
 drivers/gpio/gpio-omap.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 1adc2ec..b8f01c1 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -964,11 +964,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
                return;
        }

+       _gpio_rmw(base, bank->regs->irqstatus, l,
bank->regs->irqenable_inv == 0 );
        _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv);
-       _gpio_rmw(base, bank->regs->irqstatus, l,
-                                       bank->regs->irqenable_inv == false);
-       _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0);
-       _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0);
        if (bank->regs->debounce_en)
                _gpio_rmw(base, bank->regs->debounce_en, 0, 1);

--
1.7.0.4

[-- Attachment #2: 0001-gpio-omap-fix-omap1-register-overwrite-in-omap_gpio_.patch --]
[-- Type: application/octet-stream, Size: 1790 bytes --]

From 0014eddba696090ef3bea12fca9b2894d4a70a1b Mon Sep 17 00:00:00 2001
From: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Date: Tue, 24 Apr 2012 20:34:32 +0530
Subject: [PATCH] gpio/omap: fix omap1 register overwrite in omap_gpio_mod_init

Initialization of irqenable, irqstatus registers is the common
operation done in this function for all OMAP platforms, viz.
OMAP1, OMAP2+. The latter _gpio_rmw()'s to irqenable register
was overwriting the correctly programmed OMAP1 value at the
beginning. As a result, even though it worked on OMAP2+
platforms it was breaking OMAP1 functionality.

On closer observation it is found that the first _gpio_rmw()
which is supposedly done to take care of OMAP1 platform is
generic enough and takes care of OMAP2+ platform as well.
Therefore remove the latter _gpio_rmw() to irqenable as they
are redundant.

Also, changing the sequence and logic of initializing the
irqstatus.

Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
---
 drivers/gpio/gpio-omap.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 1adc2ec..b8f01c1 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -964,11 +964,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
 		return;
 	}
 
+	_gpio_rmw(base, bank->regs->irqstatus, l, bank->regs->irqenable_inv == 0 );
 	_gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv);
-	_gpio_rmw(base, bank->regs->irqstatus, l,
-					bank->regs->irqenable_inv == false);
-	_gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0);
-	_gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0);
 	if (bank->regs->debounce_en)
 		_gpio_rmw(base, bank->regs->debounce_en, 0, 1);
 
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function
  2012-04-24 15:36       ` DebBarma, Tarun Kanti
@ 2012-04-24 16:04         ` Tony Lindgren
  2012-04-25  4:34           ` DebBarma, Tarun Kanti
  2012-04-24 22:37         ` Janusz Krzysztofik
  1 sibling, 1 reply; 64+ messages in thread
From: Tony Lindgren @ 2012-04-24 16:04 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti
  Cc: Janusz Krzysztofik, linux-omap, grant.likely, khilman,
	linux-kernel, linux-arm-kernel, Charulatha V

* DebBarma, Tarun Kanti <tarun.kanti@ti.com> [120424 08:40]:
> Hi Janusz,
> 
> On Tue, Apr 24, 2012 at 12:24 AM, DebBarma, Tarun Kanti
> <tarun.kanti@ti.com> wrote:
> > On Sat, Apr 21, 2012 at 7:33 PM, Janusz Krzysztofik
> > <jkrzyszt@tis.icnet.pl> wrote:
> >> On Thursday 02 of February 2012 23:00:37 Tarun Kanti DebBarma wrote:
> >>> 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...
> >>>
> >>> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> >>> Signed-off-by: Charulatha V <charu@ti.com>
> >>> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >>> Acked-by: Tony Lindgren <tony@atomide.com>
> >>
> >> Sorry for being so late with my comment for chanes already present in
> >> mainline, but this patch breaks GPIO on Amstrad Delta at least, and I
> >> have neither enough spare time nor enough experience with non OMAP1
> >> machines to provide a solution myself.
> > Yes, I looked at the omap_gpio_mod_init() and OMAP1 configurations are
> > overwritten.
> > Also looks like there is issue in making distinction between omap15xx
> > and omap16xx.
> > I will post a patch and you can help me testing it in OMAP1 platform.
> > Thanks for pointing this out.
...
 
> Here is the patch, with attachment as well. I have just tested on
> OMAP4 platform.
> Testing on other OMAP2+ platforms is pending. In the meantime can you please
> validate on OMAP1 platform and confirm? Thanks.
> --
> Tarun
> 
> From: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> Date: Tue, 24 Apr 2012 20:34:32 +0530
> Subject: [PATCH] gpio/omap: fix omap1 register overwrite in omap_gpio_mod_init
> 
> Initialization of irqenable, irqstatus registers is the common
> operation done in this function for all OMAP platforms, viz.
> OMAP1, OMAP2+. The latter _gpio_rmw()'s to irqenable register
> was overwriting the correctly programmed OMAP1 value at the
> beginning. As a result, even though it worked on OMAP2+
> platforms it was breaking OMAP1 functionality.

Sounds like the original patch was never tested on omap1?
 
> On closer observation it is found that the first _gpio_rmw()
> which is supposedly done to take care of OMAP1 platform is
> generic enough and takes care of OMAP2+ platform as well.
> Therefore remove the latter _gpio_rmw() to irqenable as they
> are redundant.
> 
> Also, changing the sequence and logic of initializing the
> irqstatus.

Please mention also the breaking commit here and get this fix
merged as a regression as soon as it's tested for the current
-rc series.

Regards,

Tony

 
> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> ---
>  drivers/gpio/gpio-omap.c |    5 +----
>  1 files changed, 1 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
> index 1adc2ec..b8f01c1 100644
> --- a/drivers/gpio/gpio-omap.c
> +++ b/drivers/gpio/gpio-omap.c
> @@ -964,11 +964,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
>                 return;
>         }
> 
> +       _gpio_rmw(base, bank->regs->irqstatus, l,
> bank->regs->irqenable_inv == 0 );
>         _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv);
> -       _gpio_rmw(base, bank->regs->irqstatus, l,
> -                                       bank->regs->irqenable_inv == false);
> -       _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0);
> -       _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0);
>         if (bank->regs->debounce_en)
>                 _gpio_rmw(base, bank->regs->debounce_en, 0, 1);
> 
> --
> 1.7.0.4



^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function
  2012-04-24 15:36       ` DebBarma, Tarun Kanti
  2012-04-24 16:04         ` Tony Lindgren
@ 2012-04-24 22:37         ` Janusz Krzysztofik
  1 sibling, 0 replies; 64+ messages in thread
From: Janusz Krzysztofik @ 2012-04-24 22:37 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti
  Cc: linux-omap, grant.likely, khilman, tony, linux-kernel,
	linux-arm-kernel, Charulatha V

Dnia wtorek, 24 kwietnia 2012 21:06:59 DebBarma, Tarun Kanti pisze:
> Hi Janusz,
> 
> Here is the patch, with attachment as well. I have just tested on
> OMAP4 platform.
> Testing on other OMAP2+ platforms is pending. In the meantime can you please
> validate on OMAP1 platform and confirm? Thanks.

Hi,
Please give me a day or two.
Thanks,
Janusz

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function
  2012-04-24 16:04         ` Tony Lindgren
@ 2012-04-25  4:34           ` DebBarma, Tarun Kanti
  2012-04-25  6:39             ` Shilimkar, Santosh
  0 siblings, 1 reply; 64+ messages in thread
From: DebBarma, Tarun Kanti @ 2012-04-25  4:34 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Janusz Krzysztofik, linux-omap, grant.likely, khilman,
	linux-kernel, linux-arm-kernel, Charulatha V

On Tue, Apr 24, 2012 at 9:34 PM, Tony Lindgren <tony@atomide.com> wrote:
> * DebBarma, Tarun Kanti <tarun.kanti@ti.com> [120424 08:40]:
>> Hi Janusz,
>>
>> On Tue, Apr 24, 2012 at 12:24 AM, DebBarma, Tarun Kanti
>> <tarun.kanti@ti.com> wrote:
>> > On Sat, Apr 21, 2012 at 7:33 PM, Janusz Krzysztofik
>> > <jkrzyszt@tis.icnet.pl> wrote:
>> >> On Thursday 02 of February 2012 23:00:37 Tarun Kanti DebBarma wrote:
>> >>> 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...
>> >>>
>> >>> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
>> >>> Signed-off-by: Charulatha V <charu@ti.com>
>> >>> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> >>> Acked-by: Tony Lindgren <tony@atomide.com>
>> >>
>> >> Sorry for being so late with my comment for chanes already present in
>> >> mainline, but this patch breaks GPIO on Amstrad Delta at least, and I
>> >> have neither enough spare time nor enough experience with non OMAP1
>> >> machines to provide a solution myself.
>> > Yes, I looked at the omap_gpio_mod_init() and OMAP1 configurations are
>> > overwritten.
>> > Also looks like there is issue in making distinction between omap15xx
>> > and omap16xx.
>> > I will post a patch and you can help me testing it in OMAP1 platform.
>> > Thanks for pointing this out.
> ...
>
>> Here is the patch, with attachment as well. I have just tested on
>> OMAP4 platform.
>> Testing on other OMAP2+ platforms is pending. In the meantime can you please
>> validate on OMAP1 platform and confirm? Thanks.
>> --
>> Tarun
>>
>> From: Tarun Kanti DebBarma <tarun.kanti@ti.com>
>> Date: Tue, 24 Apr 2012 20:34:32 +0530
>> Subject: [PATCH] gpio/omap: fix omap1 register overwrite in omap_gpio_mod_init
>>
>> Initialization of irqenable, irqstatus registers is the common
>> operation done in this function for all OMAP platforms, viz.
>> OMAP1, OMAP2+. The latter _gpio_rmw()'s to irqenable register
>> was overwriting the correctly programmed OMAP1 value at the
>> beginning. As a result, even though it worked on OMAP2+
>> platforms it was breaking OMAP1 functionality.
>
> Sounds like the original patch was never tested on omap1?
That's right, only bootup test was done on OMAP1710-SDP.

>
>> On closer observation it is found that the first _gpio_rmw()
>> which is supposedly done to take care of OMAP1 platform is
>> generic enough and takes care of OMAP2+ platform as well.
>> Therefore remove the latter _gpio_rmw() to irqenable as they
>> are redundant.
>>
>> Also, changing the sequence and logic of initializing the
>> irqstatus.
>
> Please mention also the breaking commit here and get this fix
> merged as a regression as soon as it's tested for the current
> -rc series.
Sure, I will do that!
--
Tarun
>
> Regards,
>
> Tony
>
>
>> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
>> ---
>>  drivers/gpio/gpio-omap.c |    5 +----
>>  1 files changed, 1 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
>> index 1adc2ec..b8f01c1 100644
>> --- a/drivers/gpio/gpio-omap.c
>> +++ b/drivers/gpio/gpio-omap.c
>> @@ -964,11 +964,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
>>                 return;
>>         }
>>
>> +       _gpio_rmw(base, bank->regs->irqstatus, l,
>> bank->regs->irqenable_inv == 0 );
>>         _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv);
>> -       _gpio_rmw(base, bank->regs->irqstatus, l,
>> -                                       bank->regs->irqenable_inv == false);
>> -       _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0);
>> -       _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0);
>>         if (bank->regs->debounce_en)
>>                 _gpio_rmw(base, bank->regs->debounce_en, 0, 1);
>>
>> --
>> 1.7.0.4
>
>

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function
  2012-04-25  4:34           ` DebBarma, Tarun Kanti
@ 2012-04-25  6:39             ` Shilimkar, Santosh
  2012-04-25 12:54               ` DebBarma, Tarun Kanti
  0 siblings, 1 reply; 64+ messages in thread
From: Shilimkar, Santosh @ 2012-04-25  6:39 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti
  Cc: Tony Lindgren, Janusz Krzysztofik, linux-omap, grant.likely,
	khilman, linux-kernel, linux-arm-kernel, Charulatha V

On Wed, Apr 25, 2012 at 10:04 AM, DebBarma, Tarun Kanti
<tarun.kanti@ti.com> wrote:
> On Tue, Apr 24, 2012 at 9:34 PM, Tony Lindgren <tony@atomide.com> wrote:
>> * DebBarma, Tarun Kanti <tarun.kanti@ti.com> [120424 08:40]:
>>> Hi Janusz,
>>>
>>> On Tue, Apr 24, 2012 at 12:24 AM, DebBarma, Tarun Kanti
>>> <tarun.kanti@ti.com> wrote:
>>> > On Sat, Apr 21, 2012 at 7:33 PM, Janusz Krzysztofik
>>> > <jkrzyszt@tis.icnet.pl> wrote:
>>> >> On Thursday 02 of February 2012 23:00:37 Tarun Kanti DebBarma wrote:
>>> >>> 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...
>>> >>>
>>> >>> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
>>> >>> Signed-off-by: Charulatha V <charu@ti.com>
>>> >>> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>> >>> Acked-by: Tony Lindgren <tony@atomide.com>
>>> >>
>>> >> Sorry for being so late with my comment for chanes already present in
>>> >> mainline, but this patch breaks GPIO on Amstrad Delta at least, and I
>>> >> have neither enough spare time nor enough experience with non OMAP1
>>> >> machines to provide a solution myself.
>>> > Yes, I looked at the omap_gpio_mod_init() and OMAP1 configurations are
>>> > overwritten.
>>> > Also looks like there is issue in making distinction between omap15xx
>>> > and omap16xx.
>>> > I will post a patch and you can help me testing it in OMAP1 platform.
>>> > Thanks for pointing this out.
>> ...
>>
>>> Here is the patch, with attachment as well. I have just tested on
>>> OMAP4 platform.
>>> Testing on other OMAP2+ platforms is pending. In the meantime can you please
>>> validate on OMAP1 platform and confirm? Thanks.
>>> --
>>> Tarun
>>>
>>> From: Tarun Kanti DebBarma <tarun.kanti@ti.com>
>>> Date: Tue, 24 Apr 2012 20:34:32 +0530
>>> Subject: [PATCH] gpio/omap: fix omap1 register overwrite in omap_gpio_mod_init
>>>
>>> Initialization of irqenable, irqstatus registers is the common
>>> operation done in this function for all OMAP platforms, viz.
>>> OMAP1, OMAP2+. The latter _gpio_rmw()'s to irqenable register
>>> was overwriting the correctly programmed OMAP1 value at the
>>> beginning. As a result, even though it worked on OMAP2+
>>> platforms it was breaking OMAP1 functionality.
>>
>> Sounds like the original patch was never tested on omap1?
> That's right, only bootup test was done on OMAP1710-SDP.
>
>>
>>> On closer observation it is found that the first _gpio_rmw()
>>> which is supposedly done to take care of OMAP1 platform is
>>> generic enough and takes care of OMAP2+ platform as well.
>>> Therefore remove the latter _gpio_rmw() to irqenable as they
>>> are redundant.
>>>
>>> Also, changing the sequence and logic of initializing the
>>> irqstatus.
>>
>> Please mention also the breaking commit here and get this fix
>> merged as a regression as soon as it's tested for the current
>> -rc series.
> Sure, I will do that!

Looks like it is regression on 3.4 as well so CC stable when you
post the patch.

Regards
Santosh

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function
  2012-04-25  6:39             ` Shilimkar, Santosh
@ 2012-04-25 12:54               ` DebBarma, Tarun Kanti
  2012-04-25 13:45                 ` Russell King - ARM Linux
  0 siblings, 1 reply; 64+ messages in thread
From: DebBarma, Tarun Kanti @ 2012-04-25 12:54 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: Tony Lindgren, Janusz Krzysztofik, linux-omap, grant.likely,
	khilman, linux-kernel, linux-arm-kernel, Charulatha V

On Wed, Apr 25, 2012 at 12:09 PM, Shilimkar, Santosh
<santosh.shilimkar@ti.com> wrote:
> On Wed, Apr 25, 2012 at 10:04 AM, DebBarma, Tarun Kanti
> <tarun.kanti@ti.com> wrote:
>> On Tue, Apr 24, 2012 at 9:34 PM, Tony Lindgren <tony@atomide.com> wrote:
>>> * DebBarma, Tarun Kanti <tarun.kanti@ti.com> [120424 08:40]:
>>>> Hi Janusz,
>>>>
>>>> On Tue, Apr 24, 2012 at 12:24 AM, DebBarma, Tarun Kanti
>>>> <tarun.kanti@ti.com> wrote:
>>>> > On Sat, Apr 21, 2012 at 7:33 PM, Janusz Krzysztofik
>>>> > <jkrzyszt@tis.icnet.pl> wrote:
>>>> >> On Thursday 02 of February 2012 23:00:37 Tarun Kanti DebBarma wrote:
>>>> >>> 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...
>>>> >>>
>>>> >>> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
>>>> >>> Signed-off-by: Charulatha V <charu@ti.com>
>>>> >>> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>> >>> Acked-by: Tony Lindgren <tony@atomide.com>
>>>> >>
>>>> >> Sorry for being so late with my comment for chanes already present in
>>>> >> mainline, but this patch breaks GPIO on Amstrad Delta at least, and I
>>>> >> have neither enough spare time nor enough experience with non OMAP1
>>>> >> machines to provide a solution myself.
>>>> > Yes, I looked at the omap_gpio_mod_init() and OMAP1 configurations are
>>>> > overwritten.
>>>> > Also looks like there is issue in making distinction between omap15xx
>>>> > and omap16xx.
>>>> > I will post a patch and you can help me testing it in OMAP1 platform.
>>>> > Thanks for pointing this out.
>>> ...
>>>
>>>> Here is the patch, with attachment as well. I have just tested on
>>>> OMAP4 platform.
>>>> Testing on other OMAP2+ platforms is pending. In the meantime can you please
>>>> validate on OMAP1 platform and confirm? Thanks.
>>>> --
>>>> Tarun
>>>>
>>>> From: Tarun Kanti DebBarma <tarun.kanti@ti.com>
>>>> Date: Tue, 24 Apr 2012 20:34:32 +0530
>>>> Subject: [PATCH] gpio/omap: fix omap1 register overwrite in omap_gpio_mod_init
>>>>
>>>> Initialization of irqenable, irqstatus registers is the common
>>>> operation done in this function for all OMAP platforms, viz.
>>>> OMAP1, OMAP2+. The latter _gpio_rmw()'s to irqenable register
>>>> was overwriting the correctly programmed OMAP1 value at the
>>>> beginning. As a result, even though it worked on OMAP2+
>>>> platforms it was breaking OMAP1 functionality.
>>>
>>> Sounds like the original patch was never tested on omap1?
>> That's right, only bootup test was done on OMAP1710-SDP.
>>
>>>
>>>> On closer observation it is found that the first _gpio_rmw()
>>>> which is supposedly done to take care of OMAP1 platform is
>>>> generic enough and takes care of OMAP2+ platform as well.
>>>> Therefore remove the latter _gpio_rmw() to irqenable as they
>>>> are redundant.
>>>>
>>>> Also, changing the sequence and logic of initializing the
>>>> irqstatus.
>>>
>>> Please mention also the breaking commit here and get this fix
>>> merged as a regression as soon as it's tested for the current
>>> -rc series.
>> Sure, I will do that!
>
> Looks like it is regression on 3.4 as well so CC stable when you
> post the patch.
Ok, I will do that.
--
Tarun
>
> Regards
> Santosh

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function
  2012-04-25 12:54               ` DebBarma, Tarun Kanti
@ 2012-04-25 13:45                 ` Russell King - ARM Linux
  2012-04-26  5:13                   ` DebBarma, Tarun Kanti
  0 siblings, 1 reply; 64+ messages in thread
From: Russell King - ARM Linux @ 2012-04-25 13:45 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti
  Cc: Shilimkar, Santosh, khilman, Janusz Krzysztofik, Tony Lindgren,
	linux-kernel, grant.likely, linux-omap, linux-arm-kernel,
	Charulatha V

On Wed, Apr 25, 2012 at 06:24:14PM +0530, DebBarma, Tarun Kanti wrote:
> On Wed, Apr 25, 2012 at 12:09 PM, Shilimkar, Santosh
> <santosh.shilimkar@ti.com> wrote:
> > On Wed, Apr 25, 2012 at 10:04 AM, DebBarma, Tarun Kanti
> > <tarun.kanti@ti.com> wrote:
> >> On Tue, Apr 24, 2012 at 9:34 PM, Tony Lindgren <tony@atomide.com> wrote:
> >>> * DebBarma, Tarun Kanti <tarun.kanti@ti.com> [120424 08:40]:
> >>>> Hi Janusz,
> >>>>
> >>>> On Tue, Apr 24, 2012 at 12:24 AM, DebBarma, Tarun Kanti
> >>>> <tarun.kanti@ti.com> wrote:
> >>>> > On Sat, Apr 21, 2012 at 7:33 PM, Janusz Krzysztofik
> >>>> > <jkrzyszt@tis.icnet.pl> wrote:
> >>>> >> On Thursday 02 of February 2012 23:00:37 Tarun Kanti DebBarma wrote:
> >>>> >>> 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...
> >>>> >>>
> >>>> >>> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> >>>> >>> Signed-off-by: Charulatha V <charu@ti.com>
> >>>> >>> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >>>> >>> Acked-by: Tony Lindgren <tony@atomide.com>
> >>>> >>
> >>>> >> Sorry for being so late with my comment for chanes already present in
> >>>> >> mainline, but this patch breaks GPIO on Amstrad Delta at least, and I
> >>>> >> have neither enough spare time nor enough experience with non OMAP1
> >>>> >> machines to provide a solution myself.
> >>>> > Yes, I looked at the omap_gpio_mod_init() and OMAP1 configurations are
> >>>> > overwritten.
> >>>> > Also looks like there is issue in making distinction between omap15xx
> >>>> > and omap16xx.
> >>>> > I will post a patch and you can help me testing it in OMAP1 platform.
> >>>> > Thanks for pointing this out.
> >>> ...
> >>>
> >>>> Here is the patch, with attachment as well. I have just tested on
> >>>> OMAP4 platform.
> >>>> Testing on other OMAP2+ platforms is pending. In the meantime can you please
> >>>> validate on OMAP1 platform and confirm? Thanks.
> >>>> --
> >>>> Tarun
> >>>>
> >>>> From: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> >>>> Date: Tue, 24 Apr 2012 20:34:32 +0530
> >>>> Subject: [PATCH] gpio/omap: fix omap1 register overwrite in omap_gpio_mod_init
> >>>>
> >>>> Initialization of irqenable, irqstatus registers is the common
> >>>> operation done in this function for all OMAP platforms, viz.
> >>>> OMAP1, OMAP2+. The latter _gpio_rmw()'s to irqenable register
> >>>> was overwriting the correctly programmed OMAP1 value at the
> >>>> beginning. As a result, even though it worked on OMAP2+
> >>>> platforms it was breaking OMAP1 functionality.
> >>>
> >>> Sounds like the original patch was never tested on omap1?
> >> That's right, only bootup test was done on OMAP1710-SDP.
> >>
> >>>
> >>>> On closer observation it is found that the first _gpio_rmw()
> >>>> which is supposedly done to take care of OMAP1 platform is
> >>>> generic enough and takes care of OMAP2+ platform as well.
> >>>> Therefore remove the latter _gpio_rmw() to irqenable as they
> >>>> are redundant.
> >>>>
> >>>> Also, changing the sequence and logic of initializing the
> >>>> irqstatus.
> >>>
> >>> Please mention also the breaking commit here and get this fix
> >>> merged as a regression as soon as it's tested for the current
> >>> -rc series.
> >> Sure, I will do that!
> >
> > Looks like it is regression on 3.4 as well so CC stable when you
> > post the patch.
> Ok, I will do that.

Correction.

Don't email your patch in any way to the stable folk _before_ it has been
taken into Linus' tree.  However, you _may_ add in the patch attributations
a Cc: <stable@vger.kernel.org> tag if you want the stable folk to
automatically pick up your patch when it _does_ end up in Linus' tree.
But... make sure that git send-email or whatever doesn't automatically
add that to the recipients for the emailed patch.

If you send the stable people a patch before its in mainline, you'll get
a whinge telling you to read Documentation/stable_kernel_rules.txt

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function
  2012-04-25 13:45                 ` Russell King - ARM Linux
@ 2012-04-26  5:13                   ` DebBarma, Tarun Kanti
  2012-04-27 21:31                     ` Kevin Hilman
  0 siblings, 1 reply; 64+ messages in thread
From: DebBarma, Tarun Kanti @ 2012-04-26  5:13 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Shilimkar, Santosh, khilman, Janusz Krzysztofik, Tony Lindgren,
	linux-kernel, grant.likely, linux-omap, linux-arm-kernel,
	Charulatha V

On Wed, Apr 25, 2012 at 7:15 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Apr 25, 2012 at 06:24:14PM +0530, DebBarma, Tarun Kanti wrote:
>> On Wed, Apr 25, 2012 at 12:09 PM, Shilimkar, Santosh
>> <santosh.shilimkar@ti.com> wrote:
>> > On Wed, Apr 25, 2012 at 10:04 AM, DebBarma, Tarun Kanti
>> > <tarun.kanti@ti.com> wrote:
>> >> On Tue, Apr 24, 2012 at 9:34 PM, Tony Lindgren <tony@atomide.com> wrote:
>> >>> * DebBarma, Tarun Kanti <tarun.kanti@ti.com> [120424 08:40]:
>> >>>> Hi Janusz,
>> >>>>
>> >>>> On Tue, Apr 24, 2012 at 12:24 AM, DebBarma, Tarun Kanti
>> >>>> <tarun.kanti@ti.com> wrote:
>> >>>> > On Sat, Apr 21, 2012 at 7:33 PM, Janusz Krzysztofik
>> >>>> > <jkrzyszt@tis.icnet.pl> wrote:
>> >>>> >> On Thursday 02 of February 2012 23:00:37 Tarun Kanti DebBarma wrote:
>> >>>> >>> 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...
>> >>>> >>>
>> >>>> >>> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
>> >>>> >>> Signed-off-by: Charulatha V <charu@ti.com>
>> >>>> >>> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> >>>> >>> Acked-by: Tony Lindgren <tony@atomide.com>
>> >>>> >>
>> >>>> >> Sorry for being so late with my comment for chanes already present in
>> >>>> >> mainline, but this patch breaks GPIO on Amstrad Delta at least, and I
>> >>>> >> have neither enough spare time nor enough experience with non OMAP1
>> >>>> >> machines to provide a solution myself.
>> >>>> > Yes, I looked at the omap_gpio_mod_init() and OMAP1 configurations are
>> >>>> > overwritten.
>> >>>> > Also looks like there is issue in making distinction between omap15xx
>> >>>> > and omap16xx.
>> >>>> > I will post a patch and you can help me testing it in OMAP1 platform.
>> >>>> > Thanks for pointing this out.
>> >>> ...
>> >>>
>> >>>> Here is the patch, with attachment as well. I have just tested on
>> >>>> OMAP4 platform.
>> >>>> Testing on other OMAP2+ platforms is pending. In the meantime can you please
>> >>>> validate on OMAP1 platform and confirm? Thanks.
>> >>>> --
>> >>>> Tarun
>> >>>>
>> >>>> From: Tarun Kanti DebBarma <tarun.kanti@ti.com>
>> >>>> Date: Tue, 24 Apr 2012 20:34:32 +0530
>> >>>> Subject: [PATCH] gpio/omap: fix omap1 register overwrite in omap_gpio_mod_init
>> >>>>
>> >>>> Initialization of irqenable, irqstatus registers is the common
>> >>>> operation done in this function for all OMAP platforms, viz.
>> >>>> OMAP1, OMAP2+. The latter _gpio_rmw()'s to irqenable register
>> >>>> was overwriting the correctly programmed OMAP1 value at the
>> >>>> beginning. As a result, even though it worked on OMAP2+
>> >>>> platforms it was breaking OMAP1 functionality.
>> >>>
>> >>> Sounds like the original patch was never tested on omap1?
>> >> That's right, only bootup test was done on OMAP1710-SDP.
>> >>
>> >>>
>> >>>> On closer observation it is found that the first _gpio_rmw()
>> >>>> which is supposedly done to take care of OMAP1 platform is
>> >>>> generic enough and takes care of OMAP2+ platform as well.
>> >>>> Therefore remove the latter _gpio_rmw() to irqenable as they
>> >>>> are redundant.
>> >>>>
>> >>>> Also, changing the sequence and logic of initializing the
>> >>>> irqstatus.
>> >>>
>> >>> Please mention also the breaking commit here and get this fix
>> >>> merged as a regression as soon as it's tested for the current
>> >>> -rc series.
>> >> Sure, I will do that!
>> >
>> > Looks like it is regression on 3.4 as well so CC stable when you
>> > post the patch.
>> Ok, I will do that.
>
> Correction.
>
> Don't email your patch in any way to the stable folk _before_ it has been
> taken into Linus' tree.  However, you _may_ add in the patch attributations
> a Cc: <stable@vger.kernel.org> tag if you want the stable folk to
> automatically pick up your patch when it _does_ end up in Linus' tree.
> But... make sure that git send-email or whatever doesn't automatically
> add that to the recipients for the emailed patch.
>
> If you send the stable people a patch before its in mainline, you'll get
> a whinge telling you to read Documentation/stable_kernel_rules.txt

Alright, I will add Cc: <stable@vger.kernel.org> tag in the patch.
Thanks.
--
Tarun

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function
  2012-04-26  5:13                   ` DebBarma, Tarun Kanti
@ 2012-04-27 21:31                     ` Kevin Hilman
  0 siblings, 0 replies; 64+ messages in thread
From: Kevin Hilman @ 2012-04-27 21:31 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti
  Cc: Russell King - ARM Linux, Shilimkar, Santosh, Janusz Krzysztofik,
	Tony Lindgren, linux-kernel, grant.likely, linux-omap,
	linux-arm-kernel, Charulatha V

"DebBarma, Tarun Kanti" <tarun.kanti@ti.com> writes:

> On Wed, Apr 25, 2012 at 7:15 PM, Russell King - ARM Linux <linux@arm.linux.org.uk> wrote:

[...]

>> Correction.
>>
>> Don't email your patch in any way to the stable folk _before_ it has been
>> taken into Linus' tree.  However, you _may_ add in the patch attributations
>> a Cc: <stable@vger.kernel.org> tag if you want the stable folk to
>> automatically pick up your patch when it _does_ end up in Linus' tree.
>> But... make sure that git send-email or whatever doesn't automatically
>> add that to the recipients for the emailed patch.
>>
>> If you send the stable people a patch before its in mainline, you'll get
>> a whinge telling you to read Documentation/stable_kernel_rules.txt
>
> Alright, I will add Cc: <stable@vger.kernel.org> tag in the patch.

If you do that, be sure to use --suppress-cc=bodycc when you send it
with git-send-email.

Kevin

^ permalink raw reply	[flat|nested] 64+ messages in thread

end of thread, other threads:[~2012-04-27 21:31 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-02 17:30 [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 01/25] gpio/omap: remove dependency on gpio_bank_count Tarun Kanti DebBarma
2012-02-02 18:41   ` Felipe Balbi
2012-02-02 19:16     ` Grant Likely
2012-02-02 19:45       ` Felipe Balbi
2012-02-02 20:48         ` Cousson, Benoit
2012-02-02 21:49           ` Felipe Balbi
2012-02-02 21:53             ` Felipe Balbi
2012-02-02 22:00               ` Cousson, Benoit
2012-02-02 22:07                 ` Felipe Balbi
2012-02-03 17:50                   ` Kevin Hilman
2012-02-04 16:08                     ` Felipe Balbi
2012-02-05  7:07                       ` Varadarajan, Charulatha
2012-02-05  9:08                         ` Felipe Balbi
2012-02-05  9:16                           ` Shilimkar, Santosh
2012-02-05 11:35                             ` Felipe Balbi
2012-02-05 12:35                               ` Shilimkar, Santosh
2012-02-06  6:40                                 ` Felipe Balbi
2012-02-06  5:18                           ` Varadarajan, Charulatha
2012-02-02 17:30 ` [PATCH v9 02/25] gpio/omap: use flag to identify wakeup domain Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 03/25] gpio/omap: make gpio_context part of gpio_bank structure Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 04/25] gpio/omap: handle save/restore context in GPIO driver Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 05/25] gpio/omap: make non-wakeup GPIO part of pdata Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 06/25] gpio/omap: avoid cpu checks during module ena/disable Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 07/25] gpio/omap: further cleanup using wkup_en register Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 08/25] gpio/omap: use level/edge detect reg offsets Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 09/25] gpio/omap: remove hardcoded offsets in context save/restore Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 10/25] gpio/omap: cleanup set_gpio_triggering function Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 11/25] gpio/omap: cleanup omap_gpio_mod_init function Tarun Kanti DebBarma
2012-04-21 14:03   ` Janusz Krzysztofik
2012-04-23 18:54     ` DebBarma, Tarun Kanti
2012-04-24 15:36       ` DebBarma, Tarun Kanti
2012-04-24 16:04         ` Tony Lindgren
2012-04-25  4:34           ` DebBarma, Tarun Kanti
2012-04-25  6:39             ` Shilimkar, Santosh
2012-04-25 12:54               ` DebBarma, Tarun Kanti
2012-04-25 13:45                 ` Russell King - ARM Linux
2012-04-26  5:13                   ` DebBarma, Tarun Kanti
2012-04-27 21:31                     ` Kevin Hilman
2012-04-24 22:37         ` Janusz Krzysztofik
2012-02-02 17:30 ` [PATCH v9 12/25] gpio/omap: use pinctrl offset instead of macro Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 13/25] gpio/omap: remove unnecessary bit-masking for read access Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 14/25] gpio/omap: remove bank->method & METHOD_* macros Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 15/25] gpio/omap: fix bankwidth for OMAP7xx MPUIO Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 16/25] gpio/omap: use pm-runtime framework Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 17/25] gpio/omap: optimize suspend and resume functions Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 18/25] gpio/omap: cleanup prepare_for_idle and resume_after_idle Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 19/25] gpio/omap: fix debounce clock handling Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 20/25] gpio/omap: fix incorrect access of debounce module Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 21/25] gpio/omap: remove omap_gpio_save_context overhead Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 22/25] gpio/omap: save and restore debounce registers Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 23/25] gpio/omap: enable irq at the end of all configuration in restore Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 24/25] gpio/omap: restore OE only after setting the output level Tarun Kanti DebBarma
2012-02-02 17:30 ` [PATCH v9 25/25] gpio/omap: handle set_dataout reg capable IP on restore Tarun Kanti DebBarma
2012-02-02 19:42 ` [PATCH v9 00/25] gpio/omap: driver cleanup and fixes Grant Likely
2012-02-03 17:51   ` Kevin Hilman
2012-02-03 21:16     ` Grant Likely
2012-02-03  9:21 ` Hebbar, Gururaja
     [not found]   ` <CAC83ZvLoYVofH9oKXw92i-=DbP2i3NfZjLGSJwk1j0JvXcFZVQ@mail.gmail.com>
2012-02-03 12:09     ` Hebbar, Gururaja
2012-02-03 21:01 ` Kevin Hilman
2012-02-06 11:53   ` DebBarma, Tarun Kanti
2012-02-10 19:24 ` Tony Lindgren
2012-02-10 19:55   ` Kevin Hilman
2012-02-13  5:33     ` DebBarma, Tarun Kanti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).