Merge tag 'char-misc-3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregk...
[cascardo/linux.git] / arch / arm64 / kernel / smp.c
index c3cb160..3e2f5eb 100644 (file)
 #include <linux/clockchips.h>
 #include <linux/completion.h>
 #include <linux/of.h>
+#include <linux/irq_work.h>
 
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
+#include <asm/cpu.h>
 #include <asm/cputype.h>
 #include <asm/cpu_ops.h>
 #include <asm/mmu_context.h>
@@ -62,6 +64,7 @@ enum ipi_msg_type {
        IPI_CALL_FUNC_SINGLE,
        IPI_CPU_STOP,
        IPI_TIMER,
+       IPI_IRQ_WORK,
 };
 
 /*
@@ -152,6 +155,11 @@ asmlinkage void secondary_start_kernel(void)
        if (cpu_ops[cpu]->cpu_postboot)
                cpu_ops[cpu]->cpu_postboot();
 
+       /*
+        * Log the CPU info before it is marked online and might get read.
+        */
+       cpuinfo_store_cpu();
+
        /*
         * Enable GIC and timers.
         */
@@ -477,6 +485,14 @@ void arch_send_call_function_single_ipi(int cpu)
        smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
 }
 
+#ifdef CONFIG_IRQ_WORK
+void arch_irq_work_raise(void)
+{
+       if (smp_cross_call)
+               smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
+}
+#endif
+
 static const char *ipi_types[NR_IPI] = {
 #define S(x,s) [x - IPI_RESCHEDULE] = s
        S(IPI_RESCHEDULE, "Rescheduling interrupts"),
@@ -484,6 +500,7 @@ static const char *ipi_types[NR_IPI] = {
        S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
        S(IPI_CPU_STOP, "CPU stop interrupts"),
        S(IPI_TIMER, "Timer broadcast interrupts"),
+       S(IPI_IRQ_WORK, "IRQ work interrupts"),
 };
 
 void show_ipi_list(struct seq_file *p, int prec)
@@ -576,6 +593,14 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
                break;
 #endif
 
+#ifdef CONFIG_IRQ_WORK
+       case IPI_IRQ_WORK:
+               irq_enter();
+               irq_work_run();
+               irq_exit();
+               break;
+#endif
+
        default:
                pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
                break;