diff options
| author | Jim Wylder <jwylder@motorola.com> | 2014-06-10 10:11:26 -0500 | 
|---|---|---|
| committer | James Wylder <jwylder@motorola.com> | 2014-06-12 22:20:59 +0000 | 
| commit | 7ddadb752771a4c6b8f585a7278946d3d664a861 (patch) | |
| tree | 55520f3cae6654c0ebf2ed574c902bf53373b4b9 | |
| parent | 0ff908aebf6eba804c4bccb830a56d6b04dc7f47 (diff) | |
| download | olio-linux-3.10-7ddadb752771a4c6b8f585a7278946d3d664a861.tar.xz olio-linux-3.10-7ddadb752771a4c6b8f585a7278946d3d664a861.zip | |
IKXCLOCK-2206 arm: omap3: pm-debug cleanup
Save off a golden version if we hit the off state, and then
use that as a reference for future debugging messages.
Change-Id: Ib08a2c63ab6ca9d0784ffd60e228eafc5d28b01a
Signed-off-by: Jim Wylder <jwylder@motorola.com>
| -rw-r--r-- | arch/arm/mach-omap2/pm-debug-regs.c | 53 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/pm-debug-regs.h | 4 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 16 | 
3 files changed, 71 insertions, 2 deletions
| diff --git a/arch/arm/mach-omap2/pm-debug-regs.c b/arch/arm/mach-omap2/pm-debug-regs.c index 0997fe8138d..42c40d92427 100644 --- a/arch/arm/mach-omap2/pm-debug-regs.c +++ b/arch/arm/mach-omap2/pm-debug-regs.c @@ -134,6 +134,15 @@ static void pm_dbg_regset_store(u32 *ptr)  	}  } +void pm_dbg_regs_copy(int tgt, int src) +{ +	size_t sz = pm_dbg_get_regset_size(); + +	pr_debug("saved reference copy %s(%d, %d) size = %u <- %pS\n", +		__func__, tgt, src, sz, __builtin_return_address(0)); +	memcpy(pm_dbg_reg_set[tgt - 1], pm_dbg_reg_set[src - 1], sz); +} +  void pm_dbg_regs_save(int reg_set)  {  	if (pm_dbg_reg_set[reg_set - 1] == NULL) @@ -424,6 +433,50 @@ int pm_dbg_regs_dump(int reg_set)  }  EXPORT_SYMBOL(pm_dbg_regs_dump); +int pm_dbg_regs_dump_delta(int cur, int ref) +{ +	int i, j; +	unsigned long val_cur; +	u32 *ptr_cur; +	unsigned long val_ref; +	u32 *ptr_ref; + +	if ((cur <= 0) || (cur > PM_DBG_MAX_REG_SETS) || +	    (ref <= 0) || (ref > PM_DBG_MAX_REG_SETS)) { +		return -EINVAL; +	} + +	ptr_cur = pm_dbg_reg_set[cur - 1]; +	ptr_ref = pm_dbg_reg_set[ref - 1]; + +	i = 0; + +	pr_debug("   module      ( address) reg        %d          %d\n", +			cur, ref); +	while (pm_dbg_reg_modules[i].name[0] != 0) { +		bool cm = pm_dbg_reg_modules[i].type == MOD_CM; +		uint32_t addr = (u32)(OMAP3430_CM_BASE + +				pm_dbg_reg_modules[i].offset); + +		for (j = pm_dbg_reg_modules[i].low; +		     j <= pm_dbg_reg_modules[i].high; j += 4) { +			val_cur = *(ptr_cur++); +			val_ref = *(ptr_ref++); +			if (val_cur != val_ref) { +				pr_debug("MOD: %s_%-4s %s(%08x) " +					"%02x => 0x%08lx 0x%08lx\n", +					cm ? "CM_" : "PRM_", +					pm_dbg_reg_modules[i].name, +					cm ? " " : "", +					addr, j, val_cur, val_ref); +			} +		} +		i++; +	} +	return 0; +} +EXPORT_SYMBOL(pm_dbg_regs_dump_delta); +  static void __init pm_dbg_regset_init(void)  {  	int i; diff --git a/arch/arm/mach-omap2/pm-debug-regs.h b/arch/arm/mach-omap2/pm-debug-regs.h index e403977affa..f70bbe5c6a8 100644 --- a/arch/arm/mach-omap2/pm-debug-regs.h +++ b/arch/arm/mach-omap2/pm-debug-regs.h @@ -20,12 +20,16 @@  extern int  pm_dbg_regs_init(struct dentry *d);  extern void pm_dbg_regs_save(int reg_set);  extern void pm_dbg_regs_dump(int reg_set); +extern void pm_dbg_regs_dump_delta(int cur, int rfr);  extern void pm_dbg_show_wakeup_source(void); +extern void pm_dbg_regs_copy(int tgt, int src);  #else  static inline int pm_dbg_regs_init(struct dentry *d) { return 0; }  static inline void pm_dbg_regs_save(int reg_set) {};  static inline void pm_dbg_regs_dump(int reg_set) {}; +static inline void pm_dbg_regs_dump_delta(int current, int ref) {}  static inline void pm_dbg_show_wakeup_source(void) {}; +static inline void pm_dbg_regs_copy(int tgt, int src) {};  #endif  #endif diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index afe15f00637..6daf94a0223 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -62,6 +62,7 @@  /* pm34xx errata defined in pm.h */  u16 pm34xx_errata;  bool suspend_debug; +bool suspend_offmode_ref_saved;  struct power_state {  	struct powerdomain *pwrdm; @@ -391,6 +392,12 @@ void omap_sram_idle(bool in_suspend)  			omap3_cm_restore_context();  			omap3_sram_restore_context();  			omap2_sms_restore_context(); + +			if (unlikely(!suspend_offmode_ref_saved)) { +				suspend_offmode_ref_saved = true; +				pm_dbg_regs_copy(3, 1); +				pm_dbg_regs_copy(4, 2); +			}  		}  		if (core_next_state == PWRDM_POWER_OFF) {  			omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, @@ -457,8 +464,13 @@ restore:  	}  	if (ret) {  		pr_err("Could not enter target state in pm_suspend\n"); -		pm_dbg_regs_dump(1); -		pm_dbg_regs_dump(2); +		if (suspend_offmode_ref_saved) { +			pm_dbg_regs_dump_delta(1, 3); +			pm_dbg_regs_dump_delta(2, 4); +		} else { +			pm_dbg_regs_dump(1); +			pm_dbg_regs_dump(2); +		}  	} else  		pr_info("Successfully put all powerdomains to target state\n"); |