summaryrefslogtreecommitdiff
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);