aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel/mcip.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arc/kernel/mcip.c')
-rw-r--r--arch/arc/kernel/mcip.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index f61a52b01625..1119029ae7fc 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -22,10 +22,47 @@ static DEFINE_RAW_SPINLOCK(mcip_lock);
22 22
23static char smp_cpuinfo_buf[128]; 23static char smp_cpuinfo_buf[128];
24 24
25/*
26 * Set mask to halt GFRC if any online core in SMP cluster is halted.
27 * Only works for ARC HS v3.0+, on earlier versions has no effect.
28 */
29static void mcip_update_gfrc_halt_mask(int cpu)
30{
31 struct bcr_generic gfrc;
32 unsigned long flags;
33 u32 gfrc_halt_mask;
34
35 READ_BCR(ARC_REG_GFRC_BUILD, gfrc);
36
37 /*
38 * CMD_GFRC_SET_CORE and CMD_GFRC_READ_CORE commands were added in
39 * GFRC 0x3 version.
40 */
41 if (gfrc.ver < 0x3)
42 return;
43
44 raw_spin_lock_irqsave(&mcip_lock, flags);
45
46 __mcip_cmd(CMD_GFRC_READ_CORE, 0);
47 gfrc_halt_mask = read_aux_reg(ARC_REG_MCIP_READBACK);
48 gfrc_halt_mask |= BIT(cpu);
49 __mcip_cmd_data(CMD_GFRC_SET_CORE, 0, gfrc_halt_mask);
50
51 raw_spin_unlock_irqrestore(&mcip_lock, flags);
52}
53
25static void mcip_setup_per_cpu(int cpu) 54static void mcip_setup_per_cpu(int cpu)
26{ 55{
56 struct mcip_bcr mp;
57
58 READ_BCR(ARC_REG_MCIP_BCR, mp);
59
27 smp_ipi_irq_setup(cpu, IPI_IRQ); 60 smp_ipi_irq_setup(cpu, IPI_IRQ);
28 smp_ipi_irq_setup(cpu, SOFTIRQ_IRQ); 61 smp_ipi_irq_setup(cpu, SOFTIRQ_IRQ);
62
63 /* Update GFRC halt mask as new CPU came online */
64 if (mp.gfrc)
65 mcip_update_gfrc_halt_mask(cpu);
29} 66}
30 67
31static void mcip_ipi_send(int cpu) 68static void mcip_ipi_send(int cpu)