diff options
author | Dietmar Eggemann <dietmar.eggemann@arm.com> | 2012-10-14 22:25:37 +0100 |
---|---|---|
committer | Viresh Kumar <viresh.kumar@linaro.org> | 2013-01-08 16:20:16 +0530 |
commit | a59eed9aca511151189f929f9cc7fc694fe76718 (patch) | |
tree | 27a28f018306f9b9ac394ea0517110cac6870b59 | |
parent | 677c0295a1a7e60f990c52e0925440e010093622 (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>
Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 28f3c62b3658..f031a4f82934 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -28,6 +28,7 @@ #include <linux/perf_event.h> #include <linux/hw_breakpoint.h> #include <linux/smp.h> +#include <linux/cpu_pm.h> #include <asm/cacheflush.h> #include <asm/cputype.h> @@ -1031,6 +1032,31 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = { .notifier_call = dbg_reset_notify, }; +#ifdef CONFIG_CPU_PM +static int dbg_cpu_pm_notify(struct notifier_block *self, unsigned long action, + void *v) +{ + if (action == CPU_PM_EXIT) + reset_ctrl_regs(NULL); + + return NOTIFY_OK; +} + +static struct notifier_block __cpuinitdata dbg_cpu_pm_nb = { + .notifier_call = dbg_cpu_pm_notify, +}; + +static void __init pm_init(void) +{ + if (has_ossr) + cpu_pm_register_notifier(&dbg_cpu_pm_nb); +} +#else +static inline void pm_init(void) +{ +} +#endif + static int __init arch_hw_breakpoint_init(void) { debug_arch = get_debug_arch(); @@ -1082,6 +1108,8 @@ static int __init arch_hw_breakpoint_init(void) /* Register hotplug notifier. */ register_cpu_notifier(&dbg_reset_nb); + + pm_init(); return 0; } arch_initcall(arch_hw_breakpoint_init); |