summaryrefslogtreecommitdiff
path: root/arch/parisc/kernel/process.c
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2022-03-25 14:27:21 +0100
committerHelge Deller <deller@gmx.de>2022-03-29 21:37:12 +0200
commit98903688e6106d9ca68e44c7d218e61336d54631 (patch)
treeb8b4319190cb9ce7ea93283073c99a8fd1f8a1fa /arch/parisc/kernel/process.c
parent88b3aac6228baaac6a3bcc0808845083b9d9f08f (diff)
parisc: Rewrite arch_cpu_idle_dead() for CPU hotplugging
Let the PDC firmware put the CPU into firmware idle loop with the pdc_cpu_rendezvous() function. Signed-off-by: Helge Deller <deller@gmx.de>
Diffstat (limited to 'arch/parisc/kernel/process.c')
-rw-r--r--arch/parisc/kernel/process.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 2030c77592d3..28b6a2a5574c 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -38,6 +38,7 @@
#include <linux/rcupdate.h>
#include <linux/random.h>
#include <linux/nmi.h>
+#include <linux/sched/hotplug.h>
#include <asm/io.h>
#include <asm/asm-offsets.h>
@@ -46,6 +47,7 @@
#include <asm/pdc_chassis.h>
#include <asm/unwind.h>
#include <asm/sections.h>
+#include <asm/cacheflush.h>
#define COMMAND_GLOBAL F_EXTEND(0xfffe0030)
#define CMD_RESET 5 /* reset any module */
@@ -158,10 +160,29 @@ void release_thread(struct task_struct *dead_task)
int running_on_qemu __ro_after_init;
EXPORT_SYMBOL(running_on_qemu);
-void __cpuidle arch_cpu_idle_dead(void)
+/*
+ * Called from the idle thread for the CPU which has been shutdown.
+ */
+void arch_cpu_idle_dead(void)
{
- /* nop on real hardware, qemu will offline CPU. */
- asm volatile("or %%r31,%%r31,%%r31\n":::);
+#ifdef CONFIG_HOTPLUG_CPU
+ idle_task_exit();
+
+ local_irq_disable();
+
+ /* Tell __cpu_die() that this CPU is now safe to dispose of. */
+ (void)cpu_report_death();
+
+ /* Ensure that the cache lines are written out. */
+ flush_cache_all_local();
+ flush_tlb_all_local(NULL);
+
+ /* Let PDC firmware put CPU into firmware idle loop. */
+ __pdc_cpu_rendezvous();
+
+ pr_warn("PDC does not provide rendezvous function.\n");
+#endif
+ while (1);
}
void __cpuidle arch_cpu_idle(void)