diff options
Diffstat (limited to 'arch/arc/kernel/mcip.c')
-rw-r--r-- | arch/arc/kernel/mcip.c | 37 |
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 | ||
23 | static char smp_cpuinfo_buf[128]; | 23 | static 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 | */ | ||
29 | static 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 | |||
25 | static void mcip_setup_per_cpu(int cpu) | 54 | static 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 | ||
31 | static void mcip_ipi_send(int cpu) | 68 | static void mcip_ipi_send(int cpu) |