msm: hotplug: log hotplug events in msm_rtb
Keeping a log of hotplug events in uncached memory allows us to
diagnose bus hangs related to hotplug.
Change-Id: I81e5ad5bb9b30b7530cf1dc31696290cdd9be44a
Signed-off-by: Jeff Ohlstein <johlstei@codeaurora.org>
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index 616763c..8d40908 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -10,10 +10,13 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
+#include <linux/cpu.h>
#include <asm/cacheflush.h>
#include <asm/vfp.h>
+#include <mach/msm_rtb.h>
+
#include "pm.h"
#include "qdss.h"
#include "spm.h"
@@ -114,6 +117,45 @@
return cpu == 0 ? -EPERM : 0;
}
+#define CPU_SHIFT 0
+#define CPU_MASK 0xF
+#define CPU_OF(n) (((n) & CPU_MASK) << CPU_SHIFT)
+#define CPUSET_SHIFT 4
+#define CPUSET_MASK 0xFFFF
+#define CPUSET_OF(n) (((n) & CPUSET_MASK) << CPUSET_SHIFT)
+
+static int hotplug_rtb_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ /*
+ * Bits [19:4] of the data are the online mask, lower 4 bits are the
+ * cpu number that is being changed. Additionally, changes to the
+ * online_mask that will be done by the current hotplug will be made
+ * even though they aren't necessarily in the online mask yet.
+ *
+ * XXX: This design is limited to supporting at most 16 cpus
+ */
+ int this_cpumask = CPUSET_OF(1 << (int)hcpu);
+ int cpumask = CPUSET_OF(cpumask_bits(cpu_online_mask)[0]);
+ int cpudata = CPU_OF((int)hcpu) | cpumask;
+
+ switch (action & (~CPU_TASKS_FROZEN)) {
+ case CPU_STARTING:
+ uncached_logk(LOGK_HOTPLUG, (void *)(cpudata | this_cpumask));
+ break;
+ case CPU_DYING:
+ uncached_logk(LOGK_HOTPLUG, (void *)(cpudata & ~this_cpumask));
+ break;
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+static struct notifier_block hotplug_rtb_notifier = {
+ .notifier_call = hotplug_rtb_callback,
+};
+
int msm_platform_secondary_init(unsigned int cpu)
{
int ret;
@@ -132,3 +174,9 @@
return ret;
}
+
+static int __init init_hotplug_notifier(void)
+{
+ return register_hotcpu_notifier(&hotplug_rtb_notifier);
+}
+early_initcall(init_hotplug_notifier);
diff --git a/arch/arm/mach-msm/include/mach/msm_rtb.h b/arch/arm/mach-msm/include/mach/msm_rtb.h
index ac45cbd..e2a7127 100644
--- a/arch/arm/mach-msm/include/mach/msm_rtb.h
+++ b/arch/arm/mach-msm/include/mach/msm_rtb.h
@@ -18,6 +18,7 @@
LOGK_READL,
LOGK_WRITEL,
LOGK_LOGBUF,
+ LOGK_HOTPLUG,
LOGK_OTHER,
};