aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorDietmar Eggemann <dietmar.eggemann@arm.com>2012-10-14 17:25:37 -0400
committerWill Deacon <will.deacon@arm.com>2013-01-10 16:13:07 -0500
commit9a6eb310eaa5336b89a27a0bbb78da4bba35f6f1 (patch)
tree50975e4e50ffd1d91b44dfe2e389161697751a3c /arch/arm/kernel
parent57ba899731156ab01cdb7dae8d1fe6430ef4957c (diff)
ARM: hw_breakpoint: Debug powerdown support for self-hosted debug
This patch introduces debug powerdown support for self-hosted debug for v7 and v7.1 debug architecture for a SinglePower system, i.e. a system without a separate core and debug power domain. On a SinglePower system the OS Lock is lost over a powerdown. If CONFIG_CPU_PM is set the new function pm_init() registers hw_breakpoint with CPU PM for a system supporting OS Save and Restore. Receiving a CPU PM EXIT notifier indicates that a single CPU has exited a low power state. A call to reset_ctrl_regs() is hooked into the CPU PM EXIT notifier chain. This function makes sure that the sticky power-down is clear (only v7 debug), the OS Double Lock is clear (only v7.1 debug) and it clears the OS Lock for v7 debug (for a system supporting OS Save and Restore) and v7.1 debug. Furthermore, it clears any vector-catch events and all breakpoint/watchpoint control/value registers for v7 and v7.1 debug. Signed-off-by: Dietmar Eggemann <dietmar.eggemann@arm.com> [will: removed redundant has_ossr check] Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/hw_breakpoint.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 201d4406fe0d..5eae53e7a2e1 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -28,6 +28,7 @@
28#include <linux/perf_event.h> 28#include <linux/perf_event.h>
29#include <linux/hw_breakpoint.h> 29#include <linux/hw_breakpoint.h>
30#include <linux/smp.h> 30#include <linux/smp.h>
31#include <linux/cpu_pm.h>
31 32
32#include <asm/cacheflush.h> 33#include <asm/cacheflush.h>
33#include <asm/cputype.h> 34#include <asm/cputype.h>
@@ -1032,6 +1033,30 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = {
1032 .notifier_call = dbg_reset_notify, 1033 .notifier_call = dbg_reset_notify,
1033}; 1034};
1034 1035
1036#ifdef CONFIG_CPU_PM
1037static int dbg_cpu_pm_notify(struct notifier_block *self, unsigned long action,
1038 void *v)
1039{
1040 if (action == CPU_PM_EXIT)
1041 reset_ctrl_regs(NULL);
1042
1043 return NOTIFY_OK;
1044}
1045
1046static struct notifier_block __cpuinitdata dbg_cpu_pm_nb = {
1047 .notifier_call = dbg_cpu_pm_notify,
1048};
1049
1050static void __init pm_init(void)
1051{
1052 cpu_pm_register_notifier(&dbg_cpu_pm_nb);
1053}
1054#else
1055static inline void pm_init(void)
1056{
1057}
1058#endif
1059
1035static int __init arch_hw_breakpoint_init(void) 1060static int __init arch_hw_breakpoint_init(void)
1036{ 1061{
1037 debug_arch = get_debug_arch(); 1062 debug_arch = get_debug_arch();
@@ -1081,8 +1106,9 @@ static int __init arch_hw_breakpoint_init(void)
1081 hook_ifault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP, 1106 hook_ifault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP,
1082 TRAP_HWBKPT, "breakpoint debug exception"); 1107 TRAP_HWBKPT, "breakpoint debug exception");
1083 1108
1084 /* Register hotplug notifier. */ 1109 /* Register hotplug and PM notifiers. */
1085 register_cpu_notifier(&dbg_reset_nb); 1110 register_cpu_notifier(&dbg_reset_nb);
1111 pm_init();
1086 return 0; 1112 return 0;
1087} 1113}
1088arch_initcall(arch_hw_breakpoint_init); 1114arch_initcall(arch_hw_breakpoint_init);