diff options
author | Paul Mundt <lethal@linux-sh.org> | 2011-01-13 01:06:28 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-01-13 01:06:28 -0500 |
commit | f43dc23d5ea91fca257be02138a255f02d98e806 (patch) | |
tree | b29722f6e965316e90ac97abf79923ced250dc21 /arch/sh/kernel/cpu/sh4 | |
parent | f8e53553f452dcbf67cb89c8cba63a1cd6eb4cc0 (diff) | |
parent | 4162cf64973df51fc885825bc9ca4d055891c49f (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into common/serial-rework
Conflicts:
arch/sh/kernel/cpu/sh2/setup-sh7619.c
arch/sh/kernel/cpu/sh2a/setup-mxg.c
arch/sh/kernel/cpu/sh2a/setup-sh7201.c
arch/sh/kernel/cpu/sh2a/setup-sh7203.c
arch/sh/kernel/cpu/sh2a/setup-sh7206.c
arch/sh/kernel/cpu/sh3/setup-sh7705.c
arch/sh/kernel/cpu/sh3/setup-sh770x.c
arch/sh/kernel/cpu/sh3/setup-sh7710.c
arch/sh/kernel/cpu/sh3/setup-sh7720.c
arch/sh/kernel/cpu/sh4/setup-sh4-202.c
arch/sh/kernel/cpu/sh4/setup-sh7750.c
arch/sh/kernel/cpu/sh4/setup-sh7760.c
arch/sh/kernel/cpu/sh4a/setup-sh7343.c
arch/sh/kernel/cpu/sh4a/setup-sh7366.c
arch/sh/kernel/cpu/sh4a/setup-sh7722.c
arch/sh/kernel/cpu/sh4a/setup-sh7723.c
arch/sh/kernel/cpu/sh4a/setup-sh7724.c
arch/sh/kernel/cpu/sh4a/setup-sh7763.c
arch/sh/kernel/cpu/sh4a/setup-sh7770.c
arch/sh/kernel/cpu/sh4a/setup-sh7780.c
arch/sh/kernel/cpu/sh4a/setup-sh7785.c
arch/sh/kernel/cpu/sh4a/setup-sh7786.c
arch/sh/kernel/cpu/sh4a/setup-shx3.c
arch/sh/kernel/cpu/sh5/setup-sh5.c
drivers/serial/sh-sci.c
drivers/serial/sh-sci.h
include/linux/serial_sci.h
Diffstat (limited to 'arch/sh/kernel/cpu/sh4')
-rw-r--r-- | arch/sh/kernel/cpu/sh4/Makefile | 8 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/clock-sh4-202.c | 32 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/clock-sh4.c | 8 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/fpu.c | 161 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/perf_event.c | 253 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/probe.c | 39 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 40 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/setup-sh7750.c | 36 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/setup-sh7760.c | 118 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/sq.c | 25 |
10 files changed, 462 insertions, 258 deletions
diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile index 203b18347b83..3a1dbc709831 100644 --- a/arch/sh/kernel/cpu/sh4/Makefile +++ b/arch/sh/kernel/cpu/sh4/Makefile | |||
@@ -9,6 +9,11 @@ obj-$(CONFIG_HIBERNATION) += $(addprefix ../sh3/, swsusp.o) | |||
9 | obj-$(CONFIG_SH_FPU) += fpu.o softfloat.o | 9 | obj-$(CONFIG_SH_FPU) += fpu.o softfloat.o |
10 | obj-$(CONFIG_SH_STORE_QUEUES) += sq.o | 10 | obj-$(CONFIG_SH_STORE_QUEUES) += sq.o |
11 | 11 | ||
12 | # Perf events | ||
13 | perf-$(CONFIG_CPU_SUBTYPE_SH7750) := perf_event.o | ||
14 | perf-$(CONFIG_CPU_SUBTYPE_SH7750S) := perf_event.o | ||
15 | perf-$(CONFIG_CPU_SUBTYPE_SH7091) := perf_event.o | ||
16 | |||
12 | # CPU subtype setup | 17 | # CPU subtype setup |
13 | obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o | 18 | obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o |
14 | obj-$(CONFIG_CPU_SUBTYPE_SH7750R) += setup-sh7750.o | 19 | obj-$(CONFIG_CPU_SUBTYPE_SH7750R) += setup-sh7750.o |
@@ -27,4 +32,5 @@ endif | |||
27 | # Additional clocks by subtype | 32 | # Additional clocks by subtype |
28 | clock-$(CONFIG_CPU_SUBTYPE_SH4_202) += clock-sh4-202.o | 33 | clock-$(CONFIG_CPU_SUBTYPE_SH4_202) += clock-sh4-202.o |
29 | 34 | ||
30 | obj-y += $(clock-y) | 35 | obj-y += $(clock-y) |
36 | obj-$(CONFIG_PERF_EVENTS) += $(perf-y) | ||
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index 21421e34e7d5..3f6f8e98635c 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c | |||
@@ -12,9 +12,10 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/io.h> | ||
16 | #include <linux/clkdev.h> | ||
15 | #include <asm/clock.h> | 17 | #include <asm/clock.h> |
16 | #include <asm/freq.h> | 18 | #include <asm/freq.h> |
17 | #include <asm/io.h> | ||
18 | 19 | ||
19 | #define CPG2_FRQCR3 0xfe0a0018 | 20 | #define CPG2_FRQCR3 0xfe0a0018 |
20 | 21 | ||
@@ -23,7 +24,7 @@ static int frqcr3_values[] = { 0, 1, 2, 3, 4, 5, 6 }; | |||
23 | 24 | ||
24 | static unsigned long emi_clk_recalc(struct clk *clk) | 25 | static unsigned long emi_clk_recalc(struct clk *clk) |
25 | { | 26 | { |
26 | int idx = ctrl_inl(CPG2_FRQCR3) & 0x0007; | 27 | int idx = __raw_readl(CPG2_FRQCR3) & 0x0007; |
27 | return clk->parent->rate / frqcr3_divisors[idx]; | 28 | return clk->parent->rate / frqcr3_divisors[idx]; |
28 | } | 29 | } |
29 | 30 | ||
@@ -45,14 +46,13 @@ static struct clk_ops sh4202_emi_clk_ops = { | |||
45 | }; | 46 | }; |
46 | 47 | ||
47 | static struct clk sh4202_emi_clk = { | 48 | static struct clk sh4202_emi_clk = { |
48 | .name = "emi_clk", | ||
49 | .flags = CLK_ENABLE_ON_INIT, | 49 | .flags = CLK_ENABLE_ON_INIT, |
50 | .ops = &sh4202_emi_clk_ops, | 50 | .ops = &sh4202_emi_clk_ops, |
51 | }; | 51 | }; |
52 | 52 | ||
53 | static unsigned long femi_clk_recalc(struct clk *clk) | 53 | static unsigned long femi_clk_recalc(struct clk *clk) |
54 | { | 54 | { |
55 | int idx = (ctrl_inl(CPG2_FRQCR3) >> 3) & 0x0007; | 55 | int idx = (__raw_readl(CPG2_FRQCR3) >> 3) & 0x0007; |
56 | return clk->parent->rate / frqcr3_divisors[idx]; | 56 | return clk->parent->rate / frqcr3_divisors[idx]; |
57 | } | 57 | } |
58 | 58 | ||
@@ -61,7 +61,6 @@ static struct clk_ops sh4202_femi_clk_ops = { | |||
61 | }; | 61 | }; |
62 | 62 | ||
63 | static struct clk sh4202_femi_clk = { | 63 | static struct clk sh4202_femi_clk = { |
64 | .name = "femi_clk", | ||
65 | .flags = CLK_ENABLE_ON_INIT, | 64 | .flags = CLK_ENABLE_ON_INIT, |
66 | .ops = &sh4202_femi_clk_ops, | 65 | .ops = &sh4202_femi_clk_ops, |
67 | }; | 66 | }; |
@@ -82,8 +81,7 @@ static void shoc_clk_init(struct clk *clk) | |||
82 | for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) { | 81 | for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) { |
83 | int divisor = frqcr3_divisors[i]; | 82 | int divisor = frqcr3_divisors[i]; |
84 | 83 | ||
85 | if (clk->ops->set_rate(clk, clk->parent->rate / | 84 | if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0) |
86 | divisor, 0) == 0) | ||
87 | break; | 85 | break; |
88 | } | 86 | } |
89 | 87 | ||
@@ -92,7 +90,7 @@ static void shoc_clk_init(struct clk *clk) | |||
92 | 90 | ||
93 | static unsigned long shoc_clk_recalc(struct clk *clk) | 91 | static unsigned long shoc_clk_recalc(struct clk *clk) |
94 | { | 92 | { |
95 | int idx = (ctrl_inl(CPG2_FRQCR3) >> 6) & 0x0007; | 93 | int idx = (__raw_readl(CPG2_FRQCR3) >> 6) & 0x0007; |
96 | return clk->parent->rate / frqcr3_divisors[idx]; | 94 | return clk->parent->rate / frqcr3_divisors[idx]; |
97 | } | 95 | } |
98 | 96 | ||
@@ -111,7 +109,7 @@ static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate) | |||
111 | return 0; | 109 | return 0; |
112 | } | 110 | } |
113 | 111 | ||
114 | static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id) | 112 | static int shoc_clk_set_rate(struct clk *clk, unsigned long rate) |
115 | { | 113 | { |
116 | unsigned long frqcr3; | 114 | unsigned long frqcr3; |
117 | unsigned int tmp; | 115 | unsigned int tmp; |
@@ -122,10 +120,10 @@ static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id) | |||
122 | 120 | ||
123 | tmp = frqcr3_lookup(clk, rate); | 121 | tmp = frqcr3_lookup(clk, rate); |
124 | 122 | ||
125 | frqcr3 = ctrl_inl(CPG2_FRQCR3); | 123 | frqcr3 = __raw_readl(CPG2_FRQCR3); |
126 | frqcr3 &= ~(0x0007 << 6); | 124 | frqcr3 &= ~(0x0007 << 6); |
127 | frqcr3 |= tmp << 6; | 125 | frqcr3 |= tmp << 6; |
128 | ctrl_outl(frqcr3, CPG2_FRQCR3); | 126 | __raw_writel(frqcr3, CPG2_FRQCR3); |
129 | 127 | ||
130 | clk->rate = clk->parent->rate / frqcr3_divisors[tmp]; | 128 | clk->rate = clk->parent->rate / frqcr3_divisors[tmp]; |
131 | 129 | ||
@@ -139,7 +137,6 @@ static struct clk_ops sh4202_shoc_clk_ops = { | |||
139 | }; | 137 | }; |
140 | 138 | ||
141 | static struct clk sh4202_shoc_clk = { | 139 | static struct clk sh4202_shoc_clk = { |
142 | .name = "shoc_clk", | ||
143 | .flags = CLK_ENABLE_ON_INIT, | 140 | .flags = CLK_ENABLE_ON_INIT, |
144 | .ops = &sh4202_shoc_clk_ops, | 141 | .ops = &sh4202_shoc_clk_ops, |
145 | }; | 142 | }; |
@@ -150,6 +147,15 @@ static struct clk *sh4202_onchip_clocks[] = { | |||
150 | &sh4202_shoc_clk, | 147 | &sh4202_shoc_clk, |
151 | }; | 148 | }; |
152 | 149 | ||
150 | #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } | ||
151 | |||
152 | static struct clk_lookup lookups[] = { | ||
153 | /* main clocks */ | ||
154 | CLKDEV_CON_ID("emi_clk", &sh4202_emi_clk), | ||
155 | CLKDEV_CON_ID("femi_clk", &sh4202_femi_clk), | ||
156 | CLKDEV_CON_ID("shoc_clk", &sh4202_shoc_clk), | ||
157 | }; | ||
158 | |||
153 | int __init arch_clk_init(void) | 159 | int __init arch_clk_init(void) |
154 | { | 160 | { |
155 | struct clk *clk; | 161 | struct clk *clk; |
@@ -167,5 +173,7 @@ int __init arch_clk_init(void) | |||
167 | 173 | ||
168 | clk_put(clk); | 174 | clk_put(clk); |
169 | 175 | ||
176 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
177 | |||
170 | return ret; | 178 | return ret; |
171 | } | 179 | } |
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4.c b/arch/sh/kernel/cpu/sh4/clock-sh4.c index 73294d9cd049..5add75c1f539 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4.c | |||
@@ -28,7 +28,7 @@ static int pfc_divisors[] = { 2, 3, 4, 6, 8, 2, 2, 2 }; | |||
28 | 28 | ||
29 | static void master_clk_init(struct clk *clk) | 29 | static void master_clk_init(struct clk *clk) |
30 | { | 30 | { |
31 | clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0007]; | 31 | clk->rate *= pfc_divisors[__raw_readw(FRQCR) & 0x0007]; |
32 | } | 32 | } |
33 | 33 | ||
34 | static struct clk_ops sh4_master_clk_ops = { | 34 | static struct clk_ops sh4_master_clk_ops = { |
@@ -37,7 +37,7 @@ static struct clk_ops sh4_master_clk_ops = { | |||
37 | 37 | ||
38 | static unsigned long module_clk_recalc(struct clk *clk) | 38 | static unsigned long module_clk_recalc(struct clk *clk) |
39 | { | 39 | { |
40 | int idx = (ctrl_inw(FRQCR) & 0x0007); | 40 | int idx = (__raw_readw(FRQCR) & 0x0007); |
41 | return clk->parent->rate / pfc_divisors[idx]; | 41 | return clk->parent->rate / pfc_divisors[idx]; |
42 | } | 42 | } |
43 | 43 | ||
@@ -47,7 +47,7 @@ static struct clk_ops sh4_module_clk_ops = { | |||
47 | 47 | ||
48 | static unsigned long bus_clk_recalc(struct clk *clk) | 48 | static unsigned long bus_clk_recalc(struct clk *clk) |
49 | { | 49 | { |
50 | int idx = (ctrl_inw(FRQCR) >> 3) & 0x0007; | 50 | int idx = (__raw_readw(FRQCR) >> 3) & 0x0007; |
51 | return clk->parent->rate / bfc_divisors[idx]; | 51 | return clk->parent->rate / bfc_divisors[idx]; |
52 | } | 52 | } |
53 | 53 | ||
@@ -57,7 +57,7 @@ static struct clk_ops sh4_bus_clk_ops = { | |||
57 | 57 | ||
58 | static unsigned long cpu_clk_recalc(struct clk *clk) | 58 | static unsigned long cpu_clk_recalc(struct clk *clk) |
59 | { | 59 | { |
60 | int idx = (ctrl_inw(FRQCR) >> 6) & 0x0007; | 60 | int idx = (__raw_readw(FRQCR) >> 6) & 0x0007; |
61 | return clk->parent->rate / ifc_divisors[idx]; | 61 | return clk->parent->rate / ifc_divisors[idx]; |
62 | } | 62 | } |
63 | 63 | ||
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c index e3ea5411da6d..447482d7f65e 100644 --- a/arch/sh/kernel/cpu/sh4/fpu.c +++ b/arch/sh/kernel/cpu/sh4/fpu.c | |||
@@ -41,13 +41,11 @@ static unsigned int fpu_exception_flags; | |||
41 | 41 | ||
42 | /* | 42 | /* |
43 | * Save FPU registers onto task structure. | 43 | * Save FPU registers onto task structure. |
44 | * Assume called with FPU enabled (SR.FD=0). | ||
45 | */ | 44 | */ |
46 | void save_fpu(struct task_struct *tsk, struct pt_regs *regs) | 45 | void save_fpu(struct task_struct *tsk) |
47 | { | 46 | { |
48 | unsigned long dummy; | 47 | unsigned long dummy; |
49 | 48 | ||
50 | clear_tsk_thread_flag(tsk, TIF_USEDFPU); | ||
51 | enable_fpu(); | 49 | enable_fpu(); |
52 | asm volatile ("sts.l fpul, @-%0\n\t" | 50 | asm volatile ("sts.l fpul, @-%0\n\t" |
53 | "sts.l fpscr, @-%0\n\t" | 51 | "sts.l fpscr, @-%0\n\t" |
@@ -87,15 +85,14 @@ void save_fpu(struct task_struct *tsk, struct pt_regs *regs) | |||
87 | "fmov.s fr1, @-%0\n\t" | 85 | "fmov.s fr1, @-%0\n\t" |
88 | "fmov.s fr0, @-%0\n\t" | 86 | "fmov.s fr0, @-%0\n\t" |
89 | "lds %3, fpscr\n\t":"=r" (dummy) | 87 | "lds %3, fpscr\n\t":"=r" (dummy) |
90 | :"0"((char *)(&tsk->thread.fpu.hard.status)), | 88 | :"0"((char *)(&tsk->thread.xstate->hardfpu.status)), |
91 | "r"(FPSCR_RCHG), "r"(FPSCR_INIT) | 89 | "r"(FPSCR_RCHG), "r"(FPSCR_INIT) |
92 | :"memory"); | 90 | :"memory"); |
93 | 91 | ||
94 | disable_fpu(); | 92 | disable_fpu(); |
95 | release_fpu(regs); | ||
96 | } | 93 | } |
97 | 94 | ||
98 | static void restore_fpu(struct task_struct *tsk) | 95 | void restore_fpu(struct task_struct *tsk) |
99 | { | 96 | { |
100 | unsigned long dummy; | 97 | unsigned long dummy; |
101 | 98 | ||
@@ -138,62 +135,11 @@ static void restore_fpu(struct task_struct *tsk) | |||
138 | "lds.l @%0+, fpscr\n\t" | 135 | "lds.l @%0+, fpscr\n\t" |
139 | "lds.l @%0+, fpul\n\t" | 136 | "lds.l @%0+, fpul\n\t" |
140 | :"=r" (dummy) | 137 | :"=r" (dummy) |
141 | :"0"(&tsk->thread.fpu), "r"(FPSCR_RCHG) | 138 | :"0" (tsk->thread.xstate), "r" (FPSCR_RCHG) |
142 | :"memory"); | 139 | :"memory"); |
143 | disable_fpu(); | 140 | disable_fpu(); |
144 | } | 141 | } |
145 | 142 | ||
146 | /* | ||
147 | * Load the FPU with signalling NANS. This bit pattern we're using | ||
148 | * has the property that no matter wether considered as single or as | ||
149 | * double precision represents signaling NANS. | ||
150 | */ | ||
151 | |||
152 | static void fpu_init(void) | ||
153 | { | ||
154 | enable_fpu(); | ||
155 | asm volatile ( "lds %0, fpul\n\t" | ||
156 | "lds %1, fpscr\n\t" | ||
157 | "fsts fpul, fr0\n\t" | ||
158 | "fsts fpul, fr1\n\t" | ||
159 | "fsts fpul, fr2\n\t" | ||
160 | "fsts fpul, fr3\n\t" | ||
161 | "fsts fpul, fr4\n\t" | ||
162 | "fsts fpul, fr5\n\t" | ||
163 | "fsts fpul, fr6\n\t" | ||
164 | "fsts fpul, fr7\n\t" | ||
165 | "fsts fpul, fr8\n\t" | ||
166 | "fsts fpul, fr9\n\t" | ||
167 | "fsts fpul, fr10\n\t" | ||
168 | "fsts fpul, fr11\n\t" | ||
169 | "fsts fpul, fr12\n\t" | ||
170 | "fsts fpul, fr13\n\t" | ||
171 | "fsts fpul, fr14\n\t" | ||
172 | "fsts fpul, fr15\n\t" | ||
173 | "frchg\n\t" | ||
174 | "fsts fpul, fr0\n\t" | ||
175 | "fsts fpul, fr1\n\t" | ||
176 | "fsts fpul, fr2\n\t" | ||
177 | "fsts fpul, fr3\n\t" | ||
178 | "fsts fpul, fr4\n\t" | ||
179 | "fsts fpul, fr5\n\t" | ||
180 | "fsts fpul, fr6\n\t" | ||
181 | "fsts fpul, fr7\n\t" | ||
182 | "fsts fpul, fr8\n\t" | ||
183 | "fsts fpul, fr9\n\t" | ||
184 | "fsts fpul, fr10\n\t" | ||
185 | "fsts fpul, fr11\n\t" | ||
186 | "fsts fpul, fr12\n\t" | ||
187 | "fsts fpul, fr13\n\t" | ||
188 | "fsts fpul, fr14\n\t" | ||
189 | "fsts fpul, fr15\n\t" | ||
190 | "frchg\n\t" | ||
191 | "lds %2, fpscr\n\t" | ||
192 | : /* no output */ | ||
193 | :"r" (0), "r"(FPSCR_RCHG), "r"(FPSCR_INIT)); | ||
194 | disable_fpu(); | ||
195 | } | ||
196 | |||
197 | /** | 143 | /** |
198 | * denormal_to_double - Given denormalized float number, | 144 | * denormal_to_double - Given denormalized float number, |
199 | * store double float | 145 | * store double float |
@@ -285,10 +231,9 @@ static int ieee_fpe_handler(struct pt_regs *regs) | |||
285 | /* fcnvsd */ | 231 | /* fcnvsd */ |
286 | struct task_struct *tsk = current; | 232 | struct task_struct *tsk = current; |
287 | 233 | ||
288 | save_fpu(tsk, regs); | 234 | if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_CAUSE_ERROR)) |
289 | if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR)) | ||
290 | /* FPU error */ | 235 | /* FPU error */ |
291 | denormal_to_double(&tsk->thread.fpu.hard, | 236 | denormal_to_double(&tsk->thread.xstate->hardfpu, |
292 | (finsn >> 8) & 0xf); | 237 | (finsn >> 8) & 0xf); |
293 | else | 238 | else |
294 | return 0; | 239 | return 0; |
@@ -304,9 +249,9 @@ static int ieee_fpe_handler(struct pt_regs *regs) | |||
304 | 249 | ||
305 | n = (finsn >> 8) & 0xf; | 250 | n = (finsn >> 8) & 0xf; |
306 | m = (finsn >> 4) & 0xf; | 251 | m = (finsn >> 4) & 0xf; |
307 | hx = tsk->thread.fpu.hard.fp_regs[n]; | 252 | hx = tsk->thread.xstate->hardfpu.fp_regs[n]; |
308 | hy = tsk->thread.fpu.hard.fp_regs[m]; | 253 | hy = tsk->thread.xstate->hardfpu.fp_regs[m]; |
309 | fpscr = tsk->thread.fpu.hard.fpscr; | 254 | fpscr = tsk->thread.xstate->hardfpu.fpscr; |
310 | prec = fpscr & FPSCR_DBL_PRECISION; | 255 | prec = fpscr & FPSCR_DBL_PRECISION; |
311 | 256 | ||
312 | if ((fpscr & FPSCR_CAUSE_ERROR) | 257 | if ((fpscr & FPSCR_CAUSE_ERROR) |
@@ -316,18 +261,18 @@ static int ieee_fpe_handler(struct pt_regs *regs) | |||
316 | 261 | ||
317 | /* FPU error because of denormal (doubles) */ | 262 | /* FPU error because of denormal (doubles) */ |
318 | llx = ((long long)hx << 32) | 263 | llx = ((long long)hx << 32) |
319 | | tsk->thread.fpu.hard.fp_regs[n + 1]; | 264 | | tsk->thread.xstate->hardfpu.fp_regs[n + 1]; |
320 | lly = ((long long)hy << 32) | 265 | lly = ((long long)hy << 32) |
321 | | tsk->thread.fpu.hard.fp_regs[m + 1]; | 266 | | tsk->thread.xstate->hardfpu.fp_regs[m + 1]; |
322 | llx = float64_mul(llx, lly); | 267 | llx = float64_mul(llx, lly); |
323 | tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; | 268 | tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32; |
324 | tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff; | 269 | tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff; |
325 | } else if ((fpscr & FPSCR_CAUSE_ERROR) | 270 | } else if ((fpscr & FPSCR_CAUSE_ERROR) |
326 | && (!prec && ((hx & 0x7fffffff) < 0x00800000 | 271 | && (!prec && ((hx & 0x7fffffff) < 0x00800000 |
327 | || (hy & 0x7fffffff) < 0x00800000))) { | 272 | || (hy & 0x7fffffff) < 0x00800000))) { |
328 | /* FPU error because of denormal (floats) */ | 273 | /* FPU error because of denormal (floats) */ |
329 | hx = float32_mul(hx, hy); | 274 | hx = float32_mul(hx, hy); |
330 | tsk->thread.fpu.hard.fp_regs[n] = hx; | 275 | tsk->thread.xstate->hardfpu.fp_regs[n] = hx; |
331 | } else | 276 | } else |
332 | return 0; | 277 | return 0; |
333 | 278 | ||
@@ -342,9 +287,9 @@ static int ieee_fpe_handler(struct pt_regs *regs) | |||
342 | 287 | ||
343 | n = (finsn >> 8) & 0xf; | 288 | n = (finsn >> 8) & 0xf; |
344 | m = (finsn >> 4) & 0xf; | 289 | m = (finsn >> 4) & 0xf; |
345 | hx = tsk->thread.fpu.hard.fp_regs[n]; | 290 | hx = tsk->thread.xstate->hardfpu.fp_regs[n]; |
346 | hy = tsk->thread.fpu.hard.fp_regs[m]; | 291 | hy = tsk->thread.xstate->hardfpu.fp_regs[m]; |
347 | fpscr = tsk->thread.fpu.hard.fpscr; | 292 | fpscr = tsk->thread.xstate->hardfpu.fpscr; |
348 | prec = fpscr & FPSCR_DBL_PRECISION; | 293 | prec = fpscr & FPSCR_DBL_PRECISION; |
349 | 294 | ||
350 | if ((fpscr & FPSCR_CAUSE_ERROR) | 295 | if ((fpscr & FPSCR_CAUSE_ERROR) |
@@ -354,15 +299,15 @@ static int ieee_fpe_handler(struct pt_regs *regs) | |||
354 | 299 | ||
355 | /* FPU error because of denormal (doubles) */ | 300 | /* FPU error because of denormal (doubles) */ |
356 | llx = ((long long)hx << 32) | 301 | llx = ((long long)hx << 32) |
357 | | tsk->thread.fpu.hard.fp_regs[n + 1]; | 302 | | tsk->thread.xstate->hardfpu.fp_regs[n + 1]; |
358 | lly = ((long long)hy << 32) | 303 | lly = ((long long)hy << 32) |
359 | | tsk->thread.fpu.hard.fp_regs[m + 1]; | 304 | | tsk->thread.xstate->hardfpu.fp_regs[m + 1]; |
360 | if ((finsn & 0xf00f) == 0xf000) | 305 | if ((finsn & 0xf00f) == 0xf000) |
361 | llx = float64_add(llx, lly); | 306 | llx = float64_add(llx, lly); |
362 | else | 307 | else |
363 | llx = float64_sub(llx, lly); | 308 | llx = float64_sub(llx, lly); |
364 | tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; | 309 | tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32; |
365 | tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff; | 310 | tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff; |
366 | } else if ((fpscr & FPSCR_CAUSE_ERROR) | 311 | } else if ((fpscr & FPSCR_CAUSE_ERROR) |
367 | && (!prec && ((hx & 0x7fffffff) < 0x00800000 | 312 | && (!prec && ((hx & 0x7fffffff) < 0x00800000 |
368 | || (hy & 0x7fffffff) < 0x00800000))) { | 313 | || (hy & 0x7fffffff) < 0x00800000))) { |
@@ -371,7 +316,7 @@ static int ieee_fpe_handler(struct pt_regs *regs) | |||
371 | hx = float32_add(hx, hy); | 316 | hx = float32_add(hx, hy); |
372 | else | 317 | else |
373 | hx = float32_sub(hx, hy); | 318 | hx = float32_sub(hx, hy); |
374 | tsk->thread.fpu.hard.fp_regs[n] = hx; | 319 | tsk->thread.xstate->hardfpu.fp_regs[n] = hx; |
375 | } else | 320 | } else |
376 | return 0; | 321 | return 0; |
377 | 322 | ||
@@ -386,9 +331,9 @@ static int ieee_fpe_handler(struct pt_regs *regs) | |||
386 | 331 | ||
387 | n = (finsn >> 8) & 0xf; | 332 | n = (finsn >> 8) & 0xf; |
388 | m = (finsn >> 4) & 0xf; | 333 | m = (finsn >> 4) & 0xf; |
389 | hx = tsk->thread.fpu.hard.fp_regs[n]; | 334 | hx = tsk->thread.xstate->hardfpu.fp_regs[n]; |
390 | hy = tsk->thread.fpu.hard.fp_regs[m]; | 335 | hy = tsk->thread.xstate->hardfpu.fp_regs[m]; |
391 | fpscr = tsk->thread.fpu.hard.fpscr; | 336 | fpscr = tsk->thread.xstate->hardfpu.fpscr; |
392 | prec = fpscr & FPSCR_DBL_PRECISION; | 337 | prec = fpscr & FPSCR_DBL_PRECISION; |
393 | 338 | ||
394 | if ((fpscr & FPSCR_CAUSE_ERROR) | 339 | if ((fpscr & FPSCR_CAUSE_ERROR) |
@@ -398,20 +343,20 @@ static int ieee_fpe_handler(struct pt_regs *regs) | |||
398 | 343 | ||
399 | /* FPU error because of denormal (doubles) */ | 344 | /* FPU error because of denormal (doubles) */ |
400 | llx = ((long long)hx << 32) | 345 | llx = ((long long)hx << 32) |
401 | | tsk->thread.fpu.hard.fp_regs[n + 1]; | 346 | | tsk->thread.xstate->hardfpu.fp_regs[n + 1]; |
402 | lly = ((long long)hy << 32) | 347 | lly = ((long long)hy << 32) |
403 | | tsk->thread.fpu.hard.fp_regs[m + 1]; | 348 | | tsk->thread.xstate->hardfpu.fp_regs[m + 1]; |
404 | 349 | ||
405 | llx = float64_div(llx, lly); | 350 | llx = float64_div(llx, lly); |
406 | 351 | ||
407 | tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; | 352 | tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32; |
408 | tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff; | 353 | tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff; |
409 | } else if ((fpscr & FPSCR_CAUSE_ERROR) | 354 | } else if ((fpscr & FPSCR_CAUSE_ERROR) |
410 | && (!prec && ((hx & 0x7fffffff) < 0x00800000 | 355 | && (!prec && ((hx & 0x7fffffff) < 0x00800000 |
411 | || (hy & 0x7fffffff) < 0x00800000))) { | 356 | || (hy & 0x7fffffff) < 0x00800000))) { |
412 | /* FPU error because of denormal (floats) */ | 357 | /* FPU error because of denormal (floats) */ |
413 | hx = float32_div(hx, hy); | 358 | hx = float32_div(hx, hy); |
414 | tsk->thread.fpu.hard.fp_regs[n] = hx; | 359 | tsk->thread.xstate->hardfpu.fp_regs[n] = hx; |
415 | } else | 360 | } else |
416 | return 0; | 361 | return 0; |
417 | 362 | ||
@@ -424,17 +369,17 @@ static int ieee_fpe_handler(struct pt_regs *regs) | |||
424 | unsigned int hx; | 369 | unsigned int hx; |
425 | 370 | ||
426 | m = (finsn >> 8) & 0x7; | 371 | m = (finsn >> 8) & 0x7; |
427 | hx = tsk->thread.fpu.hard.fp_regs[m]; | 372 | hx = tsk->thread.xstate->hardfpu.fp_regs[m]; |
428 | 373 | ||
429 | if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR) | 374 | if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_CAUSE_ERROR) |
430 | && ((hx & 0x7fffffff) < 0x00100000)) { | 375 | && ((hx & 0x7fffffff) < 0x00100000)) { |
431 | /* subnormal double to float conversion */ | 376 | /* subnormal double to float conversion */ |
432 | long long llx; | 377 | long long llx; |
433 | 378 | ||
434 | llx = ((long long)tsk->thread.fpu.hard.fp_regs[m] << 32) | 379 | llx = ((long long)tsk->thread.xstate->hardfpu.fp_regs[m] << 32) |
435 | | tsk->thread.fpu.hard.fp_regs[m + 1]; | 380 | | tsk->thread.xstate->hardfpu.fp_regs[m + 1]; |
436 | 381 | ||
437 | tsk->thread.fpu.hard.fpul = float64_to_float32(llx); | 382 | tsk->thread.xstate->hardfpu.fpul = float64_to_float32(llx); |
438 | } else | 383 | } else |
439 | return 0; | 384 | return 0; |
440 | 385 | ||
@@ -453,7 +398,7 @@ void float_raise(unsigned int flags) | |||
453 | int float_rounding_mode(void) | 398 | int float_rounding_mode(void) |
454 | { | 399 | { |
455 | struct task_struct *tsk = current; | 400 | struct task_struct *tsk = current; |
456 | int roundingMode = FPSCR_ROUNDING_MODE(tsk->thread.fpu.hard.fpscr); | 401 | int roundingMode = FPSCR_ROUNDING_MODE(tsk->thread.xstate->hardfpu.fpscr); |
457 | return roundingMode; | 402 | return roundingMode; |
458 | } | 403 | } |
459 | 404 | ||
@@ -462,19 +407,19 @@ BUILD_TRAP_HANDLER(fpu_error) | |||
462 | struct task_struct *tsk = current; | 407 | struct task_struct *tsk = current; |
463 | TRAP_HANDLER_DECL; | 408 | TRAP_HANDLER_DECL; |
464 | 409 | ||
465 | save_fpu(tsk, regs); | 410 | __unlazy_fpu(tsk, regs); |
466 | fpu_exception_flags = 0; | 411 | fpu_exception_flags = 0; |
467 | if (ieee_fpe_handler(regs)) { | 412 | if (ieee_fpe_handler(regs)) { |
468 | tsk->thread.fpu.hard.fpscr &= | 413 | tsk->thread.xstate->hardfpu.fpscr &= |
469 | ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); | 414 | ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); |
470 | tsk->thread.fpu.hard.fpscr |= fpu_exception_flags; | 415 | tsk->thread.xstate->hardfpu.fpscr |= fpu_exception_flags; |
471 | /* Set the FPSCR flag as well as cause bits - simply | 416 | /* Set the FPSCR flag as well as cause bits - simply |
472 | * replicate the cause */ | 417 | * replicate the cause */ |
473 | tsk->thread.fpu.hard.fpscr |= (fpu_exception_flags >> 10); | 418 | tsk->thread.xstate->hardfpu.fpscr |= (fpu_exception_flags >> 10); |
474 | grab_fpu(regs); | 419 | grab_fpu(regs); |
475 | restore_fpu(tsk); | 420 | restore_fpu(tsk); |
476 | set_tsk_thread_flag(tsk, TIF_USEDFPU); | 421 | task_thread_info(tsk)->status |= TS_USEDFPU; |
477 | if ((((tsk->thread.fpu.hard.fpscr & FPSCR_ENABLE_MASK) >> 7) & | 422 | if ((((tsk->thread.xstate->hardfpu.fpscr & FPSCR_ENABLE_MASK) >> 7) & |
478 | (fpu_exception_flags >> 2)) == 0) { | 423 | (fpu_exception_flags >> 2)) == 0) { |
479 | return; | 424 | return; |
480 | } | 425 | } |
@@ -482,25 +427,3 @@ BUILD_TRAP_HANDLER(fpu_error) | |||
482 | 427 | ||
483 | force_sig(SIGFPE, tsk); | 428 | force_sig(SIGFPE, tsk); |
484 | } | 429 | } |
485 | |||
486 | BUILD_TRAP_HANDLER(fpu_state_restore) | ||
487 | { | ||
488 | struct task_struct *tsk = current; | ||
489 | TRAP_HANDLER_DECL; | ||
490 | |||
491 | grab_fpu(regs); | ||
492 | if (!user_mode(regs)) { | ||
493 | printk(KERN_ERR "BUG: FPU is used in kernel mode.\n"); | ||
494 | return; | ||
495 | } | ||
496 | |||
497 | if (used_math()) { | ||
498 | /* Using the FPU again. */ | ||
499 | restore_fpu(tsk); | ||
500 | } else { | ||
501 | /* First time FPU user. */ | ||
502 | fpu_init(); | ||
503 | set_used_math(); | ||
504 | } | ||
505 | set_tsk_thread_flag(tsk, TIF_USEDFPU); | ||
506 | } | ||
diff --git a/arch/sh/kernel/cpu/sh4/perf_event.c b/arch/sh/kernel/cpu/sh4/perf_event.c new file mode 100644 index 000000000000..748955df018d --- /dev/null +++ b/arch/sh/kernel/cpu/sh4/perf_event.c | |||
@@ -0,0 +1,253 @@ | |||
1 | /* | ||
2 | * Performance events support for SH7750-style performance counters | ||
3 | * | ||
4 | * Copyright (C) 2009 Paul Mundt | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/io.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/perf_event.h> | ||
15 | #include <asm/processor.h> | ||
16 | |||
17 | #define PM_CR_BASE 0xff000084 /* 16-bit */ | ||
18 | #define PM_CTR_BASE 0xff100004 /* 32-bit */ | ||
19 | |||
20 | #define PMCR(n) (PM_CR_BASE + ((n) * 0x04)) | ||
21 | #define PMCTRH(n) (PM_CTR_BASE + 0x00 + ((n) * 0x08)) | ||
22 | #define PMCTRL(n) (PM_CTR_BASE + 0x04 + ((n) * 0x08)) | ||
23 | |||
24 | #define PMCR_PMM_MASK 0x0000003f | ||
25 | |||
26 | #define PMCR_CLKF 0x00000100 | ||
27 | #define PMCR_PMCLR 0x00002000 | ||
28 | #define PMCR_PMST 0x00004000 | ||
29 | #define PMCR_PMEN 0x00008000 | ||
30 | |||
31 | static struct sh_pmu sh7750_pmu; | ||
32 | |||
33 | /* | ||
34 | * There are a number of events supported by each counter (33 in total). | ||
35 | * Since we have 2 counters, each counter will take the event code as it | ||
36 | * corresponds to the PMCR PMM setting. Each counter can be configured | ||
37 | * independently. | ||
38 | * | ||
39 | * Event Code Description | ||
40 | * ---------- ----------- | ||
41 | * | ||
42 | * 0x01 Operand read access | ||
43 | * 0x02 Operand write access | ||
44 | * 0x03 UTLB miss | ||
45 | * 0x04 Operand cache read miss | ||
46 | * 0x05 Operand cache write miss | ||
47 | * 0x06 Instruction fetch (w/ cache) | ||
48 | * 0x07 Instruction TLB miss | ||
49 | * 0x08 Instruction cache miss | ||
50 | * 0x09 All operand accesses | ||
51 | * 0x0a All instruction accesses | ||
52 | * 0x0b OC RAM operand access | ||
53 | * 0x0d On-chip I/O space access | ||
54 | * 0x0e Operand access (r/w) | ||
55 | * 0x0f Operand cache miss (r/w) | ||
56 | * 0x10 Branch instruction | ||
57 | * 0x11 Branch taken | ||
58 | * 0x12 BSR/BSRF/JSR | ||
59 | * 0x13 Instruction execution | ||
60 | * 0x14 Instruction execution in parallel | ||
61 | * 0x15 FPU Instruction execution | ||
62 | * 0x16 Interrupt | ||
63 | * 0x17 NMI | ||
64 | * 0x18 trapa instruction execution | ||
65 | * 0x19 UBCA match | ||
66 | * 0x1a UBCB match | ||
67 | * 0x21 Instruction cache fill | ||
68 | * 0x22 Operand cache fill | ||
69 | * 0x23 Elapsed time | ||
70 | * 0x24 Pipeline freeze by I-cache miss | ||
71 | * 0x25 Pipeline freeze by D-cache miss | ||
72 | * 0x27 Pipeline freeze by branch instruction | ||
73 | * 0x28 Pipeline freeze by CPU register | ||
74 | * 0x29 Pipeline freeze by FPU | ||
75 | */ | ||
76 | |||
77 | static const int sh7750_general_events[] = { | ||
78 | [PERF_COUNT_HW_CPU_CYCLES] = 0x0023, | ||
79 | [PERF_COUNT_HW_INSTRUCTIONS] = 0x000a, | ||
80 | [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0006, /* I-cache */ | ||
81 | [PERF_COUNT_HW_CACHE_MISSES] = 0x0008, /* I-cache */ | ||
82 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x0010, | ||
83 | [PERF_COUNT_HW_BRANCH_MISSES] = -1, | ||
84 | [PERF_COUNT_HW_BUS_CYCLES] = -1, | ||
85 | }; | ||
86 | |||
87 | #define C(x) PERF_COUNT_HW_CACHE_##x | ||
88 | |||
89 | static const int sh7750_cache_events | ||
90 | [PERF_COUNT_HW_CACHE_MAX] | ||
91 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
92 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = | ||
93 | { | ||
94 | [ C(L1D) ] = { | ||
95 | [ C(OP_READ) ] = { | ||
96 | [ C(RESULT_ACCESS) ] = 0x0001, | ||
97 | [ C(RESULT_MISS) ] = 0x0004, | ||
98 | }, | ||
99 | [ C(OP_WRITE) ] = { | ||
100 | [ C(RESULT_ACCESS) ] = 0x0002, | ||
101 | [ C(RESULT_MISS) ] = 0x0005, | ||
102 | }, | ||
103 | [ C(OP_PREFETCH) ] = { | ||
104 | [ C(RESULT_ACCESS) ] = 0, | ||
105 | [ C(RESULT_MISS) ] = 0, | ||
106 | }, | ||
107 | }, | ||
108 | |||
109 | [ C(L1I) ] = { | ||
110 | [ C(OP_READ) ] = { | ||
111 | [ C(RESULT_ACCESS) ] = 0x0006, | ||
112 | [ C(RESULT_MISS) ] = 0x0008, | ||
113 | }, | ||
114 | [ C(OP_WRITE) ] = { | ||
115 | [ C(RESULT_ACCESS) ] = -1, | ||
116 | [ C(RESULT_MISS) ] = -1, | ||
117 | }, | ||
118 | [ C(OP_PREFETCH) ] = { | ||
119 | [ C(RESULT_ACCESS) ] = 0, | ||
120 | [ C(RESULT_MISS) ] = 0, | ||
121 | }, | ||
122 | }, | ||
123 | |||
124 | [ C(LL) ] = { | ||
125 | [ C(OP_READ) ] = { | ||
126 | [ C(RESULT_ACCESS) ] = 0, | ||
127 | [ C(RESULT_MISS) ] = 0, | ||
128 | }, | ||
129 | [ C(OP_WRITE) ] = { | ||
130 | [ C(RESULT_ACCESS) ] = 0, | ||
131 | [ C(RESULT_MISS) ] = 0, | ||
132 | }, | ||
133 | [ C(OP_PREFETCH) ] = { | ||
134 | [ C(RESULT_ACCESS) ] = 0, | ||
135 | [ C(RESULT_MISS) ] = 0, | ||
136 | }, | ||
137 | }, | ||
138 | |||
139 | [ C(DTLB) ] = { | ||
140 | [ C(OP_READ) ] = { | ||
141 | [ C(RESULT_ACCESS) ] = 0, | ||
142 | [ C(RESULT_MISS) ] = 0x0003, | ||
143 | }, | ||
144 | [ C(OP_WRITE) ] = { | ||
145 | [ C(RESULT_ACCESS) ] = 0, | ||
146 | [ C(RESULT_MISS) ] = 0, | ||
147 | }, | ||
148 | [ C(OP_PREFETCH) ] = { | ||
149 | [ C(RESULT_ACCESS) ] = 0, | ||
150 | [ C(RESULT_MISS) ] = 0, | ||
151 | }, | ||
152 | }, | ||
153 | |||
154 | [ C(ITLB) ] = { | ||
155 | [ C(OP_READ) ] = { | ||
156 | [ C(RESULT_ACCESS) ] = 0, | ||
157 | [ C(RESULT_MISS) ] = 0x0007, | ||
158 | }, | ||
159 | [ C(OP_WRITE) ] = { | ||
160 | [ C(RESULT_ACCESS) ] = -1, | ||
161 | [ C(RESULT_MISS) ] = -1, | ||
162 | }, | ||
163 | [ C(OP_PREFETCH) ] = { | ||
164 | [ C(RESULT_ACCESS) ] = -1, | ||
165 | [ C(RESULT_MISS) ] = -1, | ||
166 | }, | ||
167 | }, | ||
168 | |||
169 | [ C(BPU) ] = { | ||
170 | [ C(OP_READ) ] = { | ||
171 | [ C(RESULT_ACCESS) ] = -1, | ||
172 | [ C(RESULT_MISS) ] = -1, | ||
173 | }, | ||
174 | [ C(OP_WRITE) ] = { | ||
175 | [ C(RESULT_ACCESS) ] = -1, | ||
176 | [ C(RESULT_MISS) ] = -1, | ||
177 | }, | ||
178 | [ C(OP_PREFETCH) ] = { | ||
179 | [ C(RESULT_ACCESS) ] = -1, | ||
180 | [ C(RESULT_MISS) ] = -1, | ||
181 | }, | ||
182 | }, | ||
183 | }; | ||
184 | |||
185 | static int sh7750_event_map(int event) | ||
186 | { | ||
187 | return sh7750_general_events[event]; | ||
188 | } | ||
189 | |||
190 | static u64 sh7750_pmu_read(int idx) | ||
191 | { | ||
192 | return (u64)((u64)(__raw_readl(PMCTRH(idx)) & 0xffff) << 32) | | ||
193 | __raw_readl(PMCTRL(idx)); | ||
194 | } | ||
195 | |||
196 | static void sh7750_pmu_disable(struct hw_perf_event *hwc, int idx) | ||
197 | { | ||
198 | unsigned int tmp; | ||
199 | |||
200 | tmp = __raw_readw(PMCR(idx)); | ||
201 | tmp &= ~(PMCR_PMM_MASK | PMCR_PMEN); | ||
202 | __raw_writew(tmp, PMCR(idx)); | ||
203 | } | ||
204 | |||
205 | static void sh7750_pmu_enable(struct hw_perf_event *hwc, int idx) | ||
206 | { | ||
207 | __raw_writew(__raw_readw(PMCR(idx)) | PMCR_PMCLR, PMCR(idx)); | ||
208 | __raw_writew(hwc->config | PMCR_PMEN | PMCR_PMST, PMCR(idx)); | ||
209 | } | ||
210 | |||
211 | static void sh7750_pmu_disable_all(void) | ||
212 | { | ||
213 | int i; | ||
214 | |||
215 | for (i = 0; i < sh7750_pmu.num_events; i++) | ||
216 | __raw_writew(__raw_readw(PMCR(i)) & ~PMCR_PMEN, PMCR(i)); | ||
217 | } | ||
218 | |||
219 | static void sh7750_pmu_enable_all(void) | ||
220 | { | ||
221 | int i; | ||
222 | |||
223 | for (i = 0; i < sh7750_pmu.num_events; i++) | ||
224 | __raw_writew(__raw_readw(PMCR(i)) | PMCR_PMEN, PMCR(i)); | ||
225 | } | ||
226 | |||
227 | static struct sh_pmu sh7750_pmu = { | ||
228 | .name = "sh7750", | ||
229 | .num_events = 2, | ||
230 | .event_map = sh7750_event_map, | ||
231 | .max_events = ARRAY_SIZE(sh7750_general_events), | ||
232 | .raw_event_mask = PMCR_PMM_MASK, | ||
233 | .cache_events = &sh7750_cache_events, | ||
234 | .read = sh7750_pmu_read, | ||
235 | .disable = sh7750_pmu_disable, | ||
236 | .enable = sh7750_pmu_enable, | ||
237 | .disable_all = sh7750_pmu_disable_all, | ||
238 | .enable_all = sh7750_pmu_enable_all, | ||
239 | }; | ||
240 | |||
241 | static int __init sh7750_pmu_init(void) | ||
242 | { | ||
243 | /* | ||
244 | * Make sure this CPU actually has perf counters. | ||
245 | */ | ||
246 | if (!(boot_cpu_data.flags & CPU_HAS_PERF_COUNTER)) { | ||
247 | pr_notice("HW perf events unsupported, software events only.\n"); | ||
248 | return -ENODEV; | ||
249 | } | ||
250 | |||
251 | return register_sh_pmu(&sh7750_pmu); | ||
252 | } | ||
253 | early_initcall(sh7750_pmu_init); | ||
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index 6c78d0a9c857..b93458f33b74 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
16 | #include <asm/cache.h> | 16 | #include <asm/cache.h> |
17 | 17 | ||
18 | int __init detect_cpu_and_cache_system(void) | 18 | void __cpuinit cpu_probe(void) |
19 | { | 19 | { |
20 | unsigned long pvr, prr, cvr; | 20 | unsigned long pvr, prr, cvr; |
21 | unsigned long size; | 21 | unsigned long size; |
@@ -28,9 +28,9 @@ int __init detect_cpu_and_cache_system(void) | |||
28 | [9] = (1 << 16) | 28 | [9] = (1 << 16) |
29 | }; | 29 | }; |
30 | 30 | ||
31 | pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffffff; | 31 | pvr = (__raw_readl(CCN_PVR) >> 8) & 0xffffff; |
32 | prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff; | 32 | prr = (__raw_readl(CCN_PRR) >> 4) & 0xff; |
33 | cvr = (ctrl_inl(CCN_CVR)); | 33 | cvr = (__raw_readl(CCN_CVR)); |
34 | 34 | ||
35 | /* | 35 | /* |
36 | * Setup some sane SH-4 defaults for the icache | 36 | * Setup some sane SH-4 defaults for the icache |
@@ -57,8 +57,12 @@ int __init detect_cpu_and_cache_system(void) | |||
57 | * Setup some generic flags we can probe on SH-4A parts | 57 | * Setup some generic flags we can probe on SH-4A parts |
58 | */ | 58 | */ |
59 | if (((pvr >> 16) & 0xff) == 0x10) { | 59 | if (((pvr >> 16) & 0xff) == 0x10) { |
60 | if ((cvr & 0x10000000) == 0) | 60 | boot_cpu_data.family = CPU_FAMILY_SH4A; |
61 | |||
62 | if ((cvr & 0x10000000) == 0) { | ||
61 | boot_cpu_data.flags |= CPU_HAS_DSP; | 63 | boot_cpu_data.flags |= CPU_HAS_DSP; |
64 | boot_cpu_data.family = CPU_FAMILY_SH4AL_DSP; | ||
65 | } | ||
62 | 66 | ||
63 | boot_cpu_data.flags |= CPU_HAS_LLSC | CPU_HAS_PERF_COUNTER; | 67 | boot_cpu_data.flags |= CPU_HAS_LLSC | CPU_HAS_PERF_COUNTER; |
64 | boot_cpu_data.cut_major = pvr & 0x7f; | 68 | boot_cpu_data.cut_major = pvr & 0x7f; |
@@ -67,10 +71,11 @@ int __init detect_cpu_and_cache_system(void) | |||
67 | boot_cpu_data.dcache.ways = 4; | 71 | boot_cpu_data.dcache.ways = 4; |
68 | } else { | 72 | } else { |
69 | /* And some SH-4 defaults.. */ | 73 | /* And some SH-4 defaults.. */ |
70 | boot_cpu_data.flags |= CPU_HAS_PTEA; | 74 | boot_cpu_data.flags |= CPU_HAS_PTEA | CPU_HAS_FPU; |
75 | boot_cpu_data.family = CPU_FAMILY_SH4; | ||
71 | } | 76 | } |
72 | 77 | ||
73 | /* FPU detection works for everyone */ | 78 | /* FPU detection works for almost everyone */ |
74 | if ((cvr & 0x20000000)) | 79 | if ((cvr & 0x20000000)) |
75 | boot_cpu_data.flags |= CPU_HAS_FPU; | 80 | boot_cpu_data.flags |= CPU_HAS_FPU; |
76 | 81 | ||
@@ -119,6 +124,7 @@ int __init detect_cpu_and_cache_system(void) | |||
119 | boot_cpu_data.type = CPU_SH7785; | 124 | boot_cpu_data.type = CPU_SH7785; |
120 | break; | 125 | break; |
121 | case 0x4004: | 126 | case 0x4004: |
127 | case 0x4005: | ||
122 | boot_cpu_data.type = CPU_SH7786; | 128 | boot_cpu_data.type = CPU_SH7786; |
123 | boot_cpu_data.flags |= CPU_HAS_PTEAEX | CPU_HAS_L2_CACHE; | 129 | boot_cpu_data.flags |= CPU_HAS_PTEAEX | CPU_HAS_L2_CACHE; |
124 | break; | 130 | break; |
@@ -139,8 +145,15 @@ int __init detect_cpu_and_cache_system(void) | |||
139 | } | 145 | } |
140 | break; | 146 | break; |
141 | case 0x300b: | 147 | case 0x300b: |
142 | boot_cpu_data.type = CPU_SH7724; | 148 | switch (prr) { |
143 | boot_cpu_data.flags |= CPU_HAS_L2_CACHE; | 149 | case 0x20: |
150 | boot_cpu_data.type = CPU_SH7724; | ||
151 | boot_cpu_data.flags |= CPU_HAS_L2_CACHE; | ||
152 | break; | ||
153 | case 0x10: | ||
154 | boot_cpu_data.type = CPU_SH7757; | ||
155 | break; | ||
156 | } | ||
144 | break; | 157 | break; |
145 | case 0x4000: /* 1st cut */ | 158 | case 0x4000: /* 1st cut */ |
146 | case 0x4001: /* 2nd cut */ | 159 | case 0x4001: /* 2nd cut */ |
@@ -148,6 +161,7 @@ int __init detect_cpu_and_cache_system(void) | |||
148 | break; | 161 | break; |
149 | case 0x700: | 162 | case 0x700: |
150 | boot_cpu_data.type = CPU_SH4_501; | 163 | boot_cpu_data.type = CPU_SH4_501; |
164 | boot_cpu_data.flags &= ~CPU_HAS_FPU; | ||
151 | boot_cpu_data.icache.ways = 2; | 165 | boot_cpu_data.icache.ways = 2; |
152 | boot_cpu_data.dcache.ways = 2; | 166 | boot_cpu_data.dcache.ways = 2; |
153 | break; | 167 | break; |
@@ -173,9 +187,6 @@ int __init detect_cpu_and_cache_system(void) | |||
173 | boot_cpu_data.dcache.ways = 2; | 187 | boot_cpu_data.dcache.ways = 2; |
174 | 188 | ||
175 | break; | 189 | break; |
176 | default: | ||
177 | boot_cpu_data.type = CPU_SH_NONE; | ||
178 | break; | ||
179 | } | 190 | } |
180 | 191 | ||
181 | /* | 192 | /* |
@@ -218,7 +229,7 @@ int __init detect_cpu_and_cache_system(void) | |||
218 | * Size calculation is much more sensible | 229 | * Size calculation is much more sensible |
219 | * than it is for the L1. | 230 | * than it is for the L1. |
220 | * | 231 | * |
221 | * Sizes are 128KB, 258KB, 512KB, and 1MB. | 232 | * Sizes are 128KB, 256KB, 512KB, and 1MB. |
222 | */ | 233 | */ |
223 | size = (cvr & 0xf) << 17; | 234 | size = (cvr & 0xf) << 17; |
224 | 235 | ||
@@ -240,6 +251,4 @@ int __init detect_cpu_and_cache_system(void) | |||
240 | boot_cpu_data.scache.linesz); | 251 | boot_cpu_data.scache.linesz); |
241 | } | 252 | } |
242 | } | 253 | } |
243 | |||
244 | return 0; | ||
245 | } | 254 | } |
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index ec2104b49ef7..5b2833159b7d 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c | |||
@@ -15,38 +15,31 @@ | |||
15 | #include <linux/sh_timer.h> | 15 | #include <linux/sh_timer.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | 17 | ||
18 | static struct plat_sci_port sci_platform_data[] = { | 18 | static struct plat_sci_port scif0_platform_data = { |
19 | { | 19 | .mapbase = 0xffe80000, |
20 | .mapbase = 0xffe80000, | 20 | .flags = UPF_BOOT_AUTOCONF, |
21 | .flags = UPF_BOOT_AUTOCONF, | 21 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, |
22 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | 22 | .scbrr_algo_id = SCBRR_ALGO_2, |
23 | .scbrr_algo_id = SCBRR_ALGO_2, | 23 | .type = PORT_SCIF, |
24 | .type = PORT_SCIF, | 24 | .irqs = { 40, 41, 43, 42 }, |
25 | .irqs = { 40, 41, 43, 42 }, | ||
26 | }, { | ||
27 | .flags = 0, | ||
28 | } | ||
29 | }; | 25 | }; |
30 | 26 | ||
31 | static struct platform_device sci_device = { | 27 | static struct platform_device scif0_device = { |
32 | .name = "sh-sci", | 28 | .name = "sh-sci", |
33 | .id = -1, | 29 | .id = 0, |
34 | .dev = { | 30 | .dev = { |
35 | .platform_data = sci_platform_data, | 31 | .platform_data = &scif0_platform_data, |
36 | }, | 32 | }, |
37 | }; | 33 | }; |
38 | 34 | ||
39 | static struct sh_timer_config tmu0_platform_data = { | 35 | static struct sh_timer_config tmu0_platform_data = { |
40 | .name = "TMU0", | ||
41 | .channel_offset = 0x04, | 36 | .channel_offset = 0x04, |
42 | .timer_bit = 0, | 37 | .timer_bit = 0, |
43 | .clk = "peripheral_clk", | ||
44 | .clockevent_rating = 200, | 38 | .clockevent_rating = 200, |
45 | }; | 39 | }; |
46 | 40 | ||
47 | static struct resource tmu0_resources[] = { | 41 | static struct resource tmu0_resources[] = { |
48 | [0] = { | 42 | [0] = { |
49 | .name = "TMU0", | ||
50 | .start = 0xffd80008, | 43 | .start = 0xffd80008, |
51 | .end = 0xffd80013, | 44 | .end = 0xffd80013, |
52 | .flags = IORESOURCE_MEM, | 45 | .flags = IORESOURCE_MEM, |
@@ -68,16 +61,13 @@ static struct platform_device tmu0_device = { | |||
68 | }; | 61 | }; |
69 | 62 | ||
70 | static struct sh_timer_config tmu1_platform_data = { | 63 | static struct sh_timer_config tmu1_platform_data = { |
71 | .name = "TMU1", | ||
72 | .channel_offset = 0x10, | 64 | .channel_offset = 0x10, |
73 | .timer_bit = 1, | 65 | .timer_bit = 1, |
74 | .clk = "peripheral_clk", | ||
75 | .clocksource_rating = 200, | 66 | .clocksource_rating = 200, |
76 | }; | 67 | }; |
77 | 68 | ||
78 | static struct resource tmu1_resources[] = { | 69 | static struct resource tmu1_resources[] = { |
79 | [0] = { | 70 | [0] = { |
80 | .name = "TMU1", | ||
81 | .start = 0xffd80014, | 71 | .start = 0xffd80014, |
82 | .end = 0xffd8001f, | 72 | .end = 0xffd8001f, |
83 | .flags = IORESOURCE_MEM, | 73 | .flags = IORESOURCE_MEM, |
@@ -99,15 +89,12 @@ static struct platform_device tmu1_device = { | |||
99 | }; | 89 | }; |
100 | 90 | ||
101 | static struct sh_timer_config tmu2_platform_data = { | 91 | static struct sh_timer_config tmu2_platform_data = { |
102 | .name = "TMU2", | ||
103 | .channel_offset = 0x1c, | 92 | .channel_offset = 0x1c, |
104 | .timer_bit = 2, | 93 | .timer_bit = 2, |
105 | .clk = "peripheral_clk", | ||
106 | }; | 94 | }; |
107 | 95 | ||
108 | static struct resource tmu2_resources[] = { | 96 | static struct resource tmu2_resources[] = { |
109 | [0] = { | 97 | [0] = { |
110 | .name = "TMU2", | ||
111 | .start = 0xffd80020, | 98 | .start = 0xffd80020, |
112 | .end = 0xffd8002f, | 99 | .end = 0xffd8002f, |
113 | .flags = IORESOURCE_MEM, | 100 | .flags = IORESOURCE_MEM, |
@@ -129,7 +116,7 @@ static struct platform_device tmu2_device = { | |||
129 | }; | 116 | }; |
130 | 117 | ||
131 | static struct platform_device *sh4202_devices[] __initdata = { | 118 | static struct platform_device *sh4202_devices[] __initdata = { |
132 | &sci_device, | 119 | &scif0_device, |
133 | &tmu0_device, | 120 | &tmu0_device, |
134 | &tmu1_device, | 121 | &tmu1_device, |
135 | &tmu2_device, | 122 | &tmu2_device, |
@@ -140,9 +127,10 @@ static int __init sh4202_devices_setup(void) | |||
140 | return platform_add_devices(sh4202_devices, | 127 | return platform_add_devices(sh4202_devices, |
141 | ARRAY_SIZE(sh4202_devices)); | 128 | ARRAY_SIZE(sh4202_devices)); |
142 | } | 129 | } |
143 | __initcall(sh4202_devices_setup); | 130 | arch_initcall(sh4202_devices_setup); |
144 | 131 | ||
145 | static struct platform_device *sh4202_early_devices[] __initdata = { | 132 | static struct platform_device *sh4202_early_devices[] __initdata = { |
133 | &scif0_device, | ||
146 | &tmu0_device, | 134 | &tmu0_device, |
147 | &tmu1_device, | 135 | &tmu1_device, |
148 | &tmu2_device, | 136 | &tmu2_device, |
@@ -203,7 +191,7 @@ void __init plat_irq_setup_pins(int mode) | |||
203 | { | 191 | { |
204 | switch (mode) { | 192 | switch (mode) { |
205 | case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */ | 193 | case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */ |
206 | ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); | 194 | __raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); |
207 | register_intc_controller(&intc_desc_irlm); | 195 | register_intc_controller(&intc_desc_irlm); |
208 | break; | 196 | break; |
209 | default: | 197 | default: |
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 51a945e0d72c..c2b0aaaedcae 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c | |||
@@ -39,16 +39,17 @@ static struct platform_device rtc_device = { | |||
39 | static struct plat_sci_port sci_platform_data = { | 39 | static struct plat_sci_port sci_platform_data = { |
40 | .mapbase = 0xffe00000, | 40 | .mapbase = 0xffe00000, |
41 | .flags = UPF_BOOT_AUTOCONF, | 41 | .flags = UPF_BOOT_AUTOCONF, |
42 | .type = PORT_SCI, | ||
43 | .scscr = SCSCR_TE | SCSCR_RE, | 42 | .scscr = SCSCR_TE | SCSCR_RE, |
44 | .scbrr_algo_id = SCBRR_ALGO_2, | 43 | .scbrr_algo_id = SCBRR_ALGO_2, |
44 | .type = PORT_SCI, | ||
45 | .irqs = { 23, 23, 23, 0 }, | 45 | .irqs = { 23, 23, 23, 0 }, |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static struct platform_device sci_device = { | 48 | static struct platform_device sci_device = { |
49 | .name = "sh-sci", | 49 | .name = "sh-sci", |
50 | .id = 0, | ||
50 | .dev = { | 51 | .dev = { |
51 | .platform_data = sci_platform_data, | 52 | .platform_data = &sci_platform_data, |
52 | }, | 53 | }, |
53 | }; | 54 | }; |
54 | 55 | ||
@@ -63,22 +64,20 @@ static struct plat_sci_port scif_platform_data = { | |||
63 | 64 | ||
64 | static struct platform_device scif_device = { | 65 | static struct platform_device scif_device = { |
65 | .name = "sh-sci", | 66 | .name = "sh-sci", |
67 | .id = 1, | ||
66 | .dev = { | 68 | .dev = { |
67 | .platform_data = scif_platform_data, | 69 | .platform_data = &scif_platform_data, |
68 | }, | 70 | }, |
69 | }; | 71 | }; |
70 | 72 | ||
71 | static struct sh_timer_config tmu0_platform_data = { | 73 | static struct sh_timer_config tmu0_platform_data = { |
72 | .name = "TMU0", | ||
73 | .channel_offset = 0x04, | 74 | .channel_offset = 0x04, |
74 | .timer_bit = 0, | 75 | .timer_bit = 0, |
75 | .clk = "peripheral_clk", | ||
76 | .clockevent_rating = 200, | 76 | .clockevent_rating = 200, |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static struct resource tmu0_resources[] = { | 79 | static struct resource tmu0_resources[] = { |
80 | [0] = { | 80 | [0] = { |
81 | .name = "TMU0", | ||
82 | .start = 0xffd80008, | 81 | .start = 0xffd80008, |
83 | .end = 0xffd80013, | 82 | .end = 0xffd80013, |
84 | .flags = IORESOURCE_MEM, | 83 | .flags = IORESOURCE_MEM, |
@@ -100,16 +99,13 @@ static struct platform_device tmu0_device = { | |||
100 | }; | 99 | }; |
101 | 100 | ||
102 | static struct sh_timer_config tmu1_platform_data = { | 101 | static struct sh_timer_config tmu1_platform_data = { |
103 | .name = "TMU1", | ||
104 | .channel_offset = 0x10, | 102 | .channel_offset = 0x10, |
105 | .timer_bit = 1, | 103 | .timer_bit = 1, |
106 | .clk = "peripheral_clk", | ||
107 | .clocksource_rating = 200, | 104 | .clocksource_rating = 200, |
108 | }; | 105 | }; |
109 | 106 | ||
110 | static struct resource tmu1_resources[] = { | 107 | static struct resource tmu1_resources[] = { |
111 | [0] = { | 108 | [0] = { |
112 | .name = "TMU1", | ||
113 | .start = 0xffd80014, | 109 | .start = 0xffd80014, |
114 | .end = 0xffd8001f, | 110 | .end = 0xffd8001f, |
115 | .flags = IORESOURCE_MEM, | 111 | .flags = IORESOURCE_MEM, |
@@ -131,15 +127,12 @@ static struct platform_device tmu1_device = { | |||
131 | }; | 127 | }; |
132 | 128 | ||
133 | static struct sh_timer_config tmu2_platform_data = { | 129 | static struct sh_timer_config tmu2_platform_data = { |
134 | .name = "TMU2", | ||
135 | .channel_offset = 0x1c, | 130 | .channel_offset = 0x1c, |
136 | .timer_bit = 2, | 131 | .timer_bit = 2, |
137 | .clk = "peripheral_clk", | ||
138 | }; | 132 | }; |
139 | 133 | ||
140 | static struct resource tmu2_resources[] = { | 134 | static struct resource tmu2_resources[] = { |
141 | [0] = { | 135 | [0] = { |
142 | .name = "TMU2", | ||
143 | .start = 0xffd80020, | 136 | .start = 0xffd80020, |
144 | .end = 0xffd8002f, | 137 | .end = 0xffd8002f, |
145 | .flags = IORESOURCE_MEM, | 138 | .flags = IORESOURCE_MEM, |
@@ -166,15 +159,12 @@ static struct platform_device tmu2_device = { | |||
166 | defined(CONFIG_CPU_SUBTYPE_SH7751R) | 159 | defined(CONFIG_CPU_SUBTYPE_SH7751R) |
167 | 160 | ||
168 | static struct sh_timer_config tmu3_platform_data = { | 161 | static struct sh_timer_config tmu3_platform_data = { |
169 | .name = "TMU3", | ||
170 | .channel_offset = 0x04, | 162 | .channel_offset = 0x04, |
171 | .timer_bit = 0, | 163 | .timer_bit = 0, |
172 | .clk = "peripheral_clk", | ||
173 | }; | 164 | }; |
174 | 165 | ||
175 | static struct resource tmu3_resources[] = { | 166 | static struct resource tmu3_resources[] = { |
176 | [0] = { | 167 | [0] = { |
177 | .name = "TMU3", | ||
178 | .start = 0xfe100008, | 168 | .start = 0xfe100008, |
179 | .end = 0xfe100013, | 169 | .end = 0xfe100013, |
180 | .flags = IORESOURCE_MEM, | 170 | .flags = IORESOURCE_MEM, |
@@ -196,15 +186,12 @@ static struct platform_device tmu3_device = { | |||
196 | }; | 186 | }; |
197 | 187 | ||
198 | static struct sh_timer_config tmu4_platform_data = { | 188 | static struct sh_timer_config tmu4_platform_data = { |
199 | .name = "TMU4", | ||
200 | .channel_offset = 0x10, | 189 | .channel_offset = 0x10, |
201 | .timer_bit = 1, | 190 | .timer_bit = 1, |
202 | .clk = "peripheral_clk", | ||
203 | }; | 191 | }; |
204 | 192 | ||
205 | static struct resource tmu4_resources[] = { | 193 | static struct resource tmu4_resources[] = { |
206 | [0] = { | 194 | [0] = { |
207 | .name = "TMU4", | ||
208 | .start = 0xfe100014, | 195 | .start = 0xfe100014, |
209 | .end = 0xfe10001f, | 196 | .end = 0xfe10001f, |
210 | .flags = IORESOURCE_MEM, | 197 | .flags = IORESOURCE_MEM, |
@@ -243,7 +230,6 @@ static struct platform_device *sh7750_devices[] __initdata = { | |||
243 | static int __init sh7750_devices_setup(void) | 230 | static int __init sh7750_devices_setup(void) |
244 | { | 231 | { |
245 | if (mach_is_rts7751r2d()) { | 232 | if (mach_is_rts7751r2d()) { |
246 | scif_platform_data.scscr |= SCSCR_CKE1; | ||
247 | platform_register_device(&scif_device); | 233 | platform_register_device(&scif_device); |
248 | } else { | 234 | } else { |
249 | platform_register_device(&sci_device); | 235 | platform_register_device(&sci_device); |
@@ -253,7 +239,7 @@ static int __init sh7750_devices_setup(void) | |||
253 | return platform_add_devices(sh7750_devices, | 239 | return platform_add_devices(sh7750_devices, |
254 | ARRAY_SIZE(sh7750_devices)); | 240 | ARRAY_SIZE(sh7750_devices)); |
255 | } | 241 | } |
256 | __initcall(sh7750_devices_setup); | 242 | arch_initcall(sh7750_devices_setup); |
257 | 243 | ||
258 | static struct platform_device *sh7750_early_devices[] __initdata = { | 244 | static struct platform_device *sh7750_early_devices[] __initdata = { |
259 | &tmu0_device, | 245 | &tmu0_device, |
@@ -269,6 +255,14 @@ static struct platform_device *sh7750_early_devices[] __initdata = { | |||
269 | 255 | ||
270 | void __init plat_early_device_setup(void) | 256 | void __init plat_early_device_setup(void) |
271 | { | 257 | { |
258 | if (mach_is_rts7751r2d()) { | ||
259 | scif_platform_data.scscr |= SCSCR_CKE1; | ||
260 | early_platform_add_devices(&scif_device, 1); | ||
261 | } else { | ||
262 | early_platform_add_devices(&sci_device, 1); | ||
263 | early_platform_add_devices(&scif_device, 1); | ||
264 | } | ||
265 | |||
272 | early_platform_add_devices(sh7750_early_devices, | 266 | early_platform_add_devices(sh7750_early_devices, |
273 | ARRAY_SIZE(sh7750_early_devices)); | 267 | ARRAY_SIZE(sh7750_early_devices)); |
274 | } | 268 | } |
@@ -449,7 +443,7 @@ void __init plat_irq_setup_pins(int mode) | |||
449 | 443 | ||
450 | switch (mode) { | 444 | switch (mode) { |
451 | case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */ | 445 | case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */ |
452 | ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); | 446 | __raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); |
453 | register_intc_controller(&intc_desc_irlm); | 447 | register_intc_controller(&intc_desc_irlm); |
454 | break; | 448 | break; |
455 | default: | 449 | default: |
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index cee660fe1d90..78bbf232e391 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c | |||
@@ -126,59 +126,82 @@ static struct intc_vect vectors_irq[] __initdata = { | |||
126 | static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups, | 126 | static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups, |
127 | mask_registers, prio_registers, NULL); | 127 | mask_registers, prio_registers, NULL); |
128 | 128 | ||
129 | static struct plat_sci_port sci_platform_data[] = { | 129 | static struct plat_sci_port scif0_platform_data = { |
130 | { | 130 | .mapbase = 0xfe600000, |
131 | .mapbase = 0xfe600000, | 131 | .flags = UPF_BOOT_AUTOCONF, |
132 | .flags = UPF_BOOT_AUTOCONF, | 132 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, |
133 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | 133 | .scbrr_algo_id = SCBRR_ALGO_2, |
134 | .scbrr_algo_id = SCBRR_ALGO_2, | 134 | .type = PORT_SCIF, |
135 | .type = PORT_SCIF, | 135 | .irqs = { 52, 53, 55, 54 }, |
136 | .irqs = { 52, 53, 55, 54 }, | 136 | }; |
137 | }, { | 137 | |
138 | .mapbase = 0xfe610000, | 138 | static struct platform_device scif0_device = { |
139 | .flags = UPF_BOOT_AUTOCONF, | 139 | .name = "sh-sci", |
140 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | 140 | .id = 0, |
141 | .scbrr_algo_id = SCBRR_ALGO_2, | 141 | .dev = { |
142 | .type = PORT_SCIF, | 142 | .platform_data = &scif0_platform_data, |
143 | .irqs = { 72, 73, 75, 74 }, | 143 | }, |
144 | }, { | 144 | }; |
145 | .mapbase = 0xfe620000, | 145 | |
146 | .flags = UPF_BOOT_AUTOCONF, | 146 | static struct plat_sci_port scif1_platform_data = { |
147 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | 147 | .mapbase = 0xfe610000, |
148 | .scbrr_algo_id = SCBRR_ALGO_2, | 148 | .flags = UPF_BOOT_AUTOCONF, |
149 | .type = PORT_SCIF, | 149 | .type = PORT_SCIF, |
150 | .irqs = { 76, 77, 79, 78 }, | 150 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, |
151 | }, { | 151 | .scbrr_algo_id = SCBRR_ALGO_2, |
152 | .mapbase = 0xfe480000, | 152 | .irqs = { 72, 73, 75, 74 }, |
153 | .flags = UPF_BOOT_AUTOCONF, | 153 | }; |
154 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | 154 | |
155 | .scbrr_algo_id = SCBRR_ALGO_2, | 155 | static struct platform_device scif1_device = { |
156 | .type = PORT_SCI, | 156 | .name = "sh-sci", |
157 | .irqs = { 80, 81, 82, 0 }, | 157 | .id = 1, |
158 | }, { | 158 | .dev = { |
159 | .flags = 0, | 159 | .platform_data = &scif1_platform_data, |
160 | } | 160 | }, |
161 | }; | ||
162 | |||
163 | static struct plat_sci_port scif2_platform_data = { | ||
164 | .mapbase = 0xfe620000, | ||
165 | .flags = UPF_BOOT_AUTOCONF, | ||
166 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
167 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
168 | .type = PORT_SCIF, | ||
169 | .irqs = { 76, 77, 79, 78 }, | ||
170 | }; | ||
171 | |||
172 | static struct platform_device scif2_device = { | ||
173 | .name = "sh-sci", | ||
174 | .id = 2, | ||
175 | .dev = { | ||
176 | .platform_data = &scif2_platform_data, | ||
177 | }, | ||
178 | }; | ||
179 | |||
180 | static struct plat_sci_port scif3_platform_data = { | ||
181 | .mapbase = 0xfe480000, | ||
182 | .flags = UPF_BOOT_AUTOCONF, | ||
183 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
184 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
185 | .type = PORT_SCI, | ||
186 | .irqs = { 80, 81, 82, 0 }, | ||
161 | }; | 187 | }; |
162 | 188 | ||
163 | static struct platform_device sci_device = { | 189 | static struct platform_device scif3_device = { |
164 | .name = "sh-sci", | 190 | .name = "sh-sci", |
165 | .id = -1, | 191 | .id = 3, |
166 | .dev = { | 192 | .dev = { |
167 | .platform_data = sci_platform_data, | 193 | .platform_data = &scif3_platform_data, |
168 | }, | 194 | }, |
169 | }; | 195 | }; |
170 | 196 | ||
171 | static struct sh_timer_config tmu0_platform_data = { | 197 | static struct sh_timer_config tmu0_platform_data = { |
172 | .name = "TMU0", | ||
173 | .channel_offset = 0x04, | 198 | .channel_offset = 0x04, |
174 | .timer_bit = 0, | 199 | .timer_bit = 0, |
175 | .clk = "peripheral_clk", | ||
176 | .clockevent_rating = 200, | 200 | .clockevent_rating = 200, |
177 | }; | 201 | }; |
178 | 202 | ||
179 | static struct resource tmu0_resources[] = { | 203 | static struct resource tmu0_resources[] = { |
180 | [0] = { | 204 | [0] = { |
181 | .name = "TMU0", | ||
182 | .start = 0xffd80008, | 205 | .start = 0xffd80008, |
183 | .end = 0xffd80013, | 206 | .end = 0xffd80013, |
184 | .flags = IORESOURCE_MEM, | 207 | .flags = IORESOURCE_MEM, |
@@ -200,16 +223,13 @@ static struct platform_device tmu0_device = { | |||
200 | }; | 223 | }; |
201 | 224 | ||
202 | static struct sh_timer_config tmu1_platform_data = { | 225 | static struct sh_timer_config tmu1_platform_data = { |
203 | .name = "TMU1", | ||
204 | .channel_offset = 0x10, | 226 | .channel_offset = 0x10, |
205 | .timer_bit = 1, | 227 | .timer_bit = 1, |
206 | .clk = "peripheral_clk", | ||
207 | .clocksource_rating = 200, | 228 | .clocksource_rating = 200, |
208 | }; | 229 | }; |
209 | 230 | ||
210 | static struct resource tmu1_resources[] = { | 231 | static struct resource tmu1_resources[] = { |
211 | [0] = { | 232 | [0] = { |
212 | .name = "TMU1", | ||
213 | .start = 0xffd80014, | 233 | .start = 0xffd80014, |
214 | .end = 0xffd8001f, | 234 | .end = 0xffd8001f, |
215 | .flags = IORESOURCE_MEM, | 235 | .flags = IORESOURCE_MEM, |
@@ -231,15 +251,12 @@ static struct platform_device tmu1_device = { | |||
231 | }; | 251 | }; |
232 | 252 | ||
233 | static struct sh_timer_config tmu2_platform_data = { | 253 | static struct sh_timer_config tmu2_platform_data = { |
234 | .name = "TMU2", | ||
235 | .channel_offset = 0x1c, | 254 | .channel_offset = 0x1c, |
236 | .timer_bit = 2, | 255 | .timer_bit = 2, |
237 | .clk = "peripheral_clk", | ||
238 | }; | 256 | }; |
239 | 257 | ||
240 | static struct resource tmu2_resources[] = { | 258 | static struct resource tmu2_resources[] = { |
241 | [0] = { | 259 | [0] = { |
242 | .name = "TMU2", | ||
243 | .start = 0xffd80020, | 260 | .start = 0xffd80020, |
244 | .end = 0xffd8002f, | 261 | .end = 0xffd8002f, |
245 | .flags = IORESOURCE_MEM, | 262 | .flags = IORESOURCE_MEM, |
@@ -262,7 +279,10 @@ static struct platform_device tmu2_device = { | |||
262 | 279 | ||
263 | 280 | ||
264 | static struct platform_device *sh7760_devices[] __initdata = { | 281 | static struct platform_device *sh7760_devices[] __initdata = { |
265 | &sci_device, | 282 | &scif0_device, |
283 | &scif1_device, | ||
284 | &scif2_device, | ||
285 | &scif3_device, | ||
266 | &tmu0_device, | 286 | &tmu0_device, |
267 | &tmu1_device, | 287 | &tmu1_device, |
268 | &tmu2_device, | 288 | &tmu2_device, |
@@ -273,9 +293,13 @@ static int __init sh7760_devices_setup(void) | |||
273 | return platform_add_devices(sh7760_devices, | 293 | return platform_add_devices(sh7760_devices, |
274 | ARRAY_SIZE(sh7760_devices)); | 294 | ARRAY_SIZE(sh7760_devices)); |
275 | } | 295 | } |
276 | __initcall(sh7760_devices_setup); | 296 | arch_initcall(sh7760_devices_setup); |
277 | 297 | ||
278 | static struct platform_device *sh7760_early_devices[] __initdata = { | 298 | static struct platform_device *sh7760_early_devices[] __initdata = { |
299 | &scif0_device, | ||
300 | &scif1_device, | ||
301 | &scif2_device, | ||
302 | &scif3_device, | ||
279 | &tmu0_device, | 303 | &tmu0_device, |
280 | &tmu1_device, | 304 | &tmu1_device, |
281 | &tmu2_device, | 305 | &tmu2_device, |
@@ -294,7 +318,7 @@ void __init plat_irq_setup_pins(int mode) | |||
294 | { | 318 | { |
295 | switch (mode) { | 319 | switch (mode) { |
296 | case IRQ_MODE_IRQ: | 320 | case IRQ_MODE_IRQ: |
297 | ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); | 321 | __raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); |
298 | register_intc_controller(&intc_desc_irq); | 322 | register_intc_controller(&intc_desc_irq); |
299 | break; | 323 | break; |
300 | default: | 324 | default: |
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index 8a8a993f55ea..14726eef1ce0 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c | |||
@@ -43,9 +43,9 @@ static unsigned long *sq_bitmap; | |||
43 | 43 | ||
44 | #define store_queue_barrier() \ | 44 | #define store_queue_barrier() \ |
45 | do { \ | 45 | do { \ |
46 | (void)ctrl_inl(P4SEG_STORE_QUE); \ | 46 | (void)__raw_readl(P4SEG_STORE_QUE); \ |
47 | ctrl_outl(0, P4SEG_STORE_QUE + 0); \ | 47 | __raw_writel(0, P4SEG_STORE_QUE + 0); \ |
48 | ctrl_outl(0, P4SEG_STORE_QUE + 8); \ | 48 | __raw_writel(0, P4SEG_STORE_QUE + 8); \ |
49 | } while (0); | 49 | } while (0); |
50 | 50 | ||
51 | /** | 51 | /** |
@@ -100,7 +100,7 @@ static inline void sq_mapping_list_del(struct sq_mapping *map) | |||
100 | spin_unlock_irq(&sq_mapping_lock); | 100 | spin_unlock_irq(&sq_mapping_lock); |
101 | } | 101 | } |
102 | 102 | ||
103 | static int __sq_remap(struct sq_mapping *map, unsigned long flags) | 103 | static int __sq_remap(struct sq_mapping *map, pgprot_t prot) |
104 | { | 104 | { |
105 | #if defined(CONFIG_MMU) | 105 | #if defined(CONFIG_MMU) |
106 | struct vm_struct *vma; | 106 | struct vm_struct *vma; |
@@ -113,7 +113,7 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags) | |||
113 | 113 | ||
114 | if (ioremap_page_range((unsigned long)vma->addr, | 114 | if (ioremap_page_range((unsigned long)vma->addr, |
115 | (unsigned long)vma->addr + map->size, | 115 | (unsigned long)vma->addr + map->size, |
116 | vma->phys_addr, __pgprot(flags))) { | 116 | vma->phys_addr, prot)) { |
117 | vunmap(vma->addr); | 117 | vunmap(vma->addr); |
118 | return -EAGAIN; | 118 | return -EAGAIN; |
119 | } | 119 | } |
@@ -123,8 +123,8 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags) | |||
123 | * straightforward, as we can just load up each queue's QACR with | 123 | * straightforward, as we can just load up each queue's QACR with |
124 | * the physical address appropriately masked. | 124 | * the physical address appropriately masked. |
125 | */ | 125 | */ |
126 | ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0); | 126 | __raw_writel(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0); |
127 | ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1); | 127 | __raw_writel(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1); |
128 | #endif | 128 | #endif |
129 | 129 | ||
130 | return 0; | 130 | return 0; |
@@ -135,14 +135,14 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags) | |||
135 | * @phys: Physical address of mapping. | 135 | * @phys: Physical address of mapping. |
136 | * @size: Length of mapping. | 136 | * @size: Length of mapping. |
137 | * @name: User invoking mapping. | 137 | * @name: User invoking mapping. |
138 | * @flags: Protection flags. | 138 | * @prot: Protection bits. |
139 | * | 139 | * |
140 | * Remaps the physical address @phys through the next available store queue | 140 | * Remaps the physical address @phys through the next available store queue |
141 | * address of @size length. @name is logged at boot time as well as through | 141 | * address of @size length. @name is logged at boot time as well as through |
142 | * the sysfs interface. | 142 | * the sysfs interface. |
143 | */ | 143 | */ |
144 | unsigned long sq_remap(unsigned long phys, unsigned int size, | 144 | unsigned long sq_remap(unsigned long phys, unsigned int size, |
145 | const char *name, unsigned long flags) | 145 | const char *name, pgprot_t prot) |
146 | { | 146 | { |
147 | struct sq_mapping *map; | 147 | struct sq_mapping *map; |
148 | unsigned long end; | 148 | unsigned long end; |
@@ -177,7 +177,7 @@ unsigned long sq_remap(unsigned long phys, unsigned int size, | |||
177 | 177 | ||
178 | map->sq_addr = P4SEG_STORE_QUE + (page << PAGE_SHIFT); | 178 | map->sq_addr = P4SEG_STORE_QUE + (page << PAGE_SHIFT); |
179 | 179 | ||
180 | ret = __sq_remap(map, pgprot_val(PAGE_KERNEL_NOCACHE) | flags); | 180 | ret = __sq_remap(map, prot); |
181 | if (unlikely(ret != 0)) | 181 | if (unlikely(ret != 0)) |
182 | goto out; | 182 | goto out; |
183 | 183 | ||
@@ -309,8 +309,7 @@ static ssize_t mapping_store(const char *buf, size_t count) | |||
309 | return -EIO; | 309 | return -EIO; |
310 | 310 | ||
311 | if (likely(len)) { | 311 | if (likely(len)) { |
312 | int ret = sq_remap(base, len, "Userspace", | 312 | int ret = sq_remap(base, len, "Userspace", PAGE_SHARED); |
313 | pgprot_val(PAGE_SHARED)); | ||
314 | if (ret < 0) | 313 | if (ret < 0) |
315 | return ret; | 314 | return ret; |
316 | } else | 315 | } else |
@@ -327,7 +326,7 @@ static struct attribute *sq_sysfs_attrs[] = { | |||
327 | NULL, | 326 | NULL, |
328 | }; | 327 | }; |
329 | 328 | ||
330 | static struct sysfs_ops sq_sysfs_ops = { | 329 | static const struct sysfs_ops sq_sysfs_ops = { |
331 | .show = sq_sysfs_show, | 330 | .show = sq_sysfs_show, |
332 | .store = sq_sysfs_store, | 331 | .store = sq_sysfs_store, |
333 | }; | 332 | }; |