|
@@ -35,6 +35,7 @@
|
|
#include <linux/clockchips.h>
|
|
#include <linux/clockchips.h>
|
|
#include <linux/completion.h>
|
|
#include <linux/completion.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of.h>
|
|
|
|
+#include <linux/irq_work.h>
|
|
|
|
|
|
#include <asm/atomic.h>
|
|
#include <asm/atomic.h>
|
|
#include <asm/cacheflush.h>
|
|
#include <asm/cacheflush.h>
|
|
@@ -62,6 +63,7 @@ enum ipi_msg_type {
|
|
IPI_CALL_FUNC_SINGLE,
|
|
IPI_CALL_FUNC_SINGLE,
|
|
IPI_CPU_STOP,
|
|
IPI_CPU_STOP,
|
|
IPI_TIMER,
|
|
IPI_TIMER,
|
|
|
|
+ IPI_IRQ_WORK,
|
|
};
|
|
};
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -455,6 +457,14 @@ void arch_send_call_function_single_ipi(int cpu)
|
|
smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
|
|
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] = {
|
|
static const char *ipi_types[NR_IPI] = {
|
|
#define S(x,s) [x - IPI_RESCHEDULE] = s
|
|
#define S(x,s) [x - IPI_RESCHEDULE] = s
|
|
S(IPI_RESCHEDULE, "Rescheduling interrupts"),
|
|
S(IPI_RESCHEDULE, "Rescheduling interrupts"),
|
|
@@ -462,6 +472,7 @@ static const char *ipi_types[NR_IPI] = {
|
|
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"),
|
|
S(IPI_TIMER, "Timer broadcast interrupts"),
|
|
|
|
+ S(IPI_IRQ_WORK, "IRQ work interrupts"),
|
|
};
|
|
};
|
|
|
|
|
|
void show_ipi_list(struct seq_file *p, int prec)
|
|
void show_ipi_list(struct seq_file *p, int prec)
|
|
@@ -554,6 +565,14 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
|
|
break;
|
|
break;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+#ifdef CONFIG_IRQ_WORK
|
|
|
|
+ case IPI_IRQ_WORK:
|
|
|
|
+ irq_enter();
|
|
|
|
+ irq_work_run();
|
|
|
|
+ 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;
|