diff options
Diffstat (limited to 'arch/arm/mach-omap2')
| -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"); |