]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/arm/kernel/smp.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[karo-tx-linux.git] / arch / arm / kernel / smp.c
index 3d6b7821cff8c952e73c72cad5a1f8d90cdf1758..48185a773852d4ec501702ae3a6471d38b03ce10 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/cpu.h>
 #include <linux/seq_file.h>
 #include <linux/irq.h>
+#include <linux/nmi.h>
 #include <linux/percpu.h>
 #include <linux/clockchips.h>
 #include <linux/completion.h>
@@ -72,6 +73,7 @@ enum ipi_msg_type {
        IPI_CPU_STOP,
        IPI_IRQ_WORK,
        IPI_COMPLETION,
+       IPI_CPU_BACKTRACE = 15,
 };
 
 static DECLARE_COMPLETION(cpu_running);
@@ -175,13 +177,26 @@ static int platform_cpu_disable(unsigned int cpu)
        if (smp_ops.cpu_disable)
                return smp_ops.cpu_disable(cpu);
 
+       return 0;
+}
+
+int platform_can_hotplug_cpu(unsigned int cpu)
+{
+       /* cpu_die must be specified to support hotplug */
+       if (!smp_ops.cpu_die)
+               return 0;
+
+       if (smp_ops.cpu_can_disable)
+               return smp_ops.cpu_can_disable(cpu);
+
        /*
         * By default, allow disabling all CPUs except the first one,
         * since this is special on a lot of platforms, e.g. because
         * of clock tick interrupts.
         */
-       return cpu == 0 ? -EPERM : 0;
+       return cpu != 0;
 }
+
 /*
  * __cpu_disable runs on the processor to be shutdown.
  */
@@ -253,7 +268,7 @@ void __cpu_die(unsigned int cpu)
  * of the other hotplug-cpu capable cores, so presumably coming
  * out of idle fixes this.
  */
-void __ref cpu_die(void)
+void arch_cpu_idle_dead(void)
 {
        unsigned int cpu = smp_processor_id();
 
@@ -630,6 +645,12 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
                irq_exit();
                break;
 
+       case IPI_CPU_BACKTRACE:
+               irq_enter();
+               nmi_cpu_backtrace(regs);
+               irq_exit();
+               break;
+
        default:
                pr_crit("CPU%u: Unknown IPI message 0x%x\n",
                        cpu, ipinr);
@@ -724,3 +745,13 @@ static int __init register_cpufreq_notifier(void)
 core_initcall(register_cpufreq_notifier);
 
 #endif
+
+static void raise_nmi(cpumask_t *mask)
+{
+       smp_cross_call(mask, IPI_CPU_BACKTRACE);
+}
+
+void arch_trigger_all_cpu_backtrace(bool include_self)
+{
+       nmi_trigger_all_cpu_backtrace(include_self, raise_nmi);
+}