aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/Kconfig2
-rw-r--r--arch/arm64/include/asm/hardirq.h2
-rw-r--r--arch/arm64/kernel/smp.c17
3 files changed, 20 insertions, 1 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6d4dd22ee4b7..baab4eb8bfe4 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2,6 +2,7 @@ config ARM64
2 def_bool y 2 def_bool y
3 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 3 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
4 select ARCH_USE_CMPXCHG_LOCKREF 4 select ARCH_USE_CMPXCHG_LOCKREF
5 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
5 select ARCH_WANT_OPTIONAL_GPIOLIB 6 select ARCH_WANT_OPTIONAL_GPIOLIB
6 select ARCH_WANT_COMPAT_IPC_PARSE_VERSION 7 select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
7 select ARCH_WANT_FRAME_POINTERS 8 select ARCH_WANT_FRAME_POINTERS
@@ -12,6 +13,7 @@ config ARM64
12 select CLONE_BACKWARDS 13 select CLONE_BACKWARDS
13 select COMMON_CLK 14 select COMMON_CLK
14 select GENERIC_CLOCKEVENTS 15 select GENERIC_CLOCKEVENTS
16 select GENERIC_CLOCKEVENTS_BROADCAST if SMP
15 select GENERIC_IOMAP 17 select GENERIC_IOMAP
16 select GENERIC_IRQ_PROBE 18 select GENERIC_IRQ_PROBE
17 select GENERIC_IRQ_SHOW 19 select GENERIC_IRQ_SHOW
diff --git a/arch/arm64/include/asm/hardirq.h b/arch/arm64/include/asm/hardirq.h
index 990c051e7829..ae4801d77514 100644
--- a/arch/arm64/include/asm/hardirq.h
+++ b/arch/arm64/include/asm/hardirq.h
@@ -20,7 +20,7 @@
20#include <linux/threads.h> 20#include <linux/threads.h>
21#include <asm/irq.h> 21#include <asm/irq.h>
22 22
23#define NR_IPI 4 23#define NR_IPI 5
24 24
25typedef struct { 25typedef struct {
26 unsigned int __softirq_pending; 26 unsigned int __softirq_pending;
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index a0c2ca602cf8..0b8c859e744f 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -61,6 +61,7 @@ enum ipi_msg_type {
61 IPI_CALL_FUNC, 61 IPI_CALL_FUNC,
62 IPI_CALL_FUNC_SINGLE, 62 IPI_CALL_FUNC_SINGLE,
63 IPI_CPU_STOP, 63 IPI_CPU_STOP,
64 IPI_TIMER,
64}; 65};
65 66
66/* 67/*
@@ -447,6 +448,7 @@ static const char *ipi_types[NR_IPI] = {
447 S(IPI_CALL_FUNC, "Function call interrupts"), 448 S(IPI_CALL_FUNC, "Function call interrupts"),
448 S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"), 449 S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
449 S(IPI_CPU_STOP, "CPU stop interrupts"), 450 S(IPI_CPU_STOP, "CPU stop interrupts"),
451 S(IPI_TIMER, "Timer broadcast interrupts"),
450}; 452};
451 453
452void show_ipi_list(struct seq_file *p, int prec) 454void show_ipi_list(struct seq_file *p, int prec)
@@ -532,6 +534,14 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
532 irq_exit(); 534 irq_exit();
533 break; 535 break;
534 536
537#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
538 case IPI_TIMER:
539 irq_enter();
540 tick_receive_broadcast();
541 irq_exit();
542 break;
543#endif
544
535 default: 545 default:
536 pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); 546 pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
537 break; 547 break;
@@ -544,6 +554,13 @@ void smp_send_reschedule(int cpu)
544 smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); 554 smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
545} 555}
546 556
557#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
558void tick_broadcast(const struct cpumask *mask)
559{
560 smp_cross_call(mask, IPI_TIMER);
561}
562#endif
563
547void smp_send_stop(void) 564void smp_send_stop(void)
548{ 565{
549 unsigned long timeout; 566 unsigned long timeout;