diff options
| author | Ingo Molnar <mingo@kernel.org> | 2017-02-14 07:29:14 +0100 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2017-02-14 07:29:14 +0100 |
| commit | 210f400d68a14bc89e2e61dc2e06cdd67cfeb5f6 (patch) | |
| tree | 2098a7db539f0e92676d8d953002db3cc8eb03b8 /arch/powerpc/sysdev/xics/icp-opal.c | |
| parent | f2029b1e47b607619d1dd2cb0bbb77f64ec6b7c2 (diff) | |
| parent | 7089db84e356562f8ba737c29e472cc42d530dbc (diff) | |
| download | linux-next-210f400d68a14bc89e2e61dc2e06cdd67cfeb5f6.tar.gz linux-next-210f400d68a14bc89e2e61dc2e06cdd67cfeb5f6.zip | |
Merge tag 'v4.10-rc8' into perf/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/powerpc/sysdev/xics/icp-opal.c')
| -rw-r--r-- | arch/powerpc/sysdev/xics/icp-opal.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/arch/powerpc/sysdev/xics/icp-opal.c b/arch/powerpc/sysdev/xics/icp-opal.c index 60c57657c772..f9670eabfcfa 100644 --- a/arch/powerpc/sysdev/xics/icp-opal.c +++ b/arch/powerpc/sysdev/xics/icp-opal.c @@ -120,18 +120,49 @@ static void icp_opal_cause_ipi(int cpu, unsigned long data) { int hw_cpu = get_hard_smp_processor_id(cpu); + kvmppc_set_host_ipi(cpu, 1); opal_int_set_mfrr(hw_cpu, IPI_PRIORITY); } static irqreturn_t icp_opal_ipi_action(int irq, void *dev_id) { - int hw_cpu = hard_smp_processor_id(); + int cpu = smp_processor_id(); - opal_int_set_mfrr(hw_cpu, 0xff); + kvmppc_set_host_ipi(cpu, 0); + opal_int_set_mfrr(get_hard_smp_processor_id(cpu), 0xff); return smp_ipi_demux(); } +/* + * Called when an interrupt is received on an off-line CPU to + * clear the interrupt, so that the CPU can go back to nap mode. + */ +void icp_opal_flush_interrupt(void) +{ + unsigned int xirr; + unsigned int vec; + + do { + xirr = icp_opal_get_xirr(); + vec = xirr & 0x00ffffff; + if (vec == XICS_IRQ_SPURIOUS) + break; + if (vec == XICS_IPI) { + /* Clear pending IPI */ + int cpu = smp_processor_id(); + kvmppc_set_host_ipi(cpu, 0); + opal_int_set_mfrr(get_hard_smp_processor_id(cpu), 0xff); + } else { + pr_err("XICS: hw interrupt 0x%x to offline cpu, " + "disabling\n", vec); + xics_mask_unknown_vec(vec); + } + + /* EOI the interrupt */ + } while (opal_int_eoi(xirr) > 0); +} + #endif /* CONFIG_SMP */ static const struct icp_ops icp_opal_ops = { |
