|
@@ -61,6 +61,7 @@ enum ipi_msg_type {
|
|
IPI_CALL_FUNC,
|
|
IPI_CALL_FUNC,
|
|
IPI_CALL_FUNC_SINGLE,
|
|
IPI_CALL_FUNC_SINGLE,
|
|
IPI_CPU_STOP,
|
|
IPI_CPU_STOP,
|
|
|
|
+ IPI_TIMER,
|
|
};
|
|
};
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -447,6 +448,7 @@ static const char *ipi_types[NR_IPI] = {
|
|
S(IPI_CALL_FUNC, "Function call interrupts"),
|
|
S(IPI_CALL_FUNC, "Function call interrupts"),
|
|
S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
|
|
S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
|
|
S(IPI_CPU_STOP, "CPU stop interrupts"),
|
|
S(IPI_CPU_STOP, "CPU stop interrupts"),
|
|
|
|
+ S(IPI_TIMER, "Timer broadcast interrupts"),
|
|
};
|
|
};
|
|
|
|
|
|
void show_ipi_list(struct seq_file *p, int prec)
|
|
void show_ipi_list(struct seq_file *p, int prec)
|
|
@@ -532,6 +534,14 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
|
|
irq_exit();
|
|
irq_exit();
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
|
|
|
|
+ case IPI_TIMER:
|
|
|
|
+ irq_enter();
|
|
|
|
+ tick_receive_broadcast();
|
|
|
|
+ irq_exit();
|
|
|
|
+ break;
|
|
|
|
+#endif
|
|
|
|
+
|
|
default:
|
|
default:
|
|
pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
|
|
pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
|
|
break;
|
|
break;
|
|
@@ -544,6 +554,13 @@ void smp_send_reschedule(int cpu)
|
|
smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
|
|
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)
|
|
void smp_send_stop(void)
|
|
{
|
|
{
|
|
unsigned long timeout;
|
|
unsigned long timeout;
|