summary refs log tree commit diff
path: root/arch/parisc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc')
-rw-r--r--arch/parisc/include/asm/processor.h1
-rw-r--r--arch/parisc/kernel/smp.c6
-rw-r--r--arch/parisc/kernel/time.c4
3 files changed, 10 insertions, 1 deletions
diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h
index 006364212795..4621ceb51314 100644
--- a/arch/parisc/include/asm/processor.h
+++ b/arch/parisc/include/asm/processor.h
@@ -95,6 +95,7 @@ struct cpuinfo_parisc {
 
 extern struct system_cpuinfo_parisc boot_cpu_data;
 DECLARE_PER_CPU(struct cpuinfo_parisc, cpu_data);
+extern int time_keeper_id;		/* CPU used for timekeeping */
 
 #define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
 
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 8c5ea457b6e1..24d0744c3b3a 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -465,6 +465,12 @@ int __cpu_disable(void)
 	 */
 	set_cpu_online(cpu, false);
 
+	/* Find a new timesync master */
+	if (cpu == time_keeper_id) {
+		time_keeper_id = cpumask_first(cpu_online_mask);
+		pr_info("CPU %d is now promoted to time-keeper master\n", time_keeper_id);
+	}
+
 	disable_percpu_irq(IPI_IRQ);
 
 	irq_migrate_all_off_this_cpu();
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index 874b128c5783..bb27dfeeddfc 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -40,6 +40,8 @@
 
 #include <linux/timex.h>
 
+int time_keeper_id __read_mostly;	/* CPU used for timekeeping. */
+
 static unsigned long clocktick __ro_after_init;	/* timer cycles per tick */
 
 /*
@@ -84,7 +86,7 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
 	cpuinfo->it_value = next_tick;
 
 	/* Go do system house keeping. */
-	if (cpu != 0)
+	if (IS_ENABLED(CONFIG_SMP) && (cpu != time_keeper_id))
 		ticks_elapsed = 0;
 	legacy_timer_tick(ticks_elapsed);