aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/sh4a/smp-shx3.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu/sh4a/smp-shx3.c')
-rw-r--r--arch/sh/kernel/cpu/sh4a/smp-shx3.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
index 185ec3976a25..5863e0c4d02f 100644
--- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
@@ -14,6 +14,13 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/io.h> 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
17static irqreturn_t ipi_interrupt_handler(int irq, void *arg) 24static irqreturn_t ipi_interrupt_handler(int irq, void *arg)
18{ 25{
19 unsigned int message = (unsigned int)(long)arg; 26 unsigned int message = (unsigned int)(long)arg;
@@ -21,9 +28,9 @@ static irqreturn_t ipi_interrupt_handler(int irq, void *arg)
21 unsigned int offs = 4 * cpu; 28 unsigned int offs = 4 * cpu;
22 unsigned int x; 29 unsigned int x;
23 30
24 x = ctrl_inl(0xfe410070 + offs); /* C0INITICI..CnINTICI */ 31 x = __raw_readl(0xfe410070 + offs); /* C0INITICI..CnINTICI */
25 x &= (1 << (message << 2)); 32 x &= (1 << (message << 2));
26 ctrl_outl(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */ 33 __raw_writel(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */
27 34
28 smp_message_recv(message); 35 smp_message_recv(message);
29 36
@@ -37,6 +44,9 @@ void __init plat_smp_setup(void)
37 44
38 init_cpu_possible(cpumask_of(cpu)); 45 init_cpu_possible(cpumask_of(cpu));
39 46
47 /* Enable light sleep for the boot CPU */
48 __raw_writel(__raw_readl(STBCR_REG(cpu)) | STBCR_LTSLP, STBCR_REG(cpu));
49
40 __cpu_number_map[0] = 0; 50 __cpu_number_map[0] = 0;
41 __cpu_logical_map[0] = 0; 51 __cpu_logical_map[0] = 0;
42 52
@@ -66,32 +76,23 @@ void __init plat_prepare_cpus(unsigned int max_cpus)
66 "IPI", (void *)(long)i); 76 "IPI", (void *)(long)i);
67} 77}
68 78
69#define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12))
70#define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12))
71
72#define STBCR_MSTP 0x00000001
73#define STBCR_RESET 0x00000002
74#define STBCR_LTSLP 0x80000000
75
76#define STBCR_AP_VAL (STBCR_RESET | STBCR_LTSLP)
77
78void plat_start_cpu(unsigned int cpu, unsigned long entry_point) 79void plat_start_cpu(unsigned int cpu, unsigned long entry_point)
79{ 80{
80 ctrl_outl(entry_point, RESET_REG(cpu)); 81 __raw_writel(entry_point, RESET_REG(cpu));
81 82
82 if (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP)) 83 if (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
83 ctrl_outl(STBCR_MSTP, STBCR_REG(cpu)); 84 __raw_writel(STBCR_MSTP, STBCR_REG(cpu));
84 85
85 while (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP)) 86 while (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
86 cpu_relax(); 87 cpu_relax();
87 88
88 /* Start up secondary processor by sending a reset */ 89 /* Start up secondary processor by sending a reset */
89 ctrl_outl(STBCR_AP_VAL, STBCR_REG(cpu)); 90 __raw_writel(STBCR_RESET | STBCR_LTSLP, STBCR_REG(cpu));
90} 91}
91 92
92int plat_smp_processor_id(void) 93int plat_smp_processor_id(void)
93{ 94{
94 return ctrl_inl(0xff000048); /* CPIDR */ 95 return __raw_readl(0xff000048); /* CPIDR */
95} 96}
96 97
97void plat_send_ipi(unsigned int cpu, unsigned int message) 98void plat_send_ipi(unsigned int cpu, unsigned int message)
@@ -100,5 +101,5 @@ void plat_send_ipi(unsigned int cpu, unsigned int message)
100 101
101 BUG_ON(cpu >= 4); 102 BUG_ON(cpu >= 4);
102 103
103 ctrl_outl(1 << (message << 2), addr); /* C0INTICI..CnINTICI */ 104 __raw_writel(1 << (message << 2), addr); /* C0INTICI..CnINTICI */
104} 105}