Merge remote-tracking branch 'lsk/v3.10/topic/gator' into linux-linaro-lsk
[firefly-linux-kernel-4.4.55.git] / arch / arm64 / kernel / smp.c
index 08030da7f3c27b9fb69345a101e66c7dcf998e08..7c868a2ac38b23ed03a919c70ef1f2b7e1e8c6b6 100644 (file)
@@ -49,6 +49,9 @@
 #include <asm/tlbflush.h>
 #include <asm/ptrace.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/arm-ipi.h>
+
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
  * so we need some other way of telling a new secondary core
@@ -61,6 +64,7 @@ enum ipi_msg_type {
        IPI_CALL_FUNC,
        IPI_CALL_FUNC_SINGLE,
        IPI_CPU_STOP,
+       IPI_TIMER,
 };
 
 /*
@@ -113,6 +117,11 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
        return ret;
 }
 
+static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
+{
+       store_cpu_topology(cpuid);
+}
+
 /*
  * This is the secondary CPU boot entry.  We're using this CPUs
  * idle thread stack, but a set of temporary page tables.
@@ -146,6 +155,13 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
        if (cpu_ops[cpu]->cpu_postboot)
                cpu_ops[cpu]->cpu_postboot();
 
+       /*
+        * Enable GIC and timers.
+        */
+       notify_cpu_starting(cpu);
+
+       smp_store_cpu_info(cpu);
+
        /*
         * OK, now it's safe to let the boot CPU continue.  Wait for
         * the CPU migration code to notice that the CPU is online
@@ -154,11 +170,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
        set_cpu_online(cpu, true);
        complete(&cpu_running);
 
-       /*
-        * Enable GIC and timers.
-        */
-       notify_cpu_starting(cpu);
-
+       local_dbg_enable();
        local_irq_enable();
        local_fiq_enable();
 
@@ -393,6 +405,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
        int err;
        unsigned int cpu, ncores = num_possible_cpus();
 
+       init_cpu_topology();
+
+       smp_store_cpu_info(smp_processor_id());
+
        /*
         * are we trying to boot more cores than exist?
         */
@@ -452,6 +468,7 @@ static const char *ipi_types[NR_IPI] = {
        S(IPI_CALL_FUNC, "Function call interrupts"),
        S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
        S(IPI_CPU_STOP, "CPU stop interrupts"),
+       S(IPI_TIMER, "Timer broadcast interrupts"),
 };
 
 void show_ipi_list(struct seq_file *p, int prec)
@@ -537,6 +554,14 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
                irq_exit();
                break;
 
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+       case IPI_TIMER:
+               irq_enter();
+               tick_receive_broadcast();
+               irq_exit();
+               break;
+#endif
+
        default:
                pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
                break;
@@ -549,6 +574,13 @@ void smp_send_reschedule(int cpu)
        smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
 }
 
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+void tick_broadcast(const struct cpumask *mask)
+{
+       smp_cross_call(mask, IPI_TIMER);
+}
+#endif
+
 void smp_send_stop(void)
 {
        unsigned long timeout;