Merge "msm: Add support for memory dump table" into msm-3.4
diff --git a/arch/arm/mach-msm/include/mach/msm_memory_dump.h b/arch/arm/mach-msm/include/mach/msm_memory_dump.h
new file mode 100644
index 0000000..3b8c9fd
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_memory_dump.h
@@ -0,0 +1,57 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_MEMORY_DUMP_H
+#define __MSM_MEMORY_DUMP_H
+
+#include <linux/types.h>
+
+enum dump_client_type {
+ MSM_CPU_CTXT = 0,
+ MSM_CACHE,
+ MSM_OCMEM,
+ MSM_ETB,
+ MSM_ETM,
+ MSM_TMC,
+ MAX_NUM_CLIENTS,
+};
+
+struct msm_client_dump {
+ enum dump_client_type id;
+ unsigned long start_addr;
+ unsigned long end_addr;
+};
+
+struct msm_dump_table {
+ u32 version;
+ u32 num_entries;
+ struct msm_client_dump client_entries[MAX_NUM_CLIENTS];
+};
+
+struct msm_memory_dump {
+ unsigned long dump_table_phys;
+ struct msm_dump_table *dump_table_ptr;
+};
+
+#define TABLE_MAJOR(val) (val >> 20)
+#define TABLE_MINOR(val) (val & 0xFFFFF)
+#define MK_TABLE(ma, mi) ((ma << 20) | mi)
+
+#ifndef CONFIG_MSM_MEMORY_DUMP
+static inline int msm_dump_table_register(struct msm_client_dump *entry)
+{
+ return -EIO;
+}
+#else
+int msm_dump_table_register(struct msm_client_dump *client_entry);
+#endif
+#endif
diff --git a/arch/arm/mach-msm/msm_memory_dump.c b/arch/arm/mach-msm/msm_memory_dump.c
new file mode 100644
index 0000000..4f48a0d
--- /dev/null
+++ b/arch/arm/mach-msm/msm_memory_dump.c
@@ -0,0 +1,78 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <asm/cacheflush.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/notifier.h>
+#include <linux/export.h>
+#include <mach/msm_iomap.h>
+#include <mach/msm_memory_dump.h>
+
+
+/*TODO: Needs to be set to correct value */
+#define DUMP_TABLE_OFFSET 0x20
+#define MSM_DUMP_TABLE_VERSION MK_TABLE(1, 0)
+
+static struct msm_memory_dump mem_dump_data;
+
+static int msm_memory_dump_panic(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ writel_relaxed(0, MSM_IMEM_BASE + DUMP_TABLE_OFFSET);
+ return 0;
+}
+
+static struct notifier_block msm_memory_dump_blk = {
+ .notifier_call = msm_memory_dump_panic,
+};
+
+int msm_dump_table_register(struct msm_client_dump *client_entry)
+{
+ struct msm_client_dump *entry;
+ struct msm_dump_table *table = mem_dump_data.dump_table_ptr;
+
+ if (!table || table->num_entries >= MAX_NUM_CLIENTS)
+ return -EINVAL;
+ entry = &table->client_entries[table->num_entries];
+ entry->id = client_entry->id;
+ entry->start_addr = client_entry->start_addr;
+ entry->end_addr = client_entry->end_addr;
+ table->num_entries++;
+ /* flush cache */
+ dmac_flush_range(table, table + sizeof(struct msm_dump_table));
+ return 0;
+}
+EXPORT_SYMBOL(msm_dump_table_register);
+
+static int __init init_memory_dump(void)
+{
+ struct msm_dump_table *table;
+
+ mem_dump_data.dump_table_ptr = kzalloc(sizeof(struct msm_dump_table),
+ GFP_KERNEL);
+ if (!mem_dump_data.dump_table_ptr) {
+ printk(KERN_ERR "unable to allocate memory for dump table\n");
+ return -ENOMEM;
+ }
+ table = mem_dump_data.dump_table_ptr;
+ table->version = MSM_DUMP_TABLE_VERSION;
+ mem_dump_data.dump_table_phys = virt_to_phys(table);
+ /* TODO: Need to write physical address of table to IMEM */
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &msm_memory_dump_blk);
+ printk(KERN_INFO "MSM Memory Dump table set up\n");
+ return 0;
+}
+
+early_initcall(init_memory_dump);
+