Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sh: Force boot CPU in to light sleep mode for SH-X3 SMP.

All of the secondary CPUs are forced in to light sleep mode, but we were
missing the same initialization for the boot CPU. This resulted in
inconsistent sleep modes depending on which CPU we were on, confusing the
idle loop when not polling.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

+19 -18
+19 -18
arch/sh/kernel/cpu/sh4a/smp-shx3.c
··· 14 14 #include <linux/interrupt.h> 15 15 #include <linux/io.h> 16 16 17 + #define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12)) 18 + #define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12)) 19 + 20 + #define STBCR_MSTP 0x00000001 21 + #define STBCR_RESET 0x00000002 22 + #define STBCR_LTSLP 0x80000000 23 + 17 24 static irqreturn_t ipi_interrupt_handler(int irq, void *arg) 18 25 { 19 26 unsigned int message = (unsigned int)(long)arg; ··· 28 21 unsigned int offs = 4 * cpu; 29 22 unsigned int x; 30 23 31 - x = ctrl_inl(0xfe410070 + offs); /* C0INITICI..CnINTICI */ 24 + x = __raw_readl(0xfe410070 + offs); /* C0INITICI..CnINTICI */ 32 25 x &= (1 << (message << 2)); 33 - ctrl_outl(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */ 26 + __raw_writel(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */ 34 27 35 28 smp_message_recv(message); 36 29 ··· 43 36 int i, num; 44 37 45 38 init_cpu_possible(cpumask_of(cpu)); 39 + 40 + /* Enable light sleep for the boot CPU */ 41 + __raw_writel(__raw_readl(STBCR_REG(cpu)) | STBCR_LTSLP, STBCR_REG(cpu)); 46 42 47 43 __cpu_number_map[0] = 0; 48 44 __cpu_logical_map[0] = 0; ··· 76 66 "IPI", (void *)(long)i); 77 67 } 78 68 79 - #define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12)) 80 - #define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12)) 81 - 82 - #define STBCR_MSTP 0x00000001 83 - #define STBCR_RESET 0x00000002 84 - #define STBCR_LTSLP 0x80000000 85 - 86 - #define STBCR_AP_VAL (STBCR_RESET | STBCR_LTSLP) 87 - 88 69 void plat_start_cpu(unsigned int cpu, unsigned long entry_point) 89 70 { 90 - ctrl_outl(entry_point, RESET_REG(cpu)); 71 + __raw_writel(entry_point, RESET_REG(cpu)); 91 72 92 - if (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP)) 93 - ctrl_outl(STBCR_MSTP, STBCR_REG(cpu)); 73 + if (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP)) 74 + __raw_writel(STBCR_MSTP, STBCR_REG(cpu)); 94 75 95 - while (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP)) 76 + while (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP)) 96 77 cpu_relax(); 97 78 98 79 /* Start up secondary processor by sending a reset */ 99 - ctrl_outl(STBCR_AP_VAL, STBCR_REG(cpu)); 80 + __raw_writel(STBCR_RESET | STBCR_LTSLP, STBCR_REG(cpu)); 100 81 } 101 82 102 83 int plat_smp_processor_id(void) 103 84 { 104 - return ctrl_inl(0xff000048); /* CPIDR */ 85 + return __raw_readl(0xff000048); /* CPIDR */ 105 86 } 106 87 107 88 void plat_send_ipi(unsigned int cpu, unsigned int message) ··· 101 100 102 101 BUG_ON(cpu >= 4); 103 102 104 - ctrl_outl(1 << (message << 2), addr); /* C0INTICI..CnINTICI */ 103 + __raw_writel(1 << (message << 2), addr); /* C0INTICI..CnINTICI */ 105 104 }