summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/powernv/smp.c
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2017-04-13 13:16:21 +0300
committerMichael Ellerman <mpe@ellerman.id.au>2017-04-13 16:34:33 +0300
commitb866cc2199d6a6cdcefe4acfe4cfca3ac3c6d38e (patch)
tree8baaa55d1ac71d0d18a1d932e561af6751c39c61 /arch/powerpc/platforms/powernv/smp.c
parent9b7ff0c6586bc0541ebcd1ff6773b11a49f1a058 (diff)
downloadlinux-b866cc2199d6a6cdcefe4acfe4cfca3ac3c6d38e.tar.xz
powerpc: Change the doorbell IPI calling convention
Change the doorbell callers to know about their msgsnd addressing, rather than have them set a per-cpu target data tag at boot that gets sent to the cause_ipi functions. The data is only used for doorbell IPI functions, no other IPI types, so it makes sense to keep that detail local to doorbell. Have the platform code understand doorbell IPIs, rather than the interrupt controller code understand them. Platform code can look at capabilities it has available and decide which to use. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/platforms/powernv/smp.c')
-rw-r--r--arch/powerpc/platforms/powernv/smp.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
index 39296bf7009e..33bd4dd2cb41 100644
--- a/arch/powerpc/platforms/powernv/smp.c
+++ b/arch/powerpc/platforms/powernv/smp.c
@@ -53,11 +53,6 @@ static void pnv_smp_setup_cpu(int cpu)
xive_smp_setup_cpu();
else if (cpu != boot_cpuid)
xics_setup_cpu();
-
-#ifdef CONFIG_PPC_DOORBELL
- if (cpu_has_feature(CPU_FTR_DBELL))
- doorbell_setup_this_cpu();
-#endif
}
static int pnv_smp_kick_cpu(int nr)
@@ -254,17 +249,31 @@ static int pnv_smp_prepare_cpu(int cpu)
return 0;
}
+static void pnv_cause_ipi(int cpu)
+{
+ if (doorbell_try_core_ipi(cpu))
+ return;
+
+ icp_ops->cause_ipi(cpu);
+}
+
static void __init pnv_smp_probe(void)
{
if (xive_enabled())
xive_smp_probe();
else
xics_smp_probe();
+
+ if (cpu_has_feature(CPU_FTR_DBELL) && !cpu_has_feature(CPU_FTR_ARCH_300)) {
+ smp_ops->cause_ipi = pnv_cause_ipi;
+ } else {
+ smp_ops->cause_ipi = icp_ops->cause_ipi;
+ }
}
static struct smp_ops_t pnv_smp_ops = {
- .message_pass = smp_muxed_ipi_message_pass,
- .cause_ipi = NULL, /* Filled at runtime by xi{cs,ve}_smp_probe() */
+ .message_pass = NULL, /* Use smp_muxed_ipi_message_pass */
+ .cause_ipi = NULL, /* Filled at runtime by pnv_smp_probe() */
.probe = pnv_smp_probe,
.prepare_cpu = pnv_smp_prepare_cpu,
.kick_cpu = pnv_smp_kick_cpu,