diff options
author | Johan Bjornstedt <johan.bjornstedt@stericsson.com> | 2012-01-13 12:50:31 +0100 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 11:02:41 +0200 |
commit | d97f00a621057f904db0c1c21eceab3c14dc449e (patch) | |
tree | 2a61bc2db3cc87d168a4b73f253c47caa52a2cbd | |
parent | 95e791e82c80f16e44f4ed570008b71f6888fa61 (diff) |
mach-ux500: Save dbx500 registers on panic
Before, the registers were only saved in case
of die. With this patch, also calls to panic()
will save DB registers
ST-Ericsson ID: 403009
ST-Ericsson FOSS-OUT ID: Trivial
ST-Ericsson Linux next: N/A
Change-Id: Ie18a3632acd37d5d373dd9d71b57bdf62841f44e
Signed-off-by: Johan Bjornstedt <johan.bjornstedt@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/41945
Reviewed-by: Per FRANSSON <per.xx.fransson@stericsson.com>
Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
-rw-r--r-- | arch/arm/mach-ux500/dbx500_dump.c | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/arch/arm/mach-ux500/dbx500_dump.c b/arch/arm/mach-ux500/dbx500_dump.c index 9e7b1ae535a..92e4047cd8b 100644 --- a/arch/arm/mach-ux500/dbx500_dump.c +++ b/arch/arm/mach-ux500/dbx500_dump.c @@ -9,6 +9,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/io.h> +#include <linux/spinlock.h> #include <linux/slab.h> #include <linux/kdebug.h> @@ -92,11 +93,23 @@ static struct dbx500_dump_info db5500_dump[] = { static struct dbx500_dump_info *dbx500_dump; static int dbx500_dump_size; +static bool dbx500_dump_done; + +static DEFINE_SPINLOCK(dbx500_dump_lock); static int crash_notifier(struct notifier_block *nb, unsigned long val, void *data) { int i; + unsigned long flags; + + /* + * Since there are two ways into this function (die and panic) we have + * to make sure we only dump the DB registers once + */ + spin_lock_irqsave(&dbx500_dump_lock, flags); + if (dbx500_dump_done) + return NOTIFY_DONE; pr_info("dbx500_dump notified of crash\n"); @@ -105,7 +118,10 @@ static int crash_notifier(struct notifier_block *nb, unsigned long val, dbx500_dump[i].size); } - return 0; + dbx500_dump_done = true; + spin_unlock_irqrestore(&dbx500_dump_lock, flags); + + return NOTIFY_DONE; } static void __init init_io_addresses(void) @@ -119,7 +135,10 @@ static void __init init_io_addresses(void) static struct notifier_block die_notifier = { .notifier_call = crash_notifier, - .priority = 0, +}; + +static struct notifier_block panic_notifier = { + .notifier_call = crash_notifier, }; int __init dbx500_dump_init(void) @@ -148,15 +167,27 @@ int __init dbx500_dump_init(void) init_io_addresses(); + err = atomic_notifier_chain_register(&panic_notifier_list, + &panic_notifier); + if (err != 0) { + pr_err("dbx500_dump: Unable to register a panic notifier %d\n", + err); + goto free_mem; + } + err = register_die_notifier(&die_notifier); if (err != 0) { pr_err("dbx500_dump: Unable to register a die notifier %d\n", err); - goto free_mem; + goto free_panic_notifier; } pr_info("dbx500_dump: driver initialized\n"); return err; +free_panic_notifier: + atomic_notifier_chain_unregister(&panic_notifier_list, + &panic_notifier); + free_mem: for (i = i - 1; i >= 0; i--) kfree(dbx500_dump[i].data); |