summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Bjornstedt <johan.bjornstedt@stericsson.com>2012-01-13 12:50:31 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:02:41 +0200
commitd97f00a621057f904db0c1c21eceab3c14dc449e (patch)
tree2a61bc2db3cc87d168a4b73f253c47caa52a2cbd
parent95e791e82c80f16e44f4ed570008b71f6888fa61 (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.c37
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);