aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /arch/sh/kernel
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/Makefile13
-rw-r--r--arch/sh/kernel/asm-offsets.c23
-rw-r--r--arch/sh/kernel/cpu/Makefile3
-rw-r--r--arch/sh/kernel/cpu/adc.c12
-rw-r--r--arch/sh/kernel/cpu/clock-cpg.c104
-rw-r--r--arch/sh/kernel/cpu/clock.c6
-rw-r--r--arch/sh/kernel/cpu/fpu.c85
-rw-r--r--arch/sh/kernel/cpu/hwblk.c1
-rw-r--r--arch/sh/kernel/cpu/init.c147
-rw-r--r--arch/sh/kernel/cpu/irq/intc-sh5.c14
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c7
-rw-r--r--arch/sh/kernel/cpu/sh2/clock-sh7619.c6
-rw-r--r--arch/sh/kernel/cpu/sh2/setup-sh7619.c71
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7201.c8
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7203.c6
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7206.c8
-rw-r--r--arch/sh/kernel/cpu/sh2a/fpu.c110
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-mxg.c23
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7201.c181
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7203.c89
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7206.c89
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh3.c8
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh7705.c8
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh7706.c8
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh7709.c8
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh7710.c8
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh7712.c6
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S36
-rw-r--r--arch/sh/kernel/cpu/sh3/ex.S2
-rw-r--r--arch/sh/kernel/cpu/sh3/probe.c28
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh3.c2
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c49
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh770x.c80
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c50
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7720.c50
-rw-r--r--arch/sh/kernel/cpu/sh4/Makefile8
-rw-r--r--arch/sh/kernel/cpu/sh4/clock-sh4-202.c10
-rw-r--r--arch/sh/kernel/cpu/sh4/clock-sh4.c8
-rw-r--r--arch/sh/kernel/cpu/sh4/fpu.c161
-rw-r--r--arch/sh/kernel/cpu/sh4/perf_event.c253
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c14
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh4-202.c25
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c49
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7760.c91
-rw-r--r--arch/sh/kernel/cpu/sh4/sq.c25
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile8
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7343.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7366.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c29
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7723.c30
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7724.c21
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7757.c8
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7763.c8
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7770.c8
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7780.c10
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7785.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7786.c184
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-shx3.c10
-rw-r--r--arch/sh/kernel/cpu/sh4a/perf_event.c269
-rw-r--r--arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c21
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7343.c112
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7366.c39
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c295
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7723.c199
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7724.c617
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7757.c118
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7763.c101
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7770.c245
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7780.c200
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c291
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7786.c156
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-shx3.c121
-rw-r--r--arch/sh/kernel/cpu/sh4a/smp-shx3.c40
-rw-r--r--arch/sh/kernel/cpu/sh4a/ubc.c133
-rw-r--r--arch/sh/kernel/cpu/sh5/clock-sh5.c8
-rw-r--r--arch/sh/kernel/cpu/sh5/entry.S8
-rw-r--r--arch/sh/kernel/cpu/sh5/fpu.c67
-rw-r--r--arch/sh/kernel/cpu/sh5/setup-sh5.c22
-rw-r--r--arch/sh/kernel/cpu/shmobile/cpuidle.c42
-rw-r--r--arch/sh/kernel/cpu/shmobile/pm.c118
-rw-r--r--arch/sh/kernel/cpu/shmobile/pm_runtime.c17
-rw-r--r--arch/sh/kernel/cpu/shmobile/sleep.S461
-rw-r--r--arch/sh/kernel/cpu/ubc.S59
-rw-r--r--arch/sh/kernel/cpufreq.c4
-rw-r--r--arch/sh/kernel/debugtraps.S1
-rw-r--r--arch/sh/kernel/dma-nommu.c82
-rw-r--r--arch/sh/kernel/dwarf.c369
-rw-r--r--arch/sh/kernel/early_printk.c240
-rw-r--r--arch/sh/kernel/entry-common.S10
-rw-r--r--arch/sh/kernel/ftrace.c227
-rw-r--r--arch/sh/kernel/gpio.c584
-rw-r--r--arch/sh/kernel/head_32.S219
-rw-r--r--arch/sh/kernel/head_64.S2
-rw-r--r--arch/sh/kernel/hw_breakpoint.c445
-rw-r--r--arch/sh/kernel/idle.c92
-rw-r--r--arch/sh/kernel/io_generic.c4
-rw-r--r--arch/sh/kernel/io_trapped.c18
-rw-r--r--arch/sh/kernel/irq.c18
-rw-r--r--arch/sh/kernel/irq_32.c57
-rw-r--r--arch/sh/kernel/irq_64.c51
-rw-r--r--arch/sh/kernel/kgdb.c46
-rw-r--r--arch/sh/kernel/kprobes.c1
-rw-r--r--arch/sh/kernel/machine_kexec.c22
-rw-r--r--arch/sh/kernel/machvec.c4
-rw-r--r--arch/sh/kernel/module.c9
-rw-r--r--arch/sh/kernel/perf_callchain.c95
-rw-r--r--arch/sh/kernel/perf_event.c330
-rw-r--r--arch/sh/kernel/process.c101
-rw-r--r--arch/sh/kernel/process_32.c201
-rw-r--r--arch/sh/kernel/process_64.c43
-rw-r--r--arch/sh/kernel/ptrace_32.c83
-rw-r--r--arch/sh/kernel/ptrace_64.c31
-rw-r--r--arch/sh/kernel/reboot.c98
-rw-r--r--arch/sh/kernel/return_address.c57
-rw-r--r--arch/sh/kernel/setup.c12
-rw-r--r--arch/sh/kernel/sh_bios.c129
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c67
-rw-r--r--arch/sh/kernel/sh_ksyms_64.c10
-rw-r--r--arch/sh/kernel/signal_32.c34
-rw-r--r--arch/sh/kernel/signal_64.c21
-rw-r--r--arch/sh/kernel/smp.c14
-rw-r--r--arch/sh/kernel/sys_sh.c143
-rw-r--r--arch/sh/kernel/syscalls_64.S2
-rw-r--r--arch/sh/kernel/time.c6
-rw-r--r--arch/sh/kernel/topology.c26
-rw-r--r--arch/sh/kernel/traps.c12
-rw-r--r--arch/sh/kernel/traps_32.c195
-rw-r--r--arch/sh/kernel/traps_64.c45
-rw-r--r--arch/sh/kernel/vmlinux.lds.S42
-rw-r--r--arch/sh/kernel/vsyscall/vsyscall.c1
130 files changed, 6836 insertions, 3553 deletions
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index a2d0a40f3848..02fd3ae8b0ee 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -9,8 +9,13 @@ ifdef CONFIG_FUNCTION_TRACER
9CFLAGS_REMOVE_ftrace.o = -pg 9CFLAGS_REMOVE_ftrace.o = -pg
10endif 10endif
11 11
12obj-y := debugtraps.o dumpstack.o idle.o io.o io_generic.o irq.o \ 12CFLAGS_REMOVE_return_address.o = -pg
13 machvec.o nmi_debug.o process_$(BITS).o ptrace_$(BITS).o \ 13
14obj-y := debugtraps.o dma-nommu.o dumpstack.o \
15 idle.o io.o io_generic.o irq.o \
16 irq_$(BITS).o machvec.o nmi_debug.o process.o \
17 process_$(BITS).o ptrace_$(BITS).o \
18 reboot.o return_address.o \
14 setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o \ 19 setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o \
15 syscalls_$(BITS).o time.o topology.o traps.o \ 20 syscalls_$(BITS).o time.o topology.o traps.o \
16 traps_$(BITS).o unwinder.o 21 traps_$(BITS).o unwinder.o
@@ -22,20 +27,20 @@ obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
22obj-$(CONFIG_KGDB) += kgdb.o 27obj-$(CONFIG_KGDB) += kgdb.o
23obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o 28obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
24obj-$(CONFIG_MODULES) += sh_ksyms_$(BITS).o module.o 29obj-$(CONFIG_MODULES) += sh_ksyms_$(BITS).o module.o
25obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
26obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 30obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
27obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 31obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
28obj-$(CONFIG_STACKTRACE) += stacktrace.o 32obj-$(CONFIG_STACKTRACE) += stacktrace.o
29obj-$(CONFIG_IO_TRAPPED) += io_trapped.o 33obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
30obj-$(CONFIG_KPROBES) += kprobes.o 34obj-$(CONFIG_KPROBES) += kprobes.o
31obj-$(CONFIG_GENERIC_GPIO) += gpio.o
32obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 35obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
33obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o 36obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
34obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 37obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
35obj-$(CONFIG_DUMP_CODE) += disassemble.o 38obj-$(CONFIG_DUMP_CODE) += disassemble.o
36obj-$(CONFIG_HIBERNATION) += swsusp.o 39obj-$(CONFIG_HIBERNATION) += swsusp.o
37obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o 40obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
41obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o
38 42
43obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
39obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o 44obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
40 45
41EXTRA_CFLAGS += -Werror 46EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/asm-offsets.c b/arch/sh/kernel/asm-offsets.c
index d218e808294e..08a2be775b6c 100644
--- a/arch/sh/kernel/asm-offsets.c
+++ b/arch/sh/kernel/asm-offsets.c
@@ -34,5 +34,28 @@ int main(void)
34 DEFINE(PBE_NEXT, offsetof(struct pbe, next)); 34 DEFINE(PBE_NEXT, offsetof(struct pbe, next));
35 DEFINE(SWSUSP_ARCH_REGS_SIZE, sizeof(struct swsusp_arch_regs)); 35 DEFINE(SWSUSP_ARCH_REGS_SIZE, sizeof(struct swsusp_arch_regs));
36#endif 36#endif
37
38 DEFINE(SH_SLEEP_MODE, offsetof(struct sh_sleep_data, mode));
39 DEFINE(SH_SLEEP_SF_PRE, offsetof(struct sh_sleep_data, sf_pre));
40 DEFINE(SH_SLEEP_SF_POST, offsetof(struct sh_sleep_data, sf_post));
41 DEFINE(SH_SLEEP_RESUME, offsetof(struct sh_sleep_data, resume));
42 DEFINE(SH_SLEEP_VBR, offsetof(struct sh_sleep_data, vbr));
43 DEFINE(SH_SLEEP_SPC, offsetof(struct sh_sleep_data, spc));
44 DEFINE(SH_SLEEP_SR, offsetof(struct sh_sleep_data, sr));
45 DEFINE(SH_SLEEP_SP, offsetof(struct sh_sleep_data, sp));
46 DEFINE(SH_SLEEP_BASE_ADDR, offsetof(struct sh_sleep_data, addr));
47 DEFINE(SH_SLEEP_BASE_DATA, offsetof(struct sh_sleep_data, data));
48 DEFINE(SH_SLEEP_REG_STBCR, offsetof(struct sh_sleep_regs, stbcr));
49 DEFINE(SH_SLEEP_REG_BAR, offsetof(struct sh_sleep_regs, bar));
50 DEFINE(SH_SLEEP_REG_PTEH, offsetof(struct sh_sleep_regs, pteh));
51 DEFINE(SH_SLEEP_REG_PTEL, offsetof(struct sh_sleep_regs, ptel));
52 DEFINE(SH_SLEEP_REG_TTB, offsetof(struct sh_sleep_regs, ttb));
53 DEFINE(SH_SLEEP_REG_TEA, offsetof(struct sh_sleep_regs, tea));
54 DEFINE(SH_SLEEP_REG_MMUCR, offsetof(struct sh_sleep_regs, mmucr));
55 DEFINE(SH_SLEEP_REG_PTEA, offsetof(struct sh_sleep_regs, ptea));
56 DEFINE(SH_SLEEP_REG_PASCR, offsetof(struct sh_sleep_regs, pascr));
57 DEFINE(SH_SLEEP_REG_IRMCR, offsetof(struct sh_sleep_regs, irmcr));
58 DEFINE(SH_SLEEP_REG_CCR, offsetof(struct sh_sleep_regs, ccr));
59 DEFINE(SH_SLEEP_REG_RAMCR, offsetof(struct sh_sleep_regs, ramcr));
37 return 0; 60 return 0;
38} 61}
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index 3d6b9312dc47..0e48bc61c272 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -15,8 +15,9 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/
15 15
16# Common interfaces. 16# Common interfaces.
17 17
18obj-$(CONFIG_UBC_WAKEUP) += ubc.o
19obj-$(CONFIG_SH_ADC) += adc.o 18obj-$(CONFIG_SH_ADC) += adc.o
20obj-$(CONFIG_SH_CLK_CPG) += clock-cpg.o 19obj-$(CONFIG_SH_CLK_CPG) += clock-cpg.o
20obj-$(CONFIG_SH_FPU) += fpu.o
21obj-$(CONFIG_SH_FPU_EMU) += fpu.o
21 22
22obj-y += irq/ init.o clock.o hwblk.o 23obj-y += irq/ init.o clock.o hwblk.o
diff --git a/arch/sh/kernel/cpu/adc.c b/arch/sh/kernel/cpu/adc.c
index da3d6877f93d..d307571d54b6 100644
--- a/arch/sh/kernel/cpu/adc.c
+++ b/arch/sh/kernel/cpu/adc.c
@@ -18,19 +18,19 @@ int adc_single(unsigned int channel)
18 18
19 off = (channel & 0x03) << 2; 19 off = (channel & 0x03) << 2;
20 20
21 csr = ctrl_inb(ADCSR); 21 csr = __raw_readb(ADCSR);
22 csr = channel | ADCSR_ADST | ADCSR_CKS; 22 csr = channel | ADCSR_ADST | ADCSR_CKS;
23 ctrl_outb(csr, ADCSR); 23 __raw_writeb(csr, ADCSR);
24 24
25 do { 25 do {
26 csr = ctrl_inb(ADCSR); 26 csr = __raw_readb(ADCSR);
27 } while ((csr & ADCSR_ADF) == 0); 27 } while ((csr & ADCSR_ADF) == 0);
28 28
29 csr &= ~(ADCSR_ADF | ADCSR_ADST); 29 csr &= ~(ADCSR_ADF | ADCSR_ADST);
30 ctrl_outb(csr, ADCSR); 30 __raw_writeb(csr, ADCSR);
31 31
32 return (((ctrl_inb(ADDRAH + off) << 8) | 32 return (((__raw_readb(ADDRAH + off) << 8) |
33 ctrl_inb(ADDRAL + off)) >> 6); 33 __raw_readb(ADDRAL + off)) >> 6);
34} 34}
35 35
36EXPORT_SYMBOL(adc_single); 36EXPORT_SYMBOL(adc_single);
diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c
index 6dfe2cced3fc..eed5eaff96ba 100644
--- a/arch/sh/kernel/cpu/clock-cpg.c
+++ b/arch/sh/kernel/cpu/clock-cpg.c
@@ -149,7 +149,8 @@ int __init sh_clk_div6_register(struct clk *clks, int nr)
149 149
150static unsigned long sh_clk_div4_recalc(struct clk *clk) 150static unsigned long sh_clk_div4_recalc(struct clk *clk)
151{ 151{
152 struct clk_div_mult_table *table = clk->priv; 152 struct clk_div4_table *d4t = clk->priv;
153 struct clk_div_mult_table *table = d4t->div_mult_table;
153 unsigned int idx; 154 unsigned int idx;
154 155
155 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 156 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
@@ -160,17 +161,90 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk)
160 return clk->freq_table[idx].frequency; 161 return clk->freq_table[idx].frequency;
161} 162}
162 163
164static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
165{
166 struct clk_div4_table *d4t = clk->priv;
167 struct clk_div_mult_table *table = d4t->div_mult_table;
168 u32 value;
169 int ret;
170
171 if (!strcmp("pll_clk", parent->name))
172 value = __raw_readl(clk->enable_reg) & ~(1 << 7);
173 else
174 value = __raw_readl(clk->enable_reg) | (1 << 7);
175
176 ret = clk_reparent(clk, parent);
177 if (ret < 0)
178 return ret;
179
180 __raw_writel(value, clk->enable_reg);
181
182 /* Rebiuld the frequency table */
183 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
184 table, &clk->arch_flags);
185
186 return 0;
187}
188
189static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id)
190{
191 struct clk_div4_table *d4t = clk->priv;
192 unsigned long value;
193 int idx = clk_rate_table_find(clk, clk->freq_table, rate);
194 if (idx < 0)
195 return idx;
196
197 value = __raw_readl(clk->enable_reg);
198 value &= ~(0xf << clk->enable_bit);
199 value |= (idx << clk->enable_bit);
200 __raw_writel(value, clk->enable_reg);
201
202 if (d4t->kick)
203 d4t->kick(clk);
204
205 return 0;
206}
207
208static int sh_clk_div4_enable(struct clk *clk)
209{
210 __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg);
211 return 0;
212}
213
214static void sh_clk_div4_disable(struct clk *clk)
215{
216 __raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg);
217}
218
163static struct clk_ops sh_clk_div4_clk_ops = { 219static struct clk_ops sh_clk_div4_clk_ops = {
164 .recalc = sh_clk_div4_recalc, 220 .recalc = sh_clk_div4_recalc,
221 .set_rate = sh_clk_div4_set_rate,
165 .round_rate = sh_clk_div_round_rate, 222 .round_rate = sh_clk_div_round_rate,
166}; 223};
167 224
168int __init sh_clk_div4_register(struct clk *clks, int nr, 225static struct clk_ops sh_clk_div4_enable_clk_ops = {
169 struct clk_div_mult_table *table) 226 .recalc = sh_clk_div4_recalc,
227 .set_rate = sh_clk_div4_set_rate,
228 .round_rate = sh_clk_div_round_rate,
229 .enable = sh_clk_div4_enable,
230 .disable = sh_clk_div4_disable,
231};
232
233static struct clk_ops sh_clk_div4_reparent_clk_ops = {
234 .recalc = sh_clk_div4_recalc,
235 .set_rate = sh_clk_div4_set_rate,
236 .round_rate = sh_clk_div_round_rate,
237 .enable = sh_clk_div4_enable,
238 .disable = sh_clk_div4_disable,
239 .set_parent = sh_clk_div4_set_parent,
240};
241
242static int __init sh_clk_div4_register_ops(struct clk *clks, int nr,
243 struct clk_div4_table *table, struct clk_ops *ops)
170{ 244{
171 struct clk *clkp; 245 struct clk *clkp;
172 void *freq_table; 246 void *freq_table;
173 int nr_divs = table->nr_divisors; 247 int nr_divs = table->div_mult_table->nr_divisors;
174 int freq_table_size = sizeof(struct cpufreq_frequency_table); 248 int freq_table_size = sizeof(struct cpufreq_frequency_table);
175 int ret = 0; 249 int ret = 0;
176 int k; 250 int k;
@@ -185,7 +259,7 @@ int __init sh_clk_div4_register(struct clk *clks, int nr,
185 for (k = 0; !ret && (k < nr); k++) { 259 for (k = 0; !ret && (k < nr); k++) {
186 clkp = clks + k; 260 clkp = clks + k;
187 261
188 clkp->ops = &sh_clk_div4_clk_ops; 262 clkp->ops = ops;
189 clkp->id = -1; 263 clkp->id = -1;
190 clkp->priv = table; 264 clkp->priv = table;
191 265
@@ -198,6 +272,26 @@ int __init sh_clk_div4_register(struct clk *clks, int nr,
198 return ret; 272 return ret;
199} 273}
200 274
275int __init sh_clk_div4_register(struct clk *clks, int nr,
276 struct clk_div4_table *table)
277{
278 return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops);
279}
280
281int __init sh_clk_div4_enable_register(struct clk *clks, int nr,
282 struct clk_div4_table *table)
283{
284 return sh_clk_div4_register_ops(clks, nr, table,
285 &sh_clk_div4_enable_clk_ops);
286}
287
288int __init sh_clk_div4_reparent_register(struct clk *clks, int nr,
289 struct clk_div4_table *table)
290{
291 return sh_clk_div4_register_ops(clks, nr, table,
292 &sh_clk_div4_reparent_clk_ops);
293}
294
201#ifdef CONFIG_SH_CLK_CPG_LEGACY 295#ifdef CONFIG_SH_CLK_CPG_LEGACY
202static struct clk master_clk = { 296static struct clk master_clk = {
203 .name = "master_clk", 297 .name = "master_clk",
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index f3a46be2ae81..e9fa1bfed53e 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -404,7 +404,7 @@ EXPORT_SYMBOL_GPL(clk_round_rate);
404 * If an entry has a device ID, it must match 404 * If an entry has a device ID, it must match
405 * If an entry has a connection ID, it must match 405 * If an entry has a connection ID, it must match
406 * Then we take the most specific entry - with the following 406 * Then we take the most specific entry - with the following
407 * order of precidence: dev+con > dev only > con only. 407 * order of precedence: dev+con > dev only > con only.
408 */ 408 */
409static struct clk *clk_find(const char *dev_id, const char *con_id) 409static struct clk *clk_find(const char *dev_id, const char *con_id)
410{ 410{
@@ -598,7 +598,7 @@ static struct dentry *clk_debugfs_root;
598static int clk_debugfs_register_one(struct clk *c) 598static int clk_debugfs_register_one(struct clk *c)
599{ 599{
600 int err; 600 int err;
601 struct dentry *d, *child; 601 struct dentry *d, *child, *child_tmp;
602 struct clk *pa = c->parent; 602 struct clk *pa = c->parent;
603 char s[255]; 603 char s[255];
604 char *p = s; 604 char *p = s;
@@ -630,7 +630,7 @@ static int clk_debugfs_register_one(struct clk *c)
630 630
631err_out: 631err_out:
632 d = c->dentry; 632 d = c->dentry;
633 list_for_each_entry(child, &d->d_subdirs, d_u.d_child) 633 list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
634 debugfs_remove(child); 634 debugfs_remove(child);
635 debugfs_remove(c->dentry); 635 debugfs_remove(c->dentry);
636 return err; 636 return err;
diff --git a/arch/sh/kernel/cpu/fpu.c b/arch/sh/kernel/cpu/fpu.c
new file mode 100644
index 000000000000..7f1b70cace35
--- /dev/null
+++ b/arch/sh/kernel/cpu/fpu.c
@@ -0,0 +1,85 @@
1#include <linux/sched.h>
2#include <linux/slab.h>
3#include <asm/processor.h>
4#include <asm/fpu.h>
5
6int init_fpu(struct task_struct *tsk)
7{
8 if (tsk_used_math(tsk)) {
9 if ((boot_cpu_data.flags & CPU_HAS_FPU) && tsk == current)
10 unlazy_fpu(tsk, task_pt_regs(tsk));
11 return 0;
12 }
13
14 /*
15 * Memory allocation at the first usage of the FPU and other state.
16 */
17 if (!tsk->thread.xstate) {
18 tsk->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
19 GFP_KERNEL);
20 if (!tsk->thread.xstate)
21 return -ENOMEM;
22 }
23
24 if (boot_cpu_data.flags & CPU_HAS_FPU) {
25 struct sh_fpu_hard_struct *fp = &tsk->thread.xstate->hardfpu;
26 memset(fp, 0, xstate_size);
27 fp->fpscr = FPSCR_INIT;
28 } else {
29 struct sh_fpu_soft_struct *fp = &tsk->thread.xstate->softfpu;
30 memset(fp, 0, xstate_size);
31 fp->fpscr = FPSCR_INIT;
32 }
33
34 set_stopped_child_used_math(tsk);
35 return 0;
36}
37
38#ifdef CONFIG_SH_FPU
39void __fpu_state_restore(void)
40{
41 struct task_struct *tsk = current;
42
43 restore_fpu(tsk);
44
45 task_thread_info(tsk)->status |= TS_USEDFPU;
46 tsk->fpu_counter++;
47}
48
49void fpu_state_restore(struct pt_regs *regs)
50{
51 struct task_struct *tsk = current;
52
53 if (unlikely(!user_mode(regs))) {
54 printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
55 BUG();
56 return;
57 }
58
59 if (!tsk_used_math(tsk)) {
60 local_irq_enable();
61 /*
62 * does a slab alloc which can sleep
63 */
64 if (init_fpu(tsk)) {
65 /*
66 * ran out of memory!
67 */
68 do_group_exit(SIGKILL);
69 return;
70 }
71 local_irq_disable();
72 }
73
74 grab_fpu(regs);
75
76 __fpu_state_restore();
77}
78
79BUILD_TRAP_HANDLER(fpu_state_restore)
80{
81 TRAP_HANDLER_DECL;
82
83 fpu_state_restore(regs);
84}
85#endif /* CONFIG_SH_FPU */
diff --git a/arch/sh/kernel/cpu/hwblk.c b/arch/sh/kernel/cpu/hwblk.c
index c0ad7d46e784..67a1e811cfe8 100644
--- a/arch/sh/kernel/cpu/hwblk.c
+++ b/arch/sh/kernel/cpu/hwblk.c
@@ -1,6 +1,5 @@
1#include <linux/clk.h> 1#include <linux/clk.h>
2#include <linux/compiler.h> 2#include <linux/compiler.h>
3#include <linux/slab.h>
4#include <linux/io.h> 3#include <linux/io.h>
5#include <linux/spinlock.h> 4#include <linux/spinlock.h>
6#include <asm/suspend.h> 5#include <asm/suspend.h>
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index e932ebef4738..c736422344eb 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -24,22 +24,32 @@
24#include <asm/elf.h> 24#include <asm/elf.h>
25#include <asm/io.h> 25#include <asm/io.h>
26#include <asm/smp.h> 26#include <asm/smp.h>
27#ifdef CONFIG_SUPERH32 27#include <asm/sh_bios.h>
28#include <asm/ubc.h> 28
29#ifdef CONFIG_SH_FPU
30#define cpu_has_fpu 1
31#else
32#define cpu_has_fpu 0
33#endif
34
35#ifdef CONFIG_SH_DSP
36#define cpu_has_dsp 1
37#else
38#define cpu_has_dsp 0
29#endif 39#endif
30 40
31/* 41/*
32 * Generic wrapper for command line arguments to disable on-chip 42 * Generic wrapper for command line arguments to disable on-chip
33 * peripherals (nofpu, nodsp, and so forth). 43 * peripherals (nofpu, nodsp, and so forth).
34 */ 44 */
35#define onchip_setup(x) \ 45#define onchip_setup(x) \
36static int x##_disabled __initdata = 0; \ 46static int x##_disabled __initdata = !cpu_has_##x; \
37 \ 47 \
38static int __init x##_setup(char *opts) \ 48static int __init x##_setup(char *opts) \
39{ \ 49{ \
40 x##_disabled = 1; \ 50 x##_disabled = 1; \
41 return 1; \ 51 return 1; \
42} \ 52} \
43__setup("no" __stringify(x), x##_setup); 53__setup("no" __stringify(x), x##_setup);
44 54
45onchip_setup(fpu); 55onchip_setup(fpu);
@@ -52,10 +62,10 @@ onchip_setup(dsp);
52static void __init speculative_execution_init(void) 62static void __init speculative_execution_init(void)
53{ 63{
54 /* Clear RABD */ 64 /* Clear RABD */
55 ctrl_outl(ctrl_inl(CPUOPM) & ~CPUOPM_RABD, CPUOPM); 65 __raw_writel(__raw_readl(CPUOPM) & ~CPUOPM_RABD, CPUOPM);
56 66
57 /* Flush the update */ 67 /* Flush the update */
58 (void)ctrl_inl(CPUOPM); 68 (void)__raw_readl(CPUOPM);
59 ctrl_barrier(); 69 ctrl_barrier();
60} 70}
61#else 71#else
@@ -75,16 +85,11 @@ static void __init expmask_init(void)
75 /* 85 /*
76 * Future proofing. 86 * Future proofing.
77 * 87 *
78 * Disable support for slottable sleep instruction 88 * Disable support for slottable sleep instruction, non-nop
79 * and non-nop instructions in the rte delay slot. 89 * instructions in the rte delay slot, and associative writes to
90 * the memory-mapped cache array.
80 */ 91 */
81 expmask &= ~(EXPMASK_RTEDS | EXPMASK_BRDSSLP); 92 expmask &= ~(EXPMASK_RTEDS | EXPMASK_BRDSSLP | EXPMASK_MMCAW);
82
83 /*
84 * Enable associative writes to the memory-mapped cache array
85 * until the cache flush ops have been rewritten.
86 */
87 expmask |= EXPMASK_MMCAW;
88 93
89 __raw_writel(expmask, EXPMASK); 94 __raw_writel(expmask, EXPMASK);
90 ctrl_barrier(); 95 ctrl_barrier();
@@ -94,7 +99,7 @@ static void __init expmask_init(void)
94#endif 99#endif
95 100
96/* 2nd-level cache init */ 101/* 2nd-level cache init */
97void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void) 102void __attribute__ ((weak)) l2_cache_init(void)
98{ 103{
99} 104}
100 105
@@ -102,12 +107,12 @@ void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void)
102 * Generic first-level cache init 107 * Generic first-level cache init
103 */ 108 */
104#ifdef CONFIG_SUPERH32 109#ifdef CONFIG_SUPERH32
105static void __uses_jump_to_uncached cache_init(void) 110static void cache_init(void)
106{ 111{
107 unsigned long ccr, flags; 112 unsigned long ccr, flags;
108 113
109 jump_to_uncached(); 114 jump_to_uncached();
110 ccr = ctrl_inl(CCR); 115 ccr = __raw_readl(CCR);
111 116
112 /* 117 /*
113 * At this point we don't know whether the cache is enabled or not - a 118 * At this point we don't know whether the cache is enabled or not - a
@@ -151,7 +156,7 @@ static void __uses_jump_to_uncached cache_init(void)
151 for (addr = addrstart; 156 for (addr = addrstart;
152 addr < addrstart + waysize; 157 addr < addrstart + waysize;
153 addr += current_cpu_data.dcache.linesz) 158 addr += current_cpu_data.dcache.linesz)
154 ctrl_outl(0, addr); 159 __raw_writel(0, addr);
155 160
156 addrstart += current_cpu_data.dcache.way_incr; 161 addrstart += current_cpu_data.dcache.way_incr;
157 } while (--ways); 162 } while (--ways);
@@ -184,7 +189,7 @@ static void __uses_jump_to_uncached cache_init(void)
184 189
185 l2_cache_init(); 190 l2_cache_init();
186 191
187 ctrl_outl(flags, CCR); 192 __raw_writel(flags, CCR);
188 back_to_cached(); 193 back_to_cached();
189} 194}
190#else 195#else
@@ -212,6 +217,18 @@ static void detect_cache_shape(void)
212 l2_cache_shape = -1; /* No S-cache */ 217 l2_cache_shape = -1; /* No S-cache */
213} 218}
214 219
220static void __init fpu_init(void)
221{
222 /* Disable the FPU */
223 if (fpu_disabled && (current_cpu_data.flags & CPU_HAS_FPU)) {
224 printk("FPU Disabled\n");
225 current_cpu_data.flags &= ~CPU_HAS_FPU;
226 }
227
228 disable_fpu();
229 clear_used_math();
230}
231
215#ifdef CONFIG_SH_DSP 232#ifdef CONFIG_SH_DSP
216static void __init release_dsp(void) 233static void __init release_dsp(void)
217{ 234{
@@ -249,28 +266,35 @@ static void __init dsp_init(void)
249 if (sr & SR_DSP) 266 if (sr & SR_DSP)
250 current_cpu_data.flags |= CPU_HAS_DSP; 267 current_cpu_data.flags |= CPU_HAS_DSP;
251 268
269 /* Disable the DSP */
270 if (dsp_disabled && (current_cpu_data.flags & CPU_HAS_DSP)) {
271 printk("DSP Disabled\n");
272 current_cpu_data.flags &= ~CPU_HAS_DSP;
273 }
274
252 /* Now that we've determined the DSP status, clear the DSP bit. */ 275 /* Now that we've determined the DSP status, clear the DSP bit. */
253 release_dsp(); 276 release_dsp();
254} 277}
278#else
279static inline void __init dsp_init(void) { }
255#endif /* CONFIG_SH_DSP */ 280#endif /* CONFIG_SH_DSP */
256 281
257/** 282/**
258 * sh_cpu_init 283 * sh_cpu_init
259 * 284 *
260 * This is our initial entry point for each CPU, and is invoked on the boot 285 * This is our initial entry point for each CPU, and is invoked on the
261 * CPU prior to calling start_kernel(). For SMP, a combination of this and 286 * boot CPU prior to calling start_kernel(). For SMP, a combination of
262 * start_secondary() will bring up each processor to a ready state prior 287 * this and start_secondary() will bring up each processor to a ready
263 * to hand forking the idle loop. 288 * state prior to hand forking the idle loop.
264 * 289 *
265 * We do all of the basic processor init here, including setting up the 290 * We do all of the basic processor init here, including setting up
266 * caches, FPU, DSP, kicking the UBC, etc. By the time start_kernel() is 291 * the caches, FPU, DSP, etc. By the time start_kernel() is hit (and
267 * hit (and subsequently platform_setup()) things like determining the 292 * subsequently platform_setup()) things like determining the CPU
268 * CPU subtype and initial configuration will all be done. 293 * subtype and initial configuration will all be done.
269 * 294 *
270 * Each processor family is still responsible for doing its own probing 295 * Each processor family is still responsible for doing its own probing
271 * and cache configuration in detect_cpu_and_cache_system(). 296 * and cache configuration in detect_cpu_and_cache_system().
272 */ 297 */
273
274asmlinkage void __init sh_cpu_init(void) 298asmlinkage void __init sh_cpu_init(void)
275{ 299{
276 current_thread_info()->cpu = hard_smp_processor_id(); 300 current_thread_info()->cpu = hard_smp_processor_id();
@@ -307,18 +331,8 @@ asmlinkage void __init sh_cpu_init(void)
307 detect_cache_shape(); 331 detect_cache_shape();
308 } 332 }
309 333
310 /* Disable the FPU */ 334 fpu_init();
311 if (fpu_disabled) { 335 dsp_init();
312 printk("FPU Disabled\n");
313 current_cpu_data.flags &= ~CPU_HAS_FPU;
314 disable_fpu();
315 }
316
317 /* FPU initialization */
318 if ((current_cpu_data.flags & CPU_HAS_FPU)) {
319 clear_thread_flag(TIF_USEDFPU);
320 clear_used_math();
321 }
322 336
323 /* 337 /*
324 * Initialize the per-CPU ASID cache very early, since the 338 * Initialize the per-CPU ASID cache very early, since the
@@ -326,29 +340,24 @@ asmlinkage void __init sh_cpu_init(void)
326 */ 340 */
327 current_cpu_data.asid_cache = NO_CONTEXT; 341 current_cpu_data.asid_cache = NO_CONTEXT;
328 342
329#ifdef CONFIG_SH_DSP 343 speculative_execution_init();
330 /* Probe for DSP */ 344 expmask_init();
331 dsp_init();
332 345
333 /* Disable the DSP */ 346 /* Do the rest of the boot processor setup */
334 if (dsp_disabled) { 347 if (raw_smp_processor_id() == 0) {
335 printk("DSP Disabled\n"); 348 /* Save off the BIOS VBR, if there is one */
336 current_cpu_data.flags &= ~CPU_HAS_DSP; 349 sh_bios_vbr_init();
337 release_dsp();
338 }
339#endif
340 350
341 /* 351 /*
342 * Some brain-damaged loaders decided it would be a good idea to put 352 * Setup VBR for boot CPU. Secondary CPUs do this through
343 * the UBC to sleep. This causes some issues when it comes to things 353 * start_secondary().
344 * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So .. 354 */
345 * we wake it up and hope that all is well. 355 per_cpu_trap_init();
346 */
347#ifdef CONFIG_SUPERH32
348 if (raw_smp_processor_id() == 0)
349 ubc_wakeup();
350#endif
351 356
352 speculative_execution_init(); 357 /*
353 expmask_init(); 358 * Boot processor to setup the FP and extended state
359 * context info.
360 */
361 init_thread_xstate();
362 }
354} 363}
diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c
index 06e7e2959b54..96a239583948 100644
--- a/arch/sh/kernel/cpu/irq/intc-sh5.c
+++ b/arch/sh/kernel/cpu/irq/intc-sh5.c
@@ -123,7 +123,7 @@ static void enable_intc_irq(unsigned int irq)
123 bitmask = 1 << (irq - 32); 123 bitmask = 1 << (irq - 32);
124 } 124 }
125 125
126 ctrl_outl(bitmask, reg); 126 __raw_writel(bitmask, reg);
127} 127}
128 128
129static void disable_intc_irq(unsigned int irq) 129static void disable_intc_irq(unsigned int irq)
@@ -139,7 +139,7 @@ static void disable_intc_irq(unsigned int irq)
139 bitmask = 1 << (irq - 32); 139 bitmask = 1 << (irq - 32);
140 } 140 }
141 141
142 ctrl_outl(bitmask, reg); 142 __raw_writel(bitmask, reg);
143} 143}
144 144
145static void mask_and_ack_intc(unsigned int irq) 145static void mask_and_ack_intc(unsigned int irq)
@@ -170,11 +170,11 @@ void __init plat_irq_setup(void)
170 170
171 171
172 /* Disable all interrupts and set all priorities to 0 to avoid trouble */ 172 /* Disable all interrupts and set all priorities to 0 to avoid trouble */
173 ctrl_outl(-1, INTC_INTDSB_0); 173 __raw_writel(-1, INTC_INTDSB_0);
174 ctrl_outl(-1, INTC_INTDSB_1); 174 __raw_writel(-1, INTC_INTDSB_1);
175 175
176 for (reg = INTC_INTPRI_0, i = 0; i < INTC_INTPRI_PREGS; i++, reg += 8) 176 for (reg = INTC_INTPRI_0, i = 0; i < INTC_INTPRI_PREGS; i++, reg += 8)
177 ctrl_outl( NO_PRIORITY, reg); 177 __raw_writel( NO_PRIORITY, reg);
178 178
179 179
180#ifdef CONFIG_SH_CAYMAN 180#ifdef CONFIG_SH_CAYMAN
@@ -199,7 +199,7 @@ void __init plat_irq_setup(void)
199 reg = INTC_ICR_SET; 199 reg = INTC_ICR_SET;
200 i = IRQ_IRL0; 200 i = IRQ_IRL0;
201 } 201 }
202 ctrl_outl(INTC_ICR_IRLM, reg); 202 __raw_writel(INTC_ICR_IRLM, reg);
203 203
204 /* Set interrupt priorities according to platform description */ 204 /* Set interrupt priorities according to platform description */
205 for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) { 205 for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
@@ -207,7 +207,7 @@ void __init plat_irq_setup(void)
207 ((i % INTC_INTPRI_PPREG) * 4); 207 ((i % INTC_INTPRI_PPREG) * 4);
208 if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) { 208 if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
209 /* Upon the 7th, set Priority Register */ 209 /* Upon the 7th, set Priority Register */
210 ctrl_outl(data, reg); 210 __raw_writel(data, reg);
211 data = 0; 211 data = 0;
212 reg += 8; 212 reg += 8;
213 } 213 }
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index c1508a90fc6a..9282d965a1b6 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -17,16 +17,17 @@
17 * for more details. 17 * for more details.
18 */ 18 */
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/interrupt.h>
21#include <linux/io.h>
20#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/kernel.h>
21#include <linux/module.h> 24#include <linux/module.h>
22#include <linux/io.h>
23#include <linux/interrupt.h>
24#include <linux/topology.h> 25#include <linux/topology.h>
25 26
26static inline struct ipr_desc *get_ipr_desc(unsigned int irq) 27static inline struct ipr_desc *get_ipr_desc(unsigned int irq)
27{ 28{
28 struct irq_chip *chip = get_irq_chip(irq); 29 struct irq_chip *chip = get_irq_chip(irq);
29 return (void *)((char *)chip - offsetof(struct ipr_desc, chip)); 30 return container_of(chip, struct ipr_desc, chip);
30} 31}
31 32
32static void disable_ipr_irq(unsigned int irq) 33static void disable_ipr_irq(unsigned int irq)
diff --git a/arch/sh/kernel/cpu/sh2/clock-sh7619.c b/arch/sh/kernel/cpu/sh2/clock-sh7619.c
index 4fe863170e31..0c9f24d7a02f 100644
--- a/arch/sh/kernel/cpu/sh2/clock-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/clock-sh7619.c
@@ -31,7 +31,7 @@ static const int pfc_divisors[] = {1,2,0,4};
31 31
32static void master_clk_init(struct clk *clk) 32static void master_clk_init(struct clk *clk)
33{ 33{
34 clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 7]; 34 clk->rate *= PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 7];
35} 35}
36 36
37static struct clk_ops sh7619_master_clk_ops = { 37static struct clk_ops sh7619_master_clk_ops = {
@@ -40,7 +40,7 @@ static struct clk_ops sh7619_master_clk_ops = {
40 40
41static unsigned long module_clk_recalc(struct clk *clk) 41static unsigned long module_clk_recalc(struct clk *clk)
42{ 42{
43 int idx = (ctrl_inw(FREQCR) & 0x0007); 43 int idx = (__raw_readw(FREQCR) & 0x0007);
44 return clk->parent->rate / pfc_divisors[idx]; 44 return clk->parent->rate / pfc_divisors[idx];
45} 45}
46 46
@@ -50,7 +50,7 @@ static struct clk_ops sh7619_module_clk_ops = {
50 50
51static unsigned long bus_clk_recalc(struct clk *clk) 51static unsigned long bus_clk_recalc(struct clk *clk)
52{ 52{
53 return clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 7]; 53 return clk->parent->rate / pll1rate[(__raw_readw(FREQCR) >> 8) & 7];
54} 54}
55 55
56static struct clk_ops sh7619_bus_clk_ops = { 56static struct clk_ops sh7619_bus_clk_ops = {
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index 8555c05e8667..114c7cee7184 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -59,32 +59,48 @@ static struct intc_prio_reg prio_registers[] __initdata = {
59static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, NULL, 59static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, NULL,
60 NULL, prio_registers, NULL); 60 NULL, prio_registers, NULL);
61 61
62static struct plat_sci_port sci_platform_data[] = { 62static struct plat_sci_port scif0_platform_data = {
63 { 63 .mapbase = 0xf8400000,
64 .mapbase = 0xf8400000, 64 .flags = UPF_BOOT_AUTOCONF,
65 .flags = UPF_BOOT_AUTOCONF, 65 .type = PORT_SCIF,
66 .type = PORT_SCIF, 66 .irqs = { 88, 88, 88, 88 },
67 .irqs = { 88, 88, 88, 88 }, 67};
68 }, { 68
69 .mapbase = 0xf8410000, 69static struct platform_device scif0_device = {
70 .flags = UPF_BOOT_AUTOCONF, 70 .name = "sh-sci",
71 .type = PORT_SCIF, 71 .id = 0,
72 .irqs = { 92, 92, 92, 92 }, 72 .dev = {
73 }, { 73 .platform_data = &scif0_platform_data,
74 .mapbase = 0xf8420000, 74 },
75 .flags = UPF_BOOT_AUTOCONF, 75};
76 .type = PORT_SCIF, 76
77 .irqs = { 96, 96, 96, 96 }, 77static struct plat_sci_port scif1_platform_data = {
78 }, { 78 .mapbase = 0xf8410000,
79 .flags = 0, 79 .flags = UPF_BOOT_AUTOCONF,
80 } 80 .type = PORT_SCIF,
81}; 81 .irqs = { 92, 92, 92, 92 },
82 82};
83static struct platform_device sci_device = { 83
84static struct platform_device scif1_device = {
85 .name = "sh-sci",
86 .id = 1,
87 .dev = {
88 .platform_data = &scif1_platform_data,
89 },
90};
91
92static struct plat_sci_port scif2_platform_data = {
93 .mapbase = 0xf8420000,
94 .flags = UPF_BOOT_AUTOCONF,
95 .type = PORT_SCIF,
96 .irqs = { 96, 96, 96, 96 },
97};
98
99static struct platform_device scif2_device = {
84 .name = "sh-sci", 100 .name = "sh-sci",
85 .id = -1, 101 .id = 2,
86 .dev = { 102 .dev = {
87 .platform_data = sci_platform_data, 103 .platform_data = &scif2_platform_data,
88 }, 104 },
89}; 105};
90 106
@@ -176,7 +192,9 @@ static struct platform_device cmt1_device = {
176}; 192};
177 193
178static struct platform_device *sh7619_devices[] __initdata = { 194static struct platform_device *sh7619_devices[] __initdata = {
179 &sci_device, 195 &scif0_device,
196 &scif1_device,
197 &scif2_device,
180 &eth_device, 198 &eth_device,
181 &cmt0_device, 199 &cmt0_device,
182 &cmt1_device, 200 &cmt1_device,
@@ -195,6 +213,9 @@ void __init plat_irq_setup(void)
195} 213}
196 214
197static struct platform_device *sh7619_early_devices[] __initdata = { 215static struct platform_device *sh7619_early_devices[] __initdata = {
216 &scif0_device,
217 &scif1_device,
218 &scif2_device,
198 &cmt0_device, 219 &cmt0_device,
199 &cmt1_device, 220 &cmt1_device,
200}; 221};
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
index 7814c76159a7..b26264dc2aef 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
@@ -34,7 +34,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12};
34 34
35static void master_clk_init(struct clk *clk) 35static void master_clk_init(struct clk *clk)
36{ 36{
37 return 10000000 * PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; 37 return 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
38} 38}
39 39
40static struct clk_ops sh7201_master_clk_ops = { 40static struct clk_ops sh7201_master_clk_ops = {
@@ -43,7 +43,7 @@ static struct clk_ops sh7201_master_clk_ops = {
43 43
44static unsigned long module_clk_recalc(struct clk *clk) 44static unsigned long module_clk_recalc(struct clk *clk)
45{ 45{
46 int idx = (ctrl_inw(FREQCR) & 0x0007); 46 int idx = (__raw_readw(FREQCR) & 0x0007);
47 return clk->parent->rate / pfc_divisors[idx]; 47 return clk->parent->rate / pfc_divisors[idx];
48} 48}
49 49
@@ -53,7 +53,7 @@ static struct clk_ops sh7201_module_clk_ops = {
53 53
54static unsigned long bus_clk_recalc(struct clk *clk) 54static unsigned long bus_clk_recalc(struct clk *clk)
55{ 55{
56 int idx = (ctrl_inw(FREQCR) & 0x0007); 56 int idx = (__raw_readw(FREQCR) & 0x0007);
57 return clk->parent->rate / pfc_divisors[idx]; 57 return clk->parent->rate / pfc_divisors[idx];
58} 58}
59 59
@@ -63,7 +63,7 @@ static struct clk_ops sh7201_bus_clk_ops = {
63 63
64static unsigned long cpu_clk_recalc(struct clk *clk) 64static unsigned long cpu_clk_recalc(struct clk *clk)
65{ 65{
66 int idx = ((ctrl_inw(FREQCR) >> 4) & 0x0007); 66 int idx = ((__raw_readw(FREQCR) >> 4) & 0x0007);
67 return clk->parent->rate / ifc_divisors[idx]; 67 return clk->parent->rate / ifc_divisors[idx];
68} 68}
69 69
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
index 940986965102..7e75d8f79502 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
@@ -39,7 +39,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12};
39 39
40static void master_clk_init(struct clk *clk) 40static void master_clk_init(struct clk *clk)
41{ 41{
42 clk->rate *= pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0003] * PLL2 ; 42 clk->rate *= pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0003] * PLL2 ;
43} 43}
44 44
45static struct clk_ops sh7203_master_clk_ops = { 45static struct clk_ops sh7203_master_clk_ops = {
@@ -48,7 +48,7 @@ static struct clk_ops sh7203_master_clk_ops = {
48 48
49static unsigned long module_clk_recalc(struct clk *clk) 49static unsigned long module_clk_recalc(struct clk *clk)
50{ 50{
51 int idx = (ctrl_inw(FREQCR) & 0x0007); 51 int idx = (__raw_readw(FREQCR) & 0x0007);
52 return clk->parent->rate / pfc_divisors[idx]; 52 return clk->parent->rate / pfc_divisors[idx];
53} 53}
54 54
@@ -58,7 +58,7 @@ static struct clk_ops sh7203_module_clk_ops = {
58 58
59static unsigned long bus_clk_recalc(struct clk *clk) 59static unsigned long bus_clk_recalc(struct clk *clk)
60{ 60{
61 int idx = (ctrl_inw(FREQCR) & 0x0007); 61 int idx = (__raw_readw(FREQCR) & 0x0007);
62 return clk->parent->rate / pfc_divisors[idx-2]; 62 return clk->parent->rate / pfc_divisors[idx-2];
63} 63}
64 64
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
index c2268bdeceeb..b27a5e2687ab 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
@@ -34,7 +34,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12};
34 34
35static void master_clk_init(struct clk *clk) 35static void master_clk_init(struct clk *clk)
36{ 36{
37 clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; 37 clk->rate *= PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
38} 38}
39 39
40static struct clk_ops sh7206_master_clk_ops = { 40static struct clk_ops sh7206_master_clk_ops = {
@@ -43,7 +43,7 @@ static struct clk_ops sh7206_master_clk_ops = {
43 43
44static unsigned long module_clk_recalc(struct clk *clk) 44static unsigned long module_clk_recalc(struct clk *clk)
45{ 45{
46 int idx = (ctrl_inw(FREQCR) & 0x0007); 46 int idx = (__raw_readw(FREQCR) & 0x0007);
47 return clk->parent->rate / pfc_divisors[idx]; 47 return clk->parent->rate / pfc_divisors[idx];
48} 48}
49 49
@@ -53,7 +53,7 @@ static struct clk_ops sh7206_module_clk_ops = {
53 53
54static unsigned long bus_clk_recalc(struct clk *clk) 54static unsigned long bus_clk_recalc(struct clk *clk)
55{ 55{
56 return clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; 56 return clk->parent->rate / pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
57} 57}
58 58
59static struct clk_ops sh7206_bus_clk_ops = { 59static struct clk_ops sh7206_bus_clk_ops = {
@@ -62,7 +62,7 @@ static struct clk_ops sh7206_bus_clk_ops = {
62 62
63static unsigned long cpu_clk_recalc(struct clk *clk) 63static unsigned long cpu_clk_recalc(struct clk *clk)
64{ 64{
65 int idx = (ctrl_inw(FREQCR) & 0x0007); 65 int idx = (__raw_readw(FREQCR) & 0x0007);
66 return clk->parent->rate / ifc_divisors[idx]; 66 return clk->parent->rate / ifc_divisors[idx];
67} 67}
68 68
diff --git a/arch/sh/kernel/cpu/sh2a/fpu.c b/arch/sh/kernel/cpu/sh2a/fpu.c
index 6df2fb98eb30..488d24e0cdf0 100644
--- a/arch/sh/kernel/cpu/sh2a/fpu.c
+++ b/arch/sh/kernel/cpu/sh2a/fpu.c
@@ -25,14 +25,11 @@
25 25
26/* 26/*
27 * Save FPU registers onto task structure. 27 * Save FPU registers onto task structure.
28 * Assume called with FPU enabled (SR.FD=0).
29 */ 28 */
30void 29void save_fpu(struct task_struct *tsk)
31save_fpu(struct task_struct *tsk, struct pt_regs *regs)
32{ 30{
33 unsigned long dummy; 31 unsigned long dummy;
34 32
35 clear_tsk_thread_flag(tsk, TIF_USEDFPU);
36 enable_fpu(); 33 enable_fpu();
37 asm volatile("sts.l fpul, @-%0\n\t" 34 asm volatile("sts.l fpul, @-%0\n\t"
38 "sts.l fpscr, @-%0\n\t" 35 "sts.l fpscr, @-%0\n\t"
@@ -54,17 +51,15 @@ save_fpu(struct task_struct *tsk, struct pt_regs *regs)
54 "fmov.s fr0, @-%0\n\t" 51 "fmov.s fr0, @-%0\n\t"
55 "lds %3, fpscr\n\t" 52 "lds %3, fpscr\n\t"
56 : "=r" (dummy) 53 : "=r" (dummy)
57 : "0" ((char *)(&tsk->thread.fpu.hard.status)), 54 : "0" ((char *)(&tsk->thread.xstate->hardfpu.status)),
58 "r" (FPSCR_RCHG), 55 "r" (FPSCR_RCHG),
59 "r" (FPSCR_INIT) 56 "r" (FPSCR_INIT)
60 : "memory"); 57 : "memory");
61 58
62 disable_fpu(); 59 disable_fpu();
63 release_fpu(regs);
64} 60}
65 61
66static void 62void restore_fpu(struct task_struct *tsk)
67restore_fpu(struct task_struct *tsk)
68{ 63{
69 unsigned long dummy; 64 unsigned long dummy;
70 65
@@ -88,45 +83,12 @@ restore_fpu(struct task_struct *tsk)
88 "lds.l @%0+, fpscr\n\t" 83 "lds.l @%0+, fpscr\n\t"
89 "lds.l @%0+, fpul\n\t" 84 "lds.l @%0+, fpul\n\t"
90 : "=r" (dummy) 85 : "=r" (dummy)
91 : "0" (&tsk->thread.fpu), "r" (FPSCR_RCHG) 86 : "0" (tsk->thread.xstate), "r" (FPSCR_RCHG)
92 : "memory"); 87 : "memory");
93 disable_fpu(); 88 disable_fpu();
94} 89}
95 90
96/* 91/*
97 * Load the FPU with signalling NANS. This bit pattern we're using
98 * has the property that no matter wether considered as single or as
99 * double precission represents signaling NANS.
100 */
101
102static void
103fpu_init(void)
104{
105 enable_fpu();
106 asm volatile("lds %0, fpul\n\t"
107 "fsts fpul, fr0\n\t"
108 "fsts fpul, fr1\n\t"
109 "fsts fpul, fr2\n\t"
110 "fsts fpul, fr3\n\t"
111 "fsts fpul, fr4\n\t"
112 "fsts fpul, fr5\n\t"
113 "fsts fpul, fr6\n\t"
114 "fsts fpul, fr7\n\t"
115 "fsts fpul, fr8\n\t"
116 "fsts fpul, fr9\n\t"
117 "fsts fpul, fr10\n\t"
118 "fsts fpul, fr11\n\t"
119 "fsts fpul, fr12\n\t"
120 "fsts fpul, fr13\n\t"
121 "fsts fpul, fr14\n\t"
122 "fsts fpul, fr15\n\t"
123 "lds %2, fpscr\n\t"
124 : /* no output */
125 : "r" (0), "r" (FPSCR_RCHG), "r" (FPSCR_INIT));
126 disable_fpu();
127}
128
129/*
130 * Emulate arithmetic ops on denormalized number for some FPU insns. 92 * Emulate arithmetic ops on denormalized number for some FPU insns.
131 */ 93 */
132 94
@@ -493,9 +455,9 @@ ieee_fpe_handler (struct pt_regs *regs)
493 if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */ 455 if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */
494 struct task_struct *tsk = current; 456 struct task_struct *tsk = current;
495 457
496 if ((tsk->thread.fpu.hard.fpscr & FPSCR_FPU_ERROR)) { 458 if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_FPU_ERROR)) {
497 /* FPU error */ 459 /* FPU error */
498 denormal_to_double (&tsk->thread.fpu.hard, 460 denormal_to_double (&tsk->thread.xstate->hardfpu,
499 (finsn >> 8) & 0xf); 461 (finsn >> 8) & 0xf);
500 } else 462 } else
501 return 0; 463 return 0;
@@ -510,9 +472,9 @@ ieee_fpe_handler (struct pt_regs *regs)
510 472
511 n = (finsn >> 8) & 0xf; 473 n = (finsn >> 8) & 0xf;
512 m = (finsn >> 4) & 0xf; 474 m = (finsn >> 4) & 0xf;
513 hx = tsk->thread.fpu.hard.fp_regs[n]; 475 hx = tsk->thread.xstate->hardfpu.fp_regs[n];
514 hy = tsk->thread.fpu.hard.fp_regs[m]; 476 hy = tsk->thread.xstate->hardfpu.fp_regs[m];
515 fpscr = tsk->thread.fpu.hard.fpscr; 477 fpscr = tsk->thread.xstate->hardfpu.fpscr;
516 prec = fpscr & (1 << 19); 478 prec = fpscr & (1 << 19);
517 479
518 if ((fpscr & FPSCR_FPU_ERROR) 480 if ((fpscr & FPSCR_FPU_ERROR)
@@ -522,15 +484,15 @@ ieee_fpe_handler (struct pt_regs *regs)
522 484
523 /* FPU error because of denormal */ 485 /* FPU error because of denormal */
524 llx = ((long long) hx << 32) 486 llx = ((long long) hx << 32)
525 | tsk->thread.fpu.hard.fp_regs[n+1]; 487 | tsk->thread.xstate->hardfpu.fp_regs[n+1];
526 lly = ((long long) hy << 32) 488 lly = ((long long) hy << 32)
527 | tsk->thread.fpu.hard.fp_regs[m+1]; 489 | tsk->thread.xstate->hardfpu.fp_regs[m+1];
528 if ((hx & 0x7fffffff) >= 0x00100000) 490 if ((hx & 0x7fffffff) >= 0x00100000)
529 llx = denormal_muld(lly, llx); 491 llx = denormal_muld(lly, llx);
530 else 492 else
531 llx = denormal_muld(llx, lly); 493 llx = denormal_muld(llx, lly);
532 tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; 494 tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
533 tsk->thread.fpu.hard.fp_regs[n+1] = llx & 0xffffffff; 495 tsk->thread.xstate->hardfpu.fp_regs[n+1] = llx & 0xffffffff;
534 } else if ((fpscr & FPSCR_FPU_ERROR) 496 } else if ((fpscr & FPSCR_FPU_ERROR)
535 && (!prec && ((hx & 0x7fffffff) < 0x00800000 497 && (!prec && ((hx & 0x7fffffff) < 0x00800000
536 || (hy & 0x7fffffff) < 0x00800000))) { 498 || (hy & 0x7fffffff) < 0x00800000))) {
@@ -539,7 +501,7 @@ ieee_fpe_handler (struct pt_regs *regs)
539 hx = denormal_mulf(hy, hx); 501 hx = denormal_mulf(hy, hx);
540 else 502 else
541 hx = denormal_mulf(hx, hy); 503 hx = denormal_mulf(hx, hy);
542 tsk->thread.fpu.hard.fp_regs[n] = hx; 504 tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
543 } else 505 } else
544 return 0; 506 return 0;
545 507
@@ -553,9 +515,9 @@ ieee_fpe_handler (struct pt_regs *regs)
553 515
554 n = (finsn >> 8) & 0xf; 516 n = (finsn >> 8) & 0xf;
555 m = (finsn >> 4) & 0xf; 517 m = (finsn >> 4) & 0xf;
556 hx = tsk->thread.fpu.hard.fp_regs[n]; 518 hx = tsk->thread.xstate->hardfpu.fp_regs[n];
557 hy = tsk->thread.fpu.hard.fp_regs[m]; 519 hy = tsk->thread.xstate->hardfpu.fp_regs[m];
558 fpscr = tsk->thread.fpu.hard.fpscr; 520 fpscr = tsk->thread.xstate->hardfpu.fpscr;
559 prec = fpscr & (1 << 19); 521 prec = fpscr & (1 << 19);
560 522
561 if ((fpscr & FPSCR_FPU_ERROR) 523 if ((fpscr & FPSCR_FPU_ERROR)
@@ -565,15 +527,15 @@ ieee_fpe_handler (struct pt_regs *regs)
565 527
566 /* FPU error because of denormal */ 528 /* FPU error because of denormal */
567 llx = ((long long) hx << 32) 529 llx = ((long long) hx << 32)
568 | tsk->thread.fpu.hard.fp_regs[n+1]; 530 | tsk->thread.xstate->hardfpu.fp_regs[n+1];
569 lly = ((long long) hy << 32) 531 lly = ((long long) hy << 32)
570 | tsk->thread.fpu.hard.fp_regs[m+1]; 532 | tsk->thread.xstate->hardfpu.fp_regs[m+1];
571 if ((finsn & 0xf00f) == 0xf000) 533 if ((finsn & 0xf00f) == 0xf000)
572 llx = denormal_addd(llx, lly); 534 llx = denormal_addd(llx, lly);
573 else 535 else
574 llx = denormal_addd(llx, lly ^ (1LL << 63)); 536 llx = denormal_addd(llx, lly ^ (1LL << 63));
575 tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; 537 tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
576 tsk->thread.fpu.hard.fp_regs[n+1] = llx & 0xffffffff; 538 tsk->thread.xstate->hardfpu.fp_regs[n+1] = llx & 0xffffffff;
577 } else if ((fpscr & FPSCR_FPU_ERROR) 539 } else if ((fpscr & FPSCR_FPU_ERROR)
578 && (!prec && ((hx & 0x7fffffff) < 0x00800000 540 && (!prec && ((hx & 0x7fffffff) < 0x00800000
579 || (hy & 0x7fffffff) < 0x00800000))) { 541 || (hy & 0x7fffffff) < 0x00800000))) {
@@ -582,7 +544,7 @@ ieee_fpe_handler (struct pt_regs *regs)
582 hx = denormal_addf(hx, hy); 544 hx = denormal_addf(hx, hy);
583 else 545 else
584 hx = denormal_addf(hx, hy ^ 0x80000000); 546 hx = denormal_addf(hx, hy ^ 0x80000000);
585 tsk->thread.fpu.hard.fp_regs[n] = hx; 547 tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
586 } else 548 } else
587 return 0; 549 return 0;
588 550
@@ -598,37 +560,15 @@ BUILD_TRAP_HANDLER(fpu_error)
598 struct task_struct *tsk = current; 560 struct task_struct *tsk = current;
599 TRAP_HANDLER_DECL; 561 TRAP_HANDLER_DECL;
600 562
601 save_fpu(tsk, regs); 563 __unlazy_fpu(tsk, regs);
602 if (ieee_fpe_handler(regs)) { 564 if (ieee_fpe_handler(regs)) {
603 tsk->thread.fpu.hard.fpscr &= 565 tsk->thread.xstate->hardfpu.fpscr &=
604 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); 566 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
605 grab_fpu(regs); 567 grab_fpu(regs);
606 restore_fpu(tsk); 568 restore_fpu(tsk);
607 set_tsk_thread_flag(tsk, TIF_USEDFPU); 569 task_thread_info(tsk)->status |= TS_USEDFPU;
608 return; 570 return;
609 } 571 }
610 572
611 force_sig(SIGFPE, tsk); 573 force_sig(SIGFPE, tsk);
612} 574}
613
614BUILD_TRAP_HANDLER(fpu_state_restore)
615{
616 struct task_struct *tsk = current;
617 TRAP_HANDLER_DECL;
618
619 grab_fpu(regs);
620 if (!user_mode(regs)) {
621 printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
622 return;
623 }
624
625 if (used_math()) {
626 /* Using the FPU again. */
627 restore_fpu(tsk);
628 } else {
629 /* First time FPU user. */
630 fpu_init();
631 set_used_math();
632 }
633 set_tsk_thread_flag(tsk, TIF_USEDFPU);
634}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
index b67376445315..8f669dc9b0da 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
@@ -207,27 +207,23 @@ static struct platform_device mtu2_2_device = {
207 .num_resources = ARRAY_SIZE(mtu2_2_resources), 207 .num_resources = ARRAY_SIZE(mtu2_2_resources),
208}; 208};
209 209
210static struct plat_sci_port sci_platform_data[] = { 210static struct plat_sci_port scif0_platform_data = {
211 { 211 .mapbase = 0xff804000,
212 .mapbase = 0xff804000, 212 .flags = UPF_BOOT_AUTOCONF,
213 .flags = UPF_BOOT_AUTOCONF, 213 .type = PORT_SCIF,
214 .type = PORT_SCIF, 214 .irqs = { 220, 220, 220, 220 },
215 .irqs = { 220, 220, 220, 220 },
216 }, {
217 .flags = 0,
218 }
219}; 215};
220 216
221static struct platform_device sci_device = { 217static struct platform_device scif0_device = {
222 .name = "sh-sci", 218 .name = "sh-sci",
223 .id = -1, 219 .id = 0,
224 .dev = { 220 .dev = {
225 .platform_data = sci_platform_data, 221 .platform_data = &scif0_platform_data,
226 }, 222 },
227}; 223};
228 224
229static struct platform_device *mxg_devices[] __initdata = { 225static struct platform_device *mxg_devices[] __initdata = {
230 &sci_device, 226 &scif0_device,
231 &mtu2_0_device, 227 &mtu2_0_device,
232 &mtu2_1_device, 228 &mtu2_1_device,
233 &mtu2_2_device, 229 &mtu2_2_device,
@@ -246,6 +242,7 @@ void __init plat_irq_setup(void)
246} 242}
247 243
248static struct platform_device *mxg_early_devices[] __initdata = { 244static struct platform_device *mxg_early_devices[] __initdata = {
245 &scif0_device,
249 &mtu2_0_device, 246 &mtu2_0_device,
250 &mtu2_1_device, 247 &mtu2_1_device,
251 &mtu2_2_device, 248 &mtu2_2_device,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
index fbde5b75deb9..4ccfeb59eb1a 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
@@ -177,57 +177,123 @@ static struct intc_mask_reg mask_registers[] __initdata = {
177static DECLARE_INTC_DESC(intc_desc, "sh7201", vectors, groups, 177static DECLARE_INTC_DESC(intc_desc, "sh7201", vectors, groups,
178 mask_registers, prio_registers, NULL); 178 mask_registers, prio_registers, NULL);
179 179
180static struct plat_sci_port sci_platform_data[] = { 180static struct plat_sci_port scif0_platform_data = {
181 { 181 .mapbase = 0xfffe8000,
182 .mapbase = 0xfffe8000, 182 .flags = UPF_BOOT_AUTOCONF,
183 .flags = UPF_BOOT_AUTOCONF, 183 .type = PORT_SCIF,
184 .type = PORT_SCIF, 184 .irqs = { 180, 180, 180, 180 }
185 .irqs = { 180, 180, 180, 180 } 185};
186 }, { 186
187 .mapbase = 0xfffe8800, 187static struct platform_device scif0_device = {
188 .flags = UPF_BOOT_AUTOCONF,
189 .type = PORT_SCIF,
190 .irqs = { 184, 184, 184, 184 }
191 }, {
192 .mapbase = 0xfffe9000,
193 .flags = UPF_BOOT_AUTOCONF,
194 .type = PORT_SCIF,
195 .irqs = { 188, 188, 188, 188 }
196 }, {
197 .mapbase = 0xfffe9800,
198 .flags = UPF_BOOT_AUTOCONF,
199 .type = PORT_SCIF,
200 .irqs = { 192, 192, 192, 192 }
201 }, {
202 .mapbase = 0xfffea000,
203 .flags = UPF_BOOT_AUTOCONF,
204 .type = PORT_SCIF,
205 .irqs = { 196, 196, 196, 196 }
206 }, {
207 .mapbase = 0xfffea800,
208 .flags = UPF_BOOT_AUTOCONF,
209 .type = PORT_SCIF,
210 .irqs = { 200, 200, 200, 200 }
211 }, {
212 .mapbase = 0xfffeb000,
213 .flags = UPF_BOOT_AUTOCONF,
214 .type = PORT_SCIF,
215 .irqs = { 204, 204, 204, 204 }
216 }, {
217 .mapbase = 0xfffeb800,
218 .flags = UPF_BOOT_AUTOCONF,
219 .type = PORT_SCIF,
220 .irqs = { 208, 208, 208, 208 }
221 }, {
222 .flags = 0,
223 }
224};
225
226static struct platform_device sci_device = {
227 .name = "sh-sci", 188 .name = "sh-sci",
228 .id = -1, 189 .id = 0,
190 .dev = {
191 .platform_data = &scif0_platform_data,
192 },
193};
194
195static struct plat_sci_port scif1_platform_data = {
196 .mapbase = 0xfffe8800,
197 .flags = UPF_BOOT_AUTOCONF,
198 .type = PORT_SCIF,
199 .irqs = { 184, 184, 184, 184 }
200};
201
202static struct platform_device scif1_device = {
203 .name = "sh-sci",
204 .id = 1,
205 .dev = {
206 .platform_data = &scif1_platform_data,
207 },
208};
209
210static struct plat_sci_port scif2_platform_data = {
211 .mapbase = 0xfffe9000,
212 .flags = UPF_BOOT_AUTOCONF,
213 .type = PORT_SCIF,
214 .irqs = { 188, 188, 188, 188 }
215};
216
217static struct platform_device scif2_device = {
218 .name = "sh-sci",
219 .id = 2,
220 .dev = {
221 .platform_data = &scif2_platform_data,
222 },
223};
224
225static struct plat_sci_port scif3_platform_data = {
226 .mapbase = 0xfffe9800,
227 .flags = UPF_BOOT_AUTOCONF,
228 .type = PORT_SCIF,
229 .irqs = { 192, 192, 192, 192 }
230};
231
232static struct platform_device scif3_device = {
233 .name = "sh-sci",
234 .id = 3,
235 .dev = {
236 .platform_data = &scif3_platform_data,
237 },
238};
239
240static struct plat_sci_port scif4_platform_data = {
241 .mapbase = 0xfffea000,
242 .flags = UPF_BOOT_AUTOCONF,
243 .type = PORT_SCIF,
244 .irqs = { 196, 196, 196, 196 }
245};
246
247static struct platform_device scif4_device = {
248 .name = "sh-sci",
249 .id = 4,
250 .dev = {
251 .platform_data = &scif4_platform_data,
252 },
253};
254
255static struct plat_sci_port scif5_platform_data = {
256 .mapbase = 0xfffea800,
257 .flags = UPF_BOOT_AUTOCONF,
258 .type = PORT_SCIF,
259 .irqs = { 200, 200, 200, 200 }
260};
261
262static struct platform_device scif5_device = {
263 .name = "sh-sci",
264 .id = 5,
265 .dev = {
266 .platform_data = &scif5_platform_data,
267 },
268};
269
270static struct plat_sci_port scif6_platform_data = {
271 .mapbase = 0xfffeb000,
272 .flags = UPF_BOOT_AUTOCONF,
273 .type = PORT_SCIF,
274 .irqs = { 204, 204, 204, 204 }
275};
276
277static struct platform_device scif6_device = {
278 .name = "sh-sci",
279 .id = 6,
280 .dev = {
281 .platform_data = &scif6_platform_data,
282 },
283};
284
285static struct plat_sci_port scif7_platform_data = {
286 .mapbase = 0xfffeb800,
287 .flags = UPF_BOOT_AUTOCONF,
288 .type = PORT_SCIF,
289 .irqs = { 208, 208, 208, 208 }
290};
291
292static struct platform_device scif7_device = {
293 .name = "sh-sci",
294 .id = 7,
229 .dev = { 295 .dev = {
230 .platform_data = sci_platform_data, 296 .platform_data = &scif7_platform_data,
231 }, 297 },
232}; 298};
233 299
@@ -345,7 +411,14 @@ static struct platform_device mtu2_2_device = {
345}; 411};
346 412
347static struct platform_device *sh7201_devices[] __initdata = { 413static struct platform_device *sh7201_devices[] __initdata = {
348 &sci_device, 414 &scif0_device,
415 &scif1_device,
416 &scif2_device,
417 &scif3_device,
418 &scif4_device,
419 &scif5_device,
420 &scif6_device,
421 &scif7_device,
349 &rtc_device, 422 &rtc_device,
350 &mtu2_0_device, 423 &mtu2_0_device,
351 &mtu2_1_device, 424 &mtu2_1_device,
@@ -365,6 +438,14 @@ void __init plat_irq_setup(void)
365} 438}
366 439
367static struct platform_device *sh7201_early_devices[] __initdata = { 440static struct platform_device *sh7201_early_devices[] __initdata = {
441 &scif0_device,
442 &scif1_device,
443 &scif2_device,
444 &scif3_device,
445 &scif4_device,
446 &scif5_device,
447 &scif6_device,
448 &scif7_device,
368 &mtu2_0_device, 449 &mtu2_0_device,
369 &mtu2_1_device, 450 &mtu2_1_device,
370 &mtu2_2_device, 451 &mtu2_2_device,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
index d3fd536c9a84..3136966cc9b3 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
@@ -173,37 +173,63 @@ static struct intc_mask_reg mask_registers[] __initdata = {
173static DECLARE_INTC_DESC(intc_desc, "sh7203", vectors, groups, 173static DECLARE_INTC_DESC(intc_desc, "sh7203", vectors, groups,
174 mask_registers, prio_registers, NULL); 174 mask_registers, prio_registers, NULL);
175 175
176static struct plat_sci_port sci_platform_data[] = { 176static struct plat_sci_port scif0_platform_data = {
177 { 177 .mapbase = 0xfffe8000,
178 .mapbase = 0xfffe8000, 178 .flags = UPF_BOOT_AUTOCONF,
179 .flags = UPF_BOOT_AUTOCONF, 179 .type = PORT_SCIF,
180 .type = PORT_SCIF, 180 .irqs = { 192, 192, 192, 192 },
181 .irqs = { 192, 192, 192, 192 },
182 }, {
183 .mapbase = 0xfffe8800,
184 .flags = UPF_BOOT_AUTOCONF,
185 .type = PORT_SCIF,
186 .irqs = { 196, 196, 196, 196 },
187 }, {
188 .mapbase = 0xfffe9000,
189 .flags = UPF_BOOT_AUTOCONF,
190 .type = PORT_SCIF,
191 .irqs = { 200, 200, 200, 200 },
192 }, {
193 .mapbase = 0xfffe9800,
194 .flags = UPF_BOOT_AUTOCONF,
195 .type = PORT_SCIF,
196 .irqs = { 204, 204, 204, 204 },
197 }, {
198 .flags = 0,
199 }
200}; 181};
201 182
202static struct platform_device sci_device = { 183static struct platform_device scif0_device = {
203 .name = "sh-sci", 184 .name = "sh-sci",
204 .id = -1, 185 .id = 0,
186 .dev = {
187 .platform_data = &scif0_platform_data,
188 },
189};
190
191static struct plat_sci_port scif1_platform_data = {
192 .mapbase = 0xfffe8800,
193 .flags = UPF_BOOT_AUTOCONF,
194 .type = PORT_SCIF,
195 .irqs = { 196, 196, 196, 196 },
196};
197
198static struct platform_device scif1_device = {
199 .name = "sh-sci",
200 .id = 1,
201 .dev = {
202 .platform_data = &scif1_platform_data,
203 },
204};
205
206static struct plat_sci_port scif2_platform_data = {
207 .mapbase = 0xfffe9000,
208 .flags = UPF_BOOT_AUTOCONF,
209 .type = PORT_SCIF,
210 .irqs = { 200, 200, 200, 200 },
211};
212
213static struct platform_device scif2_device = {
214 .name = "sh-sci",
215 .id = 2,
216 .dev = {
217 .platform_data = &scif2_platform_data,
218 },
219};
220
221static struct plat_sci_port scif3_platform_data = {
222 .mapbase = 0xfffe9800,
223 .flags = UPF_BOOT_AUTOCONF,
224 .type = PORT_SCIF,
225 .irqs = { 204, 204, 204, 204 },
226};
227
228static struct platform_device scif3_device = {
229 .name = "sh-sci",
230 .id = 3,
205 .dev = { 231 .dev = {
206 .platform_data = sci_platform_data, 232 .platform_data = &scif3_platform_data,
207 }, 233 },
208}; 234};
209 235
@@ -354,7 +380,10 @@ static struct platform_device rtc_device = {
354}; 380};
355 381
356static struct platform_device *sh7203_devices[] __initdata = { 382static struct platform_device *sh7203_devices[] __initdata = {
357 &sci_device, 383 &scif0_device,
384 &scif1_device,
385 &scif2_device,
386 &scif3_device,
358 &cmt0_device, 387 &cmt0_device,
359 &cmt1_device, 388 &cmt1_device,
360 &mtu2_0_device, 389 &mtu2_0_device,
@@ -375,6 +404,10 @@ void __init plat_irq_setup(void)
375} 404}
376 405
377static struct platform_device *sh7203_early_devices[] __initdata = { 406static struct platform_device *sh7203_early_devices[] __initdata = {
407 &scif0_device,
408 &scif1_device,
409 &scif2_device,
410 &scif3_device,
378 &cmt0_device, 411 &cmt0_device,
379 &cmt1_device, 412 &cmt1_device,
380 &mtu2_0_device, 413 &mtu2_0_device,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index a9ccc5e8d9e9..064873585a8b 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -133,37 +133,63 @@ static struct intc_mask_reg mask_registers[] __initdata = {
133static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups, 133static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups,
134 mask_registers, prio_registers, NULL); 134 mask_registers, prio_registers, NULL);
135 135
136static struct plat_sci_port sci_platform_data[] = { 136static struct plat_sci_port scif0_platform_data = {
137 { 137 .mapbase = 0xfffe8000,
138 .mapbase = 0xfffe8000, 138 .flags = UPF_BOOT_AUTOCONF,
139 .flags = UPF_BOOT_AUTOCONF, 139 .type = PORT_SCIF,
140 .type = PORT_SCIF, 140 .irqs = { 240, 240, 240, 240 },
141 .irqs = { 240, 240, 240, 240 },
142 }, {
143 .mapbase = 0xfffe8800,
144 .flags = UPF_BOOT_AUTOCONF,
145 .type = PORT_SCIF,
146 .irqs = { 244, 244, 244, 244 },
147 }, {
148 .mapbase = 0xfffe9000,
149 .flags = UPF_BOOT_AUTOCONF,
150 .type = PORT_SCIF,
151 .irqs = { 248, 248, 248, 248 },
152 }, {
153 .mapbase = 0xfffe9800,
154 .flags = UPF_BOOT_AUTOCONF,
155 .type = PORT_SCIF,
156 .irqs = { 252, 252, 252, 252 },
157 }, {
158 .flags = 0,
159 }
160}; 141};
161 142
162static struct platform_device sci_device = { 143static struct platform_device scif0_device = {
163 .name = "sh-sci", 144 .name = "sh-sci",
164 .id = -1, 145 .id = 0,
146 .dev = {
147 .platform_data = &scif0_platform_data,
148 },
149};
150
151static struct plat_sci_port scif1_platform_data = {
152 .mapbase = 0xfffe8800,
153 .flags = UPF_BOOT_AUTOCONF,
154 .type = PORT_SCIF,
155 .irqs = { 244, 244, 244, 244 },
156};
157
158static struct platform_device scif1_device = {
159 .name = "sh-sci",
160 .id = 1,
161 .dev = {
162 .platform_data = &scif1_platform_data,
163 },
164};
165
166static struct plat_sci_port scif2_platform_data = {
167 .mapbase = 0xfffe9000,
168 .flags = UPF_BOOT_AUTOCONF,
169 .type = PORT_SCIF,
170 .irqs = { 248, 248, 248, 248 },
171};
172
173static struct platform_device scif2_device = {
174 .name = "sh-sci",
175 .id = 2,
176 .dev = {
177 .platform_data = &scif2_platform_data,
178 },
179};
180
181static struct plat_sci_port scif3_platform_data = {
182 .mapbase = 0xfffe9800,
183 .flags = UPF_BOOT_AUTOCONF,
184 .type = PORT_SCIF,
185 .irqs = { 252, 252, 252, 252 },
186};
187
188static struct platform_device scif3_device = {
189 .name = "sh-sci",
190 .id = 3,
165 .dev = { 191 .dev = {
166 .platform_data = sci_platform_data, 192 .platform_data = &scif3_platform_data,
167 }, 193 },
168}; 194};
169 195
@@ -325,7 +351,10 @@ static struct platform_device mtu2_2_device = {
325}; 351};
326 352
327static struct platform_device *sh7206_devices[] __initdata = { 353static struct platform_device *sh7206_devices[] __initdata = {
328 &sci_device, 354 &scif0_device,
355 &scif1_device,
356 &scif2_device,
357 &scif3_device,
329 &cmt0_device, 358 &cmt0_device,
330 &cmt1_device, 359 &cmt1_device,
331 &mtu2_0_device, 360 &mtu2_0_device,
@@ -346,6 +375,10 @@ void __init plat_irq_setup(void)
346} 375}
347 376
348static struct platform_device *sh7206_early_devices[] __initdata = { 377static struct platform_device *sh7206_early_devices[] __initdata = {
378 &scif0_device,
379 &scif1_device,
380 &scif2_device,
381 &scif3_device,
349 &cmt0_device, 382 &cmt0_device,
350 &cmt1_device, 383 &cmt1_device,
351 &mtu2_0_device, 384 &mtu2_0_device,
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh3.c b/arch/sh/kernel/cpu/sh3/clock-sh3.c
index 27b8738f0b09..b78384afac09 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh3.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh3.c
@@ -28,7 +28,7 @@ static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
28 28
29static void master_clk_init(struct clk *clk) 29static void master_clk_init(struct clk *clk)
30{ 30{
31 int frqcr = ctrl_inw(FRQCR); 31 int frqcr = __raw_readw(FRQCR);
32 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); 32 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
33 33
34 clk->rate *= pfc_divisors[idx]; 34 clk->rate *= pfc_divisors[idx];
@@ -40,7 +40,7 @@ static struct clk_ops sh3_master_clk_ops = {
40 40
41static unsigned long module_clk_recalc(struct clk *clk) 41static unsigned long module_clk_recalc(struct clk *clk)
42{ 42{
43 int frqcr = ctrl_inw(FRQCR); 43 int frqcr = __raw_readw(FRQCR);
44 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); 44 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
45 45
46 return clk->parent->rate / pfc_divisors[idx]; 46 return clk->parent->rate / pfc_divisors[idx];
@@ -52,7 +52,7 @@ static struct clk_ops sh3_module_clk_ops = {
52 52
53static unsigned long bus_clk_recalc(struct clk *clk) 53static unsigned long bus_clk_recalc(struct clk *clk)
54{ 54{
55 int frqcr = ctrl_inw(FRQCR); 55 int frqcr = __raw_readw(FRQCR);
56 int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4); 56 int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4);
57 57
58 return clk->parent->rate / stc_multipliers[idx]; 58 return clk->parent->rate / stc_multipliers[idx];
@@ -64,7 +64,7 @@ static struct clk_ops sh3_bus_clk_ops = {
64 64
65static unsigned long cpu_clk_recalc(struct clk *clk) 65static unsigned long cpu_clk_recalc(struct clk *clk)
66{ 66{
67 int frqcr = ctrl_inw(FRQCR); 67 int frqcr = __raw_readw(FRQCR);
68 int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); 68 int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2);
69 69
70 return clk->parent->rate / ifc_divisors[idx]; 70 return clk->parent->rate / ifc_divisors[idx];
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7705.c b/arch/sh/kernel/cpu/sh3/clock-sh7705.c
index 0ca8f2c3646c..0ecea1451c6f 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7705.c
@@ -32,7 +32,7 @@ static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
32 32
33static void master_clk_init(struct clk *clk) 33static void master_clk_init(struct clk *clk)
34{ 34{
35 clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0003]; 35 clk->rate *= pfc_divisors[__raw_readw(FRQCR) & 0x0003];
36} 36}
37 37
38static struct clk_ops sh7705_master_clk_ops = { 38static struct clk_ops sh7705_master_clk_ops = {
@@ -41,7 +41,7 @@ static struct clk_ops sh7705_master_clk_ops = {
41 41
42static unsigned long module_clk_recalc(struct clk *clk) 42static unsigned long module_clk_recalc(struct clk *clk)
43{ 43{
44 int idx = ctrl_inw(FRQCR) & 0x0003; 44 int idx = __raw_readw(FRQCR) & 0x0003;
45 return clk->parent->rate / pfc_divisors[idx]; 45 return clk->parent->rate / pfc_divisors[idx];
46} 46}
47 47
@@ -51,7 +51,7 @@ static struct clk_ops sh7705_module_clk_ops = {
51 51
52static unsigned long bus_clk_recalc(struct clk *clk) 52static unsigned long bus_clk_recalc(struct clk *clk)
53{ 53{
54 int idx = (ctrl_inw(FRQCR) & 0x0300) >> 8; 54 int idx = (__raw_readw(FRQCR) & 0x0300) >> 8;
55 return clk->parent->rate / stc_multipliers[idx]; 55 return clk->parent->rate / stc_multipliers[idx];
56} 56}
57 57
@@ -61,7 +61,7 @@ static struct clk_ops sh7705_bus_clk_ops = {
61 61
62static unsigned long cpu_clk_recalc(struct clk *clk) 62static unsigned long cpu_clk_recalc(struct clk *clk)
63{ 63{
64 int idx = (ctrl_inw(FRQCR) & 0x0030) >> 4; 64 int idx = (__raw_readw(FRQCR) & 0x0030) >> 4;
65 return clk->parent->rate / ifc_divisors[idx]; 65 return clk->parent->rate / ifc_divisors[idx];
66} 66}
67 67
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7706.c b/arch/sh/kernel/cpu/sh3/clock-sh7706.c
index 4bf7887d310a..6f9ff8b57dd6 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh7706.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7706.c
@@ -24,7 +24,7 @@ static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 };
24 24
25static void master_clk_init(struct clk *clk) 25static void master_clk_init(struct clk *clk)
26{ 26{
27 int frqcr = ctrl_inw(FRQCR); 27 int frqcr = __raw_readw(FRQCR);
28 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); 28 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
29 29
30 clk->rate *= pfc_divisors[idx]; 30 clk->rate *= pfc_divisors[idx];
@@ -36,7 +36,7 @@ static struct clk_ops sh7706_master_clk_ops = {
36 36
37static unsigned long module_clk_recalc(struct clk *clk) 37static unsigned long module_clk_recalc(struct clk *clk)
38{ 38{
39 int frqcr = ctrl_inw(FRQCR); 39 int frqcr = __raw_readw(FRQCR);
40 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); 40 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
41 41
42 return clk->parent->rate / pfc_divisors[idx]; 42 return clk->parent->rate / pfc_divisors[idx];
@@ -48,7 +48,7 @@ static struct clk_ops sh7706_module_clk_ops = {
48 48
49static unsigned long bus_clk_recalc(struct clk *clk) 49static unsigned long bus_clk_recalc(struct clk *clk)
50{ 50{
51 int frqcr = ctrl_inw(FRQCR); 51 int frqcr = __raw_readw(FRQCR);
52 int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4); 52 int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4);
53 53
54 return clk->parent->rate / stc_multipliers[idx]; 54 return clk->parent->rate / stc_multipliers[idx];
@@ -60,7 +60,7 @@ static struct clk_ops sh7706_bus_clk_ops = {
60 60
61static unsigned long cpu_clk_recalc(struct clk *clk) 61static unsigned long cpu_clk_recalc(struct clk *clk)
62{ 62{
63 int frqcr = ctrl_inw(FRQCR); 63 int frqcr = __raw_readw(FRQCR);
64 int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); 64 int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2);
65 65
66 return clk->parent->rate / ifc_divisors[idx]; 66 return clk->parent->rate / ifc_divisors[idx];
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7709.c b/arch/sh/kernel/cpu/sh3/clock-sh7709.c
index e8749505bd2a..f302ba09e681 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh7709.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7709.c
@@ -24,7 +24,7 @@ static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 };
24 24
25static void master_clk_init(struct clk *clk) 25static void master_clk_init(struct clk *clk)
26{ 26{
27 int frqcr = ctrl_inw(FRQCR); 27 int frqcr = __raw_readw(FRQCR);
28 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); 28 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
29 29
30 clk->rate *= pfc_divisors[idx]; 30 clk->rate *= pfc_divisors[idx];
@@ -36,7 +36,7 @@ static struct clk_ops sh7709_master_clk_ops = {
36 36
37static unsigned long module_clk_recalc(struct clk *clk) 37static unsigned long module_clk_recalc(struct clk *clk)
38{ 38{
39 int frqcr = ctrl_inw(FRQCR); 39 int frqcr = __raw_readw(FRQCR);
40 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); 40 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
41 41
42 return clk->parent->rate / pfc_divisors[idx]; 42 return clk->parent->rate / pfc_divisors[idx];
@@ -48,7 +48,7 @@ static struct clk_ops sh7709_module_clk_ops = {
48 48
49static unsigned long bus_clk_recalc(struct clk *clk) 49static unsigned long bus_clk_recalc(struct clk *clk)
50{ 50{
51 int frqcr = ctrl_inw(FRQCR); 51 int frqcr = __raw_readw(FRQCR);
52 int idx = (frqcr & 0x0080) ? 52 int idx = (frqcr & 0x0080) ?
53 ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4) : 1; 53 ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4) : 1;
54 54
@@ -61,7 +61,7 @@ static struct clk_ops sh7709_bus_clk_ops = {
61 61
62static unsigned long cpu_clk_recalc(struct clk *clk) 62static unsigned long cpu_clk_recalc(struct clk *clk)
63{ 63{
64 int frqcr = ctrl_inw(FRQCR); 64 int frqcr = __raw_readw(FRQCR);
65 int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); 65 int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2);
66 66
67 return clk->parent->rate / ifc_divisors[idx]; 67 return clk->parent->rate / ifc_divisors[idx];
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7710.c b/arch/sh/kernel/cpu/sh3/clock-sh7710.c
index 030a58ba18a5..29a87d8946a4 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7710.c
@@ -26,7 +26,7 @@ static int md_table[] = { 1, 2, 3, 4, 6, 8, 12 };
26 26
27static void master_clk_init(struct clk *clk) 27static void master_clk_init(struct clk *clk)
28{ 28{
29 clk->rate *= md_table[ctrl_inw(FRQCR) & 0x0007]; 29 clk->rate *= md_table[__raw_readw(FRQCR) & 0x0007];
30} 30}
31 31
32static struct clk_ops sh7710_master_clk_ops = { 32static struct clk_ops sh7710_master_clk_ops = {
@@ -35,7 +35,7 @@ static struct clk_ops sh7710_master_clk_ops = {
35 35
36static unsigned long module_clk_recalc(struct clk *clk) 36static unsigned long module_clk_recalc(struct clk *clk)
37{ 37{
38 int idx = (ctrl_inw(FRQCR) & 0x0007); 38 int idx = (__raw_readw(FRQCR) & 0x0007);
39 return clk->parent->rate / md_table[idx]; 39 return clk->parent->rate / md_table[idx];
40} 40}
41 41
@@ -45,7 +45,7 @@ static struct clk_ops sh7710_module_clk_ops = {
45 45
46static unsigned long bus_clk_recalc(struct clk *clk) 46static unsigned long bus_clk_recalc(struct clk *clk)
47{ 47{
48 int idx = (ctrl_inw(FRQCR) & 0x0700) >> 8; 48 int idx = (__raw_readw(FRQCR) & 0x0700) >> 8;
49 return clk->parent->rate / md_table[idx]; 49 return clk->parent->rate / md_table[idx];
50} 50}
51 51
@@ -55,7 +55,7 @@ static struct clk_ops sh7710_bus_clk_ops = {
55 55
56static unsigned long cpu_clk_recalc(struct clk *clk) 56static unsigned long cpu_clk_recalc(struct clk *clk)
57{ 57{
58 int idx = (ctrl_inw(FRQCR) & 0x0070) >> 4; 58 int idx = (__raw_readw(FRQCR) & 0x0070) >> 4;
59 return clk->parent->rate / md_table[idx]; 59 return clk->parent->rate / md_table[idx];
60} 60}
61 61
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7712.c b/arch/sh/kernel/cpu/sh3/clock-sh7712.c
index 6428ee6c77ed..b0d0c5203996 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh7712.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7712.c
@@ -23,7 +23,7 @@ static int divisors[] = { 1, 2, 3, 4, 6 };
23 23
24static void master_clk_init(struct clk *clk) 24static void master_clk_init(struct clk *clk)
25{ 25{
26 int frqcr = ctrl_inw(FRQCR); 26 int frqcr = __raw_readw(FRQCR);
27 int idx = (frqcr & 0x0300) >> 8; 27 int idx = (frqcr & 0x0300) >> 8;
28 28
29 clk->rate *= multipliers[idx]; 29 clk->rate *= multipliers[idx];
@@ -35,7 +35,7 @@ static struct clk_ops sh7712_master_clk_ops = {
35 35
36static unsigned long module_clk_recalc(struct clk *clk) 36static unsigned long module_clk_recalc(struct clk *clk)
37{ 37{
38 int frqcr = ctrl_inw(FRQCR); 38 int frqcr = __raw_readw(FRQCR);
39 int idx = frqcr & 0x0007; 39 int idx = frqcr & 0x0007;
40 40
41 return clk->parent->rate / divisors[idx]; 41 return clk->parent->rate / divisors[idx];
@@ -47,7 +47,7 @@ static struct clk_ops sh7712_module_clk_ops = {
47 47
48static unsigned long cpu_clk_recalc(struct clk *clk) 48static unsigned long cpu_clk_recalc(struct clk *clk)
49{ 49{
50 int frqcr = ctrl_inw(FRQCR); 50 int frqcr = __raw_readw(FRQCR);
51 int idx = (frqcr & 0x0030) >> 4; 51 int idx = (frqcr & 0x0030) >> 4;
52 52
53 return clk->parent->rate / divisors[idx]; 53 return clk->parent->rate / divisors[idx];
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index bb407ef0b91e..f6a389c996cb 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -132,7 +132,6 @@ ENTRY(tlb_protection_violation_store)
132 mov #1, r5 132 mov #1, r5
133 133
134call_handle_tlbmiss: 134call_handle_tlbmiss:
135 setup_frame_reg
136 mov.l 1f, r0 135 mov.l 1f, r0
137 mov r5, r8 136 mov r5, r8
138 mov.l @r0, r6 137 mov.l @r0, r6
@@ -297,41 +296,8 @@ ENTRY(vbr_base)
297! 296!
298 .balign 256,0,256 297 .balign 256,0,256
299general_exception: 298general_exception:
300#ifndef CONFIG_CPU_SUBTYPE_SHX3
301 bra handle_exception 299 bra handle_exception
302 sts pr, k3 ! save original pr value in k3 300 sts pr, k3 ! save original pr value in k3
303#else
304 mov.l 1f, k4
305 mov.l @k4, k4
306
307 ! Is EXPEVT larger than 0x800?
308 mov #0x8, k0
309 shll8 k0
310 cmp/hs k0, k4
311 bf 0f
312
313 ! then add 0x580 (k2 is 0xd80 or 0xda0)
314 mov #0x58, k0
315 shll2 k0
316 shll2 k0
317 add k0, k4
3180:
319 ! Setup stack and save DSP context (k0 contains original r15 on return)
320 bsr prepare_stack
321 nop
322
323 ! Save registers / Switch to bank 0
324 mov k4, k2 ! keep vector in k2
325 mov.l 1f, k4 ! SR bits to clear in k4
326 bsr save_regs ! needs original pr value in k3
327 nop
328
329 bra handle_exception_special
330 nop
331
332 .align 2
3331: .long EXPEVT
334#endif
335 301
336! prepare_stack() 302! prepare_stack()
337! - roll back gRB 303! - roll back gRB
@@ -398,6 +364,8 @@ handle_exception:
398 mov.l @k2, k2 ! read out vector and keep in k2 364 mov.l @k2, k2 ! read out vector and keep in k2
399 365
400handle_exception_special: 366handle_exception_special:
367 setup_frame_reg
368
401 ! Setup return address and jump to exception handler 369 ! Setup return address and jump to exception handler
402 mov.l 7f, r9 ! fetch return address 370 mov.l 7f, r9 ! fetch return address
403 stc r2_bank, r0 ! k2 (vector) 371 stc r2_bank, r0 ! k2 (vector)
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index 46610c35c232..99b4d020179a 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -49,7 +49,7 @@ ENTRY(exception_handling_table)
49 .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */ 49 .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */
50 .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/ 50 .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/
51 .long nmi_trap_handler /* 1C0 */ ! Allow trap to debugger 51 .long nmi_trap_handler /* 1C0 */ ! Allow trap to debugger
52 .long break_point_trap /* 1E0 */ 52 .long breakpoint_trap_handler /* 1E0 */
53 53
54 /* 54 /*
55 * Pad the remainder of the table out, exceptions residing in far 55 * Pad the remainder of the table out, exceptions residing in far
diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c
index f9c7df64eb01..295ec4c99e98 100644
--- a/arch/sh/kernel/cpu/sh3/probe.c
+++ b/arch/sh/kernel/cpu/sh3/probe.c
@@ -16,7 +16,7 @@
16#include <asm/cache.h> 16#include <asm/cache.h>
17#include <asm/io.h> 17#include <asm/io.h>
18 18
19int __uses_jump_to_uncached detect_cpu_and_cache_system(void) 19int detect_cpu_and_cache_system(void)
20{ 20{
21 unsigned long addr0, addr1, data0, data1, data2, data3; 21 unsigned long addr0, addr1, data0, data1, data2, data3;
22 22
@@ -30,23 +30,23 @@ int __uses_jump_to_uncached detect_cpu_and_cache_system(void)
30 addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12); 30 addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12);
31 31
32 /* First, write back & invalidate */ 32 /* First, write back & invalidate */
33 data0 = ctrl_inl(addr0); 33 data0 = __raw_readl(addr0);
34 ctrl_outl(data0&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr0); 34 __raw_writel(data0&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr0);
35 data1 = ctrl_inl(addr1); 35 data1 = __raw_readl(addr1);
36 ctrl_outl(data1&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr1); 36 __raw_writel(data1&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr1);
37 37
38 /* Next, check if there's shadow or not */ 38 /* Next, check if there's shadow or not */
39 data0 = ctrl_inl(addr0); 39 data0 = __raw_readl(addr0);
40 data0 ^= SH_CACHE_VALID; 40 data0 ^= SH_CACHE_VALID;
41 ctrl_outl(data0, addr0); 41 __raw_writel(data0, addr0);
42 data1 = ctrl_inl(addr1); 42 data1 = __raw_readl(addr1);
43 data2 = data1 ^ SH_CACHE_VALID; 43 data2 = data1 ^ SH_CACHE_VALID;
44 ctrl_outl(data2, addr1); 44 __raw_writel(data2, addr1);
45 data3 = ctrl_inl(addr0); 45 data3 = __raw_readl(addr0);
46 46
47 /* Lastly, invaliate them. */ 47 /* Lastly, invaliate them. */
48 ctrl_outl(data0&~SH_CACHE_VALID, addr0); 48 __raw_writel(data0&~SH_CACHE_VALID, addr0);
49 ctrl_outl(data2&~SH_CACHE_VALID, addr1); 49 __raw_writel(data2&~SH_CACHE_VALID, addr1);
50 50
51 back_to_cached(); 51 back_to_cached();
52 52
@@ -94,9 +94,9 @@ int __uses_jump_to_uncached detect_cpu_and_cache_system(void)
94 boot_cpu_data.dcache.way_incr = (1 << 13); 94 boot_cpu_data.dcache.way_incr = (1 << 13);
95 boot_cpu_data.dcache.entry_mask = 0x1ff0; 95 boot_cpu_data.dcache.entry_mask = 0x1ff0;
96 boot_cpu_data.dcache.sets = 512; 96 boot_cpu_data.dcache.sets = 512;
97 ctrl_outl(CCR_CACHE_32KB, CCR3_REG); 97 __raw_writel(CCR_CACHE_32KB, CCR3_REG);
98#else 98#else
99 ctrl_outl(CCR_CACHE_16KB, CCR3_REG); 99 __raw_writel(CCR_CACHE_16KB, CCR3_REG);
100#endif 100#endif
101#endif 101#endif
102 } 102 }
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh3.c b/arch/sh/kernel/cpu/sh3/setup-sh3.c
index c98846857855..53be70b98116 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh3.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh3.c
@@ -58,7 +58,7 @@ static DECLARE_INTC_DESC_ACK(intc_desc_irq45, "sh3-irq45",
58void __init plat_irq_setup_pins(int mode) 58void __init plat_irq_setup_pins(int mode)
59{ 59{
60 if (mode == IRQ_MODE_IRQ) { 60 if (mode == IRQ_MODE_IRQ) {
61 ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1); 61 __raw_writew(__raw_readw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1);
62 register_intc_controller(&intc_desc_irq0123); 62 register_intc_controller(&intc_desc_irq0123);
63 return; 63 return;
64 } 64 }
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index c23105983878..7b892d60e3a0 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -67,27 +67,33 @@ static struct intc_prio_reg prio_registers[] __initdata = {
67static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, NULL, 67static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, NULL,
68 NULL, prio_registers, NULL); 68 NULL, prio_registers, NULL);
69 69
70static struct plat_sci_port sci_platform_data[] = { 70static struct plat_sci_port scif0_platform_data = {
71 { 71 .mapbase = 0xa4410000,
72 .mapbase = 0xa4410000, 72 .flags = UPF_BOOT_AUTOCONF,
73 .flags = UPF_BOOT_AUTOCONF, 73 .type = PORT_SCIF,
74 .type = PORT_SCIF, 74 .irqs = { 56, 56, 56 },
75 .irqs = { 56, 56, 56 }, 75};
76 }, { 76
77 .mapbase = 0xa4400000, 77static struct platform_device scif0_device = {
78 .flags = UPF_BOOT_AUTOCONF,
79 .type = PORT_SCIF,
80 .irqs = { 52, 52, 52 },
81 }, {
82 .flags = 0,
83 }
84};
85
86static struct platform_device sci_device = {
87 .name = "sh-sci", 78 .name = "sh-sci",
88 .id = -1, 79 .id = 0,
80 .dev = {
81 .platform_data = &scif0_platform_data,
82 },
83};
84
85static struct plat_sci_port scif1_platform_data = {
86 .mapbase = 0xa4400000,
87 .flags = UPF_BOOT_AUTOCONF,
88 .type = PORT_SCIF,
89 .irqs = { 52, 52, 52 },
90};
91
92static struct platform_device scif1_device = {
93 .name = "sh-sci",
94 .id = 1,
89 .dev = { 95 .dev = {
90 .platform_data = sci_platform_data, 96 .platform_data = &scif1_platform_data,
91 }, 97 },
92}; 98};
93 99
@@ -210,10 +216,11 @@ static struct platform_device tmu2_device = {
210}; 216};
211 217
212static struct platform_device *sh7705_devices[] __initdata = { 218static struct platform_device *sh7705_devices[] __initdata = {
219 &scif0_device,
220 &scif1_device,
213 &tmu0_device, 221 &tmu0_device,
214 &tmu1_device, 222 &tmu1_device,
215 &tmu2_device, 223 &tmu2_device,
216 &sci_device,
217 &rtc_device, 224 &rtc_device,
218}; 225};
219 226
@@ -225,6 +232,8 @@ static int __init sh7705_devices_setup(void)
225arch_initcall(sh7705_devices_setup); 232arch_initcall(sh7705_devices_setup);
226 233
227static struct platform_device *sh7705_early_devices[] __initdata = { 234static struct platform_device *sh7705_early_devices[] __initdata = {
235 &scif0_device,
236 &scif1_device,
228 &tmu0_device, 237 &tmu0_device,
229 &tmu1_device, 238 &tmu1_device,
230 &tmu2_device, 239 &tmu2_device,
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
index 347ab35d0697..bc0c4f68c7c7 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
@@ -106,44 +106,55 @@ static struct platform_device rtc_device = {
106 .resource = rtc_resources, 106 .resource = rtc_resources,
107}; 107};
108 108
109static struct plat_sci_port sci_platform_data[] = { 109static struct plat_sci_port scif0_platform_data = {
110 { 110 .mapbase = 0xfffffe80,
111 .mapbase = 0xfffffe80, 111 .flags = UPF_BOOT_AUTOCONF,
112 .flags = UPF_BOOT_AUTOCONF, 112 .type = PORT_SCI,
113 .type = PORT_SCI, 113 .irqs = { 23, 23, 23, 0 },
114 .irqs = { 23, 23, 23, 0 }, 114};
115
116static struct platform_device scif0_device = {
117 .name = "sh-sci",
118 .id = 0,
119 .dev = {
120 .platform_data = &scif0_platform_data,
115 }, 121 },
122};
116#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ 123#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
117 defined(CONFIG_CPU_SUBTYPE_SH7707) || \ 124 defined(CONFIG_CPU_SUBTYPE_SH7707) || \
118 defined(CONFIG_CPU_SUBTYPE_SH7709) 125 defined(CONFIG_CPU_SUBTYPE_SH7709)
119 { 126static struct plat_sci_port scif1_platform_data = {
120 .mapbase = 0xa4000150, 127 .mapbase = 0xa4000150,
121 .flags = UPF_BOOT_AUTOCONF, 128 .flags = UPF_BOOT_AUTOCONF,
122 .type = PORT_SCIF, 129 .type = PORT_SCIF,
123 .irqs = { 56, 56, 56, 56 }, 130 .irqs = { 56, 56, 56, 56 },
131};
132
133static struct platform_device scif1_device = {
134 .name = "sh-sci",
135 .id = 1,
136 .dev = {
137 .platform_data = &scif1_platform_data,
124 }, 138 },
139};
125#endif 140#endif
126#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ 141#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
127 defined(CONFIG_CPU_SUBTYPE_SH7709) 142 defined(CONFIG_CPU_SUBTYPE_SH7709)
128 { 143static struct plat_sci_port scif2_platform_data = {
129 .mapbase = 0xa4000140, 144 .mapbase = 0xa4000140,
130 .flags = UPF_BOOT_AUTOCONF, 145 .flags = UPF_BOOT_AUTOCONF,
131 .type = PORT_IRDA, 146 .type = PORT_IRDA,
132 .irqs = { 52, 52, 52, 52 }, 147 .irqs = { 52, 52, 52, 52 },
133 },
134#endif
135 {
136 .flags = 0,
137 }
138}; 148};
139 149
140static struct platform_device sci_device = { 150static struct platform_device scif2_device = {
141 .name = "sh-sci", 151 .name = "sh-sci",
142 .id = -1, 152 .id = 2,
143 .dev = { 153 .dev = {
144 .platform_data = sci_platform_data, 154 .platform_data = &scif2_platform_data,
145 }, 155 },
146}; 156};
157#endif
147 158
148static struct sh_timer_config tmu0_platform_data = { 159static struct sh_timer_config tmu0_platform_data = {
149 .name = "TMU0", 160 .name = "TMU0",
@@ -238,10 +249,19 @@ static struct platform_device tmu2_device = {
238}; 249};
239 250
240static struct platform_device *sh770x_devices[] __initdata = { 251static struct platform_device *sh770x_devices[] __initdata = {
252 &scif0_device,
253#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
254 defined(CONFIG_CPU_SUBTYPE_SH7707) || \
255 defined(CONFIG_CPU_SUBTYPE_SH7709)
256 &scif1_device,
257#endif
258#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
259 defined(CONFIG_CPU_SUBTYPE_SH7709)
260 &scif2_device,
261#endif
241 &tmu0_device, 262 &tmu0_device,
242 &tmu1_device, 263 &tmu1_device,
243 &tmu2_device, 264 &tmu2_device,
244 &sci_device,
245 &rtc_device, 265 &rtc_device,
246}; 266};
247 267
@@ -253,6 +273,16 @@ static int __init sh770x_devices_setup(void)
253arch_initcall(sh770x_devices_setup); 273arch_initcall(sh770x_devices_setup);
254 274
255static struct platform_device *sh770x_early_devices[] __initdata = { 275static struct platform_device *sh770x_early_devices[] __initdata = {
276 &scif0_device,
277#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
278 defined(CONFIG_CPU_SUBTYPE_SH7707) || \
279 defined(CONFIG_CPU_SUBTYPE_SH7709)
280 &scif1_device,
281#endif
282#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
283 defined(CONFIG_CPU_SUBTYPE_SH7709)
284 &scif2_device,
285#endif
256 &tmu0_device, 286 &tmu0_device,
257 &tmu1_device, 287 &tmu1_device,
258 &tmu2_device, 288 &tmu2_device,
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 717e90ae1097..0845a3ad006d 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -96,28 +96,33 @@ static struct platform_device rtc_device = {
96 }, 96 },
97}; 97};
98 98
99static struct plat_sci_port sci_platform_data[] = { 99static struct plat_sci_port scif0_platform_data = {
100 { 100 .mapbase = 0xa4400000,
101 .mapbase = 0xa4400000, 101 .flags = UPF_BOOT_AUTOCONF,
102 .flags = UPF_BOOT_AUTOCONF, 102 .type = PORT_SCIF,
103 .type = PORT_SCIF, 103 .irqs = { 52, 52, 52, 52 },
104 .irqs = { 52, 52, 52, 52 }, 104};
105 }, { 105
106 .mapbase = 0xa4410000, 106static struct platform_device scif0_device = {
107 .flags = UPF_BOOT_AUTOCONF,
108 .type = PORT_SCIF,
109 .irqs = { 56, 56, 56, 56 },
110 }, {
111
112 .flags = 0,
113 }
114};
115
116static struct platform_device sci_device = {
117 .name = "sh-sci", 107 .name = "sh-sci",
118 .id = -1, 108 .id = 0,
109 .dev = {
110 .platform_data = &scif0_platform_data,
111 },
112};
113
114static struct plat_sci_port scif1_platform_data = {
115 .mapbase = 0xa4410000,
116 .flags = UPF_BOOT_AUTOCONF,
117 .type = PORT_SCIF,
118 .irqs = { 56, 56, 56, 56 },
119};
120
121static struct platform_device scif1_device = {
122 .name = "sh-sci",
123 .id = 1,
119 .dev = { 124 .dev = {
120 .platform_data = sci_platform_data, 125 .platform_data = &scif1_platform_data,
121 }, 126 },
122}; 127};
123 128
@@ -214,10 +219,11 @@ static struct platform_device tmu2_device = {
214}; 219};
215 220
216static struct platform_device *sh7710_devices[] __initdata = { 221static struct platform_device *sh7710_devices[] __initdata = {
222 &scif0_device,
223 &scif1_device,
217 &tmu0_device, 224 &tmu0_device,
218 &tmu1_device, 225 &tmu1_device,
219 &tmu2_device, 226 &tmu2_device,
220 &sci_device,
221 &rtc_device, 227 &rtc_device,
222}; 228};
223 229
@@ -229,6 +235,8 @@ static int __init sh7710_devices_setup(void)
229arch_initcall(sh7710_devices_setup); 235arch_initcall(sh7710_devices_setup);
230 236
231static struct platform_device *sh7710_early_devices[] __initdata = { 237static struct platform_device *sh7710_early_devices[] __initdata = {
238 &scif0_device,
239 &scif1_device,
232 &tmu0_device, 240 &tmu0_device,
233 &tmu1_device, 241 &tmu1_device,
234 &tmu2_device, 242 &tmu2_device,
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index 74d8baaf8e96..a718a6231091 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -48,28 +48,33 @@ static struct platform_device rtc_device = {
48 }, 48 },
49}; 49};
50 50
51static struct plat_sci_port sci_platform_data[] = { 51static struct plat_sci_port scif0_platform_data = {
52 { 52 .mapbase = 0xa4430000,
53 .mapbase = 0xa4430000, 53 .flags = UPF_BOOT_AUTOCONF,
54 .flags = UPF_BOOT_AUTOCONF, 54 .type = PORT_SCIF,
55 .type = PORT_SCIF, 55 .irqs = { 80, 80, 80, 80 },
56 .irqs = { 80, 80, 80, 80 }, 56};
57 }, { 57
58 .mapbase = 0xa4438000, 58static struct platform_device scif0_device = {
59 .flags = UPF_BOOT_AUTOCONF,
60 .type = PORT_SCIF,
61 .irqs = { 81, 81, 81, 81 },
62 }, {
63
64 .flags = 0,
65 }
66};
67
68static struct platform_device sci_device = {
69 .name = "sh-sci", 59 .name = "sh-sci",
70 .id = -1, 60 .id = 0,
61 .dev = {
62 .platform_data = &scif0_platform_data,
63 },
64};
65
66static struct plat_sci_port scif1_platform_data = {
67 .mapbase = 0xa4438000,
68 .flags = UPF_BOOT_AUTOCONF,
69 .type = PORT_SCIF,
70 .irqs = { 81, 81, 81, 81 },
71};
72
73static struct platform_device scif1_device = {
74 .name = "sh-sci",
75 .id = 1,
71 .dev = { 76 .dev = {
72 .platform_data = sci_platform_data, 77 .platform_data = &scif1_platform_data,
73 }, 78 },
74}; 79};
75 80
@@ -369,6 +374,8 @@ static struct platform_device tmu2_device = {
369}; 374};
370 375
371static struct platform_device *sh7720_devices[] __initdata = { 376static struct platform_device *sh7720_devices[] __initdata = {
377 &scif0_device,
378 &scif1_device,
372 &cmt0_device, 379 &cmt0_device,
373 &cmt1_device, 380 &cmt1_device,
374 &cmt2_device, 381 &cmt2_device,
@@ -378,7 +385,6 @@ static struct platform_device *sh7720_devices[] __initdata = {
378 &tmu1_device, 385 &tmu1_device,
379 &tmu2_device, 386 &tmu2_device,
380 &rtc_device, 387 &rtc_device,
381 &sci_device,
382 &usb_ohci_device, 388 &usb_ohci_device,
383 &usbf_device, 389 &usbf_device,
384}; 390};
@@ -391,6 +397,8 @@ static int __init sh7720_devices_setup(void)
391arch_initcall(sh7720_devices_setup); 397arch_initcall(sh7720_devices_setup);
392 398
393static struct platform_device *sh7720_early_devices[] __initdata = { 399static struct platform_device *sh7720_early_devices[] __initdata = {
400 &scif0_device,
401 &scif1_device,
394 &cmt0_device, 402 &cmt0_device,
395 &cmt1_device, 403 &cmt1_device,
396 &cmt2_device, 404 &cmt2_device,
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)
9obj-$(CONFIG_SH_FPU) += fpu.o softfloat.o 9obj-$(CONFIG_SH_FPU) += fpu.o softfloat.o
10obj-$(CONFIG_SH_STORE_QUEUES) += sq.o 10obj-$(CONFIG_SH_STORE_QUEUES) += sq.o
11 11
12# Perf events
13perf-$(CONFIG_CPU_SUBTYPE_SH7750) := perf_event.o
14perf-$(CONFIG_CPU_SUBTYPE_SH7750S) := perf_event.o
15perf-$(CONFIG_CPU_SUBTYPE_SH7091) := perf_event.o
16
12# CPU subtype setup 17# CPU subtype setup
13obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o 18obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o
14obj-$(CONFIG_CPU_SUBTYPE_SH7750R) += setup-sh7750.o 19obj-$(CONFIG_CPU_SUBTYPE_SH7750R) += setup-sh7750.o
@@ -27,4 +32,5 @@ endif
27# Additional clocks by subtype 32# Additional clocks by subtype
28clock-$(CONFIG_CPU_SUBTYPE_SH4_202) += clock-sh4-202.o 33clock-$(CONFIG_CPU_SUBTYPE_SH4_202) += clock-sh4-202.o
29 34
30obj-y += $(clock-y) 35obj-y += $(clock-y)
36obj-$(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..6b80850294da 100644
--- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
@@ -23,7 +23,7 @@ static int frqcr3_values[] = { 0, 1, 2, 3, 4, 5, 6 };
23 23
24static unsigned long emi_clk_recalc(struct clk *clk) 24static unsigned long emi_clk_recalc(struct clk *clk)
25{ 25{
26 int idx = ctrl_inl(CPG2_FRQCR3) & 0x0007; 26 int idx = __raw_readl(CPG2_FRQCR3) & 0x0007;
27 return clk->parent->rate / frqcr3_divisors[idx]; 27 return clk->parent->rate / frqcr3_divisors[idx];
28} 28}
29 29
@@ -52,7 +52,7 @@ static struct clk sh4202_emi_clk = {
52 52
53static unsigned long femi_clk_recalc(struct clk *clk) 53static 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
@@ -92,7 +92,7 @@ static void shoc_clk_init(struct clk *clk)
92 92
93static unsigned long shoc_clk_recalc(struct clk *clk) 93static unsigned long shoc_clk_recalc(struct clk *clk)
94{ 94{
95 int idx = (ctrl_inl(CPG2_FRQCR3) >> 6) & 0x0007; 95 int idx = (__raw_readl(CPG2_FRQCR3) >> 6) & 0x0007;
96 return clk->parent->rate / frqcr3_divisors[idx]; 96 return clk->parent->rate / frqcr3_divisors[idx];
97} 97}
98 98
@@ -122,10 +122,10 @@ static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id)
122 122
123 tmp = frqcr3_lookup(clk, rate); 123 tmp = frqcr3_lookup(clk, rate);
124 124
125 frqcr3 = ctrl_inl(CPG2_FRQCR3); 125 frqcr3 = __raw_readl(CPG2_FRQCR3);
126 frqcr3 &= ~(0x0007 << 6); 126 frqcr3 &= ~(0x0007 << 6);
127 frqcr3 |= tmp << 6; 127 frqcr3 |= tmp << 6;
128 ctrl_outl(frqcr3, CPG2_FRQCR3); 128 __raw_writel(frqcr3, CPG2_FRQCR3);
129 129
130 clk->rate = clk->parent->rate / frqcr3_divisors[tmp]; 130 clk->rate = clk->parent->rate / frqcr3_divisors[tmp];
131 131
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
29static void master_clk_init(struct clk *clk) 29static 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
34static struct clk_ops sh4_master_clk_ops = { 34static struct clk_ops sh4_master_clk_ops = {
@@ -37,7 +37,7 @@ static struct clk_ops sh4_master_clk_ops = {
37 37
38static unsigned long module_clk_recalc(struct clk *clk) 38static 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
48static unsigned long bus_clk_recalc(struct clk *clk) 48static 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
58static unsigned long cpu_clk_recalc(struct clk *clk) 58static 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 */
46void save_fpu(struct task_struct *tsk, struct pt_regs *regs) 45void 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
98static void restore_fpu(struct task_struct *tsk) 95void 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
152static 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)
453int float_rounding_mode(void) 398int 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
486BUILD_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..7f9ecc9c2d02
--- /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
31static 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
77static 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
89static 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
185static int sh7750_event_map(int event)
186{
187 return sh7750_general_events[event];
188}
189
190static u64 sh7750_pmu_read(int idx)
191{
192 return (u64)((u64)(__raw_readl(PMCTRH(idx)) & 0xffff) << 32) |
193 __raw_readl(PMCTRL(idx));
194}
195
196static 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
205static 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
211static 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
219static 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
227static 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
241static 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}
253arch_initcall(sh7750_pmu_init);
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index d36f0c45f55f..822977a06d84 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -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
@@ -71,11 +71,11 @@ int __init detect_cpu_and_cache_system(void)
71 boot_cpu_data.dcache.ways = 4; 71 boot_cpu_data.dcache.ways = 4;
72 } else { 72 } else {
73 /* And some SH-4 defaults.. */ 73 /* And some SH-4 defaults.. */
74 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; 75 boot_cpu_data.family = CPU_FAMILY_SH4;
76 } 76 }
77 77
78 /* FPU detection works for everyone */ 78 /* FPU detection works for almost everyone */
79 if ((cvr & 0x20000000)) 79 if ((cvr & 0x20000000))
80 boot_cpu_data.flags |= CPU_HAS_FPU; 80 boot_cpu_data.flags |= CPU_HAS_FPU;
81 81
@@ -124,6 +124,7 @@ int __init detect_cpu_and_cache_system(void)
124 boot_cpu_data.type = CPU_SH7785; 124 boot_cpu_data.type = CPU_SH7785;
125 break; 125 break;
126 case 0x4004: 126 case 0x4004:
127 case 0x4005:
127 boot_cpu_data.type = CPU_SH7786; 128 boot_cpu_data.type = CPU_SH7786;
128 boot_cpu_data.flags |= CPU_HAS_PTEAEX | CPU_HAS_L2_CACHE; 129 boot_cpu_data.flags |= CPU_HAS_PTEAEX | CPU_HAS_L2_CACHE;
129 break; 130 break;
@@ -160,6 +161,7 @@ int __init detect_cpu_and_cache_system(void)
160 break; 161 break;
161 case 0x700: 162 case 0x700:
162 boot_cpu_data.type = CPU_SH4_501; 163 boot_cpu_data.type = CPU_SH4_501;
164 boot_cpu_data.flags &= ~CPU_HAS_FPU;
163 boot_cpu_data.icache.ways = 2; 165 boot_cpu_data.icache.ways = 2;
164 boot_cpu_data.dcache.ways = 2; 166 boot_cpu_data.dcache.ways = 2;
165 break; 167 break;
@@ -227,7 +229,7 @@ int __init detect_cpu_and_cache_system(void)
227 * Size calculation is much more sensible 229 * Size calculation is much more sensible
228 * than it is for the L1. 230 * than it is for the L1.
229 * 231 *
230 * Sizes are 128KB, 258KB, 512KB, and 1MB. 232 * Sizes are 128KB, 256KB, 512KB, and 1MB.
231 */ 233 */
232 size = (cvr & 0xf) << 17; 234 size = (cvr & 0xf) << 17;
233 235
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
index de4827df19aa..b9b7e10ad68f 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
@@ -15,22 +15,18 @@
15#include <linux/sh_timer.h> 15#include <linux/sh_timer.h>
16#include <linux/io.h> 16#include <linux/io.h>
17 17
18static struct plat_sci_port sci_platform_data[] = { 18static 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 .type = PORT_SCIF,
22 .type = PORT_SCIF, 22 .irqs = { 40, 41, 43, 42 },
23 .irqs = { 40, 41, 43, 42 },
24 }, {
25 .flags = 0,
26 }
27}; 23};
28 24
29static struct platform_device sci_device = { 25static struct platform_device scif0_device = {
30 .name = "sh-sci", 26 .name = "sh-sci",
31 .id = -1, 27 .id = 0,
32 .dev = { 28 .dev = {
33 .platform_data = sci_platform_data, 29 .platform_data = &scif0_platform_data,
34 }, 30 },
35}; 31};
36 32
@@ -127,7 +123,7 @@ static struct platform_device tmu2_device = {
127}; 123};
128 124
129static struct platform_device *sh4202_devices[] __initdata = { 125static struct platform_device *sh4202_devices[] __initdata = {
130 &sci_device, 126 &scif0_device,
131 &tmu0_device, 127 &tmu0_device,
132 &tmu1_device, 128 &tmu1_device,
133 &tmu2_device, 129 &tmu2_device,
@@ -141,6 +137,7 @@ static int __init sh4202_devices_setup(void)
141arch_initcall(sh4202_devices_setup); 137arch_initcall(sh4202_devices_setup);
142 138
143static struct platform_device *sh4202_early_devices[] __initdata = { 139static struct platform_device *sh4202_early_devices[] __initdata = {
140 &scif0_device,
144 &tmu0_device, 141 &tmu0_device,
145 &tmu1_device, 142 &tmu1_device,
146 &tmu2_device, 143 &tmu2_device,
@@ -201,7 +198,7 @@ void __init plat_irq_setup_pins(int mode)
201{ 198{
202 switch (mode) { 199 switch (mode) {
203 case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */ 200 case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */
204 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); 201 __raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
205 register_intc_controller(&intc_desc_irlm); 202 register_intc_controller(&intc_desc_irlm);
206 break; 203 break;
207 default: 204 default:
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index 1b8b122e8f3d..ffd79e57254f 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -35,29 +35,33 @@ static struct platform_device rtc_device = {
35 .resource = rtc_resources, 35 .resource = rtc_resources,
36}; 36};
37 37
38static struct plat_sci_port sci_platform_data[] = { 38static struct plat_sci_port scif0_platform_data = {
39 { 39 .mapbase = 0xffe00000,
40#ifndef CONFIG_SH_RTS7751R2D 40 .flags = UPF_BOOT_AUTOCONF,
41 .mapbase = 0xffe00000, 41 .type = PORT_SCI,
42 .flags = UPF_BOOT_AUTOCONF, 42 .irqs = { 23, 23, 23, 0 },
43 .type = PORT_SCI,
44 .irqs = { 23, 23, 23, 0 },
45 }, {
46#endif
47 .mapbase = 0xffe80000,
48 .flags = UPF_BOOT_AUTOCONF,
49 .type = PORT_SCIF,
50 .irqs = { 40, 40, 40, 40 },
51 }, {
52 .flags = 0,
53 }
54}; 43};
55 44
56static struct platform_device sci_device = { 45static struct platform_device scif0_device = {
57 .name = "sh-sci", 46 .name = "sh-sci",
58 .id = -1, 47 .id = 0,
48 .dev = {
49 .platform_data = &scif0_platform_data,
50 },
51};
52
53static struct plat_sci_port scif1_platform_data = {
54 .mapbase = 0xffe80000,
55 .flags = UPF_BOOT_AUTOCONF,
56 .type = PORT_SCIF,
57 .irqs = { 40, 40, 40, 40 },
58};
59
60static struct platform_device scif1_device = {
61 .name = "sh-sci",
62 .id = 1,
59 .dev = { 63 .dev = {
60 .platform_data = sci_platform_data, 64 .platform_data = &scif1_platform_data,
61 }, 65 },
62}; 66};
63 67
@@ -221,8 +225,9 @@ static struct platform_device tmu4_device = {
221#endif 225#endif
222 226
223static struct platform_device *sh7750_devices[] __initdata = { 227static struct platform_device *sh7750_devices[] __initdata = {
228 &scif0_device,
229 &scif1_device,
224 &rtc_device, 230 &rtc_device,
225 &sci_device,
226 &tmu0_device, 231 &tmu0_device,
227 &tmu1_device, 232 &tmu1_device,
228 &tmu2_device, 233 &tmu2_device,
@@ -242,6 +247,8 @@ static int __init sh7750_devices_setup(void)
242arch_initcall(sh7750_devices_setup); 247arch_initcall(sh7750_devices_setup);
243 248
244static struct platform_device *sh7750_early_devices[] __initdata = { 249static struct platform_device *sh7750_early_devices[] __initdata = {
250 &scif0_device,
251 &scif1_device,
245 &tmu0_device, 252 &tmu0_device,
246 &tmu1_device, 253 &tmu1_device,
247 &tmu2_device, 254 &tmu2_device,
@@ -435,7 +442,7 @@ void __init plat_irq_setup_pins(int mode)
435 442
436 switch (mode) { 443 switch (mode) {
437 case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */ 444 case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */
438 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); 445 __raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
439 register_intc_controller(&intc_desc_irlm); 446 register_intc_controller(&intc_desc_irlm);
440 break; 447 break;
441 default: 448 default:
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index 7fbb7be9284c..a16eb3656f4b 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -126,37 +126,63 @@ static struct intc_vect vectors_irq[] __initdata = {
126static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups, 126static 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
129static struct plat_sci_port sci_platform_data[] = { 129static 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 .type = PORT_SCIF,
133 .type = PORT_SCIF, 133 .irqs = { 52, 53, 55, 54 },
134 .irqs = { 52, 53, 55, 54 }, 134};
135 }, { 135
136 .mapbase = 0xfe610000, 136static struct platform_device scif0_device = {
137 .flags = UPF_BOOT_AUTOCONF, 137 .name = "sh-sci",
138 .type = PORT_SCIF, 138 .id = 0,
139 .irqs = { 72, 73, 75, 74 }, 139 .dev = {
140 }, { 140 .platform_data = &scif0_platform_data,
141 .mapbase = 0xfe620000, 141 },
142 .flags = UPF_BOOT_AUTOCONF, 142};
143 .type = PORT_SCIF, 143
144 .irqs = { 76, 77, 79, 78 }, 144static struct plat_sci_port scif1_platform_data = {
145 }, { 145 .mapbase = 0xfe610000,
146 .mapbase = 0xfe480000, 146 .flags = UPF_BOOT_AUTOCONF,
147 .flags = UPF_BOOT_AUTOCONF, 147 .type = PORT_SCIF,
148 .type = PORT_SCI, 148 .irqs = { 72, 73, 75, 74 },
149 .irqs = { 80, 81, 82, 0 }, 149};
150 }, { 150
151 .flags = 0, 151static struct platform_device scif1_device = {
152 } 152 .name = "sh-sci",
153 .id = 1,
154 .dev = {
155 .platform_data = &scif1_platform_data,
156 },
157};
158
159static struct plat_sci_port scif2_platform_data = {
160 .mapbase = 0xfe620000,
161 .flags = UPF_BOOT_AUTOCONF,
162 .type = PORT_SCIF,
163 .irqs = { 76, 77, 79, 78 },
164};
165
166static struct platform_device scif2_device = {
167 .name = "sh-sci",
168 .id = 2,
169 .dev = {
170 .platform_data = &scif2_platform_data,
171 },
172};
173
174static struct plat_sci_port scif3_platform_data = {
175 .mapbase = 0xfe480000,
176 .flags = UPF_BOOT_AUTOCONF,
177 .type = PORT_SCI,
178 .irqs = { 80, 81, 82, 0 },
153}; 179};
154 180
155static struct platform_device sci_device = { 181static struct platform_device scif3_device = {
156 .name = "sh-sci", 182 .name = "sh-sci",
157 .id = -1, 183 .id = 3,
158 .dev = { 184 .dev = {
159 .platform_data = sci_platform_data, 185 .platform_data = &scif3_platform_data,
160 }, 186 },
161}; 187};
162 188
@@ -254,7 +280,10 @@ static struct platform_device tmu2_device = {
254 280
255 281
256static struct platform_device *sh7760_devices[] __initdata = { 282static struct platform_device *sh7760_devices[] __initdata = {
257 &sci_device, 283 &scif0_device,
284 &scif1_device,
285 &scif2_device,
286 &scif3_device,
258 &tmu0_device, 287 &tmu0_device,
259 &tmu1_device, 288 &tmu1_device,
260 &tmu2_device, 289 &tmu2_device,
@@ -268,6 +297,10 @@ static int __init sh7760_devices_setup(void)
268arch_initcall(sh7760_devices_setup); 297arch_initcall(sh7760_devices_setup);
269 298
270static struct platform_device *sh7760_early_devices[] __initdata = { 299static struct platform_device *sh7760_early_devices[] __initdata = {
300 &scif0_device,
301 &scif1_device,
302 &scif2_device,
303 &scif3_device,
271 &tmu0_device, 304 &tmu0_device,
272 &tmu1_device, 305 &tmu1_device,
273 &tmu2_device, 306 &tmu2_device,
@@ -286,7 +319,7 @@ void __init plat_irq_setup_pins(int mode)
286{ 319{
287 switch (mode) { 320 switch (mode) {
288 case IRQ_MODE_IRQ: 321 case IRQ_MODE_IRQ:
289 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); 322 __raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
290 register_intc_controller(&intc_desc_irq); 323 register_intc_controller(&intc_desc_irq);
291 break; 324 break;
292 default: 325 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() \
45do { \ 45do { \
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
103static int __sq_remap(struct sq_mapping *map, unsigned long flags) 103static 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 */
144unsigned long sq_remap(unsigned long phys, unsigned int size, 144unsigned 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
330static struct sysfs_ops sq_sysfs_ops = { 329static 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};
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index 490d5dc9e372..b144e8af89dc 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -41,6 +41,8 @@ pinmux-$(CONFIG_CPU_SUBTYPE_SH7757) := pinmux-sh7757.o
41pinmux-$(CONFIG_CPU_SUBTYPE_SH7785) := pinmux-sh7785.o 41pinmux-$(CONFIG_CPU_SUBTYPE_SH7785) := pinmux-sh7785.o
42pinmux-$(CONFIG_CPU_SUBTYPE_SH7786) := pinmux-sh7786.o 42pinmux-$(CONFIG_CPU_SUBTYPE_SH7786) := pinmux-sh7786.o
43 43
44obj-y += $(clock-y) 44obj-y += $(clock-y)
45obj-$(CONFIG_SMP) += $(smp-y) 45obj-$(CONFIG_SMP) += $(smp-y)
46obj-$(CONFIG_GENERIC_GPIO) += $(pinmux-y) 46obj-$(CONFIG_GENERIC_GPIO) += $(pinmux-y)
47obj-$(CONFIG_PERF_EVENTS) += perf_event.o
48obj-$(CONFIG_HAVE_HW_BREAKPOINT) += ubc.o
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
index 0ee3ee861252..2c16df37eda6 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
@@ -107,13 +107,17 @@ struct clk *main_clks[] = {
107static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; 107static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
108static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 }; 108static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
109 109
110static struct clk_div_mult_table div4_table = { 110static struct clk_div_mult_table div4_div_mult_table = {
111 .divisors = divisors, 111 .divisors = divisors,
112 .nr_divisors = ARRAY_SIZE(divisors), 112 .nr_divisors = ARRAY_SIZE(divisors),
113 .multipliers = multipliers, 113 .multipliers = multipliers,
114 .nr_multipliers = ARRAY_SIZE(multipliers), 114 .nr_multipliers = ARRAY_SIZE(multipliers),
115}; 115};
116 116
117static struct clk_div4_table div4_table = {
118 .div_mult_table = &div4_div_mult_table,
119};
120
117enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, 121enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
118 DIV4_SIUA, DIV4_SIUB, DIV4_NR }; 122 DIV4_SIUA, DIV4_SIUB, DIV4_NR };
119 123
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
index a95ebaba095c..91588d280cd8 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
@@ -110,13 +110,17 @@ struct clk *main_clks[] = {
110static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; 110static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
111static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 }; 111static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
112 112
113static struct clk_div_mult_table div4_table = { 113static struct clk_div_mult_table div4_div_mult_table = {
114 .divisors = divisors, 114 .divisors = divisors,
115 .nr_divisors = ARRAY_SIZE(divisors), 115 .nr_divisors = ARRAY_SIZE(divisors),
116 .multipliers = multipliers, 116 .multipliers = multipliers,
117 .nr_multipliers = ARRAY_SIZE(multipliers), 117 .nr_multipliers = ARRAY_SIZE(multipliers),
118}; 118};
119 119
120static struct clk_div4_table div4_table = {
121 .div_mult_table = &div4_div_mult_table,
122};
123
120enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, 124enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
121 DIV4_SIUA, DIV4_SIUB, DIV4_NR }; 125 DIV4_SIUA, DIV4_SIUB, DIV4_NR };
122 126
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index ea38b554dc05..15db6d521c5c 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -110,19 +110,22 @@ struct clk *main_clks[] = {
110static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; 110static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
111static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 }; 111static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
112 112
113static struct clk_div_mult_table div4_table = { 113static struct clk_div_mult_table div4_div_mult_table = {
114 .divisors = divisors, 114 .divisors = divisors,
115 .nr_divisors = ARRAY_SIZE(divisors), 115 .nr_divisors = ARRAY_SIZE(divisors),
116 .multipliers = multipliers, 116 .multipliers = multipliers,
117 .nr_multipliers = ARRAY_SIZE(multipliers), 117 .nr_multipliers = ARRAY_SIZE(multipliers),
118}; 118};
119 119
120enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, 120static struct clk_div4_table div4_table = {
121 DIV4_SIUA, DIV4_SIUB, DIV4_IRDA, DIV4_NR }; 121 .div_mult_table = &div4_div_mult_table,
122};
122 123
123#define DIV4(_str, _reg, _bit, _mask, _flags) \ 124#define DIV4(_str, _reg, _bit, _mask, _flags) \
124 SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags) 125 SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags)
125 126
127enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR };
128
126struct clk div4_clks[DIV4_NR] = { 129struct clk div4_clks[DIV4_NR] = {
127 [DIV4_I] = DIV4("cpu_clk", FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT), 130 [DIV4_I] = DIV4("cpu_clk", FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT),
128 [DIV4_U] = DIV4("umem_clk", FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT), 131 [DIV4_U] = DIV4("umem_clk", FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
@@ -130,9 +133,19 @@ struct clk div4_clks[DIV4_NR] = {
130 [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT), 133 [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
131 [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT), 134 [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
132 [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x1fff, 0), 135 [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x1fff, 0),
136};
137
138enum { DIV4_IRDA, DIV4_ENABLE_NR };
139
140struct clk div4_enable_clks[DIV4_ENABLE_NR] = {
141 [DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x1fff, 0),
142};
143
144enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR };
145
146struct clk div4_reparent_clks[DIV4_REPARENT_NR] = {
133 [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x1fff, 0), 147 [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x1fff, 0),
134 [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0), 148 [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0),
135 [DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x1fff, 0),
136}; 149};
137 150
138struct clk div6_clks[] = { 151struct clk div6_clks[] = {
@@ -189,6 +202,14 @@ int __init arch_clk_init(void)
189 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); 202 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
190 203
191 if (!ret) 204 if (!ret)
205 ret = sh_clk_div4_enable_register(div4_enable_clks,
206 DIV4_ENABLE_NR, &div4_table);
207
208 if (!ret)
209 ret = sh_clk_div4_reparent_register(div4_reparent_clks,
210 DIV4_REPARENT_NR, &div4_table);
211
212 if (!ret)
192 ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks)); 213 ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
193 214
194 if (!ret) 215 if (!ret)
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index 20a31c2255a8..50babe01fe44 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -110,15 +110,18 @@ struct clk *main_clks[] = {
110static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; 110static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
111static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 }; 111static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
112 112
113static struct clk_div_mult_table div4_table = { 113static struct clk_div_mult_table div4_div_mult_table = {
114 .divisors = divisors, 114 .divisors = divisors,
115 .nr_divisors = ARRAY_SIZE(divisors), 115 .nr_divisors = ARRAY_SIZE(divisors),
116 .multipliers = multipliers, 116 .multipliers = multipliers,
117 .nr_multipliers = ARRAY_SIZE(multipliers), 117 .nr_multipliers = ARRAY_SIZE(multipliers),
118}; 118};
119 119
120enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, 120static struct clk_div4_table div4_table = {
121 DIV4_SIUA, DIV4_SIUB, DIV4_IRDA, DIV4_NR }; 121 .div_mult_table = &div4_div_mult_table,
122};
123
124enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR };
122 125
123#define DIV4(_str, _reg, _bit, _mask, _flags) \ 126#define DIV4(_str, _reg, _bit, _mask, _flags) \
124 SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags) 127 SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags)
@@ -130,11 +133,20 @@ struct clk div4_clks[DIV4_NR] = {
130 [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x0dbf, CLK_ENABLE_ON_INIT), 133 [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x0dbf, CLK_ENABLE_ON_INIT),
131 [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x0db4, CLK_ENABLE_ON_INIT), 134 [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x0db4, CLK_ENABLE_ON_INIT),
132 [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x0dbf, 0), 135 [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x0dbf, 0),
133 [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x0dbf, 0), 136};
134 [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x0dbf, 0), 137
138enum { DIV4_IRDA, DIV4_ENABLE_NR };
139
140struct clk div4_enable_clks[DIV4_ENABLE_NR] = {
135 [DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x0dbf, 0), 141 [DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x0dbf, 0),
136}; 142};
137 143
144enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR };
145
146struct clk div4_reparent_clks[DIV4_REPARENT_NR] = {
147 [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x0dbf, 0),
148 [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x0dbf, 0),
149};
138struct clk div6_clks[] = { 150struct clk div6_clks[] = {
139 SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), 151 SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
140}; 152};
@@ -216,6 +228,14 @@ int __init arch_clk_init(void)
216 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); 228 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
217 229
218 if (!ret) 230 if (!ret)
231 ret = sh_clk_div4_enable_register(div4_enable_clks,
232 DIV4_ENABLE_NR, &div4_table);
233
234 if (!ret)
235 ret = sh_clk_div4_reparent_register(div4_reparent_clks,
236 DIV4_REPARENT_NR, &div4_table);
237
238 if (!ret)
219 ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks)); 239 ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
220 240
221 if (!ret) 241 if (!ret)
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index dfe9192be63e..6707061fbf54 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -127,13 +127,28 @@ struct clk *main_clks[] = {
127 &div3_clk, 127 &div3_clk,
128}; 128};
129 129
130static void div4_kick(struct clk *clk)
131{
132 unsigned long value;
133
134 /* set KICK bit in FRQCRA to update hardware setting */
135 value = __raw_readl(FRQCRA);
136 value |= (1 << 31);
137 __raw_writel(value, FRQCRA);
138}
139
130static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 0, 24, 32, 36, 48, 0, 72 }; 140static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 0, 24, 32, 36, 48, 0, 72 };
131 141
132static struct clk_div_mult_table div4_table = { 142static struct clk_div_mult_table div4_div_mult_table = {
133 .divisors = divisors, 143 .divisors = divisors,
134 .nr_divisors = ARRAY_SIZE(divisors), 144 .nr_divisors = ARRAY_SIZE(divisors),
135}; 145};
136 146
147static struct clk_div4_table div4_table = {
148 .div_mult_table = &div4_div_mult_table,
149 .kick = div4_kick,
150};
151
137enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_P, DIV4_M1, DIV4_NR }; 152enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_P, DIV4_M1, DIV4_NR };
138 153
139#define DIV4(_str, _reg, _bit, _mask, _flags) \ 154#define DIV4(_str, _reg, _bit, _mask, _flags) \
@@ -144,7 +159,7 @@ struct clk div4_clks[DIV4_NR] = {
144 [DIV4_SH] = DIV4("shyway_clk", FRQCRA, 12, 0x2f7c, CLK_ENABLE_ON_INIT), 159 [DIV4_SH] = DIV4("shyway_clk", FRQCRA, 12, 0x2f7c, CLK_ENABLE_ON_INIT),
145 [DIV4_B] = DIV4("bus_clk", FRQCRA, 8, 0x2f7c, CLK_ENABLE_ON_INIT), 160 [DIV4_B] = DIV4("bus_clk", FRQCRA, 8, 0x2f7c, CLK_ENABLE_ON_INIT),
146 [DIV4_P] = DIV4("peripheral_clk", FRQCRA, 0, 0x2f7c, 0), 161 [DIV4_P] = DIV4("peripheral_clk", FRQCRA, 0, 0x2f7c, 0),
147 [DIV4_M1] = DIV4("vpu_clk", FRQCRB, 4, 0x2f7c, 0), 162 [DIV4_M1] = DIV4("vpu_clk", FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT),
148}; 163};
149 164
150struct clk div6_clks[] = { 165struct clk div6_clks[] = {
@@ -152,7 +167,7 @@ struct clk div6_clks[] = {
152 SH_CLK_DIV6("fsia_clk", &div3_clk, FCLKACR, 0), 167 SH_CLK_DIV6("fsia_clk", &div3_clk, FCLKACR, 0),
153 SH_CLK_DIV6("fsib_clk", &div3_clk, FCLKBCR, 0), 168 SH_CLK_DIV6("fsib_clk", &div3_clk, FCLKBCR, 0),
154 SH_CLK_DIV6("irda_clk", &div3_clk, IRDACLKCR, 0), 169 SH_CLK_DIV6("irda_clk", &div3_clk, IRDACLKCR, 0),
155 SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, 0), 170 SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT),
156}; 171};
157 172
158#define R_CLK (&r_clk) 173#define R_CLK (&r_clk)
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
index ddc235ca9664..86aae60677dc 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
@@ -35,7 +35,7 @@ static struct clk_ops sh7757_master_clk_ops = {
35 35
36static void module_clk_recalc(struct clk *clk) 36static void module_clk_recalc(struct clk *clk)
37{ 37{
38 int idx = ctrl_inl(FRQCR) & 0x0000000f; 38 int idx = __raw_readl(FRQCR) & 0x0000000f;
39 clk->rate = clk->parent->rate / p1fc_divisors[idx]; 39 clk->rate = clk->parent->rate / p1fc_divisors[idx];
40} 40}
41 41
@@ -45,7 +45,7 @@ static struct clk_ops sh7757_module_clk_ops = {
45 45
46static void bus_clk_recalc(struct clk *clk) 46static void bus_clk_recalc(struct clk *clk)
47{ 47{
48 int idx = (ctrl_inl(FRQCR) >> 8) & 0x0000000f; 48 int idx = (__raw_readl(FRQCR) >> 8) & 0x0000000f;
49 clk->rate = clk->parent->rate / bfc_divisors[idx]; 49 clk->rate = clk->parent->rate / bfc_divisors[idx];
50} 50}
51 51
@@ -55,7 +55,7 @@ static struct clk_ops sh7757_bus_clk_ops = {
55 55
56static void cpu_clk_recalc(struct clk *clk) 56static void cpu_clk_recalc(struct clk *clk)
57{ 57{
58 int idx = (ctrl_inl(FRQCR) >> 20) & 0x0000000f; 58 int idx = (__raw_readl(FRQCR) >> 20) & 0x0000000f;
59 clk->rate = clk->parent->rate / ifc_divisors[idx]; 59 clk->rate = clk->parent->rate / ifc_divisors[idx];
60} 60}
61 61
@@ -78,7 +78,7 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
78 78
79static void shyway_clk_recalc(struct clk *clk) 79static void shyway_clk_recalc(struct clk *clk)
80{ 80{
81 int idx = (ctrl_inl(FRQCR) >> 12) & 0x0000000f; 81 int idx = (__raw_readl(FRQCR) >> 12) & 0x0000000f;
82 clk->rate = clk->parent->rate / sfc_divisors[idx]; 82 clk->rate = clk->parent->rate / sfc_divisors[idx];
83} 83}
84 84
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
index 370cd47642ef..9f401163e71e 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
@@ -22,7 +22,7 @@ static int cfc_divisors[] = { 1, 1, 4, 1, 1, 1, 1, 1 };
22 22
23static void master_clk_init(struct clk *clk) 23static void master_clk_init(struct clk *clk)
24{ 24{
25 clk->rate *= p0fc_divisors[(ctrl_inl(FRQCR) >> 4) & 0x07]; 25 clk->rate *= p0fc_divisors[(__raw_readl(FRQCR) >> 4) & 0x07];
26} 26}
27 27
28static struct clk_ops sh7763_master_clk_ops = { 28static struct clk_ops sh7763_master_clk_ops = {
@@ -31,7 +31,7 @@ static struct clk_ops sh7763_master_clk_ops = {
31 31
32static unsigned long module_clk_recalc(struct clk *clk) 32static unsigned long module_clk_recalc(struct clk *clk)
33{ 33{
34 int idx = ((ctrl_inl(FRQCR) >> 4) & 0x07); 34 int idx = ((__raw_readl(FRQCR) >> 4) & 0x07);
35 return clk->parent->rate / p0fc_divisors[idx]; 35 return clk->parent->rate / p0fc_divisors[idx];
36} 36}
37 37
@@ -41,7 +41,7 @@ static struct clk_ops sh7763_module_clk_ops = {
41 41
42static unsigned long bus_clk_recalc(struct clk *clk) 42static unsigned long bus_clk_recalc(struct clk *clk)
43{ 43{
44 int idx = ((ctrl_inl(FRQCR) >> 16) & 0x07); 44 int idx = ((__raw_readl(FRQCR) >> 16) & 0x07);
45 return clk->parent->rate / bfc_divisors[idx]; 45 return clk->parent->rate / bfc_divisors[idx];
46} 46}
47 47
@@ -68,7 +68,7 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
68 68
69static unsigned long shyway_clk_recalc(struct clk *clk) 69static unsigned long shyway_clk_recalc(struct clk *clk)
70{ 70{
71 int idx = ((ctrl_inl(FRQCR) >> 20) & 0x07); 71 int idx = ((__raw_readl(FRQCR) >> 20) & 0x07);
72 return clk->parent->rate / cfc_divisors[idx]; 72 return clk->parent->rate / cfc_divisors[idx];
73} 73}
74 74
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7770.c b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c
index e0b896769205..9e3354365d40 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7770.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c
@@ -21,7 +21,7 @@ static int pfc_divisors[] = { 1, 8, 1,10,12,16, 1, 1 };
21 21
22static void master_clk_init(struct clk *clk) 22static void master_clk_init(struct clk *clk)
23{ 23{
24 clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> 28) & 0x000f]; 24 clk->rate *= pfc_divisors[(__raw_readl(FRQCR) >> 28) & 0x000f];
25} 25}
26 26
27static struct clk_ops sh7770_master_clk_ops = { 27static struct clk_ops sh7770_master_clk_ops = {
@@ -30,7 +30,7 @@ static struct clk_ops sh7770_master_clk_ops = {
30 30
31static unsigned long module_clk_recalc(struct clk *clk) 31static unsigned long module_clk_recalc(struct clk *clk)
32{ 32{
33 int idx = ((ctrl_inl(FRQCR) >> 28) & 0x000f); 33 int idx = ((__raw_readl(FRQCR) >> 28) & 0x000f);
34 return clk->parent->rate / pfc_divisors[idx]; 34 return clk->parent->rate / pfc_divisors[idx];
35} 35}
36 36
@@ -40,7 +40,7 @@ static struct clk_ops sh7770_module_clk_ops = {
40 40
41static unsigned long bus_clk_recalc(struct clk *clk) 41static unsigned long bus_clk_recalc(struct clk *clk)
42{ 42{
43 int idx = (ctrl_inl(FRQCR) & 0x000f); 43 int idx = (__raw_readl(FRQCR) & 0x000f);
44 return clk->parent->rate / bfc_divisors[idx]; 44 return clk->parent->rate / bfc_divisors[idx];
45} 45}
46 46
@@ -50,7 +50,7 @@ static struct clk_ops sh7770_bus_clk_ops = {
50 50
51static unsigned long cpu_clk_recalc(struct clk *clk) 51static unsigned long cpu_clk_recalc(struct clk *clk)
52{ 52{
53 int idx = ((ctrl_inl(FRQCR) >> 24) & 0x000f); 53 int idx = ((__raw_readl(FRQCR) >> 24) & 0x000f);
54 return clk->parent->rate / ifc_divisors[idx]; 54 return clk->parent->rate / ifc_divisors[idx];
55} 55}
56 56
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
index a249d823578e..150963a6001e 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
@@ -22,7 +22,7 @@ static int cfc_divisors[] = { 1, 1, 4, 1, 6, 1, 1, 1 };
22 22
23static void master_clk_init(struct clk *clk) 23static void master_clk_init(struct clk *clk)
24{ 24{
25 clk->rate *= pfc_divisors[ctrl_inl(FRQCR) & 0x0003]; 25 clk->rate *= pfc_divisors[__raw_readl(FRQCR) & 0x0003];
26} 26}
27 27
28static struct clk_ops sh7780_master_clk_ops = { 28static struct clk_ops sh7780_master_clk_ops = {
@@ -31,7 +31,7 @@ static struct clk_ops sh7780_master_clk_ops = {
31 31
32static unsigned long module_clk_recalc(struct clk *clk) 32static unsigned long module_clk_recalc(struct clk *clk)
33{ 33{
34 int idx = (ctrl_inl(FRQCR) & 0x0003); 34 int idx = (__raw_readl(FRQCR) & 0x0003);
35 return clk->parent->rate / pfc_divisors[idx]; 35 return clk->parent->rate / pfc_divisors[idx];
36} 36}
37 37
@@ -41,7 +41,7 @@ static struct clk_ops sh7780_module_clk_ops = {
41 41
42static unsigned long bus_clk_recalc(struct clk *clk) 42static unsigned long bus_clk_recalc(struct clk *clk)
43{ 43{
44 int idx = ((ctrl_inl(FRQCR) >> 16) & 0x0007); 44 int idx = ((__raw_readl(FRQCR) >> 16) & 0x0007);
45 return clk->parent->rate / bfc_divisors[idx]; 45 return clk->parent->rate / bfc_divisors[idx];
46} 46}
47 47
@@ -51,7 +51,7 @@ static struct clk_ops sh7780_bus_clk_ops = {
51 51
52static unsigned long cpu_clk_recalc(struct clk *clk) 52static unsigned long cpu_clk_recalc(struct clk *clk)
53{ 53{
54 int idx = ((ctrl_inl(FRQCR) >> 24) & 0x0001); 54 int idx = ((__raw_readl(FRQCR) >> 24) & 0x0001);
55 return clk->parent->rate / ifc_divisors[idx]; 55 return clk->parent->rate / ifc_divisors[idx];
56} 56}
57 57
@@ -74,7 +74,7 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
74 74
75static unsigned long shyway_clk_recalc(struct clk *clk) 75static unsigned long shyway_clk_recalc(struct clk *clk)
76{ 76{
77 int idx = ((ctrl_inl(FRQCR) >> 20) & 0x0007); 77 int idx = ((__raw_readl(FRQCR) >> 20) & 0x0007);
78 return clk->parent->rate / cfc_divisors[idx]; 78 return clk->parent->rate / cfc_divisors[idx];
79} 79}
80 80
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
index 73abfbf2f16d..d997f0a25b10 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
@@ -57,11 +57,15 @@ static struct clk *clks[] = {
57static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18, 57static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
58 24, 32, 36, 48 }; 58 24, 32, 36, 48 };
59 59
60static struct clk_div_mult_table div4_table = { 60static struct clk_div_mult_table div4_div_mult_table = {
61 .divisors = div2, 61 .divisors = div2,
62 .nr_divisors = ARRAY_SIZE(div2), 62 .nr_divisors = ARRAY_SIZE(div2),
63}; 63};
64 64
65static struct clk_div4_table div4_table = {
66 .div_mult_table = &div4_div_mult_table,
67};
68
65enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_GA, 69enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_GA,
66 DIV4_DU, DIV4_P, DIV4_NR }; 70 DIV4_DU, DIV4_P, DIV4_NR };
67 71
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
index a0e8869071ac..af69fd468703 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
@@ -3,11 +3,7 @@
3 * 3 *
4 * SH7786 support for the clock framework 4 * SH7786 support for the clock framework
5 * 5 *
6 * Copyright (C) 2008, 2009 Renesas Solutions Corp. 6 * Copyright (C) 2010 Paul Mundt
7 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
8 *
9 * Based on SH7785
10 * Copyright (C) 2007 Paul Mundt
11 * 7 *
12 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file "COPYING" in the main directory of this archive 9 * License. See the file "COPYING" in the main directory of this archive
@@ -15,127 +11,127 @@
15 */ 11 */
16#include <linux/init.h> 12#include <linux/init.h>
17#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/clk.h>
15#include <linux/io.h>
18#include <asm/clock.h> 16#include <asm/clock.h>
19#include <asm/freq.h> 17#include <asm/freq.h>
20#include <asm/io.h>
21
22static int ifc_divisors[] = { 1, 2, 4, 1 };
23static int sfc_divisors[] = { 1, 1, 4, 1 };
24static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 1,
25 24, 32, 1, 1, 1, 1, 1, 1 };
26static int mfc_divisors[] = { 1, 1, 4, 1 };
27static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 16, 1,
28 24, 32, 1, 48, 1, 1, 1, 1 };
29 18
30static void master_clk_init(struct clk *clk) 19/*
31{ 20 * Default rate for the root input clock, reset this with clk_set_rate()
32 clk->rate *= pfc_divisors[ctrl_inl(FRQMR1) & 0x000f]; 21 * from the platform code.
33} 22 */
34 23static struct clk extal_clk = {
35static struct clk_ops sh7786_master_clk_ops = { 24 .name = "extal",
36 .init = master_clk_init, 25 .id = -1,
26 .rate = 33333333,
37}; 27};
38 28
39static unsigned long module_clk_recalc(struct clk *clk) 29static unsigned long pll_recalc(struct clk *clk)
40{ 30{
41 int idx = (ctrl_inl(FRQMR1) & 0x000f); 31 int multiplier;
42 return clk->parent->rate / pfc_divisors[idx];
43}
44 32
45static struct clk_ops sh7786_module_clk_ops = { 33 /*
46 .recalc = module_clk_recalc, 34 * Clock modes 0, 1, and 2 use an x64 multiplier against PLL1,
47}; 35 * while modes 3, 4, and 5 use an x32.
36 */
37 multiplier = (sh_mv.mv_mode_pins() & 0xf) < 3 ? 64 : 32;
48 38
49static unsigned long bus_clk_recalc(struct clk *clk) 39 return clk->parent->rate * multiplier;
50{
51 int idx = ((ctrl_inl(FRQMR1) >> 16) & 0x000f);
52 return clk->parent->rate / bfc_divisors[idx];
53} 40}
54 41
55static struct clk_ops sh7786_bus_clk_ops = { 42static struct clk_ops pll_clk_ops = {
56 .recalc = bus_clk_recalc, 43 .recalc = pll_recalc,
57}; 44};
58 45
59static unsigned long cpu_clk_recalc(struct clk *clk) 46static struct clk pll_clk = {
60{ 47 .name = "pll_clk",
61 int idx = ((ctrl_inl(FRQMR1) >> 28) & 0x0003); 48 .id = -1,
62 return clk->parent->rate / ifc_divisors[idx]; 49 .ops = &pll_clk_ops,
63} 50 .parent = &extal_clk,
64 51 .flags = CLK_ENABLE_ON_INIT,
65static struct clk_ops sh7786_cpu_clk_ops = {
66 .recalc = cpu_clk_recalc,
67}; 52};
68 53
69static struct clk_ops *sh7786_clk_ops[] = { 54static struct clk *clks[] = {
70 &sh7786_master_clk_ops, 55 &extal_clk,
71 &sh7786_module_clk_ops, 56 &pll_clk,
72 &sh7786_bus_clk_ops,
73 &sh7786_cpu_clk_ops,
74}; 57};
75 58
76void __init arch_init_clk_ops(struct clk_ops **ops, int idx) 59static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
77{ 60 24, 32, 36, 48 };
78 if (idx < ARRAY_SIZE(sh7786_clk_ops))
79 *ops = sh7786_clk_ops[idx];
80}
81 61
82static unsigned long shyway_clk_recalc(struct clk *clk) 62static struct clk_div_mult_table div4_div_mult_table = {
83{ 63 .divisors = div2,
84 int idx = ((ctrl_inl(FRQMR1) >> 20) & 0x0003); 64 .nr_divisors = ARRAY_SIZE(div2),
85 return clk->parent->rate / sfc_divisors[idx];
86}
87
88static struct clk_ops sh7786_shyway_clk_ops = {
89 .recalc = shyway_clk_recalc,
90}; 65};
91 66
92static struct clk sh7786_shyway_clk = { 67static struct clk_div4_table div4_table = {
93 .name = "shyway_clk", 68 .div_mult_table = &div4_div_mult_table,
94 .flags = CLK_ENABLE_ON_INIT,
95 .ops = &sh7786_shyway_clk_ops,
96}; 69};
97 70
98static unsigned long ddr_clk_recalc(struct clk *clk) 71enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_DU, DIV4_P, DIV4_NR };
99{
100 int idx = ((ctrl_inl(FRQMR1) >> 12) & 0x0003);
101 return clk->parent->rate / mfc_divisors[idx];
102}
103 72
104static struct clk_ops sh7786_ddr_clk_ops = { 73#define DIV4(_str, _bit, _mask, _flags) \
105 .recalc = ddr_clk_recalc, 74 SH_CLK_DIV4(_str, &pll_clk, FRQMR1, _bit, _mask, _flags)
106};
107 75
108static struct clk sh7786_ddr_clk = { 76struct clk div4_clks[DIV4_NR] = {
109 .name = "ddr_clk", 77 [DIV4_P] = DIV4("peripheral_clk", 0, 0x0b40, 0),
110 .flags = CLK_ENABLE_ON_INIT, 78 [DIV4_DU] = DIV4("du_clk", 4, 0x0010, 0),
111 .ops = &sh7786_ddr_clk_ops, 79 [DIV4_DDR] = DIV4("ddr_clk", 12, 0x0002, CLK_ENABLE_ON_INIT),
80 [DIV4_B] = DIV4("bus_clk", 16, 0x0360, CLK_ENABLE_ON_INIT),
81 [DIV4_SH] = DIV4("shyway_clk", 20, 0x0002, CLK_ENABLE_ON_INIT),
82 [DIV4_I] = DIV4("cpu_clk", 28, 0x0006, CLK_ENABLE_ON_INIT),
112}; 83};
113 84
114/* 85#define MSTPCR0 0xffc40030
115 * Additional SH7786-specific on-chip clocks that aren't already part of the 86#define MSTPCR1 0xffc40034
116 * clock framework 87
117 */ 88static struct clk mstp_clks[] = {
118static struct clk *sh7786_onchip_clocks[] = { 89 /* MSTPCR0 */
119 &sh7786_shyway_clk, 90 SH_CLK_MSTP32("scif_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0),
120 &sh7786_ddr_clk, 91 SH_CLK_MSTP32("scif_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0),
92 SH_CLK_MSTP32("scif_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0),
93 SH_CLK_MSTP32("scif_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0),
94 SH_CLK_MSTP32("scif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0),
95 SH_CLK_MSTP32("scif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0),
96 SH_CLK_MSTP32("ssi_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 23, 0),
97 SH_CLK_MSTP32("ssi_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 22, 0),
98 SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0),
99 SH_CLK_MSTP32("ssi_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 20, 0),
100 SH_CLK_MSTP32("hac_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 17, 0),
101 SH_CLK_MSTP32("hac_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 16, 0),
102 SH_CLK_MSTP32("i2c_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 15, 0),
103 SH_CLK_MSTP32("i2c_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 14, 0),
104 SH_CLK_MSTP32("tmu9_11_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 11, 0),
105 SH_CLK_MSTP32("tmu678_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 10, 0),
106 SH_CLK_MSTP32("tmu345_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 9, 0),
107 SH_CLK_MSTP32("tmu012_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 8, 0),
108 SH_CLK_MSTP32("sdif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 5, 0),
109 SH_CLK_MSTP32("sdif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 4, 0),
110 SH_CLK_MSTP32("hspi_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 2, 0),
111
112 /* MSTPCR1 */
113 SH_CLK_MSTP32("usb_fck", -1, NULL, MSTPCR1, 12, 0),
114 SH_CLK_MSTP32("pcie_fck", 2, NULL, MSTPCR1, 10, 0),
115 SH_CLK_MSTP32("pcie_fck", 1, NULL, MSTPCR1, 9, 0),
116 SH_CLK_MSTP32("pcie_fck", 0, NULL, MSTPCR1, 8, 0),
117 SH_CLK_MSTP32("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0),
118 SH_CLK_MSTP32("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0),
119 SH_CLK_MSTP32("du_fck", -1, NULL, MSTPCR1, 3, 0),
120 SH_CLK_MSTP32("ether_fck", -1, NULL, MSTPCR1, 2, 0),
121}; 121};
122 122
123int __init arch_clk_init(void) 123int __init arch_clk_init(void)
124{ 124{
125 struct clk *clk;
126 int i, ret = 0; 125 int i, ret = 0;
127 126
128 cpg_clk_init(); 127 for (i = 0; i < ARRAY_SIZE(clks); i++)
129 128 ret |= clk_register(clks[i]);
130 clk = clk_get(NULL, "master_clk");
131 for (i = 0; i < ARRAY_SIZE(sh7786_onchip_clocks); i++) {
132 struct clk *clkp = sh7786_onchip_clocks[i];
133
134 clkp->parent = clk;
135 ret |= clk_register(clkp);
136 }
137 129
138 clk_put(clk); 130 if (!ret)
131 ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
132 &div4_table);
133 if (!ret)
134 ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
139 135
140 return ret; 136 return ret;
141} 137}
diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
index 23c27d32d982..e75c57bdfa5e 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
@@ -33,7 +33,7 @@ static int cfc_divisors[] = { 1, 1, 4, 6 };
33 33
34static void master_clk_init(struct clk *clk) 34static void master_clk_init(struct clk *clk)
35{ 35{
36 clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK]; 36 clk->rate *= pfc_divisors[(__raw_readl(FRQCR) >> PFC_POS) & PFC_MSK];
37} 37}
38 38
39static struct clk_ops shx3_master_clk_ops = { 39static struct clk_ops shx3_master_clk_ops = {
@@ -42,7 +42,7 @@ static struct clk_ops shx3_master_clk_ops = {
42 42
43static unsigned long module_clk_recalc(struct clk *clk) 43static unsigned long module_clk_recalc(struct clk *clk)
44{ 44{
45 int idx = ((ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK); 45 int idx = ((__raw_readl(FRQCR) >> PFC_POS) & PFC_MSK);
46 return clk->parent->rate / pfc_divisors[idx]; 46 return clk->parent->rate / pfc_divisors[idx];
47} 47}
48 48
@@ -52,7 +52,7 @@ static struct clk_ops shx3_module_clk_ops = {
52 52
53static unsigned long bus_clk_recalc(struct clk *clk) 53static unsigned long bus_clk_recalc(struct clk *clk)
54{ 54{
55 int idx = ((ctrl_inl(FRQCR) >> BFC_POS) & BFC_MSK); 55 int idx = ((__raw_readl(FRQCR) >> BFC_POS) & BFC_MSK);
56 return clk->parent->rate / bfc_divisors[idx]; 56 return clk->parent->rate / bfc_divisors[idx];
57} 57}
58 58
@@ -62,7 +62,7 @@ static struct clk_ops shx3_bus_clk_ops = {
62 62
63static unsigned long cpu_clk_recalc(struct clk *clk) 63static unsigned long cpu_clk_recalc(struct clk *clk)
64{ 64{
65 int idx = ((ctrl_inl(FRQCR) >> IFC_POS) & IFC_MSK); 65 int idx = ((__raw_readl(FRQCR) >> IFC_POS) & IFC_MSK);
66 return clk->parent->rate / ifc_divisors[idx]; 66 return clk->parent->rate / ifc_divisors[idx];
67} 67}
68 68
@@ -85,7 +85,7 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
85 85
86static unsigned long shyway_clk_recalc(struct clk *clk) 86static unsigned long shyway_clk_recalc(struct clk *clk)
87{ 87{
88 int idx = ((ctrl_inl(FRQCR) >> CFC_POS) & CFC_MSK); 88 int idx = ((__raw_readl(FRQCR) >> CFC_POS) & CFC_MSK);
89 return clk->parent->rate / cfc_divisors[idx]; 89 return clk->parent->rate / cfc_divisors[idx];
90} 90}
91 91
diff --git a/arch/sh/kernel/cpu/sh4a/perf_event.c b/arch/sh/kernel/cpu/sh4a/perf_event.c
new file mode 100644
index 000000000000..eddc21973fa1
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/perf_event.c
@@ -0,0 +1,269 @@
1/*
2 * Performance events support for SH-4A 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 PPC_CCBR(idx) (0xff200800 + (sizeof(u32) * idx))
18#define PPC_PMCTR(idx) (0xfc100000 + (sizeof(u32) * idx))
19
20#define CCBR_CIT_MASK (0x7ff << 6)
21#define CCBR_DUC (1 << 3)
22#define CCBR_CMDS (1 << 1)
23#define CCBR_PPCE (1 << 0)
24
25#define PPC_PMCAT 0xfc100080
26
27#define PMCAT_OVF3 (1 << 27)
28#define PMCAT_CNN3 (1 << 26)
29#define PMCAT_CLR3 (1 << 25)
30#define PMCAT_OVF2 (1 << 19)
31#define PMCAT_CLR2 (1 << 17)
32#define PMCAT_OVF1 (1 << 11)
33#define PMCAT_CNN1 (1 << 10)
34#define PMCAT_CLR1 (1 << 9)
35#define PMCAT_OVF0 (1 << 3)
36#define PMCAT_CLR0 (1 << 1)
37
38static struct sh_pmu sh4a_pmu;
39
40/*
41 * Supported raw event codes:
42 *
43 * Event Code Description
44 * ---------- -----------
45 *
46 * 0x0000 number of elapsed cycles
47 * 0x0200 number of elapsed cycles in privileged mode
48 * 0x0280 number of elapsed cycles while SR.BL is asserted
49 * 0x0202 instruction execution
50 * 0x0203 instruction execution in parallel
51 * 0x0204 number of unconditional branches
52 * 0x0208 number of exceptions
53 * 0x0209 number of interrupts
54 * 0x0220 UTLB miss caused by instruction fetch
55 * 0x0222 UTLB miss caused by operand access
56 * 0x02a0 number of ITLB misses
57 * 0x0028 number of accesses to instruction memories
58 * 0x0029 number of accesses to instruction cache
59 * 0x002a instruction cache miss
60 * 0x022e number of access to instruction X/Y memory
61 * 0x0030 number of reads to operand memories
62 * 0x0038 number of writes to operand memories
63 * 0x0031 number of operand cache read accesses
64 * 0x0039 number of operand cache write accesses
65 * 0x0032 operand cache read miss
66 * 0x003a operand cache write miss
67 * 0x0236 number of reads to operand X/Y memory
68 * 0x023e number of writes to operand X/Y memory
69 * 0x0237 number of reads to operand U memory
70 * 0x023f number of writes to operand U memory
71 * 0x0337 number of U memory read buffer misses
72 * 0x02b4 number of wait cycles due to operand read access
73 * 0x02bc number of wait cycles due to operand write access
74 * 0x0033 number of wait cycles due to operand cache read miss
75 * 0x003b number of wait cycles due to operand cache write miss
76 */
77
78/*
79 * Special reserved bits used by hardware emulators, read values will
80 * vary, but writes must always be 0.
81 */
82#define PMCAT_EMU_CLR_MASK ((1 << 24) | (1 << 16) | (1 << 8) | (1 << 0))
83
84static const int sh4a_general_events[] = {
85 [PERF_COUNT_HW_CPU_CYCLES] = 0x0000,
86 [PERF_COUNT_HW_INSTRUCTIONS] = 0x0202,
87 [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0029, /* I-cache */
88 [PERF_COUNT_HW_CACHE_MISSES] = 0x002a, /* I-cache */
89 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x0204,
90 [PERF_COUNT_HW_BRANCH_MISSES] = -1,
91 [PERF_COUNT_HW_BUS_CYCLES] = -1,
92};
93
94#define C(x) PERF_COUNT_HW_CACHE_##x
95
96static const int sh4a_cache_events
97 [PERF_COUNT_HW_CACHE_MAX]
98 [PERF_COUNT_HW_CACHE_OP_MAX]
99 [PERF_COUNT_HW_CACHE_RESULT_MAX] =
100{
101 [ C(L1D) ] = {
102 [ C(OP_READ) ] = {
103 [ C(RESULT_ACCESS) ] = 0x0031,
104 [ C(RESULT_MISS) ] = 0x0032,
105 },
106 [ C(OP_WRITE) ] = {
107 [ C(RESULT_ACCESS) ] = 0x0039,
108 [ C(RESULT_MISS) ] = 0x003a,
109 },
110 [ C(OP_PREFETCH) ] = {
111 [ C(RESULT_ACCESS) ] = 0,
112 [ C(RESULT_MISS) ] = 0,
113 },
114 },
115
116 [ C(L1I) ] = {
117 [ C(OP_READ) ] = {
118 [ C(RESULT_ACCESS) ] = 0x0029,
119 [ C(RESULT_MISS) ] = 0x002a,
120 },
121 [ C(OP_WRITE) ] = {
122 [ C(RESULT_ACCESS) ] = -1,
123 [ C(RESULT_MISS) ] = -1,
124 },
125 [ C(OP_PREFETCH) ] = {
126 [ C(RESULT_ACCESS) ] = 0,
127 [ C(RESULT_MISS) ] = 0,
128 },
129 },
130
131 [ C(LL) ] = {
132 [ C(OP_READ) ] = {
133 [ C(RESULT_ACCESS) ] = 0x0030,
134 [ C(RESULT_MISS) ] = 0,
135 },
136 [ C(OP_WRITE) ] = {
137 [ C(RESULT_ACCESS) ] = 0x0038,
138 [ C(RESULT_MISS) ] = 0,
139 },
140 [ C(OP_PREFETCH) ] = {
141 [ C(RESULT_ACCESS) ] = 0,
142 [ C(RESULT_MISS) ] = 0,
143 },
144 },
145
146 [ C(DTLB) ] = {
147 [ C(OP_READ) ] = {
148 [ C(RESULT_ACCESS) ] = 0x0222,
149 [ C(RESULT_MISS) ] = 0x0220,
150 },
151 [ C(OP_WRITE) ] = {
152 [ C(RESULT_ACCESS) ] = 0,
153 [ C(RESULT_MISS) ] = 0,
154 },
155 [ C(OP_PREFETCH) ] = {
156 [ C(RESULT_ACCESS) ] = 0,
157 [ C(RESULT_MISS) ] = 0,
158 },
159 },
160
161 [ C(ITLB) ] = {
162 [ C(OP_READ) ] = {
163 [ C(RESULT_ACCESS) ] = 0,
164 [ C(RESULT_MISS) ] = 0x02a0,
165 },
166 [ C(OP_WRITE) ] = {
167 [ C(RESULT_ACCESS) ] = -1,
168 [ C(RESULT_MISS) ] = -1,
169 },
170 [ C(OP_PREFETCH) ] = {
171 [ C(RESULT_ACCESS) ] = -1,
172 [ C(RESULT_MISS) ] = -1,
173 },
174 },
175
176 [ C(BPU) ] = {
177 [ C(OP_READ) ] = {
178 [ C(RESULT_ACCESS) ] = -1,
179 [ C(RESULT_MISS) ] = -1,
180 },
181 [ C(OP_WRITE) ] = {
182 [ C(RESULT_ACCESS) ] = -1,
183 [ C(RESULT_MISS) ] = -1,
184 },
185 [ C(OP_PREFETCH) ] = {
186 [ C(RESULT_ACCESS) ] = -1,
187 [ C(RESULT_MISS) ] = -1,
188 },
189 },
190};
191
192static int sh4a_event_map(int event)
193{
194 return sh4a_general_events[event];
195}
196
197static u64 sh4a_pmu_read(int idx)
198{
199 return __raw_readl(PPC_PMCTR(idx));
200}
201
202static void sh4a_pmu_disable(struct hw_perf_event *hwc, int idx)
203{
204 unsigned int tmp;
205
206 tmp = __raw_readl(PPC_CCBR(idx));
207 tmp &= ~(CCBR_CIT_MASK | CCBR_DUC);
208 __raw_writel(tmp, PPC_CCBR(idx));
209}
210
211static void sh4a_pmu_enable(struct hw_perf_event *hwc, int idx)
212{
213 unsigned int tmp;
214
215 tmp = __raw_readl(PPC_PMCAT);
216 tmp &= ~PMCAT_EMU_CLR_MASK;
217 tmp |= idx ? PMCAT_CLR1 : PMCAT_CLR0;
218 __raw_writel(tmp, PPC_PMCAT);
219
220 tmp = __raw_readl(PPC_CCBR(idx));
221 tmp |= (hwc->config << 6) | CCBR_CMDS | CCBR_PPCE;
222 __raw_writel(tmp, PPC_CCBR(idx));
223
224 __raw_writel(__raw_readl(PPC_CCBR(idx)) | CCBR_DUC, PPC_CCBR(idx));
225}
226
227static void sh4a_pmu_disable_all(void)
228{
229 int i;
230
231 for (i = 0; i < sh4a_pmu.num_events; i++)
232 __raw_writel(__raw_readl(PPC_CCBR(i)) & ~CCBR_DUC, PPC_CCBR(i));
233}
234
235static void sh4a_pmu_enable_all(void)
236{
237 int i;
238
239 for (i = 0; i < sh4a_pmu.num_events; i++)
240 __raw_writel(__raw_readl(PPC_CCBR(i)) | CCBR_DUC, PPC_CCBR(i));
241}
242
243static struct sh_pmu sh4a_pmu = {
244 .name = "SH-4A",
245 .num_events = 2,
246 .event_map = sh4a_event_map,
247 .max_events = ARRAY_SIZE(sh4a_general_events),
248 .raw_event_mask = 0x3ff,
249 .cache_events = &sh4a_cache_events,
250 .read = sh4a_pmu_read,
251 .disable = sh4a_pmu_disable,
252 .enable = sh4a_pmu_enable,
253 .disable_all = sh4a_pmu_disable_all,
254 .enable_all = sh4a_pmu_enable_all,
255};
256
257static int __init sh4a_pmu_init(void)
258{
259 /*
260 * Make sure this CPU actually has perf counters.
261 */
262 if (!(boot_cpu_data.flags & CPU_HAS_PERF_COUNTER)) {
263 pr_notice("HW perf events unsupported, software events only.\n");
264 return -ENODEV;
265 }
266
267 return register_sh_pmu(&sh4a_pmu);
268}
269arch_initcall(sh4a_pmu_init);
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c
index cb9d07bd59f8..0688a7502f86 100644
--- a/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c
@@ -278,6 +278,7 @@ enum {
278 HIZA8_LCDC, HIZA8_HIZ, 278 HIZA8_LCDC, HIZA8_HIZ,
279 HIZA7_LCDC, HIZA7_HIZ, 279 HIZA7_LCDC, HIZA7_HIZ,
280 HIZA6_LCDC, HIZA6_HIZ, 280 HIZA6_LCDC, HIZA6_HIZ,
281 HIZB4_SIUA, HIZB4_HIZ,
281 HIZB1_VIO, HIZB1_HIZ, 282 HIZB1_VIO, HIZB1_HIZ,
282 HIZB0_VIO, HIZB0_HIZ, 283 HIZB0_VIO, HIZB0_HIZ,
283 HIZC15_IRQ7, HIZC15_HIZ, 284 HIZC15_IRQ7, HIZC15_HIZ,
@@ -546,7 +547,7 @@ static pinmux_enum_t pinmux_data[] = {
546 PINMUX_DATA(VIO_VD2_MARK, PSE3_VIO, MSELB9_VIO2, 547 PINMUX_DATA(VIO_VD2_MARK, PSE3_VIO, MSELB9_VIO2,
547 HIZB0_VIO, FOE_VIO_VD2), 548 HIZB0_VIO, FOE_VIO_VD2),
548 PINMUX_DATA(VIO_HD2_MARK, PSE3_VIO, MSELB9_VIO2, 549 PINMUX_DATA(VIO_HD2_MARK, PSE3_VIO, MSELB9_VIO2,
549 HIZB1_VIO, HIZB1_VIO, FCE_VIO_HD2), 550 HIZB1_VIO, FCE_VIO_HD2),
550 PINMUX_DATA(VIO_CLK2_MARK, PSE3_VIO, MSELB9_VIO2, 551 PINMUX_DATA(VIO_CLK2_MARK, PSE3_VIO, MSELB9_VIO2,
551 HIZB1_VIO, FRB_VIO_CLK2), 552 HIZB1_VIO, FRB_VIO_CLK2),
552 553
@@ -658,14 +659,14 @@ static pinmux_enum_t pinmux_data[] = {
658 PINMUX_DATA(SDHICLK_MARK, SDHICLK), 659 PINMUX_DATA(SDHICLK_MARK, SDHICLK),
659 660
660 /* SIU - Port A */ 661 /* SIU - Port A */
661 PINMUX_DATA(SIUAOLR_MARK, PSC13_SIUAOLR, SIUAOLR_SIOF1_SYNC), 662 PINMUX_DATA(SIUAOLR_MARK, PSC13_SIUAOLR, HIZB4_SIUA, SIUAOLR_SIOF1_SYNC),
662 PINMUX_DATA(SIUAOBT_MARK, PSC14_SIUAOBT, SIUAOBT_SIOF1_SCK), 663 PINMUX_DATA(SIUAOBT_MARK, PSC14_SIUAOBT, HIZB4_SIUA, SIUAOBT_SIOF1_SCK),
663 PINMUX_DATA(SIUAISLD_MARK, PSC15_SIUAISLD, SIUAISLD_SIOF1_RXD), 664 PINMUX_DATA(SIUAISLD_MARK, PSC15_SIUAISLD, HIZB4_SIUA, SIUAISLD_SIOF1_RXD),
664 PINMUX_DATA(SIUAILR_MARK, PSC11_SIUAILR, SIUAILR_SIOF1_SS2), 665 PINMUX_DATA(SIUAILR_MARK, PSC11_SIUAILR, HIZB4_SIUA, SIUAILR_SIOF1_SS2),
665 PINMUX_DATA(SIUAIBT_MARK, PSC12_SIUAIBT, SIUAIBT_SIOF1_SS1), 666 PINMUX_DATA(SIUAIBT_MARK, PSC12_SIUAIBT, HIZB4_SIUA, SIUAIBT_SIOF1_SS1),
666 PINMUX_DATA(SIUAOSLD_MARK, PSB0_SIUAOSLD, SIUAOSLD_SIOF1_TXD), 667 PINMUX_DATA(SIUAOSLD_MARK, PSB0_SIUAOSLD, HIZB4_SIUA, SIUAOSLD_SIOF1_TXD),
667 PINMUX_DATA(SIUMCKA_MARK, PSE11_SIUMCKA_SIOF1_MCK, PSB1_SIUMCKA, PTK0), 668 PINMUX_DATA(SIUMCKA_MARK, PSE11_SIUMCKA_SIOF1_MCK, HIZB4_SIUA, PSB1_SIUMCKA, PTK0),
668 PINMUX_DATA(SIUFCKA_MARK, PSE11_SIUFCKA, PTK0), 669 PINMUX_DATA(SIUFCKA_MARK, PSE11_SIUFCKA, HIZB4_SIUA, PTK0),
669 670
670 /* SIU - Port B */ 671 /* SIU - Port B */
671 PINMUX_DATA(SIUBOLR_MARK, PSB11_SIUBOLR, SIOSTRB1_SIUBOLR), 672 PINMUX_DATA(SIUBOLR_MARK, PSB11_SIUBOLR, SIOSTRB1_SIUBOLR),
@@ -1612,7 +1613,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
1612 0, 0, 1613 0, 0,
1613 0, 0, 1614 0, 0,
1614 0, 0, 1615 0, 0,
1615 0, 0, 1616 HIZB4_SIUA, HIZB4_HIZ,
1616 0, 0, 1617 0, 0,
1617 0, 0, 1618 0, 0,
1618 HIZB1_VIO, HIZB1_HIZ, 1619 HIZB1_VIO, HIZB1_HIZ,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index ac4d5672ec1a..45eb1bfd42c9 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -15,6 +15,71 @@
15#include <linux/sh_timer.h> 15#include <linux/sh_timer.h>
16#include <asm/clock.h> 16#include <asm/clock.h>
17 17
18/* Serial */
19static struct plat_sci_port scif0_platform_data = {
20 .mapbase = 0xffe00000,
21 .flags = UPF_BOOT_AUTOCONF,
22 .type = PORT_SCIF,
23 .irqs = { 80, 80, 80, 80 },
24 .clk = "scif0",
25};
26
27static struct platform_device scif0_device = {
28 .name = "sh-sci",
29 .id = 0,
30 .dev = {
31 .platform_data = &scif0_platform_data,
32 },
33};
34
35static struct plat_sci_port scif1_platform_data = {
36 .mapbase = 0xffe10000,
37 .flags = UPF_BOOT_AUTOCONF,
38 .type = PORT_SCIF,
39 .irqs = { 81, 81, 81, 81 },
40 .clk = "scif1",
41};
42
43static struct platform_device scif1_device = {
44 .name = "sh-sci",
45 .id = 1,
46 .dev = {
47 .platform_data = &scif1_platform_data,
48 },
49};
50
51static struct plat_sci_port scif2_platform_data = {
52 .mapbase = 0xffe20000,
53 .flags = UPF_BOOT_AUTOCONF,
54 .type = PORT_SCIF,
55 .irqs = { 82, 82, 82, 82 },
56 .clk = "scif2",
57};
58
59static struct platform_device scif2_device = {
60 .name = "sh-sci",
61 .id = 2,
62 .dev = {
63 .platform_data = &scif2_platform_data,
64 },
65};
66
67static struct plat_sci_port scif3_platform_data = {
68 .mapbase = 0xffe30000,
69 .flags = UPF_BOOT_AUTOCONF,
70 .type = PORT_SCIF,
71 .irqs = { 83, 83, 83, 83 },
72 .clk = "scif3",
73};
74
75static struct platform_device scif3_device = {
76 .name = "sh-sci",
77 .id = 3,
78 .dev = {
79 .platform_data = &scif3_platform_data,
80 },
81};
82
18static struct resource iic0_resources[] = { 83static struct resource iic0_resources[] = {
19 [0] = { 84 [0] = {
20 .name = "IIC0", 85 .name = "IIC0",
@@ -265,52 +330,17 @@ static struct platform_device tmu2_device = {
265 .num_resources = ARRAY_SIZE(tmu2_resources), 330 .num_resources = ARRAY_SIZE(tmu2_resources),
266}; 331};
267 332
268static struct plat_sci_port sci_platform_data[] = {
269 {
270 .mapbase = 0xffe00000,
271 .flags = UPF_BOOT_AUTOCONF,
272 .type = PORT_SCIF,
273 .irqs = { 80, 80, 80, 80 },
274 .clk = "scif0",
275 }, {
276 .mapbase = 0xffe10000,
277 .flags = UPF_BOOT_AUTOCONF,
278 .type = PORT_SCIF,
279 .irqs = { 81, 81, 81, 81 },
280 .clk = "scif1",
281 }, {
282 .mapbase = 0xffe20000,
283 .flags = UPF_BOOT_AUTOCONF,
284 .type = PORT_SCIF,
285 .irqs = { 82, 82, 82, 82 },
286 .clk = "scif2",
287 }, {
288 .mapbase = 0xffe30000,
289 .flags = UPF_BOOT_AUTOCONF,
290 .type = PORT_SCIF,
291 .irqs = { 83, 83, 83, 83 },
292 .clk = "scif3",
293 }, {
294 .flags = 0,
295 }
296};
297
298static struct platform_device sci_device = {
299 .name = "sh-sci",
300 .id = -1,
301 .dev = {
302 .platform_data = sci_platform_data,
303 },
304};
305
306static struct platform_device *sh7343_devices[] __initdata = { 333static struct platform_device *sh7343_devices[] __initdata = {
334 &scif0_device,
335 &scif1_device,
336 &scif2_device,
337 &scif3_device,
307 &cmt_device, 338 &cmt_device,
308 &tmu0_device, 339 &tmu0_device,
309 &tmu1_device, 340 &tmu1_device,
310 &tmu2_device, 341 &tmu2_device,
311 &iic0_device, 342 &iic0_device,
312 &iic1_device, 343 &iic1_device,
313 &sci_device,
314 &vpu_device, 344 &vpu_device,
315 &veu_device, 345 &veu_device,
316 &jpu_device, 346 &jpu_device,
@@ -328,6 +358,10 @@ static int __init sh7343_devices_setup(void)
328arch_initcall(sh7343_devices_setup); 358arch_initcall(sh7343_devices_setup);
329 359
330static struct platform_device *sh7343_early_devices[] __initdata = { 360static struct platform_device *sh7343_early_devices[] __initdata = {
361 &scif0_device,
362 &scif1_device,
363 &scif2_device,
364 &scif3_device,
331 &cmt_device, 365 &cmt_device,
332 &tmu0_device, 366 &tmu0_device,
333 &tmu1_device, 367 &tmu1_device,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index 4a9010bf4fd3..c494c193e3b6 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -18,6 +18,22 @@
18#include <linux/usb/r8a66597.h> 18#include <linux/usb/r8a66597.h>
19#include <asm/clock.h> 19#include <asm/clock.h>
20 20
21static struct plat_sci_port scif0_platform_data = {
22 .mapbase = 0xffe00000,
23 .flags = UPF_BOOT_AUTOCONF,
24 .type = PORT_SCIF,
25 .irqs = { 80, 80, 80, 80 },
26 .clk = "scif0",
27};
28
29static struct platform_device scif0_device = {
30 .name = "sh-sci",
31 .id = 0,
32 .dev = {
33 .platform_data = &scif0_platform_data,
34 },
35};
36
21static struct resource iic_resources[] = { 37static struct resource iic_resources[] = {
22 [0] = { 38 [0] = {
23 .name = "IIC", 39 .name = "IIC",
@@ -276,33 +292,13 @@ static struct platform_device tmu2_device = {
276 .num_resources = ARRAY_SIZE(tmu2_resources), 292 .num_resources = ARRAY_SIZE(tmu2_resources),
277}; 293};
278 294
279static struct plat_sci_port sci_platform_data[] = {
280 {
281 .mapbase = 0xffe00000,
282 .flags = UPF_BOOT_AUTOCONF,
283 .type = PORT_SCIF,
284 .irqs = { 80, 80, 80, 80 },
285 .clk = "scif0",
286 }, {
287 .flags = 0,
288 }
289};
290
291static struct platform_device sci_device = {
292 .name = "sh-sci",
293 .id = -1,
294 .dev = {
295 .platform_data = sci_platform_data,
296 },
297};
298
299static struct platform_device *sh7366_devices[] __initdata = { 295static struct platform_device *sh7366_devices[] __initdata = {
296 &scif0_device,
300 &cmt_device, 297 &cmt_device,
301 &tmu0_device, 298 &tmu0_device,
302 &tmu1_device, 299 &tmu1_device,
303 &tmu2_device, 300 &tmu2_device,
304 &iic_device, 301 &iic_device,
305 &sci_device,
306 &usb_host_device, 302 &usb_host_device,
307 &vpu_device, 303 &vpu_device,
308 &veu0_device, 304 &veu0_device,
@@ -321,6 +317,7 @@ static int __init sh7366_devices_setup(void)
321arch_initcall(sh7366_devices_setup); 317arch_initcall(sh7366_devices_setup);
322 318
323static struct platform_device *sh7366_early_devices[] __initdata = { 319static struct platform_device *sh7366_early_devices[] __initdata = {
320 &scif0_device,
324 &cmt_device, 321 &cmt_device,
325 &tmu0_device, 322 &tmu0_device,
326 &tmu1_device, 323 &tmu1_device,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index 5491b094cf05..fd7e3639e845 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -7,19 +7,216 @@
7 * License. See the file "COPYING" in the main directory of this archive 7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details. 8 * for more details.
9 */ 9 */
10#include <linux/platform_device.h>
11#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/mm.h>
12#include <linux/platform_device.h>
12#include <linux/serial.h> 13#include <linux/serial.h>
13#include <linux/serial_sci.h> 14#include <linux/serial_sci.h>
14#include <linux/mm.h> 15#include <linux/sh_timer.h>
15#include <linux/uio_driver.h> 16#include <linux/uio_driver.h>
16#include <linux/usb/m66592.h> 17#include <linux/usb/m66592.h>
17#include <linux/sh_timer.h> 18
18#include <asm/clock.h> 19#include <asm/clock.h>
20#include <asm/dmaengine.h>
19#include <asm/mmzone.h> 21#include <asm/mmzone.h>
20#include <asm/dma-sh.h> 22#include <asm/siu.h>
23
24#include <cpu/dma-register.h>
21#include <cpu/sh7722.h> 25#include <cpu/sh7722.h>
22 26
27static struct sh_dmae_slave_config sh7722_dmae_slaves[] = {
28 {
29 .slave_id = SHDMA_SLAVE_SCIF0_TX,
30 .addr = 0xffe0000c,
31 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
32 .mid_rid = 0x21,
33 }, {
34 .slave_id = SHDMA_SLAVE_SCIF0_RX,
35 .addr = 0xffe00014,
36 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
37 .mid_rid = 0x22,
38 }, {
39 .slave_id = SHDMA_SLAVE_SCIF1_TX,
40 .addr = 0xffe1000c,
41 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
42 .mid_rid = 0x25,
43 }, {
44 .slave_id = SHDMA_SLAVE_SCIF1_RX,
45 .addr = 0xffe10014,
46 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
47 .mid_rid = 0x26,
48 }, {
49 .slave_id = SHDMA_SLAVE_SCIF2_TX,
50 .addr = 0xffe2000c,
51 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
52 .mid_rid = 0x29,
53 }, {
54 .slave_id = SHDMA_SLAVE_SCIF2_RX,
55 .addr = 0xffe20014,
56 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
57 .mid_rid = 0x2a,
58 }, {
59 .slave_id = SHDMA_SLAVE_SIUA_TX,
60 .addr = 0xa454c098,
61 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
62 .mid_rid = 0xb1,
63 }, {
64 .slave_id = SHDMA_SLAVE_SIUA_RX,
65 .addr = 0xa454c090,
66 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
67 .mid_rid = 0xb2,
68 }, {
69 .slave_id = SHDMA_SLAVE_SIUB_TX,
70 .addr = 0xa454c09c,
71 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
72 .mid_rid = 0xb5,
73 }, {
74 .slave_id = SHDMA_SLAVE_SIUB_RX,
75 .addr = 0xa454c094,
76 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
77 .mid_rid = 0xb6,
78 },
79};
80
81static struct sh_dmae_channel sh7722_dmae_channels[] = {
82 {
83 .offset = 0,
84 .dmars = 0,
85 .dmars_bit = 0,
86 }, {
87 .offset = 0x10,
88 .dmars = 0,
89 .dmars_bit = 8,
90 }, {
91 .offset = 0x20,
92 .dmars = 4,
93 .dmars_bit = 0,
94 }, {
95 .offset = 0x30,
96 .dmars = 4,
97 .dmars_bit = 8,
98 }, {
99 .offset = 0x50,
100 .dmars = 8,
101 .dmars_bit = 0,
102 }, {
103 .offset = 0x60,
104 .dmars = 8,
105 .dmars_bit = 8,
106 }
107};
108
109static unsigned int ts_shift[] = TS_SHIFT;
110
111static struct sh_dmae_pdata dma_platform_data = {
112 .slave = sh7722_dmae_slaves,
113 .slave_num = ARRAY_SIZE(sh7722_dmae_slaves),
114 .channel = sh7722_dmae_channels,
115 .channel_num = ARRAY_SIZE(sh7722_dmae_channels),
116 .ts_low_shift = CHCR_TS_LOW_SHIFT,
117 .ts_low_mask = CHCR_TS_LOW_MASK,
118 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
119 .ts_high_mask = CHCR_TS_HIGH_MASK,
120 .ts_shift = ts_shift,
121 .ts_shift_num = ARRAY_SIZE(ts_shift),
122 .dmaor_init = DMAOR_INIT,
123};
124
125static struct resource sh7722_dmae_resources[] = {
126 [0] = {
127 /* Channel registers and DMAOR */
128 .start = 0xfe008020,
129 .end = 0xfe00808f,
130 .flags = IORESOURCE_MEM,
131 },
132 [1] = {
133 /* DMARSx */
134 .start = 0xfe009000,
135 .end = 0xfe00900b,
136 .flags = IORESOURCE_MEM,
137 },
138 {
139 /* DMA error IRQ */
140 .start = 78,
141 .end = 78,
142 .flags = IORESOURCE_IRQ,
143 },
144 {
145 /* IRQ for channels 0-3 */
146 .start = 48,
147 .end = 51,
148 .flags = IORESOURCE_IRQ,
149 },
150 {
151 /* IRQ for channels 4-5 */
152 .start = 76,
153 .end = 77,
154 .flags = IORESOURCE_IRQ,
155 },
156};
157
158struct platform_device dma_device = {
159 .name = "sh-dma-engine",
160 .id = -1,
161 .resource = sh7722_dmae_resources,
162 .num_resources = ARRAY_SIZE(sh7722_dmae_resources),
163 .dev = {
164 .platform_data = &dma_platform_data,
165 },
166 .archdata = {
167 .hwblk_id = HWBLK_DMAC,
168 },
169};
170
171/* Serial */
172static struct plat_sci_port scif0_platform_data = {
173 .mapbase = 0xffe00000,
174 .flags = UPF_BOOT_AUTOCONF,
175 .type = PORT_SCIF,
176 .irqs = { 80, 80, 80, 80 },
177 .clk = "scif0",
178};
179
180static struct platform_device scif0_device = {
181 .name = "sh-sci",
182 .id = 0,
183 .dev = {
184 .platform_data = &scif0_platform_data,
185 },
186};
187
188static struct plat_sci_port scif1_platform_data = {
189 .mapbase = 0xffe10000,
190 .flags = UPF_BOOT_AUTOCONF,
191 .type = PORT_SCIF,
192 .irqs = { 81, 81, 81, 81 },
193 .clk = "scif1",
194};
195
196static struct platform_device scif1_device = {
197 .name = "sh-sci",
198 .id = 1,
199 .dev = {
200 .platform_data = &scif1_platform_data,
201 },
202};
203
204static struct plat_sci_port scif2_platform_data = {
205 .mapbase = 0xffe20000,
206 .flags = UPF_BOOT_AUTOCONF,
207 .type = PORT_SCIF,
208 .irqs = { 82, 82, 82, 82 },
209 .clk = "scif2",
210};
211
212static struct platform_device scif2_device = {
213 .name = "sh-sci",
214 .id = 2,
215 .dev = {
216 .platform_data = &scif2_platform_data,
217 },
218};
219
23static struct resource rtc_resources[] = { 220static struct resource rtc_resources[] = {
24 [0] = { 221 [0] = {
25 .start = 0xa465fec0, 222 .start = 0xa465fec0,
@@ -339,54 +536,43 @@ static struct platform_device tmu2_device = {
339 }, 536 },
340}; 537};
341 538
342static struct plat_sci_port sci_platform_data[] = { 539static struct siu_platform siu_platform_data = {
343 { 540 .dma_dev = &dma_device.dev,
344 .mapbase = 0xffe00000, 541 .dma_slave_tx_a = SHDMA_SLAVE_SIUA_TX,
345 .flags = UPF_BOOT_AUTOCONF, 542 .dma_slave_rx_a = SHDMA_SLAVE_SIUA_RX,
346 .type = PORT_SCIF, 543 .dma_slave_tx_b = SHDMA_SLAVE_SIUB_TX,
347 .irqs = { 80, 80, 80, 80 }, 544 .dma_slave_rx_b = SHDMA_SLAVE_SIUB_RX,
348 .clk = "scif0",
349 },
350 {
351 .mapbase = 0xffe10000,
352 .flags = UPF_BOOT_AUTOCONF,
353 .type = PORT_SCIF,
354 .irqs = { 81, 81, 81, 81 },
355 .clk = "scif1",
356 },
357 {
358 .mapbase = 0xffe20000,
359 .flags = UPF_BOOT_AUTOCONF,
360 .type = PORT_SCIF,
361 .irqs = { 82, 82, 82, 82 },
362 .clk = "scif2",
363 },
364 {
365 .flags = 0,
366 }
367}; 545};
368 546
369static struct platform_device sci_device = { 547static struct resource siu_resources[] = {
370 .name = "sh-sci", 548 [0] = {
371 .id = -1, 549 .start = 0xa4540000,
372 .dev = { 550 .end = 0xa454c10f,
373 .platform_data = sci_platform_data, 551 .flags = IORESOURCE_MEM,
552 },
553 [1] = {
554 .start = 108,
555 .flags = IORESOURCE_IRQ,
374 }, 556 },
375}; 557};
376 558
377static struct sh_dmae_pdata dma_platform_data = { 559static struct platform_device siu_device = {
378 .mode = 0, 560 .name = "sh_siu",
379};
380
381static struct platform_device dma_device = {
382 .name = "sh-dma-engine",
383 .id = -1, 561 .id = -1,
384 .dev = { 562 .dev = {
385 .platform_data = &dma_platform_data, 563 .platform_data = &siu_platform_data,
564 },
565 .resource = siu_resources,
566 .num_resources = ARRAY_SIZE(siu_resources),
567 .archdata = {
568 .hwblk_id = HWBLK_SIU,
386 }, 569 },
387}; 570};
388 571
389static struct platform_device *sh7722_devices[] __initdata = { 572static struct platform_device *sh7722_devices[] __initdata = {
573 &scif0_device,
574 &scif1_device,
575 &scif2_device,
390 &cmt_device, 576 &cmt_device,
391 &tmu0_device, 577 &tmu0_device,
392 &tmu1_device, 578 &tmu1_device,
@@ -394,10 +580,10 @@ static struct platform_device *sh7722_devices[] __initdata = {
394 &rtc_device, 580 &rtc_device,
395 &usbf_device, 581 &usbf_device,
396 &iic_device, 582 &iic_device,
397 &sci_device,
398 &vpu_device, 583 &vpu_device,
399 &veu_device, 584 &veu_device,
400 &jpu_device, 585 &jpu_device,
586 &siu_device,
401 &dma_device, 587 &dma_device,
402}; 588};
403 589
@@ -413,6 +599,9 @@ static int __init sh7722_devices_setup(void)
413arch_initcall(sh7722_devices_setup); 599arch_initcall(sh7722_devices_setup);
414 600
415static struct platform_device *sh7722_early_devices[] __initdata = { 601static struct platform_device *sh7722_early_devices[] __initdata = {
602 &scif0_device,
603 &scif1_device,
604 &scif2_device,
416 &cmt_device, 605 &cmt_device,
417 &tmu0_device, 606 &tmu0_device,
418 &tmu1_device, 607 &tmu1_device,
@@ -427,6 +616,8 @@ void __init plat_early_device_setup(void)
427 616
428enum { 617enum {
429 UNUSED=0, 618 UNUSED=0,
619 ENABLED,
620 DISABLED,
430 621
431 /* interrupt sources */ 622 /* interrupt sources */
432 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, 623 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
@@ -442,7 +633,6 @@ enum {
442 SCIF0, SCIF1, SCIF2, SIOF0, SIOF1, SIO, 633 SCIF0, SCIF1, SCIF2, SIOF0, SIOF1, SIO,
443 FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, 634 FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
444 I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI, 635 I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI,
445 SDHI0, SDHI1, SDHI2, SDHI3,
446 CMT, TSIF, SIU, TWODG, 636 CMT, TSIF, SIU, TWODG,
447 TMU0, TMU1, TMU2, 637 TMU0, TMU1, TMU2,
448 IRDA, JPU, LCDC, 638 IRDA, JPU, LCDC,
@@ -475,8 +665,8 @@ static struct intc_vect vectors[] __initdata = {
475 INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0), 665 INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0),
476 INTC_VECT(I2C_ALI, 0xe00), INTC_VECT(I2C_TACKI, 0xe20), 666 INTC_VECT(I2C_ALI, 0xe00), INTC_VECT(I2C_TACKI, 0xe20),
477 INTC_VECT(I2C_WAITI, 0xe40), INTC_VECT(I2C_DTEI, 0xe60), 667 INTC_VECT(I2C_WAITI, 0xe40), INTC_VECT(I2C_DTEI, 0xe60),
478 INTC_VECT(SDHI0, 0xe80), INTC_VECT(SDHI1, 0xea0), 668 INTC_VECT(SDHI, 0xe80), INTC_VECT(SDHI, 0xea0),
479 INTC_VECT(SDHI2, 0xec0), INTC_VECT(SDHI3, 0xee0), 669 INTC_VECT(SDHI, 0xec0), INTC_VECT(SDHI, 0xee0),
480 INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20), 670 INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20),
481 INTC_VECT(SIU, 0xf80), INTC_VECT(TWODG, 0xfa0), 671 INTC_VECT(SIU, 0xf80), INTC_VECT(TWODG, 0xfa0),
482 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), 672 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
@@ -494,7 +684,6 @@ static struct intc_group groups[] __initdata = {
494 INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI, 684 INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI,
495 FLCTL_FLTREQ0I, FLCTL_FLTREQ1I), 685 FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
496 INTC_GROUP(I2C, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI), 686 INTC_GROUP(I2C, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI),
497 INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3),
498}; 687};
499 688
500static struct intc_mask_reg mask_registers[] __initdata = { 689static struct intc_mask_reg mask_registers[] __initdata = {
@@ -516,7 +705,7 @@ static struct intc_mask_reg mask_registers[] __initdata = {
516 { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, 705 { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI,
517 FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } }, 706 FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } },
518 { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ 707 { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
519 { SDHI3, SDHI2, SDHI1, SDHI0, 0, 0, TWODG, SIU } }, 708 { DISABLED, DISABLED, ENABLED, ENABLED, 0, 0, TWODG, SIU } },
520 { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ 709 { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
521 { 0, 0, 0, CMT, 0, USB_USBI1, USB_USBI0, } }, 710 { 0, 0, 0, CMT, 0, USB_USBI1, USB_USBI0, } },
522 { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ 711 { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */
@@ -554,9 +743,13 @@ static struct intc_mask_reg ack_registers[] __initdata = {
554 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 743 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
555}; 744};
556 745
557static DECLARE_INTC_DESC_ACK(intc_desc, "sh7722", vectors, groups, 746static struct intc_desc intc_desc __initdata = {
558 mask_registers, prio_registers, sense_registers, 747 .name = "sh7722",
559 ack_registers); 748 .force_enable = ENABLED,
749 .force_disable = DISABLED,
750 .hw = INTC_HW_DESC(vectors, groups, mask_registers,
751 prio_registers, sense_registers, ack_registers),
752};
560 753
561void __init plat_irq_setup(void) 754void __init plat_irq_setup(void)
562{ 755{
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index 4caa5a7ca86e..85c61f624702 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -20,6 +20,103 @@
20#include <asm/mmzone.h> 20#include <asm/mmzone.h>
21#include <cpu/sh7723.h> 21#include <cpu/sh7723.h>
22 22
23/* Serial */
24static struct plat_sci_port scif0_platform_data = {
25 .mapbase = 0xffe00000,
26 .flags = UPF_BOOT_AUTOCONF,
27 .type = PORT_SCIF,
28 .irqs = { 80, 80, 80, 80 },
29 .clk = "scif0",
30};
31
32static struct platform_device scif0_device = {
33 .name = "sh-sci",
34 .id = 0,
35 .dev = {
36 .platform_data = &scif0_platform_data,
37 },
38};
39
40static struct plat_sci_port scif1_platform_data = {
41 .mapbase = 0xffe10000,
42 .flags = UPF_BOOT_AUTOCONF,
43 .type = PORT_SCIF,
44 .irqs = { 81, 81, 81, 81 },
45 .clk = "scif1",
46};
47
48static struct platform_device scif1_device = {
49 .name = "sh-sci",
50 .id = 1,
51 .dev = {
52 .platform_data = &scif1_platform_data,
53 },
54};
55
56static struct plat_sci_port scif2_platform_data = {
57 .mapbase = 0xffe20000,
58 .flags = UPF_BOOT_AUTOCONF,
59 .type = PORT_SCIF,
60 .irqs = { 82, 82, 82, 82 },
61 .clk = "scif2",
62};
63
64static struct platform_device scif2_device = {
65 .name = "sh-sci",
66 .id = 2,
67 .dev = {
68 .platform_data = &scif2_platform_data,
69 },
70};
71
72static struct plat_sci_port scif3_platform_data = {
73 .mapbase = 0xa4e30000,
74 .flags = UPF_BOOT_AUTOCONF,
75 .type = PORT_SCIFA,
76 .irqs = { 56, 56, 56, 56 },
77 .clk = "scif3",
78};
79
80static struct platform_device scif3_device = {
81 .name = "sh-sci",
82 .id = 3,
83 .dev = {
84 .platform_data = &scif3_platform_data,
85 },
86};
87
88static struct plat_sci_port scif4_platform_data = {
89 .mapbase = 0xa4e40000,
90 .flags = UPF_BOOT_AUTOCONF,
91 .type = PORT_SCIFA,
92 .irqs = { 88, 88, 88, 88 },
93 .clk = "scif4",
94};
95
96static struct platform_device scif4_device = {
97 .name = "sh-sci",
98 .id = 4,
99 .dev = {
100 .platform_data = &scif4_platform_data,
101 },
102};
103
104static struct plat_sci_port scif5_platform_data = {
105 .mapbase = 0xa4e50000,
106 .flags = UPF_BOOT_AUTOCONF,
107 .type = PORT_SCIFA,
108 .irqs = { 109, 109, 109, 109 },
109 .clk = "scif5",
110};
111
112static struct platform_device scif5_device = {
113 .name = "sh-sci",
114 .id = 5,
115 .dev = {
116 .platform_data = &scif5_platform_data,
117 },
118};
119
23static struct uio_info vpu_platform_data = { 120static struct uio_info vpu_platform_data = {
24 .name = "VPU5", 121 .name = "VPU5",
25 .version = "0", 122 .version = "0",
@@ -348,56 +445,6 @@ static struct platform_device tmu5_device = {
348 }, 445 },
349}; 446};
350 447
351static struct plat_sci_port sci_platform_data[] = {
352 {
353 .mapbase = 0xffe00000,
354 .flags = UPF_BOOT_AUTOCONF,
355 .type = PORT_SCIF,
356 .irqs = { 80, 80, 80, 80 },
357 .clk = "scif0",
358 },{
359 .mapbase = 0xffe10000,
360 .flags = UPF_BOOT_AUTOCONF,
361 .type = PORT_SCIF,
362 .irqs = { 81, 81, 81, 81 },
363 .clk = "scif1",
364 },{
365 .mapbase = 0xffe20000,
366 .flags = UPF_BOOT_AUTOCONF,
367 .type = PORT_SCIF,
368 .irqs = { 82, 82, 82, 82 },
369 .clk = "scif2",
370 },{
371 .mapbase = 0xa4e30000,
372 .flags = UPF_BOOT_AUTOCONF,
373 .type = PORT_SCIFA,
374 .irqs = { 56, 56, 56, 56 },
375 .clk = "scif3",
376 },{
377 .mapbase = 0xa4e40000,
378 .flags = UPF_BOOT_AUTOCONF,
379 .type = PORT_SCIFA,
380 .irqs = { 88, 88, 88, 88 },
381 .clk = "scif4",
382 },{
383 .mapbase = 0xa4e50000,
384 .flags = UPF_BOOT_AUTOCONF,
385 .type = PORT_SCIFA,
386 .irqs = { 109, 109, 109, 109 },
387 .clk = "scif5",
388 }, {
389 .flags = 0,
390 }
391};
392
393static struct platform_device sci_device = {
394 .name = "sh-sci",
395 .id = -1,
396 .dev = {
397 .platform_data = sci_platform_data,
398 },
399};
400
401static struct resource rtc_resources[] = { 448static struct resource rtc_resources[] = {
402 [0] = { 449 [0] = {
403 .start = 0xa465fec0, 450 .start = 0xa465fec0,
@@ -488,6 +535,12 @@ static struct platform_device iic_device = {
488}; 535};
489 536
490static struct platform_device *sh7723_devices[] __initdata = { 537static struct platform_device *sh7723_devices[] __initdata = {
538 &scif0_device,
539 &scif1_device,
540 &scif2_device,
541 &scif3_device,
542 &scif4_device,
543 &scif5_device,
491 &cmt_device, 544 &cmt_device,
492 &tmu0_device, 545 &tmu0_device,
493 &tmu1_device, 546 &tmu1_device,
@@ -495,7 +548,6 @@ static struct platform_device *sh7723_devices[] __initdata = {
495 &tmu3_device, 548 &tmu3_device,
496 &tmu4_device, 549 &tmu4_device,
497 &tmu5_device, 550 &tmu5_device,
498 &sci_device,
499 &rtc_device, 551 &rtc_device,
500 &iic_device, 552 &iic_device,
501 &sh7723_usb_host_device, 553 &sh7723_usb_host_device,
@@ -516,6 +568,12 @@ static int __init sh7723_devices_setup(void)
516arch_initcall(sh7723_devices_setup); 568arch_initcall(sh7723_devices_setup);
517 569
518static struct platform_device *sh7723_early_devices[] __initdata = { 570static struct platform_device *sh7723_early_devices[] __initdata = {
571 &scif0_device,
572 &scif1_device,
573 &scif2_device,
574 &scif3_device,
575 &scif4_device,
576 &scif5_device,
519 &cmt_device, 577 &cmt_device,
520 &tmu0_device, 578 &tmu0_device,
521 &tmu1_device, 579 &tmu1_device,
@@ -534,14 +592,17 @@ void __init plat_early_device_setup(void)
534#define RAMCR_CACHE_L2FC 0x0002 592#define RAMCR_CACHE_L2FC 0x0002
535#define RAMCR_CACHE_L2E 0x0001 593#define RAMCR_CACHE_L2E 0x0001
536#define L2_CACHE_ENABLE (RAMCR_CACHE_L2E|RAMCR_CACHE_L2FC) 594#define L2_CACHE_ENABLE (RAMCR_CACHE_L2E|RAMCR_CACHE_L2FC)
537void __uses_jump_to_uncached l2_cache_init(void) 595
596void l2_cache_init(void)
538{ 597{
539 /* Enable L2 cache */ 598 /* Enable L2 cache */
540 ctrl_outl(L2_CACHE_ENABLE, RAMCR); 599 __raw_writel(L2_CACHE_ENABLE, RAMCR);
541} 600}
542 601
543enum { 602enum {
544 UNUSED=0, 603 UNUSED=0,
604 ENABLED,
605 DISABLED,
545 606
546 /* interrupt sources */ 607 /* interrupt sources */
547 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, 608 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
@@ -564,7 +625,6 @@ enum {
564 SCIFA_SCIFA1, 625 SCIFA_SCIFA1,
565 FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I, 626 FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I,
566 I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI, 627 I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI,
567 SDHI0_SDHII0,SDHI0_SDHII1,SDHI0_SDHII2,
568 CMT_CMTI, 628 CMT_CMTI,
569 TSIF_TSIFI, 629 TSIF_TSIFI,
570 SIU_SIUI, 630 SIU_SIUI,
@@ -572,7 +632,6 @@ enum {
572 TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2, 632 TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2,
573 IRDA_IRDAI, 633 IRDA_IRDAI,
574 ATAPI_ATAPII, 634 ATAPI_ATAPII,
575 SDHI1_SDHII0,SDHI1_SDHII1,SDHI1_SDHII2,
576 VEU2H1_VEU2HI, 635 VEU2H1_VEU2HI,
577 LCDC_LCDCI, 636 LCDC_LCDCI,
578 TMU1_TUNI0,TMU1_TUNI1,TMU1_TUNI2, 637 TMU1_TUNI0,TMU1_TUNI1,TMU1_TUNI2,
@@ -643,9 +702,9 @@ static struct intc_vect vectors[] __initdata = {
643 INTC_VECT(I2C_WAITI,0xE40), 702 INTC_VECT(I2C_WAITI,0xE40),
644 INTC_VECT(I2C_DTEI,0xE60), 703 INTC_VECT(I2C_DTEI,0xE60),
645 704
646 INTC_VECT(SDHI0_SDHII0,0xE80), 705 INTC_VECT(SDHI0, 0xE80),
647 INTC_VECT(SDHI0_SDHII1,0xEA0), 706 INTC_VECT(SDHI0, 0xEA0),
648 INTC_VECT(SDHI0_SDHII2,0xEC0), 707 INTC_VECT(SDHI0, 0xEC0),
649 708
650 INTC_VECT(CMT_CMTI,0xF00), 709 INTC_VECT(CMT_CMTI,0xF00),
651 INTC_VECT(TSIF_TSIFI,0xF20), 710 INTC_VECT(TSIF_TSIFI,0xF20),
@@ -659,9 +718,9 @@ static struct intc_vect vectors[] __initdata = {
659 INTC_VECT(IRDA_IRDAI,0x480), 718 INTC_VECT(IRDA_IRDAI,0x480),
660 INTC_VECT(ATAPI_ATAPII,0x4A0), 719 INTC_VECT(ATAPI_ATAPII,0x4A0),
661 720
662 INTC_VECT(SDHI1_SDHII0,0x4E0), 721 INTC_VECT(SDHI1, 0x4E0),
663 INTC_VECT(SDHI1_SDHII1,0x500), 722 INTC_VECT(SDHI1, 0x500),
664 INTC_VECT(SDHI1_SDHII2,0x520), 723 INTC_VECT(SDHI1, 0x520),
665 724
666 INTC_VECT(VEU2H1_VEU2HI,0x560), 725 INTC_VECT(VEU2H1_VEU2HI,0x560),
667 INTC_VECT(LCDC_LCDCI,0x580), 726 INTC_VECT(LCDC_LCDCI,0x580),
@@ -680,15 +739,14 @@ static struct intc_group groups[] __initdata = {
680 INTC_GROUP(FLCTL,FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I), 739 INTC_GROUP(FLCTL,FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I),
681 INTC_GROUP(I2C,I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI), 740 INTC_GROUP(I2C,I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI),
682 INTC_GROUP(_2DG, _2DG_TRI,_2DG_INI,_2DG_CEI), 741 INTC_GROUP(_2DG, _2DG_TRI,_2DG_INI,_2DG_CEI),
683 INTC_GROUP(SDHI1, SDHI1_SDHII0,SDHI1_SDHII1,SDHI1_SDHII2),
684 INTC_GROUP(RTC, RTC_ATI,RTC_PRI,RTC_CUI), 742 INTC_GROUP(RTC, RTC_ATI,RTC_PRI,RTC_CUI),
685 INTC_GROUP(DMAC1B, DMAC1B_DEI4,DMAC1B_DEI5,DMAC1B_DADERR), 743 INTC_GROUP(DMAC1B, DMAC1B_DEI4,DMAC1B_DEI5,DMAC1B_DADERR),
686 INTC_GROUP(SDHI0,SDHI0_SDHII0,SDHI0_SDHII1,SDHI0_SDHII2),
687}; 744};
688 745
689static struct intc_mask_reg mask_registers[] __initdata = { 746static struct intc_mask_reg mask_registers[] __initdata = {
690 { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ 747 { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
691 { 0, TMU1_TUNI2,TMU1_TUNI1,TMU1_TUNI0,0,SDHI1_SDHII2,SDHI1_SDHII1,SDHI1_SDHII0} }, 748 { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0,
749 0, DISABLED, ENABLED, ENABLED } },
692 { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ 750 { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
693 { VIO_VOUI, VIO_VEU2HI,VIO_BEUI,VIO_CEUI,DMAC0A_DEI3,DMAC0A_DEI2,DMAC0A_DEI1,DMAC0A_DEI0 } }, 751 { VIO_VOUI, VIO_VEU2HI,VIO_BEUI,VIO_CEUI,DMAC0A_DEI3,DMAC0A_DEI2,DMAC0A_DEI1,DMAC0A_DEI0 } },
694 { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */ 752 { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */
@@ -705,7 +763,8 @@ static struct intc_mask_reg mask_registers[] __initdata = {
705 { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, 763 { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI,
706 FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, 764 FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
707 { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ 765 { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
708 { 0,SDHI0_SDHII2,SDHI0_SDHII1,SDHI0_SDHII0,0,0,SCIFA_SCIFA2,SIU_SIUI } }, 766 { 0, DISABLED, ENABLED, ENABLED,
767 0, 0, SCIFA_SCIFA2, SIU_SIUI } },
709 { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ 768 { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
710 { 0, 0, 0, CMT_CMTI, 0, 0, USB_USI0,0 } }, 769 { 0, 0, 0, CMT_CMTI, 0, 0, USB_USI0,0 } },
711 { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ 770 { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */
@@ -745,9 +804,13 @@ static struct intc_mask_reg ack_registers[] __initdata = {
745 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 804 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
746}; 805};
747 806
748static DECLARE_INTC_DESC_ACK(intc_desc, "sh7723", vectors, groups, 807static struct intc_desc intc_desc __initdata = {
749 mask_registers, prio_registers, sense_registers, 808 .name = "sh7723",
750 ack_registers); 809 .force_enable = ENABLED,
810 .force_disable = DISABLED,
811 .hw = INTC_HW_DESC(vectors, groups, mask_registers,
812 prio_registers, sense_registers, ack_registers),
813};
751 814
752void __init plat_irq_setup(void) 815void __init plat_irq_setup(void)
753{ 816{
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index f3851fd757ec..e7fa2a92fc1f 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -20,58 +20,287 @@
20#include <linux/uio_driver.h> 20#include <linux/uio_driver.h>
21#include <linux/sh_timer.h> 21#include <linux/sh_timer.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/notifier.h>
24
25#include <asm/suspend.h>
23#include <asm/clock.h> 26#include <asm/clock.h>
27#include <asm/dmaengine.h>
24#include <asm/mmzone.h> 28#include <asm/mmzone.h>
29
30#include <cpu/dma-register.h>
25#include <cpu/sh7724.h> 31#include <cpu/sh7724.h>
26 32
27/* Serial */ 33/* DMA */
28static struct plat_sci_port sci_platform_data[] = { 34static struct sh_dmae_channel sh7724_dmae0_channels[] = {
29 { 35 {
30 .mapbase = 0xffe00000, 36 .offset = 0,
31 .flags = UPF_BOOT_AUTOCONF, 37 .dmars = 0,
32 .type = PORT_SCIF, 38 .dmars_bit = 0,
33 .irqs = { 80, 80, 80, 80 }, 39 }, {
34 .clk = "scif0", 40 .offset = 0x10,
41 .dmars = 0,
42 .dmars_bit = 8,
43 }, {
44 .offset = 0x20,
45 .dmars = 4,
46 .dmars_bit = 0,
47 }, {
48 .offset = 0x30,
49 .dmars = 4,
50 .dmars_bit = 8,
35 }, { 51 }, {
36 .mapbase = 0xffe10000, 52 .offset = 0x50,
37 .flags = UPF_BOOT_AUTOCONF, 53 .dmars = 8,
38 .type = PORT_SCIF, 54 .dmars_bit = 0,
39 .irqs = { 81, 81, 81, 81 }, 55 }, {
40 .clk = "scif1", 56 .offset = 0x60,
57 .dmars = 8,
58 .dmars_bit = 8,
59 }
60};
61
62static struct sh_dmae_channel sh7724_dmae1_channels[] = {
63 {
64 .offset = 0,
65 .dmars = 0,
66 .dmars_bit = 0,
41 }, { 67 }, {
42 .mapbase = 0xffe20000, 68 .offset = 0x10,
43 .flags = UPF_BOOT_AUTOCONF, 69 .dmars = 0,
44 .type = PORT_SCIF, 70 .dmars_bit = 8,
45 .irqs = { 82, 82, 82, 82 },
46 .clk = "scif2",
47 }, { 71 }, {
48 .mapbase = 0xa4e30000, 72 .offset = 0x20,
49 .flags = UPF_BOOT_AUTOCONF, 73 .dmars = 4,
50 .type = PORT_SCIFA, 74 .dmars_bit = 0,
51 .irqs = { 56, 56, 56, 56 },
52 .clk = "scif3",
53 }, { 75 }, {
54 .mapbase = 0xa4e40000, 76 .offset = 0x30,
55 .flags = UPF_BOOT_AUTOCONF, 77 .dmars = 4,
56 .type = PORT_SCIFA, 78 .dmars_bit = 8,
57 .irqs = { 88, 88, 88, 88 },
58 .clk = "scif4",
59 }, { 79 }, {
60 .mapbase = 0xa4e50000, 80 .offset = 0x50,
61 .flags = UPF_BOOT_AUTOCONF, 81 .dmars = 8,
62 .type = PORT_SCIFA, 82 .dmars_bit = 0,
63 .irqs = { 109, 109, 109, 109 },
64 .clk = "scif5",
65 }, { 83 }, {
66 .flags = 0, 84 .offset = 0x60,
85 .dmars = 8,
86 .dmars_bit = 8,
67 } 87 }
68}; 88};
69 89
70static struct platform_device sci_device = { 90static unsigned int ts_shift[] = TS_SHIFT;
91
92static struct sh_dmae_pdata dma0_platform_data = {
93 .channel = sh7724_dmae0_channels,
94 .channel_num = ARRAY_SIZE(sh7724_dmae0_channels),
95 .ts_low_shift = CHCR_TS_LOW_SHIFT,
96 .ts_low_mask = CHCR_TS_LOW_MASK,
97 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
98 .ts_high_mask = CHCR_TS_HIGH_MASK,
99 .ts_shift = ts_shift,
100 .ts_shift_num = ARRAY_SIZE(ts_shift),
101 .dmaor_init = DMAOR_INIT,
102};
103
104static struct sh_dmae_pdata dma1_platform_data = {
105 .channel = sh7724_dmae1_channels,
106 .channel_num = ARRAY_SIZE(sh7724_dmae1_channels),
107 .ts_low_shift = CHCR_TS_LOW_SHIFT,
108 .ts_low_mask = CHCR_TS_LOW_MASK,
109 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
110 .ts_high_mask = CHCR_TS_HIGH_MASK,
111 .ts_shift = ts_shift,
112 .ts_shift_num = ARRAY_SIZE(ts_shift),
113 .dmaor_init = DMAOR_INIT,
114};
115
116/* Resource order important! */
117static struct resource sh7724_dmae0_resources[] = {
118 {
119 /* Channel registers and DMAOR */
120 .start = 0xfe008020,
121 .end = 0xfe00808f,
122 .flags = IORESOURCE_MEM,
123 },
124 {
125 /* DMARSx */
126 .start = 0xfe009000,
127 .end = 0xfe00900b,
128 .flags = IORESOURCE_MEM,
129 },
130 {
131 /* DMA error IRQ */
132 .start = 78,
133 .end = 78,
134 .flags = IORESOURCE_IRQ,
135 },
136 {
137 /* IRQ for channels 0-3 */
138 .start = 48,
139 .end = 51,
140 .flags = IORESOURCE_IRQ,
141 },
142 {
143 /* IRQ for channels 4-5 */
144 .start = 76,
145 .end = 77,
146 .flags = IORESOURCE_IRQ,
147 },
148};
149
150/* Resource order important! */
151static struct resource sh7724_dmae1_resources[] = {
152 {
153 /* Channel registers and DMAOR */
154 .start = 0xfdc08020,
155 .end = 0xfdc0808f,
156 .flags = IORESOURCE_MEM,
157 },
158 {
159 /* DMARSx */
160 .start = 0xfdc09000,
161 .end = 0xfdc0900b,
162 .flags = IORESOURCE_MEM,
163 },
164 {
165 /* DMA error IRQ */
166 .start = 74,
167 .end = 74,
168 .flags = IORESOURCE_IRQ,
169 },
170 {
171 /* IRQ for channels 0-3 */
172 .start = 40,
173 .end = 43,
174 .flags = IORESOURCE_IRQ,
175 },
176 {
177 /* IRQ for channels 4-5 */
178 .start = 72,
179 .end = 73,
180 .flags = IORESOURCE_IRQ,
181 },
182};
183
184static struct platform_device dma0_device = {
185 .name = "sh-dma-engine",
186 .id = 0,
187 .resource = sh7724_dmae0_resources,
188 .num_resources = ARRAY_SIZE(sh7724_dmae0_resources),
189 .dev = {
190 .platform_data = &dma0_platform_data,
191 },
192 .archdata = {
193 .hwblk_id = HWBLK_DMAC0,
194 },
195};
196
197static struct platform_device dma1_device = {
198 .name = "sh-dma-engine",
199 .id = 1,
200 .resource = sh7724_dmae1_resources,
201 .num_resources = ARRAY_SIZE(sh7724_dmae1_resources),
202 .dev = {
203 .platform_data = &dma1_platform_data,
204 },
205 .archdata = {
206 .hwblk_id = HWBLK_DMAC1,
207 },
208};
209
210/* Serial */
211static struct plat_sci_port scif0_platform_data = {
212 .mapbase = 0xffe00000,
213 .flags = UPF_BOOT_AUTOCONF,
214 .type = PORT_SCIF,
215 .irqs = { 80, 80, 80, 80 },
216 .clk = "scif0",
217};
218
219static struct platform_device scif0_device = {
71 .name = "sh-sci", 220 .name = "sh-sci",
72 .id = -1, 221 .id = 0,
222 .dev = {
223 .platform_data = &scif0_platform_data,
224 },
225};
226
227static struct plat_sci_port scif1_platform_data = {
228 .mapbase = 0xffe10000,
229 .flags = UPF_BOOT_AUTOCONF,
230 .type = PORT_SCIF,
231 .irqs = { 81, 81, 81, 81 },
232 .clk = "scif1",
233};
234
235static struct platform_device scif1_device = {
236 .name = "sh-sci",
237 .id = 1,
73 .dev = { 238 .dev = {
74 .platform_data = sci_platform_data, 239 .platform_data = &scif1_platform_data,
240 },
241};
242
243static struct plat_sci_port scif2_platform_data = {
244 .mapbase = 0xffe20000,
245 .flags = UPF_BOOT_AUTOCONF,
246 .type = PORT_SCIF,
247 .irqs = { 82, 82, 82, 82 },
248 .clk = "scif2",
249};
250
251static struct platform_device scif2_device = {
252 .name = "sh-sci",
253 .id = 2,
254 .dev = {
255 .platform_data = &scif2_platform_data,
256 },
257};
258
259static struct plat_sci_port scif3_platform_data = {
260 .mapbase = 0xa4e30000,
261 .flags = UPF_BOOT_AUTOCONF,
262 .type = PORT_SCIFA,
263 .irqs = { 56, 56, 56, 56 },
264 .clk = "scif3",
265};
266
267static struct platform_device scif3_device = {
268 .name = "sh-sci",
269 .id = 3,
270 .dev = {
271 .platform_data = &scif3_platform_data,
272 },
273};
274
275static struct plat_sci_port scif4_platform_data = {
276 .mapbase = 0xa4e40000,
277 .flags = UPF_BOOT_AUTOCONF,
278 .type = PORT_SCIFA,
279 .irqs = { 88, 88, 88, 88 },
280 .clk = "scif4",
281};
282
283static struct platform_device scif4_device = {
284 .name = "sh-sci",
285 .id = 4,
286 .dev = {
287 .platform_data = &scif4_platform_data,
288 },
289};
290
291static struct plat_sci_port scif5_platform_data = {
292 .mapbase = 0xa4e50000,
293 .flags = UPF_BOOT_AUTOCONF,
294 .type = PORT_SCIFA,
295 .irqs = { 109, 109, 109, 109 },
296 .clk = "scif5",
297};
298
299static struct platform_device scif5_device = {
300 .name = "sh-sci",
301 .id = 5,
302 .dev = {
303 .platform_data = &scif5_platform_data,
75 }, 304 },
76}; 305};
77 306
@@ -202,7 +431,7 @@ static struct resource veu0_resources[] = {
202 [0] = { 431 [0] = {
203 .name = "VEU3F0", 432 .name = "VEU3F0",
204 .start = 0xfe920000, 433 .start = 0xfe920000,
205 .end = 0xfe9200cb - 1, 434 .end = 0xfe9200cb,
206 .flags = IORESOURCE_MEM, 435 .flags = IORESOURCE_MEM,
207 }, 436 },
208 [1] = { 437 [1] = {
@@ -234,7 +463,7 @@ static struct resource veu1_resources[] = {
234 [0] = { 463 [0] = {
235 .name = "VEU3F1", 464 .name = "VEU3F1",
236 .start = 0xfe924000, 465 .start = 0xfe924000,
237 .end = 0xfe9240cb - 1, 466 .end = 0xfe9240cb,
238 .flags = IORESOURCE_MEM, 467 .flags = IORESOURCE_MEM,
239 }, 468 },
240 [1] = { 469 [1] = {
@@ -523,7 +752,77 @@ static struct platform_device jpu_device = {
523 }, 752 },
524}; 753};
525 754
755/* SPU2DSP0 */
756static struct uio_info spu0_platform_data = {
757 .name = "SPU2DSP0",
758 .version = "0",
759 .irq = 86,
760};
761
762static struct resource spu0_resources[] = {
763 [0] = {
764 .name = "SPU2DSP0",
765 .start = 0xFE200000,
766 .end = 0xFE2FFFFF,
767 .flags = IORESOURCE_MEM,
768 },
769 [1] = {
770 /* place holder for contiguous memory */
771 },
772};
773
774static struct platform_device spu0_device = {
775 .name = "uio_pdrv_genirq",
776 .id = 4,
777 .dev = {
778 .platform_data = &spu0_platform_data,
779 },
780 .resource = spu0_resources,
781 .num_resources = ARRAY_SIZE(spu0_resources),
782 .archdata = {
783 .hwblk_id = HWBLK_SPU,
784 },
785};
786
787/* SPU2DSP1 */
788static struct uio_info spu1_platform_data = {
789 .name = "SPU2DSP1",
790 .version = "0",
791 .irq = 87,
792};
793
794static struct resource spu1_resources[] = {
795 [0] = {
796 .name = "SPU2DSP1",
797 .start = 0xFE300000,
798 .end = 0xFE3FFFFF,
799 .flags = IORESOURCE_MEM,
800 },
801 [1] = {
802 /* place holder for contiguous memory */
803 },
804};
805
806static struct platform_device spu1_device = {
807 .name = "uio_pdrv_genirq",
808 .id = 5,
809 .dev = {
810 .platform_data = &spu1_platform_data,
811 },
812 .resource = spu1_resources,
813 .num_resources = ARRAY_SIZE(spu1_resources),
814 .archdata = {
815 .hwblk_id = HWBLK_SPU,
816 },
817};
818
526static struct platform_device *sh7724_devices[] __initdata = { 819static struct platform_device *sh7724_devices[] __initdata = {
820 &scif0_device,
821 &scif1_device,
822 &scif2_device,
823 &scif3_device,
824 &scif4_device,
825 &scif5_device,
527 &cmt_device, 826 &cmt_device,
528 &tmu0_device, 827 &tmu0_device,
529 &tmu1_device, 828 &tmu1_device,
@@ -531,7 +830,8 @@ static struct platform_device *sh7724_devices[] __initdata = {
531 &tmu3_device, 830 &tmu3_device,
532 &tmu4_device, 831 &tmu4_device,
533 &tmu5_device, 832 &tmu5_device,
534 &sci_device, 833 &dma0_device,
834 &dma1_device,
535 &rtc_device, 835 &rtc_device,
536 &iic0_device, 836 &iic0_device,
537 &iic1_device, 837 &iic1_device,
@@ -539,6 +839,8 @@ static struct platform_device *sh7724_devices[] __initdata = {
539 &veu0_device, 839 &veu0_device,
540 &veu1_device, 840 &veu1_device,
541 &jpu_device, 841 &jpu_device,
842 &spu0_device,
843 &spu1_device,
542}; 844};
543 845
544static int __init sh7724_devices_setup(void) 846static int __init sh7724_devices_setup(void)
@@ -547,6 +849,8 @@ static int __init sh7724_devices_setup(void)
547 platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20); 849 platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20);
548 platform_resource_setup_memory(&veu1_device, "veu1", 2 << 20); 850 platform_resource_setup_memory(&veu1_device, "veu1", 2 << 20);
549 platform_resource_setup_memory(&jpu_device, "jpu", 2 << 20); 851 platform_resource_setup_memory(&jpu_device, "jpu", 2 << 20);
852 platform_resource_setup_memory(&spu0_device, "spu0", 2 << 20);
853 platform_resource_setup_memory(&spu1_device, "spu1", 2 << 20);
550 854
551 return platform_add_devices(sh7724_devices, 855 return platform_add_devices(sh7724_devices,
552 ARRAY_SIZE(sh7724_devices)); 856 ARRAY_SIZE(sh7724_devices));
@@ -554,6 +858,12 @@ static int __init sh7724_devices_setup(void)
554arch_initcall(sh7724_devices_setup); 858arch_initcall(sh7724_devices_setup);
555 859
556static struct platform_device *sh7724_early_devices[] __initdata = { 860static struct platform_device *sh7724_early_devices[] __initdata = {
861 &scif0_device,
862 &scif1_device,
863 &scif2_device,
864 &scif3_device,
865 &scif4_device,
866 &scif5_device,
557 &cmt_device, 867 &cmt_device,
558 &tmu0_device, 868 &tmu0_device,
559 &tmu1_device, 869 &tmu1_device,
@@ -572,14 +882,17 @@ void __init plat_early_device_setup(void)
572#define RAMCR_CACHE_L2FC 0x0002 882#define RAMCR_CACHE_L2FC 0x0002
573#define RAMCR_CACHE_L2E 0x0001 883#define RAMCR_CACHE_L2E 0x0001
574#define L2_CACHE_ENABLE (RAMCR_CACHE_L2E|RAMCR_CACHE_L2FC) 884#define L2_CACHE_ENABLE (RAMCR_CACHE_L2E|RAMCR_CACHE_L2FC)
575void __uses_jump_to_uncached l2_cache_init(void) 885
886void l2_cache_init(void)
576{ 887{
577 /* Enable L2 cache */ 888 /* Enable L2 cache */
578 ctrl_outl(L2_CACHE_ENABLE, RAMCR); 889 __raw_writel(L2_CACHE_ENABLE, RAMCR);
579} 890}
580 891
581enum { 892enum {
582 UNUSED = 0, 893 UNUSED = 0,
894 ENABLED,
895 DISABLED,
583 896
584 /* interrupt sources */ 897 /* interrupt sources */
585 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, 898 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
@@ -608,14 +921,12 @@ enum {
608 ETHI, 921 ETHI,
609 I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI, 922 I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI,
610 I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI, 923 I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI,
611 SDHI0_SDHII0, SDHI0_SDHII1, SDHI0_SDHII2, SDHI0_SDHII3,
612 CMT, 924 CMT,
613 TSIF, 925 TSIF,
614 FSI, 926 FSI,
615 SCIFA5, 927 SCIFA5,
616 TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2, 928 TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2,
617 IRDA, 929 IRDA,
618 SDHI1_SDHII0, SDHI1_SDHII1, SDHI1_SDHII2,
619 JPU, 930 JPU,
620 _2DDMAC, 931 _2DDMAC,
621 MMC_MMC2I, MMC_MMC3I, 932 MMC_MMC2I, MMC_MMC3I,
@@ -697,10 +1008,10 @@ static struct intc_vect vectors[] __initdata = {
697 INTC_VECT(I2C0_WAITI, 0xE40), 1008 INTC_VECT(I2C0_WAITI, 0xE40),
698 INTC_VECT(I2C0_DTEI, 0xE60), 1009 INTC_VECT(I2C0_DTEI, 0xE60),
699 1010
700 INTC_VECT(SDHI0_SDHII0, 0xE80), 1011 INTC_VECT(SDHI0, 0xE80),
701 INTC_VECT(SDHI0_SDHII1, 0xEA0), 1012 INTC_VECT(SDHI0, 0xEA0),
702 INTC_VECT(SDHI0_SDHII2, 0xEC0), 1013 INTC_VECT(SDHI0, 0xEC0),
703 INTC_VECT(SDHI0_SDHII3, 0xEE0), 1014 INTC_VECT(SDHI0, 0xEE0),
704 1015
705 INTC_VECT(CMT, 0xF00), 1016 INTC_VECT(CMT, 0xF00),
706 INTC_VECT(TSIF, 0xF20), 1017 INTC_VECT(TSIF, 0xF20),
@@ -713,9 +1024,9 @@ static struct intc_vect vectors[] __initdata = {
713 1024
714 INTC_VECT(IRDA, 0x480), 1025 INTC_VECT(IRDA, 0x480),
715 1026
716 INTC_VECT(SDHI1_SDHII0, 0x4E0), 1027 INTC_VECT(SDHI1, 0x4E0),
717 INTC_VECT(SDHI1_SDHII1, 0x500), 1028 INTC_VECT(SDHI1, 0x500),
718 INTC_VECT(SDHI1_SDHII2, 0x520), 1029 INTC_VECT(SDHI1, 0x520),
719 1030
720 INTC_VECT(JPU, 0x560), 1031 INTC_VECT(JPU, 0x560),
721 INTC_VECT(_2DDMAC, 0x4A0), 1032 INTC_VECT(_2DDMAC, 0x4A0),
@@ -741,8 +1052,6 @@ static struct intc_group groups[] __initdata = {
741 INTC_GROUP(DMAC0B, DMAC0B_DEI4, DMAC0B_DEI5, DMAC0B_DADERR), 1052 INTC_GROUP(DMAC0B, DMAC0B_DEI4, DMAC0B_DEI5, DMAC0B_DADERR),
742 INTC_GROUP(I2C0, I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI), 1053 INTC_GROUP(I2C0, I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI),
743 INTC_GROUP(I2C1, I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI), 1054 INTC_GROUP(I2C1, I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI),
744 INTC_GROUP(SDHI0, SDHI0_SDHII0, SDHI0_SDHII1, SDHI0_SDHII2, SDHI0_SDHII3),
745 INTC_GROUP(SDHI1, SDHI1_SDHII0, SDHI1_SDHII1, SDHI1_SDHII2),
746 INTC_GROUP(SPU, SPU_SPUI0, SPU_SPUI1), 1055 INTC_GROUP(SPU, SPU_SPUI0, SPU_SPUI1),
747 INTC_GROUP(MMCIF, MMC_MMC2I, MMC_MMC3I), 1056 INTC_GROUP(MMCIF, MMC_MMC2I, MMC_MMC3I),
748}; 1057};
@@ -750,7 +1059,7 @@ static struct intc_group groups[] __initdata = {
750static struct intc_mask_reg mask_registers[] __initdata = { 1059static struct intc_mask_reg mask_registers[] __initdata = {
751 { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ 1060 { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
752 { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0, 1061 { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0,
753 0, SDHI1_SDHII2, SDHI1_SDHII1, SDHI1_SDHII0 } }, 1062 0, DISABLED, ENABLED, ENABLED } },
754 { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ 1063 { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
755 { VIO_VOU, VIO_VEU1, VIO_BEU0, VIO_CEU0, 1064 { VIO_VOU, VIO_VEU1, VIO_BEU0, VIO_CEU0,
756 DMAC0A_DEI3, DMAC0A_DEI2, DMAC0A_DEI1, DMAC0A_DEI0 } }, 1065 DMAC0A_DEI3, DMAC0A_DEI2, DMAC0A_DEI1, DMAC0A_DEI0 } },
@@ -772,7 +1081,7 @@ static struct intc_mask_reg mask_registers[] __initdata = {
772 { I2C0_DTEI, I2C0_WAITI, I2C0_TACKI, I2C0_ALI, 1081 { I2C0_DTEI, I2C0_WAITI, I2C0_TACKI, I2C0_ALI,
773 I2C1_DTEI, I2C1_WAITI, I2C1_TACKI, I2C1_ALI } }, 1082 I2C1_DTEI, I2C1_WAITI, I2C1_TACKI, I2C1_ALI } },
774 { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ 1083 { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
775 { SDHI0_SDHII3, SDHI0_SDHII2, SDHI0_SDHII1, SDHI0_SDHII0, 1084 { DISABLED, DISABLED, ENABLED, ENABLED,
776 0, 0, SCIFA5, FSI } }, 1085 0, 0, SCIFA5, FSI } },
777 { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ 1086 { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
778 { 0, 0, 0, CMT, 0, USB1, USB0, 0 } }, 1087 { 0, 0, 0, CMT, 0, USB1, USB0, 0 } },
@@ -819,11 +1128,205 @@ static struct intc_mask_reg ack_registers[] __initdata = {
819 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 1128 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
820}; 1129};
821 1130
822static DECLARE_INTC_DESC_ACK(intc_desc, "sh7724", vectors, groups, 1131static struct intc_desc intc_desc __initdata = {
823 mask_registers, prio_registers, sense_registers, 1132 .name = "sh7724",
824 ack_registers); 1133 .force_enable = ENABLED,
1134 .force_disable = DISABLED,
1135 .hw = INTC_HW_DESC(vectors, groups, mask_registers,
1136 prio_registers, sense_registers, ack_registers),
1137};
825 1138
826void __init plat_irq_setup(void) 1139void __init plat_irq_setup(void)
827{ 1140{
828 register_intc_controller(&intc_desc); 1141 register_intc_controller(&intc_desc);
829} 1142}
1143
1144static struct {
1145 /* BSC */
1146 unsigned long mmselr;
1147 unsigned long cs0bcr;
1148 unsigned long cs4bcr;
1149 unsigned long cs5abcr;
1150 unsigned long cs5bbcr;
1151 unsigned long cs6abcr;
1152 unsigned long cs6bbcr;
1153 unsigned long cs4wcr;
1154 unsigned long cs5awcr;
1155 unsigned long cs5bwcr;
1156 unsigned long cs6awcr;
1157 unsigned long cs6bwcr;
1158 /* INTC */
1159 unsigned short ipra;
1160 unsigned short iprb;
1161 unsigned short iprc;
1162 unsigned short iprd;
1163 unsigned short ipre;
1164 unsigned short iprf;
1165 unsigned short iprg;
1166 unsigned short iprh;
1167 unsigned short ipri;
1168 unsigned short iprj;
1169 unsigned short iprk;
1170 unsigned short iprl;
1171 unsigned char imr0;
1172 unsigned char imr1;
1173 unsigned char imr2;
1174 unsigned char imr3;
1175 unsigned char imr4;
1176 unsigned char imr5;
1177 unsigned char imr6;
1178 unsigned char imr7;
1179 unsigned char imr8;
1180 unsigned char imr9;
1181 unsigned char imr10;
1182 unsigned char imr11;
1183 unsigned char imr12;
1184 /* RWDT */
1185 unsigned short rwtcnt;
1186 unsigned short rwtcsr;
1187 /* CPG */
1188 unsigned long irdaclk;
1189 unsigned long spuclk;
1190} sh7724_rstandby_state;
1191
1192static int sh7724_pre_sleep_notifier_call(struct notifier_block *nb,
1193 unsigned long flags, void *unused)
1194{
1195 if (!(flags & SUSP_SH_RSTANDBY))
1196 return NOTIFY_DONE;
1197
1198 /* BCR */
1199 sh7724_rstandby_state.mmselr = __raw_readl(0xff800020); /* MMSELR */
1200 sh7724_rstandby_state.mmselr |= 0xa5a50000;
1201 sh7724_rstandby_state.cs0bcr = __raw_readl(0xfec10004); /* CS0BCR */
1202 sh7724_rstandby_state.cs4bcr = __raw_readl(0xfec10010); /* CS4BCR */
1203 sh7724_rstandby_state.cs5abcr = __raw_readl(0xfec10014); /* CS5ABCR */
1204 sh7724_rstandby_state.cs5bbcr = __raw_readl(0xfec10018); /* CS5BBCR */
1205 sh7724_rstandby_state.cs6abcr = __raw_readl(0xfec1001c); /* CS6ABCR */
1206 sh7724_rstandby_state.cs6bbcr = __raw_readl(0xfec10020); /* CS6BBCR */
1207 sh7724_rstandby_state.cs4wcr = __raw_readl(0xfec10030); /* CS4WCR */
1208 sh7724_rstandby_state.cs5awcr = __raw_readl(0xfec10034); /* CS5AWCR */
1209 sh7724_rstandby_state.cs5bwcr = __raw_readl(0xfec10038); /* CS5BWCR */
1210 sh7724_rstandby_state.cs6awcr = __raw_readl(0xfec1003c); /* CS6AWCR */
1211 sh7724_rstandby_state.cs6bwcr = __raw_readl(0xfec10040); /* CS6BWCR */
1212
1213 /* INTC */
1214 sh7724_rstandby_state.ipra = __raw_readw(0xa4080000); /* IPRA */
1215 sh7724_rstandby_state.iprb = __raw_readw(0xa4080004); /* IPRB */
1216 sh7724_rstandby_state.iprc = __raw_readw(0xa4080008); /* IPRC */
1217 sh7724_rstandby_state.iprd = __raw_readw(0xa408000c); /* IPRD */
1218 sh7724_rstandby_state.ipre = __raw_readw(0xa4080010); /* IPRE */
1219 sh7724_rstandby_state.iprf = __raw_readw(0xa4080014); /* IPRF */
1220 sh7724_rstandby_state.iprg = __raw_readw(0xa4080018); /* IPRG */
1221 sh7724_rstandby_state.iprh = __raw_readw(0xa408001c); /* IPRH */
1222 sh7724_rstandby_state.ipri = __raw_readw(0xa4080020); /* IPRI */
1223 sh7724_rstandby_state.iprj = __raw_readw(0xa4080024); /* IPRJ */
1224 sh7724_rstandby_state.iprk = __raw_readw(0xa4080028); /* IPRK */
1225 sh7724_rstandby_state.iprl = __raw_readw(0xa408002c); /* IPRL */
1226 sh7724_rstandby_state.imr0 = __raw_readb(0xa4080080); /* IMR0 */
1227 sh7724_rstandby_state.imr1 = __raw_readb(0xa4080084); /* IMR1 */
1228 sh7724_rstandby_state.imr2 = __raw_readb(0xa4080088); /* IMR2 */
1229 sh7724_rstandby_state.imr3 = __raw_readb(0xa408008c); /* IMR3 */
1230 sh7724_rstandby_state.imr4 = __raw_readb(0xa4080090); /* IMR4 */
1231 sh7724_rstandby_state.imr5 = __raw_readb(0xa4080094); /* IMR5 */
1232 sh7724_rstandby_state.imr6 = __raw_readb(0xa4080098); /* IMR6 */
1233 sh7724_rstandby_state.imr7 = __raw_readb(0xa408009c); /* IMR7 */
1234 sh7724_rstandby_state.imr8 = __raw_readb(0xa40800a0); /* IMR8 */
1235 sh7724_rstandby_state.imr9 = __raw_readb(0xa40800a4); /* IMR9 */
1236 sh7724_rstandby_state.imr10 = __raw_readb(0xa40800a8); /* IMR10 */
1237 sh7724_rstandby_state.imr11 = __raw_readb(0xa40800ac); /* IMR11 */
1238 sh7724_rstandby_state.imr12 = __raw_readb(0xa40800b0); /* IMR12 */
1239
1240 /* RWDT */
1241 sh7724_rstandby_state.rwtcnt = __raw_readb(0xa4520000); /* RWTCNT */
1242 sh7724_rstandby_state.rwtcnt |= 0x5a00;
1243 sh7724_rstandby_state.rwtcsr = __raw_readb(0xa4520004); /* RWTCSR */
1244 sh7724_rstandby_state.rwtcsr |= 0xa500;
1245 __raw_writew(sh7724_rstandby_state.rwtcsr & 0x07, 0xa4520004);
1246
1247 /* CPG */
1248 sh7724_rstandby_state.irdaclk = __raw_readl(0xa4150018); /* IRDACLKCR */
1249 sh7724_rstandby_state.spuclk = __raw_readl(0xa415003c); /* SPUCLKCR */
1250
1251 return NOTIFY_DONE;
1252}
1253
1254static int sh7724_post_sleep_notifier_call(struct notifier_block *nb,
1255 unsigned long flags, void *unused)
1256{
1257 if (!(flags & SUSP_SH_RSTANDBY))
1258 return NOTIFY_DONE;
1259
1260 /* BCR */
1261 __raw_writel(sh7724_rstandby_state.mmselr, 0xff800020); /* MMSELR */
1262 __raw_writel(sh7724_rstandby_state.cs0bcr, 0xfec10004); /* CS0BCR */
1263 __raw_writel(sh7724_rstandby_state.cs4bcr, 0xfec10010); /* CS4BCR */
1264 __raw_writel(sh7724_rstandby_state.cs5abcr, 0xfec10014); /* CS5ABCR */
1265 __raw_writel(sh7724_rstandby_state.cs5bbcr, 0xfec10018); /* CS5BBCR */
1266 __raw_writel(sh7724_rstandby_state.cs6abcr, 0xfec1001c); /* CS6ABCR */
1267 __raw_writel(sh7724_rstandby_state.cs6bbcr, 0xfec10020); /* CS6BBCR */
1268 __raw_writel(sh7724_rstandby_state.cs4wcr, 0xfec10030); /* CS4WCR */
1269 __raw_writel(sh7724_rstandby_state.cs5awcr, 0xfec10034); /* CS5AWCR */
1270 __raw_writel(sh7724_rstandby_state.cs5bwcr, 0xfec10038); /* CS5BWCR */
1271 __raw_writel(sh7724_rstandby_state.cs6awcr, 0xfec1003c); /* CS6AWCR */
1272 __raw_writel(sh7724_rstandby_state.cs6bwcr, 0xfec10040); /* CS6BWCR */
1273
1274 /* INTC */
1275 __raw_writew(sh7724_rstandby_state.ipra, 0xa4080000); /* IPRA */
1276 __raw_writew(sh7724_rstandby_state.iprb, 0xa4080004); /* IPRB */
1277 __raw_writew(sh7724_rstandby_state.iprc, 0xa4080008); /* IPRC */
1278 __raw_writew(sh7724_rstandby_state.iprd, 0xa408000c); /* IPRD */
1279 __raw_writew(sh7724_rstandby_state.ipre, 0xa4080010); /* IPRE */
1280 __raw_writew(sh7724_rstandby_state.iprf, 0xa4080014); /* IPRF */
1281 __raw_writew(sh7724_rstandby_state.iprg, 0xa4080018); /* IPRG */
1282 __raw_writew(sh7724_rstandby_state.iprh, 0xa408001c); /* IPRH */
1283 __raw_writew(sh7724_rstandby_state.ipri, 0xa4080020); /* IPRI */
1284 __raw_writew(sh7724_rstandby_state.iprj, 0xa4080024); /* IPRJ */
1285 __raw_writew(sh7724_rstandby_state.iprk, 0xa4080028); /* IPRK */
1286 __raw_writew(sh7724_rstandby_state.iprl, 0xa408002c); /* IPRL */
1287 __raw_writeb(sh7724_rstandby_state.imr0, 0xa4080080); /* IMR0 */
1288 __raw_writeb(sh7724_rstandby_state.imr1, 0xa4080084); /* IMR1 */
1289 __raw_writeb(sh7724_rstandby_state.imr2, 0xa4080088); /* IMR2 */
1290 __raw_writeb(sh7724_rstandby_state.imr3, 0xa408008c); /* IMR3 */
1291 __raw_writeb(sh7724_rstandby_state.imr4, 0xa4080090); /* IMR4 */
1292 __raw_writeb(sh7724_rstandby_state.imr5, 0xa4080094); /* IMR5 */
1293 __raw_writeb(sh7724_rstandby_state.imr6, 0xa4080098); /* IMR6 */
1294 __raw_writeb(sh7724_rstandby_state.imr7, 0xa408009c); /* IMR7 */
1295 __raw_writeb(sh7724_rstandby_state.imr8, 0xa40800a0); /* IMR8 */
1296 __raw_writeb(sh7724_rstandby_state.imr9, 0xa40800a4); /* IMR9 */
1297 __raw_writeb(sh7724_rstandby_state.imr10, 0xa40800a8); /* IMR10 */
1298 __raw_writeb(sh7724_rstandby_state.imr11, 0xa40800ac); /* IMR11 */
1299 __raw_writeb(sh7724_rstandby_state.imr12, 0xa40800b0); /* IMR12 */
1300
1301 /* RWDT */
1302 __raw_writew(sh7724_rstandby_state.rwtcnt, 0xa4520000); /* RWTCNT */
1303 __raw_writew(sh7724_rstandby_state.rwtcsr, 0xa4520004); /* RWTCSR */
1304
1305 /* CPG */
1306 __raw_writel(sh7724_rstandby_state.irdaclk, 0xa4150018); /* IRDACLKCR */
1307 __raw_writel(sh7724_rstandby_state.spuclk, 0xa415003c); /* SPUCLKCR */
1308
1309 return NOTIFY_DONE;
1310}
1311
1312static struct notifier_block sh7724_pre_sleep_notifier = {
1313 .notifier_call = sh7724_pre_sleep_notifier_call,
1314 .priority = SH_MOBILE_PRE(SH_MOBILE_SLEEP_CPU),
1315};
1316
1317static struct notifier_block sh7724_post_sleep_notifier = {
1318 .notifier_call = sh7724_post_sleep_notifier_call,
1319 .priority = SH_MOBILE_POST(SH_MOBILE_SLEEP_CPU),
1320};
1321
1322static int __init sh7724_sleep_setup(void)
1323{
1324 atomic_notifier_chain_register(&sh_mobile_pre_sleep_notifier_list,
1325 &sh7724_pre_sleep_notifier);
1326
1327 atomic_notifier_chain_register(&sh_mobile_post_sleep_notifier_list,
1328 &sh7724_post_sleep_notifier);
1329 return 0;
1330}
1331arch_initcall(sh7724_sleep_setup);
1332
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
index c470e15f2e03..e75edf58796a 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -17,6 +17,51 @@
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/sh_timer.h> 18#include <linux/sh_timer.h>
19 19
20static struct plat_sci_port scif2_platform_data = {
21 .mapbase = 0xfe4b0000, /* SCIF2 */
22 .flags = UPF_BOOT_AUTOCONF,
23 .type = PORT_SCIF,
24 .irqs = { 40, 40, 40, 40 },
25};
26
27static struct platform_device scif2_device = {
28 .name = "sh-sci",
29 .id = 2,
30 .dev = {
31 .platform_data = &scif2_platform_data,
32 },
33};
34
35static struct plat_sci_port scif3_platform_data = {
36 .mapbase = 0xfe4c0000, /* SCIF3 */
37 .flags = UPF_BOOT_AUTOCONF,
38 .type = PORT_SCIF,
39 .irqs = { 76, 76, 76, 76 },
40};
41
42static struct platform_device scif3_device = {
43 .name = "sh-sci",
44 .id = 3,
45 .dev = {
46 .platform_data = &scif3_platform_data,
47 },
48};
49
50static struct plat_sci_port scif4_platform_data = {
51 .mapbase = 0xfe4d0000, /* SCIF4 */
52 .flags = UPF_BOOT_AUTOCONF,
53 .type = PORT_SCIF,
54 .irqs = { 104, 104, 104, 104 },
55};
56
57static struct platform_device scif4_device = {
58 .name = "sh-sci",
59 .id = 4,
60 .dev = {
61 .platform_data = &scif4_platform_data,
62 },
63};
64
20static struct sh_timer_config tmu0_platform_data = { 65static struct sh_timer_config tmu0_platform_data = {
21 .name = "TMU0", 66 .name = "TMU0",
22 .channel_offset = 0x04, 67 .channel_offset = 0x04,
@@ -79,39 +124,12 @@ static struct platform_device tmu1_device = {
79 .num_resources = ARRAY_SIZE(tmu1_resources), 124 .num_resources = ARRAY_SIZE(tmu1_resources),
80}; 125};
81 126
82static struct plat_sci_port sci_platform_data[] = {
83 {
84 .mapbase = 0xfe4b0000, /* SCIF2 */
85 .flags = UPF_BOOT_AUTOCONF,
86 .type = PORT_SCIF,
87 .irqs = { 40, 40, 40, 40 },
88 }, {
89 .mapbase = 0xfe4c0000, /* SCIF3 */
90 .flags = UPF_BOOT_AUTOCONF,
91 .type = PORT_SCIF,
92 .irqs = { 76, 76, 76, 76 },
93 }, {
94 .mapbase = 0xfe4d0000, /* SCIF4 */
95 .flags = UPF_BOOT_AUTOCONF,
96 .type = PORT_SCIF,
97 .irqs = { 104, 104, 104, 104 },
98 }, {
99 .flags = 0,
100 }
101};
102
103static struct platform_device sci_device = {
104 .name = "sh-sci",
105 .id = -1,
106 .dev = {
107 .platform_data = sci_platform_data,
108 },
109};
110
111static struct platform_device *sh7757_devices[] __initdata = { 127static struct platform_device *sh7757_devices[] __initdata = {
128 &scif2_device,
129 &scif3_device,
130 &scif4_device,
112 &tmu0_device, 131 &tmu0_device,
113 &tmu1_device, 132 &tmu1_device,
114 &sci_device,
115}; 133};
116 134
117static int __init sh7757_devices_setup(void) 135static int __init sh7757_devices_setup(void)
@@ -121,6 +139,20 @@ static int __init sh7757_devices_setup(void)
121} 139}
122arch_initcall(sh7757_devices_setup); 140arch_initcall(sh7757_devices_setup);
123 141
142static struct platform_device *sh7757_early_devices[] __initdata = {
143 &scif2_device,
144 &scif3_device,
145 &scif4_device,
146 &tmu0_device,
147 &tmu1_device,
148};
149
150void __init plat_early_device_setup(void)
151{
152 early_platform_add_devices(sh7757_early_devices,
153 ARRAY_SIZE(sh7757_early_devices));
154}
155
124enum { 156enum {
125 UNUSED = 0, 157 UNUSED = 0,
126 158
@@ -455,17 +487,17 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7757-irl4567", vectors_irl4567,
455void __init plat_irq_setup(void) 487void __init plat_irq_setup(void)
456{ 488{
457 /* disable IRQ3-0 + IRQ7-4 */ 489 /* disable IRQ3-0 + IRQ7-4 */
458 ctrl_outl(0xff000000, INTC_INTMSK0); 490 __raw_writel(0xff000000, INTC_INTMSK0);
459 491
460 /* disable IRL3-0 + IRL7-4 */ 492 /* disable IRL3-0 + IRL7-4 */
461 ctrl_outl(0xc0000000, INTC_INTMSK1); 493 __raw_writel(0xc0000000, INTC_INTMSK1);
462 ctrl_outl(0xfffefffe, INTC_INTMSK2); 494 __raw_writel(0xfffefffe, INTC_INTMSK2);
463 495
464 /* select IRL mode for IRL3-0 + IRL7-4 */ 496 /* select IRL mode for IRL3-0 + IRL7-4 */
465 ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); 497 __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
466 498
467 /* disable holding function, ie enable "SH-4 Mode" */ 499 /* disable holding function, ie enable "SH-4 Mode" */
468 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0); 500 __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
469 501
470 register_intc_controller(&intc_desc); 502 register_intc_controller(&intc_desc);
471} 503}
@@ -475,32 +507,32 @@ void __init plat_irq_setup_pins(int mode)
475 switch (mode) { 507 switch (mode) {
476 case IRQ_MODE_IRQ7654: 508 case IRQ_MODE_IRQ7654:
477 /* select IRQ mode for IRL7-4 */ 509 /* select IRQ mode for IRL7-4 */
478 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0); 510 __raw_writel(__raw_readl(INTC_ICR0) | 0x00400000, INTC_ICR0);
479 register_intc_controller(&intc_desc_irq4567); 511 register_intc_controller(&intc_desc_irq4567);
480 break; 512 break;
481 case IRQ_MODE_IRQ3210: 513 case IRQ_MODE_IRQ3210:
482 /* select IRQ mode for IRL3-0 */ 514 /* select IRQ mode for IRL3-0 */
483 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0); 515 __raw_writel(__raw_readl(INTC_ICR0) | 0x00800000, INTC_ICR0);
484 register_intc_controller(&intc_desc_irq0123); 516 register_intc_controller(&intc_desc_irq0123);
485 break; 517 break;
486 case IRQ_MODE_IRL7654: 518 case IRQ_MODE_IRL7654:
487 /* enable IRL7-4 but don't provide any masking */ 519 /* enable IRL7-4 but don't provide any masking */
488 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 520 __raw_writel(0x40000000, INTC_INTMSKCLR1);
489 ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); 521 __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
490 break; 522 break;
491 case IRQ_MODE_IRL3210: 523 case IRQ_MODE_IRL3210:
492 /* enable IRL0-3 but don't provide any masking */ 524 /* enable IRL0-3 but don't provide any masking */
493 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 525 __raw_writel(0x80000000, INTC_INTMSKCLR1);
494 ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); 526 __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
495 break; 527 break;
496 case IRQ_MODE_IRL7654_MASK: 528 case IRQ_MODE_IRL7654_MASK:
497 /* enable IRL7-4 and mask using cpu intc controller */ 529 /* enable IRL7-4 and mask using cpu intc controller */
498 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 530 __raw_writel(0x40000000, INTC_INTMSKCLR1);
499 register_intc_controller(&intc_desc_irl4567); 531 register_intc_controller(&intc_desc_irl4567);
500 break; 532 break;
501 case IRQ_MODE_IRL3210_MASK: 533 case IRQ_MODE_IRL3210_MASK:
502 /* enable IRL0-3 and mask using cpu intc controller */ 534 /* enable IRL0-3 and mask using cpu intc controller */
503 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 535 __raw_writel(0x80000000, INTC_INTMSKCLR1);
504 register_intc_controller(&intc_desc_irl0123); 536 register_intc_controller(&intc_desc_irl0123);
505 break; 537 break;
506 default: 538 default:
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
index 4659fff6b842..7f6b0a5f7f82 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
@@ -16,6 +16,51 @@
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/serial_sci.h> 17#include <linux/serial_sci.h>
18 18
19static struct plat_sci_port scif0_platform_data = {
20 .mapbase = 0xffe00000,
21 .flags = UPF_BOOT_AUTOCONF,
22 .type = PORT_SCIF,
23 .irqs = { 40, 40, 40, 40 },
24};
25
26static struct platform_device scif0_device = {
27 .name = "sh-sci",
28 .id = 0,
29 .dev = {
30 .platform_data = &scif0_platform_data,
31 },
32};
33
34static struct plat_sci_port scif1_platform_data = {
35 .mapbase = 0xffe08000,
36 .flags = UPF_BOOT_AUTOCONF,
37 .type = PORT_SCIF,
38 .irqs = { 76, 76, 76, 76 },
39};
40
41static struct platform_device scif1_device = {
42 .name = "sh-sci",
43 .id = 1,
44 .dev = {
45 .platform_data = &scif1_platform_data,
46 },
47};
48
49static struct plat_sci_port scif2_platform_data = {
50 .mapbase = 0xffe10000,
51 .flags = UPF_BOOT_AUTOCONF,
52 .type = PORT_SCIF,
53 .irqs = { 104, 104, 104, 104 },
54};
55
56static struct platform_device scif2_device = {
57 .name = "sh-sci",
58 .id = 2,
59 .dev = {
60 .platform_data = &scif2_platform_data,
61 },
62};
63
19static struct resource rtc_resources[] = { 64static struct resource rtc_resources[] = {
20 [0] = { 65 [0] = {
21 .start = 0xffe80000, 66 .start = 0xffe80000,
@@ -36,35 +81,6 @@ static struct platform_device rtc_device = {
36 .resource = rtc_resources, 81 .resource = rtc_resources,
37}; 82};
38 83
39static struct plat_sci_port sci_platform_data[] = {
40 {
41 .mapbase = 0xffe00000,
42 .flags = UPF_BOOT_AUTOCONF,
43 .type = PORT_SCIF,
44 .irqs = { 40, 40, 40, 40 },
45 }, {
46 .mapbase = 0xffe08000,
47 .flags = UPF_BOOT_AUTOCONF,
48 .type = PORT_SCIF,
49 .irqs = { 76, 76, 76, 76 },
50 }, {
51 .mapbase = 0xffe10000,
52 .flags = UPF_BOOT_AUTOCONF,
53 .type = PORT_SCIF,
54 .irqs = { 104, 104, 104, 104 },
55 }, {
56 .flags = 0,
57 }
58};
59
60static struct platform_device sci_device = {
61 .name = "sh-sci",
62 .id = -1,
63 .dev = {
64 .platform_data = sci_platform_data,
65 },
66};
67
68static struct resource usb_ohci_resources[] = { 84static struct resource usb_ohci_resources[] = {
69 [0] = { 85 [0] = {
70 .start = 0xffec8000, 86 .start = 0xffec8000,
@@ -297,6 +313,9 @@ static struct platform_device tmu5_device = {
297}; 313};
298 314
299static struct platform_device *sh7763_devices[] __initdata = { 315static struct platform_device *sh7763_devices[] __initdata = {
316 &scif0_device,
317 &scif1_device,
318 &scif2_device,
300 &tmu0_device, 319 &tmu0_device,
301 &tmu1_device, 320 &tmu1_device,
302 &tmu2_device, 321 &tmu2_device,
@@ -304,7 +323,6 @@ static struct platform_device *sh7763_devices[] __initdata = {
304 &tmu4_device, 323 &tmu4_device,
305 &tmu5_device, 324 &tmu5_device,
306 &rtc_device, 325 &rtc_device,
307 &sci_device,
308 &usb_ohci_device, 326 &usb_ohci_device,
309 &usbf_device, 327 &usbf_device,
310}; 328};
@@ -317,6 +335,9 @@ static int __init sh7763_devices_setup(void)
317arch_initcall(sh7763_devices_setup); 335arch_initcall(sh7763_devices_setup);
318 336
319static struct platform_device *sh7763_early_devices[] __initdata = { 337static struct platform_device *sh7763_early_devices[] __initdata = {
338 &scif0_device,
339 &scif1_device,
340 &scif2_device,
320 &tmu0_device, 341 &tmu0_device,
321 &tmu1_device, 342 &tmu1_device,
322 &tmu2_device, 343 &tmu2_device,
@@ -517,11 +538,11 @@ static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7763-irl3210", irl_vectors,
517void __init plat_irq_setup(void) 538void __init plat_irq_setup(void)
518{ 539{
519 /* disable IRQ7-0 */ 540 /* disable IRQ7-0 */
520 ctrl_outl(0xff000000, INTC_INTMSK0); 541 __raw_writel(0xff000000, INTC_INTMSK0);
521 542
522 /* disable IRL3-0 + IRL7-4 */ 543 /* disable IRL3-0 + IRL7-4 */
523 ctrl_outl(0xc0000000, INTC_INTMSK1); 544 __raw_writel(0xc0000000, INTC_INTMSK1);
524 ctrl_outl(0xfffefffe, INTC_INTMSK2); 545 __raw_writel(0xfffefffe, INTC_INTMSK2);
525 546
526 register_intc_controller(&intc_desc); 547 register_intc_controller(&intc_desc);
527} 548}
@@ -531,27 +552,27 @@ void __init plat_irq_setup_pins(int mode)
531 switch (mode) { 552 switch (mode) {
532 case IRQ_MODE_IRQ: 553 case IRQ_MODE_IRQ:
533 /* select IRQ mode for IRL3-0 + IRL7-4 */ 554 /* select IRQ mode for IRL3-0 + IRL7-4 */
534 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0); 555 __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
535 register_intc_controller(&intc_irq_desc); 556 register_intc_controller(&intc_irq_desc);
536 break; 557 break;
537 case IRQ_MODE_IRL7654: 558 case IRQ_MODE_IRL7654:
538 /* enable IRL7-4 but don't provide any masking */ 559 /* enable IRL7-4 but don't provide any masking */
539 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 560 __raw_writel(0x40000000, INTC_INTMSKCLR1);
540 ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); 561 __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
541 break; 562 break;
542 case IRQ_MODE_IRL3210: 563 case IRQ_MODE_IRL3210:
543 /* enable IRL0-3 but don't provide any masking */ 564 /* enable IRL0-3 but don't provide any masking */
544 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 565 __raw_writel(0x80000000, INTC_INTMSKCLR1);
545 ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); 566 __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
546 break; 567 break;
547 case IRQ_MODE_IRL7654_MASK: 568 case IRQ_MODE_IRL7654_MASK:
548 /* enable IRL7-4 and mask using cpu intc controller */ 569 /* enable IRL7-4 and mask using cpu intc controller */
549 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 570 __raw_writel(0x40000000, INTC_INTMSKCLR1);
550 register_intc_controller(&intc_irl7654_desc); 571 register_intc_controller(&intc_irl7654_desc);
551 break; 572 break;
552 case IRQ_MODE_IRL3210_MASK: 573 case IRQ_MODE_IRL3210_MASK:
553 /* enable IRL0-3 and mask using cpu intc controller */ 574 /* enable IRL0-3 and mask using cpu intc controller */
554 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 575 __raw_writel(0x80000000, INTC_INTMSKCLR1);
555 register_intc_controller(&intc_irl3210_desc); 576 register_intc_controller(&intc_irl3210_desc);
556 break; 577 break;
557 default: 578 default:
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
index eead08d89d32..86d681ecf90e 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
@@ -14,67 +14,153 @@
14#include <linux/sh_timer.h> 14#include <linux/sh_timer.h>
15#include <linux/io.h> 15#include <linux/io.h>
16 16
17static struct plat_sci_port sci_platform_data[] = { 17static struct plat_sci_port scif0_platform_data = {
18 { 18 .mapbase = 0xff923000,
19 .mapbase = 0xff923000, 19 .flags = UPF_BOOT_AUTOCONF,
20 .flags = UPF_BOOT_AUTOCONF, 20 .type = PORT_SCIF,
21 .type = PORT_SCIF, 21 .irqs = { 61, 61, 61, 61 },
22 .irqs = { 61, 61, 61, 61 }, 22};
23 }, { 23
24 .mapbase = 0xff924000, 24static struct platform_device scif0_device = {
25 .flags = UPF_BOOT_AUTOCONF, 25 .name = "sh-sci",
26 .type = PORT_SCIF, 26 .id = 0,
27 .irqs = { 62, 62, 62, 62 }, 27 .dev = {
28 }, { 28 .platform_data = &scif0_platform_data,
29 .mapbase = 0xff925000, 29 },
30 .flags = UPF_BOOT_AUTOCONF, 30};
31 .type = PORT_SCIF, 31
32 .irqs = { 63, 63, 63, 63 }, 32static struct plat_sci_port scif1_platform_data = {
33 }, { 33 .mapbase = 0xff924000,
34 .mapbase = 0xff926000, 34 .flags = UPF_BOOT_AUTOCONF,
35 .flags = UPF_BOOT_AUTOCONF, 35 .type = PORT_SCIF,
36 .type = PORT_SCIF, 36 .irqs = { 62, 62, 62, 62 },
37 .irqs = { 64, 64, 64, 64 }, 37};
38 }, { 38
39 .mapbase = 0xff927000, 39static struct platform_device scif1_device = {
40 .flags = UPF_BOOT_AUTOCONF, 40 .name = "sh-sci",
41 .type = PORT_SCIF, 41 .id = 1,
42 .irqs = { 65, 65, 65, 65 }, 42 .dev = {
43 }, { 43 .platform_data = &scif1_platform_data,
44 .mapbase = 0xff928000, 44 },
45 .flags = UPF_BOOT_AUTOCONF, 45};
46 .type = PORT_SCIF, 46
47 .irqs = { 66, 66, 66, 66 }, 47static struct plat_sci_port scif2_platform_data = {
48 }, { 48 .mapbase = 0xff925000,
49 .mapbase = 0xff929000, 49 .flags = UPF_BOOT_AUTOCONF,
50 .flags = UPF_BOOT_AUTOCONF, 50 .type = PORT_SCIF,
51 .type = PORT_SCIF, 51 .irqs = { 63, 63, 63, 63 },
52 .irqs = { 67, 67, 67, 67 }, 52};
53 }, { 53
54 .mapbase = 0xff92a000, 54static struct platform_device scif2_device = {
55 .flags = UPF_BOOT_AUTOCONF, 55 .name = "sh-sci",
56 .type = PORT_SCIF, 56 .id = 2,
57 .irqs = { 68, 68, 68, 68 }, 57 .dev = {
58 }, { 58 .platform_data = &scif2_platform_data,
59 .mapbase = 0xff92b000, 59 },
60 .flags = UPF_BOOT_AUTOCONF, 60};
61 .type = PORT_SCIF, 61
62 .irqs = { 69, 69, 69, 69 }, 62static struct plat_sci_port scif3_platform_data = {
63 }, { 63 .mapbase = 0xff926000,
64 .mapbase = 0xff92c000, 64 .flags = UPF_BOOT_AUTOCONF,
65 .flags = UPF_BOOT_AUTOCONF, 65 .type = PORT_SCIF,
66 .type = PORT_SCIF, 66 .irqs = { 64, 64, 64, 64 },
67 .irqs = { 70, 70, 70, 70 }, 67};
68 }, { 68
69 .flags = 0, 69static struct platform_device scif3_device = {
70 } 70 .name = "sh-sci",
71 .id = 3,
72 .dev = {
73 .platform_data = &scif3_platform_data,
74 },
75};
76
77static struct plat_sci_port scif4_platform_data = {
78 .mapbase = 0xff927000,
79 .flags = UPF_BOOT_AUTOCONF,
80 .type = PORT_SCIF,
81 .irqs = { 65, 65, 65, 65 },
82};
83
84static struct platform_device scif4_device = {
85 .name = "sh-sci",
86 .id = 4,
87 .dev = {
88 .platform_data = &scif4_platform_data,
89 },
90};
91
92static struct plat_sci_port scif5_platform_data = {
93 .mapbase = 0xff928000,
94 .flags = UPF_BOOT_AUTOCONF,
95 .type = PORT_SCIF,
96 .irqs = { 66, 66, 66, 66 },
97};
98
99static struct platform_device scif5_device = {
100 .name = "sh-sci",
101 .id = 5,
102 .dev = {
103 .platform_data = &scif5_platform_data,
104 },
105};
106
107static struct plat_sci_port scif6_platform_data = {
108 .mapbase = 0xff929000,
109 .flags = UPF_BOOT_AUTOCONF,
110 .type = PORT_SCIF,
111 .irqs = { 67, 67, 67, 67 },
112};
113
114static struct platform_device scif6_device = {
115 .name = "sh-sci",
116 .id = 6,
117 .dev = {
118 .platform_data = &scif6_platform_data,
119 },
120};
121
122static struct plat_sci_port scif7_platform_data = {
123 .mapbase = 0xff92a000,
124 .flags = UPF_BOOT_AUTOCONF,
125 .type = PORT_SCIF,
126 .irqs = { 68, 68, 68, 68 },
127};
128
129static struct platform_device scif7_device = {
130 .name = "sh-sci",
131 .id = 7,
132 .dev = {
133 .platform_data = &scif7_platform_data,
134 },
135};
136
137static struct plat_sci_port scif8_platform_data = {
138 .mapbase = 0xff92b000,
139 .flags = UPF_BOOT_AUTOCONF,
140 .type = PORT_SCIF,
141 .irqs = { 69, 69, 69, 69 },
142};
143
144static struct platform_device scif8_device = {
145 .name = "sh-sci",
146 .id = 8,
147 .dev = {
148 .platform_data = &scif8_platform_data,
149 },
150};
151
152static struct plat_sci_port scif9_platform_data = {
153 .mapbase = 0xff92c000,
154 .flags = UPF_BOOT_AUTOCONF,
155 .type = PORT_SCIF,
156 .irqs = { 70, 70, 70, 70 },
71}; 157};
72 158
73static struct platform_device sci_device = { 159static struct platform_device scif9_device = {
74 .name = "sh-sci", 160 .name = "sh-sci",
75 .id = -1, 161 .id = 9,
76 .dev = { 162 .dev = {
77 .platform_data = sci_platform_data, 163 .platform_data = &scif9_platform_data,
78 }, 164 },
79}; 165};
80 166
@@ -351,6 +437,16 @@ static struct platform_device tmu8_device = {
351}; 437};
352 438
353static struct platform_device *sh7770_devices[] __initdata = { 439static struct platform_device *sh7770_devices[] __initdata = {
440 &scif0_device,
441 &scif1_device,
442 &scif2_device,
443 &scif3_device,
444 &scif4_device,
445 &scif5_device,
446 &scif6_device,
447 &scif7_device,
448 &scif8_device,
449 &scif9_device,
354 &tmu0_device, 450 &tmu0_device,
355 &tmu1_device, 451 &tmu1_device,
356 &tmu2_device, 452 &tmu2_device,
@@ -360,7 +456,6 @@ static struct platform_device *sh7770_devices[] __initdata = {
360 &tmu6_device, 456 &tmu6_device,
361 &tmu7_device, 457 &tmu7_device,
362 &tmu8_device, 458 &tmu8_device,
363 &sci_device,
364}; 459};
365 460
366static int __init sh7770_devices_setup(void) 461static int __init sh7770_devices_setup(void)
@@ -371,6 +466,16 @@ static int __init sh7770_devices_setup(void)
371arch_initcall(sh7770_devices_setup); 466arch_initcall(sh7770_devices_setup);
372 467
373static struct platform_device *sh7770_early_devices[] __initdata = { 468static struct platform_device *sh7770_early_devices[] __initdata = {
469 &scif0_device,
470 &scif1_device,
471 &scif2_device,
472 &scif3_device,
473 &scif4_device,
474 &scif5_device,
475 &scif6_device,
476 &scif7_device,
477 &scif8_device,
478 &scif9_device,
374 &tmu0_device, 479 &tmu0_device,
375 &tmu1_device, 480 &tmu1_device,
376 &tmu2_device, 481 &tmu2_device,
@@ -589,17 +694,17 @@ static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors,
589void __init plat_irq_setup(void) 694void __init plat_irq_setup(void)
590{ 695{
591 /* disable IRQ7-0 */ 696 /* disable IRQ7-0 */
592 ctrl_outl(0xff000000, INTC_INTMSK0); 697 __raw_writel(0xff000000, INTC_INTMSK0);
593 698
594 /* disable IRL3-0 + IRL7-4 */ 699 /* disable IRL3-0 + IRL7-4 */
595 ctrl_outl(0xc0000000, INTC_INTMSK1); 700 __raw_writel(0xc0000000, INTC_INTMSK1);
596 ctrl_outl(0xfffefffe, INTC_INTMSK2); 701 __raw_writel(0xfffefffe, INTC_INTMSK2);
597 702
598 /* select IRL mode for IRL3-0 + IRL7-4 */ 703 /* select IRL mode for IRL3-0 + IRL7-4 */
599 ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); 704 __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
600 705
601 /* disable holding function, ie enable "SH-4 Mode" */ 706 /* disable holding function, ie enable "SH-4 Mode" */
602 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0); 707 __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
603 708
604 register_intc_controller(&intc_desc); 709 register_intc_controller(&intc_desc);
605} 710}
@@ -609,27 +714,27 @@ void __init plat_irq_setup_pins(int mode)
609 switch (mode) { 714 switch (mode) {
610 case IRQ_MODE_IRQ: 715 case IRQ_MODE_IRQ:
611 /* select IRQ mode for IRL3-0 + IRL7-4 */ 716 /* select IRQ mode for IRL3-0 + IRL7-4 */
612 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0); 717 __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
613 register_intc_controller(&intc_irq_desc); 718 register_intc_controller(&intc_irq_desc);
614 break; 719 break;
615 case IRQ_MODE_IRL7654: 720 case IRQ_MODE_IRL7654:
616 /* enable IRL7-4 but don't provide any masking */ 721 /* enable IRL7-4 but don't provide any masking */
617 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 722 __raw_writel(0x40000000, INTC_INTMSKCLR1);
618 ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); 723 __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
619 break; 724 break;
620 case IRQ_MODE_IRL3210: 725 case IRQ_MODE_IRL3210:
621 /* enable IRL0-3 but don't provide any masking */ 726 /* enable IRL0-3 but don't provide any masking */
622 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 727 __raw_writel(0x80000000, INTC_INTMSKCLR1);
623 ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); 728 __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
624 break; 729 break;
625 case IRQ_MODE_IRL7654_MASK: 730 case IRQ_MODE_IRL7654_MASK:
626 /* enable IRL7-4 and mask using cpu intc controller */ 731 /* enable IRL7-4 and mask using cpu intc controller */
627 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 732 __raw_writel(0x40000000, INTC_INTMSKCLR1);
628 register_intc_controller(&intc_irl7654_desc); 733 register_intc_controller(&intc_irl7654_desc);
629 break; 734 break;
630 case IRQ_MODE_IRL3210_MASK: 735 case IRQ_MODE_IRL3210_MASK:
631 /* enable IRL0-3 and mask using cpu intc controller */ 736 /* enable IRL0-3 and mask using cpu intc controller */
632 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 737 __raw_writel(0x80000000, INTC_INTMSKCLR1);
633 register_intc_controller(&intc_irl3210_desc); 738 register_intc_controller(&intc_irl3210_desc);
634 break; 739 break;
635 default: 740 default:
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index 12ff56f19c5c..02e792c90de6 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -13,7 +13,40 @@
13#include <linux/io.h> 13#include <linux/io.h>
14#include <linux/serial_sci.h> 14#include <linux/serial_sci.h>
15#include <linux/sh_timer.h> 15#include <linux/sh_timer.h>
16#include <asm/dma-sh.h> 16
17#include <asm/dmaengine.h>
18
19#include <cpu/dma-register.h>
20
21static struct plat_sci_port scif0_platform_data = {
22 .mapbase = 0xffe00000,
23 .flags = UPF_BOOT_AUTOCONF,
24 .type = PORT_SCIF,
25 .irqs = { 40, 40, 40, 40 },
26};
27
28static struct platform_device scif0_device = {
29 .name = "sh-sci",
30 .id = 0,
31 .dev = {
32 .platform_data = &scif0_platform_data,
33 },
34};
35
36static struct plat_sci_port scif1_platform_data = {
37 .mapbase = 0xffe10000,
38 .flags = UPF_BOOT_AUTOCONF,
39 .type = PORT_SCIF,
40 .irqs = { 76, 76, 76, 76 },
41};
42
43static struct platform_device scif1_device = {
44 .name = "sh-sci",
45 .id = 1,
46 .dev = {
47 .platform_data = &scif1_platform_data,
48 },
49};
17 50
18static struct sh_timer_config tmu0_platform_data = { 51static struct sh_timer_config tmu0_platform_data = {
19 .name = "TMU0", 52 .name = "TMU0",
@@ -217,43 +250,137 @@ static struct platform_device rtc_device = {
217 .resource = rtc_resources, 250 .resource = rtc_resources,
218}; 251};
219 252
220static struct plat_sci_port sci_platform_data[] = { 253/* DMA */
254static struct sh_dmae_channel sh7780_dmae0_channels[] = {
221 { 255 {
222 .mapbase = 0xffe00000, 256 .offset = 0,
223 .flags = UPF_BOOT_AUTOCONF, 257 .dmars = 0,
224 .type = PORT_SCIF, 258 .dmars_bit = 0,
225 .irqs = { 40, 40, 40, 40 }, 259 }, {
260 .offset = 0x10,
261 .dmars = 0,
262 .dmars_bit = 8,
263 }, {
264 .offset = 0x20,
265 .dmars = 4,
266 .dmars_bit = 0,
267 }, {
268 .offset = 0x30,
269 .dmars = 4,
270 .dmars_bit = 8,
226 }, { 271 }, {
227 .mapbase = 0xffe10000, 272 .offset = 0x50,
228 .flags = UPF_BOOT_AUTOCONF, 273 .dmars = 8,
229 .type = PORT_SCIF, 274 .dmars_bit = 0,
230 .irqs = { 76, 76, 76, 76 },
231 }, { 275 }, {
232 .flags = 0, 276 .offset = 0x60,
277 .dmars = 8,
278 .dmars_bit = 8,
233 } 279 }
234}; 280};
235 281
236static struct platform_device sci_device = { 282static struct sh_dmae_channel sh7780_dmae1_channels[] = {
237 .name = "sh-sci", 283 {
238 .id = -1, 284 .offset = 0,
239 .dev = { 285 }, {
240 .platform_data = sci_platform_data, 286 .offset = 0x10,
287 }, {
288 .offset = 0x20,
289 }, {
290 .offset = 0x30,
291 }, {
292 .offset = 0x50,
293 }, {
294 .offset = 0x60,
295 }
296};
297
298static unsigned int ts_shift[] = TS_SHIFT;
299
300static struct sh_dmae_pdata dma0_platform_data = {
301 .channel = sh7780_dmae0_channels,
302 .channel_num = ARRAY_SIZE(sh7780_dmae0_channels),
303 .ts_low_shift = CHCR_TS_LOW_SHIFT,
304 .ts_low_mask = CHCR_TS_LOW_MASK,
305 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
306 .ts_high_mask = CHCR_TS_HIGH_MASK,
307 .ts_shift = ts_shift,
308 .ts_shift_num = ARRAY_SIZE(ts_shift),
309 .dmaor_init = DMAOR_INIT,
310};
311
312static struct sh_dmae_pdata dma1_platform_data = {
313 .channel = sh7780_dmae1_channels,
314 .channel_num = ARRAY_SIZE(sh7780_dmae1_channels),
315 .ts_low_shift = CHCR_TS_LOW_SHIFT,
316 .ts_low_mask = CHCR_TS_LOW_MASK,
317 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
318 .ts_high_mask = CHCR_TS_HIGH_MASK,
319 .ts_shift = ts_shift,
320 .ts_shift_num = ARRAY_SIZE(ts_shift),
321 .dmaor_init = DMAOR_INIT,
322};
323
324static struct resource sh7780_dmae0_resources[] = {
325 [0] = {
326 /* Channel registers and DMAOR */
327 .start = 0xfc808020,
328 .end = 0xfc80808f,
329 .flags = IORESOURCE_MEM,
330 },
331 [1] = {
332 /* DMARSx */
333 .start = 0xfc809000,
334 .end = 0xfc80900b,
335 .flags = IORESOURCE_MEM,
336 },
337 {
338 /* Real DMA error IRQ is 38, and channel IRQs are 34-37, 44-45 */
339 .start = 34,
340 .end = 34,
341 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
241 }, 342 },
242}; 343};
243 344
244static struct sh_dmae_pdata dma_platform_data = { 345static struct resource sh7780_dmae1_resources[] = {
245 .mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1), 346 [0] = {
347 /* Channel registers and DMAOR */
348 .start = 0xfc818020,
349 .end = 0xfc81808f,
350 .flags = IORESOURCE_MEM,
351 },
352 /* DMAC1 has no DMARS */
353 {
354 /* Real DMA error IRQ is 38, and channel IRQs are 46-47, 92-95 */
355 .start = 46,
356 .end = 46,
357 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
358 },
246}; 359};
247 360
248static struct platform_device dma_device = { 361static struct platform_device dma0_device = {
249 .name = "sh-dma-engine", 362 .name = "sh-dma-engine",
250 .id = -1, 363 .id = 0,
364 .resource = sh7780_dmae0_resources,
365 .num_resources = ARRAY_SIZE(sh7780_dmae0_resources),
251 .dev = { 366 .dev = {
252 .platform_data = &dma_platform_data, 367 .platform_data = &dma0_platform_data,
368 },
369};
370
371static struct platform_device dma1_device = {
372 .name = "sh-dma-engine",
373 .id = 1,
374 .resource = sh7780_dmae1_resources,
375 .num_resources = ARRAY_SIZE(sh7780_dmae1_resources),
376 .dev = {
377 .platform_data = &dma1_platform_data,
253 }, 378 },
254}; 379};
255 380
256static struct platform_device *sh7780_devices[] __initdata = { 381static struct platform_device *sh7780_devices[] __initdata = {
382 &scif0_device,
383 &scif1_device,
257 &tmu0_device, 384 &tmu0_device,
258 &tmu1_device, 385 &tmu1_device,
259 &tmu2_device, 386 &tmu2_device,
@@ -261,8 +388,8 @@ static struct platform_device *sh7780_devices[] __initdata = {
261 &tmu4_device, 388 &tmu4_device,
262 &tmu5_device, 389 &tmu5_device,
263 &rtc_device, 390 &rtc_device,
264 &sci_device, 391 &dma0_device,
265 &dma_device, 392 &dma1_device,
266}; 393};
267 394
268static int __init sh7780_devices_setup(void) 395static int __init sh7780_devices_setup(void)
@@ -271,8 +398,9 @@ static int __init sh7780_devices_setup(void)
271 ARRAY_SIZE(sh7780_devices)); 398 ARRAY_SIZE(sh7780_devices));
272} 399}
273arch_initcall(sh7780_devices_setup); 400arch_initcall(sh7780_devices_setup);
274
275static struct platform_device *sh7780_early_devices[] __initdata = { 401static struct platform_device *sh7780_early_devices[] __initdata = {
402 &scif0_device,
403 &scif1_device,
276 &tmu0_device, 404 &tmu0_device,
277 &tmu1_device, 405 &tmu1_device,
278 &tmu2_device, 406 &tmu2_device,
@@ -453,17 +581,17 @@ static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors,
453void __init plat_irq_setup(void) 581void __init plat_irq_setup(void)
454{ 582{
455 /* disable IRQ7-0 */ 583 /* disable IRQ7-0 */
456 ctrl_outl(0xff000000, INTC_INTMSK0); 584 __raw_writel(0xff000000, INTC_INTMSK0);
457 585
458 /* disable IRL3-0 + IRL7-4 */ 586 /* disable IRL3-0 + IRL7-4 */
459 ctrl_outl(0xc0000000, INTC_INTMSK1); 587 __raw_writel(0xc0000000, INTC_INTMSK1);
460 ctrl_outl(0xfffefffe, INTC_INTMSK2); 588 __raw_writel(0xfffefffe, INTC_INTMSK2);
461 589
462 /* select IRL mode for IRL3-0 + IRL7-4 */ 590 /* select IRL mode for IRL3-0 + IRL7-4 */
463 ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); 591 __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
464 592
465 /* disable holding function, ie enable "SH-4 Mode" */ 593 /* disable holding function, ie enable "SH-4 Mode" */
466 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0); 594 __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
467 595
468 register_intc_controller(&intc_desc); 596 register_intc_controller(&intc_desc);
469} 597}
@@ -473,27 +601,27 @@ void __init plat_irq_setup_pins(int mode)
473 switch (mode) { 601 switch (mode) {
474 case IRQ_MODE_IRQ: 602 case IRQ_MODE_IRQ:
475 /* select IRQ mode for IRL3-0 + IRL7-4 */ 603 /* select IRQ mode for IRL3-0 + IRL7-4 */
476 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0); 604 __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
477 register_intc_controller(&intc_irq_desc); 605 register_intc_controller(&intc_irq_desc);
478 break; 606 break;
479 case IRQ_MODE_IRL7654: 607 case IRQ_MODE_IRL7654:
480 /* enable IRL7-4 but don't provide any masking */ 608 /* enable IRL7-4 but don't provide any masking */
481 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 609 __raw_writel(0x40000000, INTC_INTMSKCLR1);
482 ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); 610 __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
483 break; 611 break;
484 case IRQ_MODE_IRL3210: 612 case IRQ_MODE_IRL3210:
485 /* enable IRL0-3 but don't provide any masking */ 613 /* enable IRL0-3 but don't provide any masking */
486 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 614 __raw_writel(0x80000000, INTC_INTMSKCLR1);
487 ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); 615 __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
488 break; 616 break;
489 case IRQ_MODE_IRL7654_MASK: 617 case IRQ_MODE_IRL7654_MASK:
490 /* enable IRL7-4 and mask using cpu intc controller */ 618 /* enable IRL7-4 and mask using cpu intc controller */
491 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 619 __raw_writel(0x40000000, INTC_INTMSKCLR1);
492 register_intc_controller(&intc_irl7654_desc); 620 register_intc_controller(&intc_irl7654_desc);
493 break; 621 break;
494 case IRQ_MODE_IRL3210_MASK: 622 case IRQ_MODE_IRL3210_MASK:
495 /* enable IRL0-3 and mask using cpu intc controller */ 623 /* enable IRL0-3 and mask using cpu intc controller */
496 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 624 __raw_writel(0x80000000, INTC_INTMSKCLR1);
497 register_intc_controller(&intc_irl3210_desc); 625 register_intc_controller(&intc_irl3210_desc);
498 break; 626 break;
499 default: 627 default:
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index 7f6c718b6c36..1fcd88b1671e 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -14,8 +14,108 @@
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/sh_timer.h> 16#include <linux/sh_timer.h>
17
18#include <asm/dmaengine.h>
17#include <asm/mmzone.h> 19#include <asm/mmzone.h>
18 20
21#include <cpu/dma-register.h>
22
23static struct plat_sci_port scif0_platform_data = {
24 .mapbase = 0xffea0000,
25 .flags = UPF_BOOT_AUTOCONF,
26 .type = PORT_SCIF,
27 .irqs = { 40, 40, 40, 40 },
28 .clk = "scif_fck",
29};
30
31static struct platform_device scif0_device = {
32 .name = "sh-sci",
33 .id = 0,
34 .dev = {
35 .platform_data = &scif0_platform_data,
36 },
37};
38
39static struct plat_sci_port scif1_platform_data = {
40 .mapbase = 0xffeb0000,
41 .flags = UPF_BOOT_AUTOCONF,
42 .type = PORT_SCIF,
43 .irqs = { 44, 44, 44, 44 },
44 .clk = "scif_fck",
45};
46
47static struct platform_device scif1_device = {
48 .name = "sh-sci",
49 .id = 1,
50 .dev = {
51 .platform_data = &scif1_platform_data,
52 },
53};
54
55static struct plat_sci_port scif2_platform_data = {
56 .mapbase = 0xffec0000,
57 .flags = UPF_BOOT_AUTOCONF,
58 .type = PORT_SCIF,
59 .irqs = { 60, 60, 60, 60 },
60 .clk = "scif_fck",
61};
62
63static struct platform_device scif2_device = {
64 .name = "sh-sci",
65 .id = 2,
66 .dev = {
67 .platform_data = &scif2_platform_data,
68 },
69};
70
71static struct plat_sci_port scif3_platform_data = {
72 .mapbase = 0xffed0000,
73 .flags = UPF_BOOT_AUTOCONF,
74 .type = PORT_SCIF,
75 .irqs = { 61, 61, 61, 61 },
76 .clk = "scif_fck",
77};
78
79static struct platform_device scif3_device = {
80 .name = "sh-sci",
81 .id = 3,
82 .dev = {
83 .platform_data = &scif3_platform_data,
84 },
85};
86
87static struct plat_sci_port scif4_platform_data = {
88 .mapbase = 0xffee0000,
89 .flags = UPF_BOOT_AUTOCONF,
90 .type = PORT_SCIF,
91 .irqs = { 62, 62, 62, 62 },
92 .clk = "scif_fck",
93};
94
95static struct platform_device scif4_device = {
96 .name = "sh-sci",
97 .id = 4,
98 .dev = {
99 .platform_data = &scif4_platform_data,
100 },
101};
102
103static struct plat_sci_port scif5_platform_data = {
104 .mapbase = 0xffef0000,
105 .flags = UPF_BOOT_AUTOCONF,
106 .type = PORT_SCIF,
107 .irqs = { 63, 63, 63, 63 },
108 .clk = "scif_fck",
109};
110
111static struct platform_device scif5_device = {
112 .name = "sh-sci",
113 .id = 5,
114 .dev = {
115 .platform_data = &scif5_platform_data,
116 },
117};
118
19static struct sh_timer_config tmu0_platform_data = { 119static struct sh_timer_config tmu0_platform_data = {
20 .name = "TMU0", 120 .name = "TMU0",
21 .channel_offset = 0x04, 121 .channel_offset = 0x04,
@@ -198,64 +298,149 @@ static struct platform_device tmu5_device = {
198 .num_resources = ARRAY_SIZE(tmu5_resources), 298 .num_resources = ARRAY_SIZE(tmu5_resources),
199}; 299};
200 300
201static struct plat_sci_port sci_platform_data[] = { 301/* DMA */
302static struct sh_dmae_channel sh7785_dmae0_channels[] = {
202 { 303 {
203 .mapbase = 0xffea0000, 304 .offset = 0,
204 .flags = UPF_BOOT_AUTOCONF, 305 .dmars = 0,
205 .type = PORT_SCIF, 306 .dmars_bit = 0,
206 .irqs = { 40, 40, 40, 40 },
207 .clk = "scif_fck",
208 }, { 307 }, {
209 .mapbase = 0xffeb0000, 308 .offset = 0x10,
210 .flags = UPF_BOOT_AUTOCONF, 309 .dmars = 0,
211 .type = PORT_SCIF, 310 .dmars_bit = 8,
212 .irqs = { 44, 44, 44, 44 },
213 .clk = "scif_fck",
214 }, { 311 }, {
215 .mapbase = 0xffec0000, 312 .offset = 0x20,
216 .flags = UPF_BOOT_AUTOCONF, 313 .dmars = 4,
217 .type = PORT_SCIF, 314 .dmars_bit = 0,
218 .irqs = { 60, 60, 60, 60 },
219 .clk = "scif_fck",
220 }, { 315 }, {
221 .mapbase = 0xffed0000, 316 .offset = 0x30,
222 .flags = UPF_BOOT_AUTOCONF, 317 .dmars = 4,
223 .type = PORT_SCIF, 318 .dmars_bit = 8,
224 .irqs = { 61, 61, 61, 61 },
225 .clk = "scif_fck",
226 }, { 319 }, {
227 .mapbase = 0xffee0000, 320 .offset = 0x50,
228 .flags = UPF_BOOT_AUTOCONF, 321 .dmars = 8,
229 .type = PORT_SCIF, 322 .dmars_bit = 0,
230 .irqs = { 62, 62, 62, 62 },
231 .clk = "scif_fck",
232 }, { 323 }, {
233 .mapbase = 0xffef0000, 324 .offset = 0x60,
234 .flags = UPF_BOOT_AUTOCONF, 325 .dmars = 8,
235 .type = PORT_SCIF, 326 .dmars_bit = 8,
236 .irqs = { 63, 63, 63, 63 }, 327 }
237 .clk = "scif_fck", 328};
329
330static struct sh_dmae_channel sh7785_dmae1_channels[] = {
331 {
332 .offset = 0,
238 }, { 333 }, {
239 .flags = 0, 334 .offset = 0x10,
335 }, {
336 .offset = 0x20,
337 }, {
338 .offset = 0x30,
339 }, {
340 .offset = 0x50,
341 }, {
342 .offset = 0x60,
240 } 343 }
241}; 344};
242 345
243static struct platform_device sci_device = { 346static unsigned int ts_shift[] = TS_SHIFT;
244 .name = "sh-sci", 347
245 .id = -1, 348static struct sh_dmae_pdata dma0_platform_data = {
349 .channel = sh7785_dmae0_channels,
350 .channel_num = ARRAY_SIZE(sh7785_dmae0_channels),
351 .ts_low_shift = CHCR_TS_LOW_SHIFT,
352 .ts_low_mask = CHCR_TS_LOW_MASK,
353 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
354 .ts_high_mask = CHCR_TS_HIGH_MASK,
355 .ts_shift = ts_shift,
356 .ts_shift_num = ARRAY_SIZE(ts_shift),
357 .dmaor_init = DMAOR_INIT,
358};
359
360static struct sh_dmae_pdata dma1_platform_data = {
361 .channel = sh7785_dmae1_channels,
362 .channel_num = ARRAY_SIZE(sh7785_dmae1_channels),
363 .ts_low_shift = CHCR_TS_LOW_SHIFT,
364 .ts_low_mask = CHCR_TS_LOW_MASK,
365 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
366 .ts_high_mask = CHCR_TS_HIGH_MASK,
367 .ts_shift = ts_shift,
368 .ts_shift_num = ARRAY_SIZE(ts_shift),
369 .dmaor_init = DMAOR_INIT,
370};
371
372static struct resource sh7785_dmae0_resources[] = {
373 [0] = {
374 /* Channel registers and DMAOR */
375 .start = 0xfc808020,
376 .end = 0xfc80808f,
377 .flags = IORESOURCE_MEM,
378 },
379 [1] = {
380 /* DMARSx */
381 .start = 0xfc809000,
382 .end = 0xfc80900b,
383 .flags = IORESOURCE_MEM,
384 },
385 {
386 /* Real DMA error IRQ is 39, and channel IRQs are 33-38 */
387 .start = 33,
388 .end = 33,
389 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
390 },
391};
392
393static struct resource sh7785_dmae1_resources[] = {
394 [0] = {
395 /* Channel registers and DMAOR */
396 .start = 0xfcc08020,
397 .end = 0xfcc0808f,
398 .flags = IORESOURCE_MEM,
399 },
400 /* DMAC1 has no DMARS */
401 {
402 /* Real DMA error IRQ is 58, and channel IRQs are 52-57 */
403 .start = 52,
404 .end = 52,
405 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
406 },
407};
408
409static struct platform_device dma0_device = {
410 .name = "sh-dma-engine",
411 .id = 0,
412 .resource = sh7785_dmae0_resources,
413 .num_resources = ARRAY_SIZE(sh7785_dmae0_resources),
414 .dev = {
415 .platform_data = &dma0_platform_data,
416 },
417};
418
419static struct platform_device dma1_device = {
420 .name = "sh-dma-engine",
421 .id = 1,
422 .resource = sh7785_dmae1_resources,
423 .num_resources = ARRAY_SIZE(sh7785_dmae1_resources),
246 .dev = { 424 .dev = {
247 .platform_data = sci_platform_data, 425 .platform_data = &dma1_platform_data,
248 }, 426 },
249}; 427};
250 428
251static struct platform_device *sh7785_devices[] __initdata = { 429static struct platform_device *sh7785_devices[] __initdata = {
430 &scif0_device,
431 &scif1_device,
432 &scif2_device,
433 &scif3_device,
434 &scif4_device,
435 &scif5_device,
252 &tmu0_device, 436 &tmu0_device,
253 &tmu1_device, 437 &tmu1_device,
254 &tmu2_device, 438 &tmu2_device,
255 &tmu3_device, 439 &tmu3_device,
256 &tmu4_device, 440 &tmu4_device,
257 &tmu5_device, 441 &tmu5_device,
258 &sci_device, 442 &dma0_device,
443 &dma1_device,
259}; 444};
260 445
261static int __init sh7785_devices_setup(void) 446static int __init sh7785_devices_setup(void)
@@ -266,6 +451,12 @@ static int __init sh7785_devices_setup(void)
266arch_initcall(sh7785_devices_setup); 451arch_initcall(sh7785_devices_setup);
267 452
268static struct platform_device *sh7785_early_devices[] __initdata = { 453static struct platform_device *sh7785_early_devices[] __initdata = {
454 &scif0_device,
455 &scif1_device,
456 &scif2_device,
457 &scif3_device,
458 &scif4_device,
459 &scif5_device,
269 &tmu0_device, 460 &tmu0_device,
270 &tmu1_device, 461 &tmu1_device,
271 &tmu2_device, 462 &tmu2_device,
@@ -470,17 +661,17 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7785-irl4567", vectors_irl4567,
470void __init plat_irq_setup(void) 661void __init plat_irq_setup(void)
471{ 662{
472 /* disable IRQ3-0 + IRQ7-4 */ 663 /* disable IRQ3-0 + IRQ7-4 */
473 ctrl_outl(0xff000000, INTC_INTMSK0); 664 __raw_writel(0xff000000, INTC_INTMSK0);
474 665
475 /* disable IRL3-0 + IRL7-4 */ 666 /* disable IRL3-0 + IRL7-4 */
476 ctrl_outl(0xc0000000, INTC_INTMSK1); 667 __raw_writel(0xc0000000, INTC_INTMSK1);
477 ctrl_outl(0xfffefffe, INTC_INTMSK2); 668 __raw_writel(0xfffefffe, INTC_INTMSK2);
478 669
479 /* select IRL mode for IRL3-0 + IRL7-4 */ 670 /* select IRL mode for IRL3-0 + IRL7-4 */
480 ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); 671 __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
481 672
482 /* disable holding function, ie enable "SH-4 Mode" */ 673 /* disable holding function, ie enable "SH-4 Mode" */
483 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0); 674 __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
484 675
485 register_intc_controller(&intc_desc); 676 register_intc_controller(&intc_desc);
486} 677}
@@ -490,32 +681,32 @@ void __init plat_irq_setup_pins(int mode)
490 switch (mode) { 681 switch (mode) {
491 case IRQ_MODE_IRQ7654: 682 case IRQ_MODE_IRQ7654:
492 /* select IRQ mode for IRL7-4 */ 683 /* select IRQ mode for IRL7-4 */
493 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0); 684 __raw_writel(__raw_readl(INTC_ICR0) | 0x00400000, INTC_ICR0);
494 register_intc_controller(&intc_desc_irq4567); 685 register_intc_controller(&intc_desc_irq4567);
495 break; 686 break;
496 case IRQ_MODE_IRQ3210: 687 case IRQ_MODE_IRQ3210:
497 /* select IRQ mode for IRL3-0 */ 688 /* select IRQ mode for IRL3-0 */
498 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0); 689 __raw_writel(__raw_readl(INTC_ICR0) | 0x00800000, INTC_ICR0);
499 register_intc_controller(&intc_desc_irq0123); 690 register_intc_controller(&intc_desc_irq0123);
500 break; 691 break;
501 case IRQ_MODE_IRL7654: 692 case IRQ_MODE_IRL7654:
502 /* enable IRL7-4 but don't provide any masking */ 693 /* enable IRL7-4 but don't provide any masking */
503 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 694 __raw_writel(0x40000000, INTC_INTMSKCLR1);
504 ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); 695 __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
505 break; 696 break;
506 case IRQ_MODE_IRL3210: 697 case IRQ_MODE_IRL3210:
507 /* enable IRL0-3 but don't provide any masking */ 698 /* enable IRL0-3 but don't provide any masking */
508 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 699 __raw_writel(0x80000000, INTC_INTMSKCLR1);
509 ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); 700 __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
510 break; 701 break;
511 case IRQ_MODE_IRL7654_MASK: 702 case IRQ_MODE_IRL7654_MASK:
512 /* enable IRL7-4 and mask using cpu intc controller */ 703 /* enable IRL7-4 and mask using cpu intc controller */
513 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 704 __raw_writel(0x40000000, INTC_INTMSKCLR1);
514 register_intc_controller(&intc_desc_irl4567); 705 register_intc_controller(&intc_desc_irl4567);
515 break; 706 break;
516 case IRQ_MODE_IRL3210_MASK: 707 case IRQ_MODE_IRL3210_MASK:
517 /* enable IRL0-3 and mask using cpu intc controller */ 708 /* enable IRL0-3 and mask using cpu intc controller */
518 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 709 __raw_writel(0x80000000, INTC_INTMSKCLR1);
519 register_intc_controller(&intc_desc_irl0123); 710 register_intc_controller(&intc_desc_irl0123);
520 break; 711 break;
521 default: 712 default:
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
index 0104a8ec5369..7e585320710a 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -23,51 +23,96 @@
23#include <linux/sh_timer.h> 23#include <linux/sh_timer.h>
24#include <asm/mmzone.h> 24#include <asm/mmzone.h>
25 25
26static struct plat_sci_port sci_platform_data[] = { 26static struct plat_sci_port scif0_platform_data = {
27 { 27 .mapbase = 0xffea0000,
28 .mapbase = 0xffea0000, 28 .flags = UPF_BOOT_AUTOCONF,
29 .flags = UPF_BOOT_AUTOCONF, 29 .type = PORT_SCIF,
30 .type = PORT_SCIF, 30 .irqs = { 40, 41, 43, 42 },
31 .irqs = { 40, 41, 43, 42 }, 31};
32
33static struct platform_device scif0_device = {
34 .name = "sh-sci",
35 .id = 0,
36 .dev = {
37 .platform_data = &scif0_platform_data,
32 }, 38 },
33 /*
34 * The rest of these all have multiplexed IRQs
35 */
36 {
37 .mapbase = 0xffeb0000,
38 .flags = UPF_BOOT_AUTOCONF,
39 .type = PORT_SCIF,
40 .irqs = { 44, 44, 44, 44 },
41 }, {
42 .mapbase = 0xffec0000,
43 .flags = UPF_BOOT_AUTOCONF,
44 .type = PORT_SCIF,
45 .irqs = { 50, 50, 50, 50 },
46 }, {
47 .mapbase = 0xffed0000,
48 .flags = UPF_BOOT_AUTOCONF,
49 .type = PORT_SCIF,
50 .irqs = { 51, 51, 51, 51 },
51 }, {
52 .mapbase = 0xffee0000,
53 .flags = UPF_BOOT_AUTOCONF,
54 .type = PORT_SCIF,
55 .irqs = { 52, 52, 52, 52 },
56 }, {
57 .mapbase = 0xffef0000,
58 .flags = UPF_BOOT_AUTOCONF,
59 .type = PORT_SCIF,
60 .irqs = { 53, 53, 53, 53 },
61 }, {
62 .flags = 0,
63 }
64}; 39};
65 40
66static struct platform_device sci_device = { 41/*
42 * The rest of these all have multiplexed IRQs
43 */
44static struct plat_sci_port scif1_platform_data = {
45 .mapbase = 0xffeb0000,
46 .flags = UPF_BOOT_AUTOCONF,
47 .type = PORT_SCIF,
48 .irqs = { 44, 44, 44, 44 },
49};
50
51static struct platform_device scif1_device = {
67 .name = "sh-sci", 52 .name = "sh-sci",
68 .id = -1, 53 .id = 1,
54 .dev = {
55 .platform_data = &scif1_platform_data,
56 },
57};
58
59static struct plat_sci_port scif2_platform_data = {
60 .mapbase = 0xffec0000,
61 .flags = UPF_BOOT_AUTOCONF,
62 .type = PORT_SCIF,
63 .irqs = { 50, 50, 50, 50 },
64};
65
66static struct platform_device scif2_device = {
67 .name = "sh-sci",
68 .id = 2,
69 .dev = {
70 .platform_data = &scif2_platform_data,
71 },
72};
73
74static struct plat_sci_port scif3_platform_data = {
75 .mapbase = 0xffed0000,
76 .flags = UPF_BOOT_AUTOCONF,
77 .type = PORT_SCIF,
78 .irqs = { 51, 51, 51, 51 },
79};
80
81static struct platform_device scif3_device = {
82 .name = "sh-sci",
83 .id = 3,
84 .dev = {
85 .platform_data = &scif3_platform_data,
86 },
87};
88
89static struct plat_sci_port scif4_platform_data = {
90 .mapbase = 0xffee0000,
91 .flags = UPF_BOOT_AUTOCONF,
92 .type = PORT_SCIF,
93 .irqs = { 52, 52, 52, 52 },
94};
95
96static struct platform_device scif4_device = {
97 .name = "sh-sci",
98 .id = 4,
99 .dev = {
100 .platform_data = &scif4_platform_data,
101 },
102};
103
104static struct plat_sci_port scif5_platform_data = {
105 .mapbase = 0xffef0000,
106 .flags = UPF_BOOT_AUTOCONF,
107 .type = PORT_SCIF,
108 .irqs = { 53, 53, 53, 53 },
109};
110
111static struct platform_device scif5_device = {
112 .name = "sh-sci",
113 .id = 5,
69 .dev = { 114 .dev = {
70 .platform_data = sci_platform_data, 115 .platform_data = &scif5_platform_data,
71 }, 116 },
72}; 117};
73 118
@@ -459,6 +504,12 @@ static struct platform_device usb_ohci_device = {
459}; 504};
460 505
461static struct platform_device *sh7786_early_devices[] __initdata = { 506static struct platform_device *sh7786_early_devices[] __initdata = {
507 &scif0_device,
508 &scif1_device,
509 &scif2_device,
510 &scif3_device,
511 &scif4_device,
512 &scif5_device,
462 &tmu0_device, 513 &tmu0_device,
463 &tmu1_device, 514 &tmu1_device,
464 &tmu2_device, 515 &tmu2_device,
@@ -474,7 +525,6 @@ static struct platform_device *sh7786_early_devices[] __initdata = {
474}; 525};
475 526
476static struct platform_device *sh7786_devices[] __initdata = { 527static struct platform_device *sh7786_devices[] __initdata = {
477 &sci_device,
478 &usb_ohci_device, 528 &usb_ohci_device,
479}; 529};
480 530
@@ -817,14 +867,14 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7786-irl4567", vectors_irl4567,
817void __init plat_irq_setup(void) 867void __init plat_irq_setup(void)
818{ 868{
819 /* disable IRQ3-0 + IRQ7-4 */ 869 /* disable IRQ3-0 + IRQ7-4 */
820 ctrl_outl(0xff000000, INTC_INTMSK0); 870 __raw_writel(0xff000000, INTC_INTMSK0);
821 871
822 /* disable IRL3-0 + IRL7-4 */ 872 /* disable IRL3-0 + IRL7-4 */
823 ctrl_outl(0xc0000000, INTC_INTMSK1); 873 __raw_writel(0xc0000000, INTC_INTMSK1);
824 ctrl_outl(0xfffefffe, INTC_INTMSK2); 874 __raw_writel(0xfffefffe, INTC_INTMSK2);
825 875
826 /* select IRL mode for IRL3-0 + IRL7-4 */ 876 /* select IRL mode for IRL3-0 + IRL7-4 */
827 ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); 877 __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
828 878
829 register_intc_controller(&intc_desc); 879 register_intc_controller(&intc_desc);
830} 880}
@@ -834,32 +884,32 @@ void __init plat_irq_setup_pins(int mode)
834 switch (mode) { 884 switch (mode) {
835 case IRQ_MODE_IRQ7654: 885 case IRQ_MODE_IRQ7654:
836 /* select IRQ mode for IRL7-4 */ 886 /* select IRQ mode for IRL7-4 */
837 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0); 887 __raw_writel(__raw_readl(INTC_ICR0) | 0x00400000, INTC_ICR0);
838 register_intc_controller(&intc_desc_irq4567); 888 register_intc_controller(&intc_desc_irq4567);
839 break; 889 break;
840 case IRQ_MODE_IRQ3210: 890 case IRQ_MODE_IRQ3210:
841 /* select IRQ mode for IRL3-0 */ 891 /* select IRQ mode for IRL3-0 */
842 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0); 892 __raw_writel(__raw_readl(INTC_ICR0) | 0x00800000, INTC_ICR0);
843 register_intc_controller(&intc_desc_irq0123); 893 register_intc_controller(&intc_desc_irq0123);
844 break; 894 break;
845 case IRQ_MODE_IRL7654: 895 case IRQ_MODE_IRL7654:
846 /* enable IRL7-4 but don't provide any masking */ 896 /* enable IRL7-4 but don't provide any masking */
847 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 897 __raw_writel(0x40000000, INTC_INTMSKCLR1);
848 ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); 898 __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
849 break; 899 break;
850 case IRQ_MODE_IRL3210: 900 case IRQ_MODE_IRL3210:
851 /* enable IRL0-3 but don't provide any masking */ 901 /* enable IRL0-3 but don't provide any masking */
852 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 902 __raw_writel(0x80000000, INTC_INTMSKCLR1);
853 ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); 903 __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
854 break; 904 break;
855 case IRQ_MODE_IRL7654_MASK: 905 case IRQ_MODE_IRL7654_MASK:
856 /* enable IRL7-4 and mask using cpu intc controller */ 906 /* enable IRL7-4 and mask using cpu intc controller */
857 ctrl_outl(0x40000000, INTC_INTMSKCLR1); 907 __raw_writel(0x40000000, INTC_INTMSKCLR1);
858 register_intc_controller(&intc_desc_irl4567); 908 register_intc_controller(&intc_desc_irl4567);
859 break; 909 break;
860 case IRQ_MODE_IRL3210_MASK: 910 case IRQ_MODE_IRL3210_MASK:
861 /* enable IRL0-3 and mask using cpu intc controller */ 911 /* enable IRL0-3 and mask using cpu intc controller */
862 ctrl_outl(0x80000000, INTC_INTMSKCLR1); 912 __raw_writel(0x80000000, INTC_INTMSKCLR1);
863 register_intc_controller(&intc_desc_irl0123); 913 register_intc_controller(&intc_desc_irl0123);
864 break; 914 break;
865 default: 915 default:
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index e848443deeb9..780ba17a5599 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -15,37 +15,57 @@
15#include <linux/sh_timer.h> 15#include <linux/sh_timer.h>
16#include <asm/mmzone.h> 16#include <asm/mmzone.h>
17 17
18static struct plat_sci_port sci_platform_data[] = { 18/*
19 { 19 * This intentionally only registers SCIF ports 0, 1, and 3. SCIF 2
20 .mapbase = 0xffc30000, 20 * INTEVT values overlap with the FPU EXPEVT ones, requiring special
21 .flags = UPF_BOOT_AUTOCONF, 21 * demuxing in the exception dispatch path.
22 .type = PORT_SCIF, 22 *
23 .irqs = { 40, 41, 43, 42 }, 23 * As this overlap is something that never should have made it in to
24 }, { 24 * silicon in the first place, we just refuse to deal with the port at
25 .mapbase = 0xffc40000, 25 * all rather than adding infrastructure to hack around it.
26 .flags = UPF_BOOT_AUTOCONF, 26 */
27 .type = PORT_SCIF, 27static struct plat_sci_port scif0_platform_data = {
28 .irqs = { 44, 45, 47, 46 }, 28 .mapbase = 0xffc30000,
29 }, { 29 .flags = UPF_BOOT_AUTOCONF,
30 .mapbase = 0xffc50000, 30 .type = PORT_SCIF,
31 .flags = UPF_BOOT_AUTOCONF, 31 .irqs = { 40, 41, 43, 42 },
32 .type = PORT_SCIF,
33 .irqs = { 48, 49, 51, 50 },
34 }, {
35 .mapbase = 0xffc60000,
36 .flags = UPF_BOOT_AUTOCONF,
37 .type = PORT_SCIF,
38 .irqs = { 52, 53, 55, 54 },
39 }, {
40 .flags = 0,
41 }
42}; 32};
43 33
44static struct platform_device sci_device = { 34static struct platform_device scif0_device = {
45 .name = "sh-sci", 35 .name = "sh-sci",
46 .id = -1, 36 .id = 0,
37 .dev = {
38 .platform_data = &scif0_platform_data,
39 },
40};
41
42static struct plat_sci_port scif1_platform_data = {
43 .mapbase = 0xffc40000,
44 .flags = UPF_BOOT_AUTOCONF,
45 .type = PORT_SCIF,
46 .irqs = { 44, 45, 47, 46 },
47};
48
49static struct platform_device scif1_device = {
50 .name = "sh-sci",
51 .id = 1,
47 .dev = { 52 .dev = {
48 .platform_data = sci_platform_data, 53 .platform_data = &scif1_platform_data,
54 },
55};
56
57static struct plat_sci_port scif2_platform_data = {
58 .mapbase = 0xffc60000,
59 .flags = UPF_BOOT_AUTOCONF,
60 .type = PORT_SCIF,
61 .irqs = { 52, 53, 55, 54 },
62};
63
64static struct platform_device scif2_device = {
65 .name = "sh-sci",
66 .id = 2,
67 .dev = {
68 .platform_data = &scif2_platform_data,
49 }, 69 },
50}; 70};
51 71
@@ -232,6 +252,9 @@ static struct platform_device tmu5_device = {
232}; 252};
233 253
234static struct platform_device *shx3_early_devices[] __initdata = { 254static struct platform_device *shx3_early_devices[] __initdata = {
255 &scif0_device,
256 &scif1_device,
257 &scif2_device,
235 &tmu0_device, 258 &tmu0_device,
236 &tmu1_device, 259 &tmu1_device,
237 &tmu2_device, 260 &tmu2_device,
@@ -240,21 +263,10 @@ static struct platform_device *shx3_early_devices[] __initdata = {
240 &tmu5_device, 263 &tmu5_device,
241}; 264};
242 265
243static struct platform_device *shx3_devices[] __initdata = {
244 &sci_device,
245};
246
247static int __init shx3_devices_setup(void) 266static int __init shx3_devices_setup(void)
248{ 267{
249 int ret; 268 return platform_add_devices(shx3_early_devices,
250
251 ret = platform_add_devices(shx3_early_devices,
252 ARRAY_SIZE(shx3_early_devices)); 269 ARRAY_SIZE(shx3_early_devices));
253 if (unlikely(ret != 0))
254 return ret;
255
256 return platform_add_devices(shx3_devices,
257 ARRAY_SIZE(shx3_devices));
258} 270}
259arch_initcall(shx3_devices_setup); 271arch_initcall(shx3_devices_setup);
260 272
@@ -268,7 +280,11 @@ enum {
268 UNUSED = 0, 280 UNUSED = 0,
269 281
270 /* interrupt sources */ 282 /* interrupt sources */
271 IRL, IRQ0, IRQ1, IRQ2, IRQ3, 283 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
284 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
285 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
286 IRL_HHLL, IRL_HHLH, IRL_HHHL,
287 IRQ0, IRQ1, IRQ2, IRQ3,
272 HUDII, 288 HUDII,
273 TMU0, TMU1, TMU2, TMU3, TMU4, TMU5, 289 TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
274 PCII0, PCII1, PCII2, PCII3, PCII4, 290 PCII0, PCII1, PCII2, PCII3, PCII4,
@@ -291,7 +307,7 @@ enum {
291 INTICI4, INTICI5, INTICI6, INTICI7, 307 INTICI4, INTICI5, INTICI6, INTICI7,
292 308
293 /* interrupt groups */ 309 /* interrupt groups */
294 PCII56789, SCIF0, SCIF1, SCIF2, SCIF3, 310 IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
295 DMAC0, DMAC1, 311 DMAC0, DMAC1,
296}; 312};
297 313
@@ -309,8 +325,6 @@ static struct intc_vect vectors[] __initdata = {
309 INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760), 325 INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
310 INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0), 326 INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
311 INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0), 327 INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
312 INTC_VECT(SCIF2_ERI, 0x800), INTC_VECT(SCIF2_RXI, 0x820),
313 INTC_VECT(SCIF2_BRI, 0x840), INTC_VECT(SCIF2_TXI, 0x860),
314 INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0), 328 INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0),
315 INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0), 329 INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0),
316 INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920), 330 INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920),
@@ -344,10 +358,13 @@ static struct intc_vect vectors[] __initdata = {
344}; 358};
345 359
346static struct intc_group groups[] __initdata = { 360static struct intc_group groups[] __initdata = {
361 INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
362 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
363 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
364 IRL_HHLL, IRL_HHLH, IRL_HHHL),
347 INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9), 365 INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
348 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), 366 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
349 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI), 367 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
350 INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
351 INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI), 368 INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI),
352 INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, 369 INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
353 DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE), 370 DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
@@ -419,14 +436,14 @@ static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups,
419 436
420/* External interrupt pins in IRL mode */ 437/* External interrupt pins in IRL mode */
421static struct intc_vect vectors_irl[] __initdata = { 438static struct intc_vect vectors_irl[] __initdata = {
422 INTC_VECT(IRL, 0x200), INTC_VECT(IRL, 0x220), 439 INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
423 INTC_VECT(IRL, 0x240), INTC_VECT(IRL, 0x260), 440 INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
424 INTC_VECT(IRL, 0x280), INTC_VECT(IRL, 0x2a0), 441 INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
425 INTC_VECT(IRL, 0x2c0), INTC_VECT(IRL, 0x2e0), 442 INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
426 INTC_VECT(IRL, 0x300), INTC_VECT(IRL, 0x320), 443 INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
427 INTC_VECT(IRL, 0x340), INTC_VECT(IRL, 0x360), 444 INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
428 INTC_VECT(IRL, 0x380), INTC_VECT(IRL, 0x3a0), 445 INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
429 INTC_VECT(IRL, 0x3c0), 446 INTC_VECT(IRL_HHHL, 0x3c0),
430}; 447};
431 448
432static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups, 449static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
index 185ec3976a25..11bf4c1e25c0 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,26 @@ 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 if (__in_29bit_mode())
82 __raw_writel(entry_point, RESET_REG(cpu));
83 else
84 __raw_writel(virt_to_phys(entry_point), RESET_REG(cpu));
81 85
82 if (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP)) 86 if (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
83 ctrl_outl(STBCR_MSTP, STBCR_REG(cpu)); 87 __raw_writel(STBCR_MSTP, STBCR_REG(cpu));
84 88
85 while (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP)) 89 while (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
86 cpu_relax(); 90 cpu_relax();
87 91
88 /* Start up secondary processor by sending a reset */ 92 /* Start up secondary processor by sending a reset */
89 ctrl_outl(STBCR_AP_VAL, STBCR_REG(cpu)); 93 __raw_writel(STBCR_RESET | STBCR_LTSLP, STBCR_REG(cpu));
90} 94}
91 95
92int plat_smp_processor_id(void) 96int plat_smp_processor_id(void)
93{ 97{
94 return ctrl_inl(0xff000048); /* CPIDR */ 98 return __raw_readl(0xff000048); /* CPIDR */
95} 99}
96 100
97void plat_send_ipi(unsigned int cpu, unsigned int message) 101void plat_send_ipi(unsigned int cpu, unsigned int message)
@@ -100,5 +104,5 @@ void plat_send_ipi(unsigned int cpu, unsigned int message)
100 104
101 BUG_ON(cpu >= 4); 105 BUG_ON(cpu >= 4);
102 106
103 ctrl_outl(1 << (message << 2), addr); /* C0INTICI..CnINTICI */ 107 __raw_writel(1 << (message << 2), addr); /* C0INTICI..CnINTICI */
104} 108}
diff --git a/arch/sh/kernel/cpu/sh4a/ubc.c b/arch/sh/kernel/cpu/sh4a/ubc.c
new file mode 100644
index 000000000000..efb2745bcb36
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/ubc.c
@@ -0,0 +1,133 @@
1/*
2 * arch/sh/kernel/cpu/sh4a/ubc.c
3 *
4 * On-chip UBC support for SH-4A CPUs.
5 *
6 * Copyright (C) 2009 - 2010 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/err.h>
14#include <linux/clk.h>
15#include <linux/io.h>
16#include <asm/hw_breakpoint.h>
17
18#define UBC_CBR(idx) (0xff200000 + (0x20 * idx))
19#define UBC_CRR(idx) (0xff200004 + (0x20 * idx))
20#define UBC_CAR(idx) (0xff200008 + (0x20 * idx))
21#define UBC_CAMR(idx) (0xff20000c + (0x20 * idx))
22
23#define UBC_CCMFR 0xff200600
24#define UBC_CBCR 0xff200620
25
26/* CRR */
27#define UBC_CRR_PCB (1 << 1)
28#define UBC_CRR_BIE (1 << 0)
29
30/* CBR */
31#define UBC_CBR_CE (1 << 0)
32
33static struct sh_ubc sh4a_ubc;
34
35static void sh4a_ubc_enable(struct arch_hw_breakpoint *info, int idx)
36{
37 __raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR(idx));
38 __raw_writel(info->address, UBC_CAR(idx));
39}
40
41static void sh4a_ubc_disable(struct arch_hw_breakpoint *info, int idx)
42{
43 __raw_writel(0, UBC_CBR(idx));
44 __raw_writel(0, UBC_CAR(idx));
45}
46
47static void sh4a_ubc_enable_all(unsigned long mask)
48{
49 int i;
50
51 for (i = 0; i < sh4a_ubc.num_events; i++)
52 if (mask & (1 << i))
53 __raw_writel(__raw_readl(UBC_CBR(i)) | UBC_CBR_CE,
54 UBC_CBR(i));
55}
56
57static void sh4a_ubc_disable_all(void)
58{
59 int i;
60
61 for (i = 0; i < sh4a_ubc.num_events; i++)
62 __raw_writel(__raw_readl(UBC_CBR(i)) & ~UBC_CBR_CE,
63 UBC_CBR(i));
64}
65
66static unsigned long sh4a_ubc_active_mask(void)
67{
68 unsigned long active = 0;
69 int i;
70
71 for (i = 0; i < sh4a_ubc.num_events; i++)
72 if (__raw_readl(UBC_CBR(i)) & UBC_CBR_CE)
73 active |= (1 << i);
74
75 return active;
76}
77
78static unsigned long sh4a_ubc_triggered_mask(void)
79{
80 return __raw_readl(UBC_CCMFR);
81}
82
83static void sh4a_ubc_clear_triggered_mask(unsigned long mask)
84{
85 __raw_writel(__raw_readl(UBC_CCMFR) & ~mask, UBC_CCMFR);
86}
87
88static struct sh_ubc sh4a_ubc = {
89 .name = "SH-4A",
90 .num_events = 2,
91 .trap_nr = 0x1e0,
92 .enable = sh4a_ubc_enable,
93 .disable = sh4a_ubc_disable,
94 .enable_all = sh4a_ubc_enable_all,
95 .disable_all = sh4a_ubc_disable_all,
96 .active_mask = sh4a_ubc_active_mask,
97 .triggered_mask = sh4a_ubc_triggered_mask,
98 .clear_triggered_mask = sh4a_ubc_clear_triggered_mask,
99};
100
101static int __init sh4a_ubc_init(void)
102{
103 struct clk *ubc_iclk = clk_get(NULL, "ubc0");
104 int i;
105
106 /*
107 * The UBC MSTP bit is optional, as not all platforms will have
108 * it. Just ignore it if we can't find it.
109 */
110 if (IS_ERR(ubc_iclk))
111 ubc_iclk = NULL;
112
113 clk_enable(ubc_iclk);
114
115 __raw_writel(0, UBC_CBCR);
116
117 for (i = 0; i < sh4a_ubc.num_events; i++) {
118 __raw_writel(0, UBC_CAMR(i));
119 __raw_writel(0, UBC_CBR(i));
120
121 __raw_writel(UBC_CRR_BIE | UBC_CRR_PCB, UBC_CRR(i));
122
123 /* dummy read for write posting */
124 (void)__raw_readl(UBC_CRR(i));
125 }
126
127 clk_disable(ubc_iclk);
128
129 sh4a_ubc.clk = ubc_iclk;
130
131 return register_sh_ubc(&sh4a_ubc);
132}
133arch_initcall(sh4a_ubc_init);
diff --git a/arch/sh/kernel/cpu/sh5/clock-sh5.c b/arch/sh/kernel/cpu/sh5/clock-sh5.c
index 7f864ebc51d3..9cfc19b8dbe4 100644
--- a/arch/sh/kernel/cpu/sh5/clock-sh5.c
+++ b/arch/sh/kernel/cpu/sh5/clock-sh5.c
@@ -24,7 +24,7 @@ static unsigned long cprc_base;
24 24
25static void master_clk_init(struct clk *clk) 25static void master_clk_init(struct clk *clk)
26{ 26{
27 int idx = (ctrl_inl(cprc_base + 0x00) >> 6) & 0x0007; 27 int idx = (__raw_readl(cprc_base + 0x00) >> 6) & 0x0007;
28 clk->rate *= ifc_table[idx]; 28 clk->rate *= ifc_table[idx];
29} 29}
30 30
@@ -34,7 +34,7 @@ static struct clk_ops sh5_master_clk_ops = {
34 34
35static unsigned long module_clk_recalc(struct clk *clk) 35static unsigned long module_clk_recalc(struct clk *clk)
36{ 36{
37 int idx = (ctrl_inw(cprc_base) >> 12) & 0x0007; 37 int idx = (__raw_readw(cprc_base) >> 12) & 0x0007;
38 return clk->parent->rate / ifc_table[idx]; 38 return clk->parent->rate / ifc_table[idx];
39} 39}
40 40
@@ -44,7 +44,7 @@ static struct clk_ops sh5_module_clk_ops = {
44 44
45static unsigned long bus_clk_recalc(struct clk *clk) 45static unsigned long bus_clk_recalc(struct clk *clk)
46{ 46{
47 int idx = (ctrl_inw(cprc_base) >> 3) & 0x0007; 47 int idx = (__raw_readw(cprc_base) >> 3) & 0x0007;
48 return clk->parent->rate / ifc_table[idx]; 48 return clk->parent->rate / ifc_table[idx];
49} 49}
50 50
@@ -54,7 +54,7 @@ static struct clk_ops sh5_bus_clk_ops = {
54 54
55static unsigned long cpu_clk_recalc(struct clk *clk) 55static unsigned long cpu_clk_recalc(struct clk *clk)
56{ 56{
57 int idx = (ctrl_inw(cprc_base) & 0x0007); 57 int idx = (__raw_readw(cprc_base) & 0x0007);
58 return clk->parent->rate / ifc_table[idx]; 58 return clk->parent->rate / ifc_table[idx];
59} 59}
60 60
diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S
index b0aacf675258..6b80295dd7a4 100644
--- a/arch/sh/kernel/cpu/sh5/entry.S
+++ b/arch/sh/kernel/cpu/sh5/entry.S
@@ -187,7 +187,7 @@ trap_jtable:
187 .rept 6 187 .rept 6
188 .long do_exception_error /* 0x880 - 0x920 */ 188 .long do_exception_error /* 0x880 - 0x920 */
189 .endr 189 .endr
190 .long do_software_break_point /* 0x940 */ 190 .long breakpoint_trap_handler /* 0x940 */
191 .long do_exception_error /* 0x960 */ 191 .long do_exception_error /* 0x960 */
192 .long do_single_step /* 0x980 */ 192 .long do_single_step /* 0x980 */
193 193
@@ -933,7 +933,7 @@ ret_with_reschedule:
933 933
934 pta restore_all, tr1 934 pta restore_all, tr1
935 935
936 movi (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r8 936 movi _TIF_SIGPENDING, r8
937 and r8, r7, r8 937 and r8, r7, r8
938 pta work_notifysig, tr0 938 pta work_notifysig, tr0
939 bne r8, ZERO, tr0 939 bne r8, ZERO, tr0
@@ -1124,7 +1124,7 @@ fpu_error_or_IRQA:
1124 pta its_IRQ, tr0 1124 pta its_IRQ, tr0
1125 beqi/l r4, EVENT_INTERRUPT, tr0 1125 beqi/l r4, EVENT_INTERRUPT, tr0
1126#ifdef CONFIG_SH_FPU 1126#ifdef CONFIG_SH_FPU
1127 movi do_fpu_state_restore, r6 1127 movi fpu_state_restore_trap_handler, r6
1128#else 1128#else
1129 movi do_exception_error, r6 1129 movi do_exception_error, r6
1130#endif 1130#endif
@@ -1135,7 +1135,7 @@ fpu_error_or_IRQB:
1135 pta its_IRQ, tr0 1135 pta its_IRQ, tr0
1136 beqi/l r4, EVENT_INTERRUPT, tr0 1136 beqi/l r4, EVENT_INTERRUPT, tr0
1137#ifdef CONFIG_SH_FPU 1137#ifdef CONFIG_SH_FPU
1138 movi do_fpu_state_restore, r6 1138 movi fpu_state_restore_trap_handler, r6
1139#else 1139#else
1140 movi do_exception_error, r6 1140 movi do_exception_error, r6
1141#endif 1141#endif
diff --git a/arch/sh/kernel/cpu/sh5/fpu.c b/arch/sh/kernel/cpu/sh5/fpu.c
index dd4f51ffb50e..4b3bb35e99f3 100644
--- a/arch/sh/kernel/cpu/sh5/fpu.c
+++ b/arch/sh/kernel/cpu/sh5/fpu.c
@@ -15,26 +15,8 @@
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/signal.h> 16#include <linux/signal.h>
17#include <asm/processor.h> 17#include <asm/processor.h>
18#include <asm/user.h>
19#include <asm/io.h>
20#include <asm/fpu.h>
21 18
22/* 19void save_fpu(struct task_struct *tsk)
23 * Initially load the FPU with signalling NANS. This bit pattern
24 * has the property that no matter whether considered as single or as
25 * double precision, it still represents a signalling NAN.
26 */
27#define sNAN64 0xFFFFFFFFFFFFFFFFULL
28#define sNAN32 0xFFFFFFFFUL
29
30static union sh_fpu_union init_fpuregs = {
31 .hard = {
32 .fp_regs = { [0 ... 63] = sNAN32 },
33 .fpscr = FPSCR_INIT
34 }
35};
36
37void save_fpu(struct task_struct *tsk, struct pt_regs *regs)
38{ 20{
39 asm volatile("fst.p %0, (0*8), fp0\n\t" 21 asm volatile("fst.p %0, (0*8), fp0\n\t"
40 "fst.p %0, (1*8), fp2\n\t" 22 "fst.p %0, (1*8), fp2\n\t"
@@ -72,12 +54,11 @@ void save_fpu(struct task_struct *tsk, struct pt_regs *regs)
72 "fgetscr fr63\n\t" 54 "fgetscr fr63\n\t"
73 "fst.s %0, (32*8), fr63\n\t" 55 "fst.s %0, (32*8), fr63\n\t"
74 : /* no output */ 56 : /* no output */
75 : "r" (&tsk->thread.fpu.hard) 57 : "r" (&tsk->thread.xstate->hardfpu)
76 : "memory"); 58 : "memory");
77} 59}
78 60
79static inline void 61void restore_fpu(struct task_struct *tsk)
80fpload(struct sh_fpu_hard_struct *fpregs)
81{ 62{
82 asm volatile("fld.p %0, (0*8), fp0\n\t" 63 asm volatile("fld.p %0, (0*8), fp0\n\t"
83 "fld.p %0, (1*8), fp2\n\t" 64 "fld.p %0, (1*8), fp2\n\t"
@@ -116,16 +97,11 @@ fpload(struct sh_fpu_hard_struct *fpregs)
116 97
117 "fld.p %0, (31*8), fp62\n\t" 98 "fld.p %0, (31*8), fp62\n\t"
118 : /* no output */ 99 : /* no output */
119 : "r" (fpregs) ); 100 : "r" (&tsk->thread.xstate->hardfpu)
120} 101 : "memory");
121
122void fpinit(struct sh_fpu_hard_struct *fpregs)
123{
124 *fpregs = init_fpuregs.hard;
125} 102}
126 103
127asmlinkage void 104asmlinkage void do_fpu_error(unsigned long ex, struct pt_regs *regs)
128do_fpu_error(unsigned long ex, struct pt_regs *regs)
129{ 105{
130 struct task_struct *tsk = current; 106 struct task_struct *tsk = current;
131 107
@@ -133,35 +109,6 @@ do_fpu_error(unsigned long ex, struct pt_regs *regs)
133 109
134 tsk->thread.trap_no = 11; 110 tsk->thread.trap_no = 11;
135 tsk->thread.error_code = 0; 111 tsk->thread.error_code = 0;
136 force_sig(SIGFPE, tsk);
137}
138
139
140asmlinkage void
141do_fpu_state_restore(unsigned long ex, struct pt_regs *regs)
142{
143 void die(const char *str, struct pt_regs *regs, long err);
144
145 if (! user_mode(regs))
146 die("FPU used in kernel", regs, ex);
147 112
148 regs->sr &= ~SR_FD; 113 force_sig(SIGFPE, tsk);
149
150 if (last_task_used_math == current)
151 return;
152
153 enable_fpu();
154 if (last_task_used_math != NULL)
155 /* Other processes fpu state, save away */
156 save_fpu(last_task_used_math, regs);
157
158 last_task_used_math = current;
159 if (used_math()) {
160 fpload(&current->thread.fpu.hard);
161 } else {
162 /* First time FPU user. */
163 fpload(&init_fpuregs.hard);
164 set_used_math();
165 }
166 disable_fpu();
167} 114}
diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c
index 6a0f82f70032..e7a3c1e4b604 100644
--- a/arch/sh/kernel/cpu/sh5/setup-sh5.c
+++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c
@@ -16,22 +16,18 @@
16#include <linux/sh_timer.h> 16#include <linux/sh_timer.h>
17#include <asm/addrspace.h> 17#include <asm/addrspace.h>
18 18
19static struct plat_sci_port sci_platform_data[] = { 19static struct plat_sci_port scif0_platform_data = {
20 { 20 .mapbase = PHYS_PERIPHERAL_BLOCK + 0x01030000,
21 .mapbase = PHYS_PERIPHERAL_BLOCK + 0x01030000, 21 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
22 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, 22 .type = PORT_SCIF,
23 .type = PORT_SCIF, 23 .irqs = { 39, 40, 42, 0 },
24 .irqs = { 39, 40, 42, 0 },
25 }, {
26 .flags = 0,
27 }
28}; 24};
29 25
30static struct platform_device sci_device = { 26static struct platform_device scif0_device = {
31 .name = "sh-sci", 27 .name = "sh-sci",
32 .id = -1, 28 .id = 0,
33 .dev = { 29 .dev = {
34 .platform_data = sci_platform_data, 30 .platform_data = &scif0_platform_data,
35 }, 31 },
36}; 32};
37 33
@@ -164,13 +160,13 @@ static struct platform_device tmu2_device = {
164}; 160};
165 161
166static struct platform_device *sh5_early_devices[] __initdata = { 162static struct platform_device *sh5_early_devices[] __initdata = {
163 &scif0_device,
167 &tmu0_device, 164 &tmu0_device,
168 &tmu1_device, 165 &tmu1_device,
169 &tmu2_device, 166 &tmu2_device,
170}; 167};
171 168
172static struct platform_device *sh5_devices[] __initdata = { 169static struct platform_device *sh5_devices[] __initdata = {
173 &sci_device,
174 &rtc_device, 170 &rtc_device,
175}; 171};
176 172
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c
index 1c504bd972c3..83972aa319c2 100644
--- a/arch/sh/kernel/cpu/shmobile/cpuidle.c
+++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c
@@ -87,25 +87,31 @@ void sh_mobile_setup_cpuidle(void)
87 87
88 dev->safe_state = state; 88 dev->safe_state = state;
89 89
90 state = &dev->states[i++]; 90 if (sh_mobile_sleep_supported & SUSP_SH_SF) {
91 snprintf(state->name, CPUIDLE_NAME_LEN, "C1"); 91 state = &dev->states[i++];
92 strncpy(state->desc, "SuperH Sleep Mode [SF]", CPUIDLE_DESC_LEN); 92 snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
93 state->exit_latency = 100; 93 strncpy(state->desc, "SuperH Sleep Mode [SF]",
94 state->target_residency = 1 * 2; 94 CPUIDLE_DESC_LEN);
95 state->power_usage = 1; 95 state->exit_latency = 100;
96 state->flags = 0; 96 state->target_residency = 1 * 2;
97 state->flags |= CPUIDLE_FLAG_TIME_VALID; 97 state->power_usage = 1;
98 state->enter = cpuidle_sleep_enter; 98 state->flags = 0;
99 state->flags |= CPUIDLE_FLAG_TIME_VALID;
100 state->enter = cpuidle_sleep_enter;
101 }
99 102
100 state = &dev->states[i++]; 103 if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) {
101 snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); 104 state = &dev->states[i++];
102 strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", CPUIDLE_DESC_LEN); 105 snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
103 state->exit_latency = 2300; 106 strncpy(state->desc, "SuperH Mobile Standby Mode [SF]",
104 state->target_residency = 1 * 2; 107 CPUIDLE_DESC_LEN);
105 state->power_usage = 1; 108 state->exit_latency = 2300;
106 state->flags = 0; 109 state->target_residency = 1 * 2;
107 state->flags |= CPUIDLE_FLAG_TIME_VALID; 110 state->power_usage = 1;
108 state->enter = cpuidle_sleep_enter; 111 state->flags = 0;
112 state->flags |= CPUIDLE_FLAG_TIME_VALID;
113 state->enter = cpuidle_sleep_enter;
114 }
109 115
110 dev->state_count = i; 116 dev->state_count = i;
111 117
diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c
index ee3c2aaf66fb..e55968712706 100644
--- a/arch/sh/kernel/cpu/shmobile/pm.c
+++ b/arch/sh/kernel/cpu/shmobile/pm.c
@@ -15,6 +15,13 @@
15#include <linux/suspend.h> 15#include <linux/suspend.h>
16#include <asm/suspend.h> 16#include <asm/suspend.h>
17#include <asm/uaccess.h> 17#include <asm/uaccess.h>
18#include <asm/cacheflush.h>
19
20/*
21 * Notifier lists for pre/post sleep notification
22 */
23ATOMIC_NOTIFIER_HEAD(sh_mobile_pre_sleep_notifier_list);
24ATOMIC_NOTIFIER_HEAD(sh_mobile_post_sleep_notifier_list);
18 25
19/* 26/*
20 * Sleep modes available on SuperH Mobile: 27 * Sleep modes available on SuperH Mobile:
@@ -26,30 +33,106 @@
26#define SUSP_MODE_SLEEP (SUSP_SH_SLEEP) 33#define SUSP_MODE_SLEEP (SUSP_SH_SLEEP)
27#define SUSP_MODE_SLEEP_SF (SUSP_SH_SLEEP | SUSP_SH_SF) 34#define SUSP_MODE_SLEEP_SF (SUSP_SH_SLEEP | SUSP_SH_SF)
28#define SUSP_MODE_STANDBY_SF (SUSP_SH_STANDBY | SUSP_SH_SF) 35#define SUSP_MODE_STANDBY_SF (SUSP_SH_STANDBY | SUSP_SH_SF)
36#define SUSP_MODE_RSTANDBY_SF \
37 (SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_REGS | SUSP_SH_SF)
38 /*
39 * U-standby mode is unsupported since it needs bootloader hacks
40 */
29 41
30/* 42#ifdef CONFIG_CPU_SUBTYPE_SH7724
31 * The following modes are not there yet: 43#define RAM_BASE 0xfd800000 /* RSMEM */
32 * 44#else
33 * R-standby mode is unsupported, but will be added in the future 45#define RAM_BASE 0xe5200000 /* ILRAM */
34 * U-standby mode is low priority since it needs bootloader hacks 46#endif
35 */
36
37#define ILRAM_BASE 0xe5200000
38
39extern const unsigned char sh_mobile_standby[];
40extern const unsigned int sh_mobile_standby_size;
41 47
42void sh_mobile_call_standby(unsigned long mode) 48void sh_mobile_call_standby(unsigned long mode)
43{ 49{
44 void *onchip_mem = (void *)ILRAM_BASE; 50 void *onchip_mem = (void *)RAM_BASE;
45 void (*standby_onchip_mem)(unsigned long, unsigned long) = onchip_mem; 51 struct sh_sleep_data *sdp = onchip_mem;
52 void (*standby_onchip_mem)(unsigned long, unsigned long);
53
54 /* code located directly after data structure */
55 standby_onchip_mem = (void *)(sdp + 1);
56
57 atomic_notifier_call_chain(&sh_mobile_pre_sleep_notifier_list,
58 mode, NULL);
59
60 /* flush the caches if MMU flag is set */
61 if (mode & SUSP_SH_MMU)
62 flush_cache_all();
46 63
47 /* Let assembly snippet in on-chip memory handle the rest */ 64 /* Let assembly snippet in on-chip memory handle the rest */
48 standby_onchip_mem(mode, ILRAM_BASE); 65 standby_onchip_mem(mode, RAM_BASE);
66
67 atomic_notifier_call_chain(&sh_mobile_post_sleep_notifier_list,
68 mode, NULL);
69}
70
71extern char sh_mobile_sleep_enter_start;
72extern char sh_mobile_sleep_enter_end;
73
74extern char sh_mobile_sleep_resume_start;
75extern char sh_mobile_sleep_resume_end;
76
77unsigned long sh_mobile_sleep_supported = SUSP_SH_SLEEP;
78
79void sh_mobile_register_self_refresh(unsigned long flags,
80 void *pre_start, void *pre_end,
81 void *post_start, void *post_end)
82{
83 void *onchip_mem = (void *)RAM_BASE;
84 void *vp;
85 struct sh_sleep_data *sdp;
86 int n;
87
88 /* part 0: data area */
89 sdp = onchip_mem;
90 sdp->addr.stbcr = 0xa4150020; /* STBCR */
91 sdp->addr.bar = 0xa4150040; /* BAR */
92 sdp->addr.pteh = 0xff000000; /* PTEH */
93 sdp->addr.ptel = 0xff000004; /* PTEL */
94 sdp->addr.ttb = 0xff000008; /* TTB */
95 sdp->addr.tea = 0xff00000c; /* TEA */
96 sdp->addr.mmucr = 0xff000010; /* MMUCR */
97 sdp->addr.ptea = 0xff000034; /* PTEA */
98 sdp->addr.pascr = 0xff000070; /* PASCR */
99 sdp->addr.irmcr = 0xff000078; /* IRMCR */
100 sdp->addr.ccr = 0xff00001c; /* CCR */
101 sdp->addr.ramcr = 0xff000074; /* RAMCR */
102 vp = sdp + 1;
103
104 /* part 1: common code to enter sleep mode */
105 n = &sh_mobile_sleep_enter_end - &sh_mobile_sleep_enter_start;
106 memcpy(vp, &sh_mobile_sleep_enter_start, n);
107 vp += roundup(n, 4);
108
109 /* part 2: board specific code to enter self-refresh mode */
110 n = pre_end - pre_start;
111 memcpy(vp, pre_start, n);
112 sdp->sf_pre = (unsigned long)vp;
113 vp += roundup(n, 4);
114
115 /* part 3: board specific code to resume from self-refresh mode */
116 n = post_end - post_start;
117 memcpy(vp, post_start, n);
118 sdp->sf_post = (unsigned long)vp;
119 vp += roundup(n, 4);
120
121 /* part 4: common code to resume from sleep mode */
122 WARN_ON(vp > (onchip_mem + 0x600));
123 vp = onchip_mem + 0x600; /* located at interrupt vector */
124 n = &sh_mobile_sleep_resume_end - &sh_mobile_sleep_resume_start;
125 memcpy(vp, &sh_mobile_sleep_resume_start, n);
126 sdp->resume = (unsigned long)vp;
127
128 sh_mobile_sleep_supported |= flags;
49} 129}
50 130
51static int sh_pm_enter(suspend_state_t state) 131static int sh_pm_enter(suspend_state_t state)
52{ 132{
133 if (!(sh_mobile_sleep_supported & SUSP_MODE_STANDBY_SF))
134 return -ENXIO;
135
53 local_irq_disable(); 136 local_irq_disable();
54 set_bl_bit(); 137 set_bl_bit();
55 sh_mobile_call_standby(SUSP_MODE_STANDBY_SF); 138 sh_mobile_call_standby(SUSP_MODE_STANDBY_SF);
@@ -65,13 +148,6 @@ static struct platform_suspend_ops sh_pm_ops = {
65 148
66static int __init sh_pm_init(void) 149static int __init sh_pm_init(void)
67{ 150{
68 void *onchip_mem = (void *)ILRAM_BASE;
69
70 /* Copy the assembly snippet to the otherwise ununsed ILRAM */
71 memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size);
72 wmb();
73 ctrl_barrier();
74
75 suspend_set_ops(&sh_pm_ops); 151 suspend_set_ops(&sh_pm_ops);
76 sh_mobile_setup_cpuidle(); 152 sh_mobile_setup_cpuidle();
77 return 0; 153 return 0;
diff --git a/arch/sh/kernel/cpu/shmobile/pm_runtime.c b/arch/sh/kernel/cpu/shmobile/pm_runtime.c
index 7c615b17e209..6dcb8166a64d 100644
--- a/arch/sh/kernel/cpu/shmobile/pm_runtime.c
+++ b/arch/sh/kernel/cpu/shmobile/pm_runtime.c
@@ -45,12 +45,14 @@ static int __platform_pm_runtime_resume(struct platform_device *pdev)
45 45
46 dev_dbg(d, "__platform_pm_runtime_resume() [%d]\n", hwblk); 46 dev_dbg(d, "__platform_pm_runtime_resume() [%d]\n", hwblk);
47 47
48 if (d->driver && d->driver->pm && d->driver->pm->runtime_resume) { 48 if (d->driver) {
49 hwblk_enable(hwblk_info, hwblk); 49 hwblk_enable(hwblk_info, hwblk);
50 ret = 0; 50 ret = 0;
51 51
52 if (test_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags)) { 52 if (test_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags)) {
53 ret = d->driver->pm->runtime_resume(d); 53 if (d->driver->pm && d->driver->pm->runtime_resume)
54 ret = d->driver->pm->runtime_resume(d);
55
54 if (!ret) 56 if (!ret)
55 clear_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags); 57 clear_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
56 else 58 else
@@ -73,12 +75,15 @@ static int __platform_pm_runtime_suspend(struct platform_device *pdev)
73 75
74 dev_dbg(d, "__platform_pm_runtime_suspend() [%d]\n", hwblk); 76 dev_dbg(d, "__platform_pm_runtime_suspend() [%d]\n", hwblk);
75 77
76 if (d->driver && d->driver->pm && d->driver->pm->runtime_suspend) { 78 if (d->driver) {
77 BUG_ON(!test_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags)); 79 BUG_ON(!test_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags));
80 ret = 0;
78 81
79 hwblk_enable(hwblk_info, hwblk); 82 if (d->driver->pm && d->driver->pm->runtime_suspend) {
80 ret = d->driver->pm->runtime_suspend(d); 83 hwblk_enable(hwblk_info, hwblk);
81 hwblk_disable(hwblk_info, hwblk); 84 ret = d->driver->pm->runtime_suspend(d);
85 hwblk_disable(hwblk_info, hwblk);
86 }
82 87
83 if (!ret) { 88 if (!ret) {
84 set_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags); 89 set_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
diff --git a/arch/sh/kernel/cpu/shmobile/sleep.S b/arch/sh/kernel/cpu/shmobile/sleep.S
index a439e6c7824f..e6aac65f5750 100644
--- a/arch/sh/kernel/cpu/shmobile/sleep.S
+++ b/arch/sh/kernel/cpu/shmobile/sleep.S
@@ -20,79 +20,143 @@
20 * Kernel mode register usage, see entry.S: 20 * Kernel mode register usage, see entry.S:
21 * k0 scratch 21 * k0 scratch
22 * k1 scratch 22 * k1 scratch
23 * k4 scratch
24 */ 23 */
25#define k0 r0 24#define k0 r0
26#define k1 r1 25#define k1 r1
27#define k4 r4
28 26
29/* manage self-refresh and enter standby mode. 27/* manage self-refresh and enter standby mode. must be self-contained.
30 * this code will be copied to on-chip memory and executed from there. 28 * this code will be copied to on-chip memory and executed from there.
31 */ 29 */
30 .balign 4
31ENTRY(sh_mobile_sleep_enter_start)
32 32
33 .balign 4096,0,4096 33 /* save mode flags */
34ENTRY(sh_mobile_standby) 34 mov.l r4, @(SH_SLEEP_MODE, r5)
35 35
36 /* save original vbr */ 36 /* save original vbr */
37 stc vbr, r1 37 stc vbr, r0
38 mova saved_vbr, r0 38 mov.l r0, @(SH_SLEEP_VBR, r5)
39 mov.l r1, @r0
40 39
41 /* point vbr to our on-chip memory page */ 40 /* point vbr to our on-chip memory page */
42 ldc r5, vbr 41 ldc r5, vbr
43 42
44 /* save return address */ 43 /* save return address */
45 mova saved_spc, r0 44 sts pr, r0
46 sts pr, r5 45 mov.l r0, @(SH_SLEEP_SPC, r5)
47 mov.l r5, @r0
48 46
49 /* save sr */ 47 /* save sr */
50 mova saved_sr, r0 48 stc sr, r0
51 stc sr, r5 49 mov.l r0, @(SH_SLEEP_SR, r5)
52 mov.l r5, @r0 50
51 /* save general purpose registers to stack if needed */
52 mov.l @(SH_SLEEP_MODE, r5), r0
53 tst #SUSP_SH_REGS, r0
54 bt skip_regs_save
55
56 sts.l pr, @-r15
57 mov.l r14, @-r15
58 mov.l r13, @-r15
59 mov.l r12, @-r15
60 mov.l r11, @-r15
61 mov.l r10, @-r15
62 mov.l r9, @-r15
63 mov.l r8, @-r15
64
65 /* make sure bank0 is selected, save low registers */
66 mov.l rb_bit, r9
67 not r9, r9
68 bsr set_sr
69 mov #0, r10
70
71 bsr save_low_regs
72 nop
53 73
54 /* save mode flags */ 74 /* switch to bank 1, save low registers */
55 mova saved_mode, r0 75 mov.l rb_bit, r10
56 mov.l r4, @r0 76 bsr set_sr
77 mov #-1, r9
78
79 bsr save_low_regs
80 nop
81
82 /* switch back to bank 0 */
83 mov.l rb_bit, r9
84 not r9, r9
85 bsr set_sr
86 mov #0, r10
87
88skip_regs_save:
89
90 /* save sp, also set to internal ram */
91 mov.l r15, @(SH_SLEEP_SP, r5)
92 mov r5, r15
93
94 /* save stbcr */
95 bsr save_register
96 mov #SH_SLEEP_REG_STBCR, r0
97
98 /* save mmu and cache context if needed */
99 mov.l @(SH_SLEEP_MODE, r5), r0
100 tst #SUSP_SH_MMU, r0
101 bt skip_mmu_save_disable
102
103 /* save mmu state */
104 bsr save_register
105 mov #SH_SLEEP_REG_PTEH, r0
106
107 bsr save_register
108 mov #SH_SLEEP_REG_PTEL, r0
109
110 bsr save_register
111 mov #SH_SLEEP_REG_TTB, r0
112
113 bsr save_register
114 mov #SH_SLEEP_REG_TEA, r0
115
116 bsr save_register
117 mov #SH_SLEEP_REG_MMUCR, r0
118
119 bsr save_register
120 mov #SH_SLEEP_REG_PTEA, r0
121
122 bsr save_register
123 mov #SH_SLEEP_REG_PASCR, r0
57 124
58 /* put mode flags in r0 */ 125 bsr save_register
59 mov r4, r0 126 mov #SH_SLEEP_REG_IRMCR, r0
60 127
128 /* invalidate TLBs and disable the MMU */
129 bsr get_register
130 mov #SH_SLEEP_REG_MMUCR, r0
131 mov #4, r1
132 mov.l r1, @r0
133 icbi @r0
134
135 /* save cache registers and disable caches */
136 bsr save_register
137 mov #SH_SLEEP_REG_CCR, r0
138
139 bsr save_register
140 mov #SH_SLEEP_REG_RAMCR, r0
141
142 bsr get_register
143 mov #SH_SLEEP_REG_CCR, r0
144 mov #0, r1
145 mov.l r1, @r0
146 icbi @r0
147
148skip_mmu_save_disable:
149 /* call self-refresh entering code if needed */
150 mov.l @(SH_SLEEP_MODE, r5), r0
61 tst #SUSP_SH_SF, r0 151 tst #SUSP_SH_SF, r0
62 bt skip_set_sf 152 bt skip_set_sf
63#ifdef CONFIG_CPU_SUBTYPE_SH7724 153
64 /* DBSC: put memory in self-refresh mode */ 154 mov.l @(SH_SLEEP_SF_PRE, r5), r0
65 mov.l dben_reg, r4 155 jsr @r0
66 mov.l dben_data0, r1 156 nop
67 mov.l r1, @r4
68
69 mov.l dbrfpdn0_reg, r4
70 mov.l dbrfpdn0_data0, r1
71 mov.l r1, @r4
72
73 mov.l dbcmdcnt_reg, r4
74 mov.l dbcmdcnt_data0, r1
75 mov.l r1, @r4
76
77 mov.l dbcmdcnt_reg, r4
78 mov.l dbcmdcnt_data1, r1
79 mov.l r1, @r4
80
81 mov.l dbrfpdn0_reg, r4
82 mov.l dbrfpdn0_data1, r1
83 mov.l r1, @r4
84#else
85 /* SBSC: disable power down and put in self-refresh mode */
86 mov.l 1f, r4
87 mov.l 2f, r1
88 mov.l @r4, r2
89 or r1, r2
90 mov.l 3f, r3
91 and r3, r2
92 mov.l r2, @r4
93#endif
94 157
95skip_set_sf: 158skip_set_sf:
159 mov.l @(SH_SLEEP_MODE, r5), r0
96 tst #SUSP_SH_STANDBY, r0 160 tst #SUSP_SH_STANDBY, r0
97 bt test_rstandby 161 bt test_rstandby
98 162
@@ -104,6 +168,12 @@ test_rstandby:
104 tst #SUSP_SH_RSTANDBY, r0 168 tst #SUSP_SH_RSTANDBY, r0
105 bt test_ustandby 169 bt test_ustandby
106 170
171 /* setup BAR register */
172 bsr get_register
173 mov #SH_SLEEP_REG_BAR, r0
174 mov.l @(SH_SLEEP_RESUME, r5), r1
175 mov.l r1, @r0
176
107 /* set mode to "r-standby mode" */ 177 /* set mode to "r-standby mode" */
108 bra do_sleep 178 bra do_sleep
109 mov #0x20, r1 179 mov #0x20, r1
@@ -123,124 +193,213 @@ force_sleep:
123 193
124do_sleep: 194do_sleep:
125 /* setup and enter selected standby mode */ 195 /* setup and enter selected standby mode */
126 mov.l 5f, r4 196 bsr get_register
127 mov.l r1, @r4 197 mov #SH_SLEEP_REG_STBCR, r0
198 mov.l r1, @r0
128again: 199again:
129 sleep 200 sleep
130 bra again 201 bra again
131 nop 202 nop
132 203
133restore_jump_vbr: 204save_register:
205 add #SH_SLEEP_BASE_ADDR, r0
206 mov.l @(r0, r5), r1
207 add #-SH_SLEEP_BASE_ADDR, r0
208 mov.l @r1, r1
209 add #SH_SLEEP_BASE_DATA, r0
210 mov.l r1, @(r0, r5)
211 add #-SH_SLEEP_BASE_DATA, r0
212 rts
213 nop
214
215get_register:
216 add #SH_SLEEP_BASE_ADDR, r0
217 mov.l @(r0, r5), r0
218 rts
219 nop
220
221set_sr:
222 stc sr, r8
223 and r9, r8
224 or r10, r8
225 ldc r8, sr
226 rts
227 nop
228
229save_low_regs:
230 mov.l r7, @-r15
231 mov.l r6, @-r15
232 mov.l r5, @-r15
233 mov.l r4, @-r15
234 mov.l r3, @-r15
235 mov.l r2, @-r15
236 mov.l r1, @-r15
237 rts
238 mov.l r0, @-r15
239
240 .balign 4
241rb_bit: .long 0x20000000 ! RB=1
242
243ENTRY(sh_mobile_sleep_enter_end)
244
245 .balign 4
246ENTRY(sh_mobile_sleep_resume_start)
247
248 /* figure out start address */
249 bsr 0f
250 nop
2510:
252 sts pr, k1
253 mov.l 1f, k0
254 and k0, k1
255
256 /* store pointer to data area in VBR */
257 ldc k1, vbr
258
259 /* setup sr with saved sr */
260 mov.l @(SH_SLEEP_SR, k1), k0
261 ldc k0, sr
262
263 /* now: user register set! */
264 stc vbr, r5
265
134 /* setup spc with return address to c code */ 266 /* setup spc with return address to c code */
135 mov.l saved_spc, k0 267 mov.l @(SH_SLEEP_SPC, r5), r0
136 ldc k0, spc 268 ldc r0, spc
137 269
138 /* restore vbr */ 270 /* restore vbr */
139 mov.l saved_vbr, k0 271 mov.l @(SH_SLEEP_VBR, r5), r0
140 ldc k0, vbr 272 ldc r0, vbr
141 273
142 /* setup ssr with saved sr */ 274 /* setup ssr with saved sr */
143 mov.l saved_sr, k0 275 mov.l @(SH_SLEEP_SR, r5), r0
144 ldc k0, ssr 276 ldc r0, ssr
145 277
146 /* get mode flags */ 278 /* restore sp */
147 mov.l saved_mode, k0 279 mov.l @(SH_SLEEP_SP, r5), r15
148 280
149done_sleep: 281 /* restore sleep mode register */
150 /* reset standby mode to sleep mode */ 282 bsr restore_register
151 mov.l 5f, k4 283 mov #SH_SLEEP_REG_STBCR, r0
152 mov #0x00, k1
153 mov.l k1, @k4
154 284
155 tst #SUSP_SH_SF, k0 285 /* call self-refresh resume code if needed */
286 mov.l @(SH_SLEEP_MODE, r5), r0
287 tst #SUSP_SH_SF, r0
156 bt skip_restore_sf 288 bt skip_restore_sf
157 289
158#ifdef CONFIG_CPU_SUBTYPE_SH7724 290 mov.l @(SH_SLEEP_SF_POST, r5), r0
159 /* DBSC: put memory in auto-refresh mode */ 291 jsr @r0
160 mov.l dbrfpdn0_reg, k4 292 nop
161 mov.l dbrfpdn0_data0, k1 293
162 mov.l k1, @k4
163
164 nop /* sleep 140 ns */
165 nop
166 nop
167 nop
168
169 mov.l dbcmdcnt_reg, k4
170 mov.l dbcmdcnt_data0, k1
171 mov.l k1, @k4
172
173 mov.l dbcmdcnt_reg, k4
174 mov.l dbcmdcnt_data1, k1
175 mov.l k1, @k4
176
177 mov.l dben_reg, k4
178 mov.l dben_data1, k1
179 mov.l k1, @k4
180
181 mov.l dbrfpdn0_reg, k4
182 mov.l dbrfpdn0_data2, k1
183 mov.l k1, @k4
184#else
185 /* SBSC: set auto-refresh mode */
186 mov.l 1f, k4
187 mov.l @k4, k0
188 mov.l 4f, k1
189 and k1, k0
190 mov.l k0, @k4
191 mov.l 6f, k4
192 mov.l 8f, k0
193 mov.l @k4, k1
194 mov #-1, k4
195 add k4, k1
196 or k1, k0
197 mov.l 7f, k1
198 mov.l k0, @k1
199#endif
200skip_restore_sf: 294skip_restore_sf:
201 /* jump to vbr vector */ 295 /* restore mmu and cache state if needed */
202 mov.l saved_vbr, k0 296 mov.l @(SH_SLEEP_MODE, r5), r0
203 mov.l offset_vbr, k4 297 tst #SUSP_SH_MMU, r0
204 add k4, k0 298 bt skip_restore_mmu
205 jmp @k0 299
300 /* restore mmu state */
301 bsr restore_register
302 mov #SH_SLEEP_REG_PTEH, r0
303
304 bsr restore_register
305 mov #SH_SLEEP_REG_PTEL, r0
306
307 bsr restore_register
308 mov #SH_SLEEP_REG_TTB, r0
309
310 bsr restore_register
311 mov #SH_SLEEP_REG_TEA, r0
312
313 bsr restore_register
314 mov #SH_SLEEP_REG_PTEA, r0
315
316 bsr restore_register
317 mov #SH_SLEEP_REG_PASCR, r0
318
319 bsr restore_register
320 mov #SH_SLEEP_REG_IRMCR, r0
321
322 bsr restore_register
323 mov #SH_SLEEP_REG_MMUCR, r0
324 icbi @r0
325
326 /* restore cache settings */
327 bsr restore_register
328 mov #SH_SLEEP_REG_RAMCR, r0
329 icbi @r0
330
331 bsr restore_register
332 mov #SH_SLEEP_REG_CCR, r0
333 icbi @r0
334
335skip_restore_mmu:
336
337 /* restore general purpose registers if needed */
338 mov.l @(SH_SLEEP_MODE, r5), r0
339 tst #SUSP_SH_REGS, r0
340 bt skip_restore_regs
341
342 /* switch to bank 1, restore low registers */
343 mov.l _rb_bit, r10
344 bsr _set_sr
345 mov #-1, r9
346
347 bsr restore_low_regs
206 nop 348 nop
207 349
208 .balign 4 350 /* switch to bank0, restore low registers */
209saved_mode: .long 0 351 mov.l _rb_bit, r9
210saved_spc: .long 0 352 not r9, r9
211saved_sr: .long 0 353 bsr _set_sr
212saved_vbr: .long 0 354 mov #0, r10
213offset_vbr: .long 0x600 355
214#ifdef CONFIG_CPU_SUBTYPE_SH7724 356 bsr restore_low_regs
215dben_reg: .long 0xfd000010 /* DBEN */
216dben_data0: .long 0
217dben_data1: .long 1
218dbrfpdn0_reg: .long 0xfd000040 /* DBRFPDN0 */
219dbrfpdn0_data0: .long 0
220dbrfpdn0_data1: .long 1
221dbrfpdn0_data2: .long 0x00010000
222dbcmdcnt_reg: .long 0xfd000014 /* DBCMDCNT */
223dbcmdcnt_data0: .long 2
224dbcmdcnt_data1: .long 4
225#else
2261: .long 0xfe400008 /* SDCR0 */
2272: .long 0x00000400
2283: .long 0xffff7fff
2294: .long 0xfffffbff
230#endif
2315: .long 0xa4150020 /* STBCR */
2326: .long 0xfe40001c /* RTCOR */
2337: .long 0xfe400018 /* RTCNT */
2348: .long 0xa55a0000
235
236
237/* interrupt vector @ 0x600 */
238 .balign 0x400,0,0x400
239 .long 0xdeadbeef
240 .balign 0x200,0,0x200
241 bra restore_jump_vbr
242 nop 357 nop
243sh_mobile_standby_end:
244 358
245ENTRY(sh_mobile_standby_size) 359 /* restore the rest of the registers */
246 .long sh_mobile_standby_end - sh_mobile_standby 360 mov.l @r15+, r8
361 mov.l @r15+, r9
362 mov.l @r15+, r10
363 mov.l @r15+, r11
364 mov.l @r15+, r12
365 mov.l @r15+, r13
366 mov.l @r15+, r14
367 lds.l @r15+, pr
368
369skip_restore_regs:
370 rte
371 nop
372
373restore_register:
374 add #SH_SLEEP_BASE_DATA, r0
375 mov.l @(r0, r5), r1
376 add #-SH_SLEEP_BASE_DATA, r0
377 add #SH_SLEEP_BASE_ADDR, r0
378 mov.l @(r0, r5), r0
379 mov.l r1, @r0
380 rts
381 nop
382
383_set_sr:
384 stc sr, r8
385 and r9, r8
386 or r10, r8
387 ldc r8, sr
388 rts
389 nop
390
391restore_low_regs:
392 mov.l @r15+, r0
393 mov.l @r15+, r1
394 mov.l @r15+, r2
395 mov.l @r15+, r3
396 mov.l @r15+, r4
397 mov.l @r15+, r5
398 mov.l @r15+, r6
399 rts
400 mov.l @r15+, r7
401
402 .balign 4
403_rb_bit: .long 0x20000000 ! RB=1
4041: .long ~0x7ff
405ENTRY(sh_mobile_sleep_resume_end)
diff --git a/arch/sh/kernel/cpu/ubc.S b/arch/sh/kernel/cpu/ubc.S
deleted file mode 100644
index 81923079fa12..000000000000
--- a/arch/sh/kernel/cpu/ubc.S
+++ /dev/null
@@ -1,59 +0,0 @@
1/*
2 * arch/sh/kernel/cpu/ubc.S
3 *
4 * Set of management routines for the User Break Controller (UBC)
5 *
6 * Copyright (C) 2002 Paul Mundt
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13#include <linux/linkage.h>
14#include <asm/ubc.h>
15
16#define STBCR2 0xffc00010
17
18ENTRY(ubc_sleep)
19 mov #0, r0
20
21 mov.l 1f, r1 ! Zero out UBC_BBRA ..
22 mov.w r0, @r1
23
24 mov.l 2f, r1 ! .. same for BBRB ..
25 mov.w r0, @r1
26
27 mov.l 3f, r1 ! .. and again for BRCR.
28 mov.w r0, @r1
29
30 mov.w @r1, r0 ! Dummy read BRCR
31
32 mov.l 4f, r1 ! Set MSTP5 in STBCR2
33 mov.b @r1, r0
34 or #0x01, r0
35 mov.b r0, @r1
36
37 mov.b @r1, r0 ! Two dummy reads ..
38 mov.b @r1, r0
39
40 rts
41 nop
42
43ENTRY(ubc_wakeup)
44 mov.l 4f, r1 ! Clear MSTP5
45 mov.b @r1, r0
46 and #0xfe, r0
47 mov.b r0, @r1
48
49 mov.b @r1, r0 ! Two more dummy reads ..
50 mov.b @r1, r0
51
52 rts
53 nop
54
551: .long UBC_BBRA
562: .long UBC_BBRB
573: .long UBC_BRCR
584: .long STBCR2
59
diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c
index dce4f3ff0932..0fffacea6ed9 100644
--- a/arch/sh/kernel/cpufreq.c
+++ b/arch/sh/kernel/cpufreq.c
@@ -48,7 +48,7 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy,
48 return -ENODEV; 48 return -ENODEV;
49 49
50 cpus_allowed = current->cpus_allowed; 50 cpus_allowed = current->cpus_allowed;
51 set_cpus_allowed(current, cpumask_of_cpu(cpu)); 51 set_cpus_allowed_ptr(current, cpumask_of(cpu));
52 52
53 BUG_ON(smp_processor_id() != cpu); 53 BUG_ON(smp_processor_id() != cpu);
54 54
@@ -66,7 +66,7 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy,
66 freqs.flags = 0; 66 freqs.flags = 0;
67 67
68 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 68 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
69 set_cpus_allowed(current, cpus_allowed); 69 set_cpus_allowed_ptr(current, &cpus_allowed);
70 clk_set_rate(cpuclk, freq); 70 clk_set_rate(cpuclk, freq);
71 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 71 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
72 72
diff --git a/arch/sh/kernel/debugtraps.S b/arch/sh/kernel/debugtraps.S
index 591741383ee6..7a1b46fec0f4 100644
--- a/arch/sh/kernel/debugtraps.S
+++ b/arch/sh/kernel/debugtraps.S
@@ -13,7 +13,6 @@
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14 14
15#if !defined(CONFIG_KGDB) 15#if !defined(CONFIG_KGDB)
16#define breakpoint_trap_handler debug_trap_handler
17#define singlestep_trap_handler debug_trap_handler 16#define singlestep_trap_handler debug_trap_handler
18#endif 17#endif
19 18
diff --git a/arch/sh/kernel/dma-nommu.c b/arch/sh/kernel/dma-nommu.c
new file mode 100644
index 000000000000..3c55b87f8b63
--- /dev/null
+++ b/arch/sh/kernel/dma-nommu.c
@@ -0,0 +1,82 @@
1/*
2 * DMA mapping support for platforms lacking IOMMUs.
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/dma-mapping.h>
11#include <linux/io.h>
12
13static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
14 unsigned long offset, size_t size,
15 enum dma_data_direction dir,
16 struct dma_attrs *attrs)
17{
18 dma_addr_t addr = page_to_phys(page) + offset;
19
20 WARN_ON(size == 0);
21 dma_cache_sync(dev, page_address(page) + offset, size, dir);
22
23 return addr;
24}
25
26static int nommu_map_sg(struct device *dev, struct scatterlist *sg,
27 int nents, enum dma_data_direction dir,
28 struct dma_attrs *attrs)
29{
30 struct scatterlist *s;
31 int i;
32
33 WARN_ON(nents == 0 || sg[0].length == 0);
34
35 for_each_sg(sg, s, nents, i) {
36 BUG_ON(!sg_page(s));
37
38 dma_cache_sync(dev, sg_virt(s), s->length, dir);
39
40 s->dma_address = sg_phys(s);
41 s->dma_length = s->length;
42 }
43
44 return nents;
45}
46
47#ifdef CONFIG_DMA_NONCOHERENT
48static void nommu_sync_single(struct device *dev, dma_addr_t addr,
49 size_t size, enum dma_data_direction dir)
50{
51 dma_cache_sync(dev, phys_to_virt(addr), size, dir);
52}
53
54static void nommu_sync_sg(struct device *dev, struct scatterlist *sg,
55 int nelems, enum dma_data_direction dir)
56{
57 struct scatterlist *s;
58 int i;
59
60 for_each_sg(sg, s, nelems, i)
61 dma_cache_sync(dev, sg_virt(s), s->length, dir);
62}
63#endif
64
65struct dma_map_ops nommu_dma_ops = {
66 .alloc_coherent = dma_generic_alloc_coherent,
67 .free_coherent = dma_generic_free_coherent,
68 .map_page = nommu_map_page,
69 .map_sg = nommu_map_sg,
70#ifdef CONFIG_DMA_NONCOHERENT
71 .sync_single_for_device = nommu_sync_single,
72 .sync_sg_for_device = nommu_sync_sg,
73#endif
74 .is_phys = 1,
75};
76
77void __init no_iommu_init(void)
78{
79 if (dma_ops)
80 return;
81 dma_ops = &nommu_dma_ops;
82}
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index d76a23170dbb..a8234b2010d1 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -20,7 +20,9 @@
20#include <linux/list.h> 20#include <linux/list.h>
21#include <linux/mempool.h> 21#include <linux/mempool.h>
22#include <linux/mm.h> 22#include <linux/mm.h>
23#include <linux/elf.h>
23#include <linux/ftrace.h> 24#include <linux/ftrace.h>
25#include <linux/slab.h>
24#include <asm/dwarf.h> 26#include <asm/dwarf.h>
25#include <asm/unwinder.h> 27#include <asm/unwinder.h>
26#include <asm/sections.h> 28#include <asm/sections.h>
@@ -38,10 +40,10 @@ static mempool_t *dwarf_frame_pool;
38static struct kmem_cache *dwarf_reg_cachep; 40static struct kmem_cache *dwarf_reg_cachep;
39static mempool_t *dwarf_reg_pool; 41static mempool_t *dwarf_reg_pool;
40 42
41static LIST_HEAD(dwarf_cie_list); 43static struct rb_root cie_root;
42static DEFINE_SPINLOCK(dwarf_cie_lock); 44static DEFINE_SPINLOCK(dwarf_cie_lock);
43 45
44static LIST_HEAD(dwarf_fde_list); 46static struct rb_root fde_root;
45static DEFINE_SPINLOCK(dwarf_fde_lock); 47static DEFINE_SPINLOCK(dwarf_fde_lock);
46 48
47static struct dwarf_cie *cached_cie; 49static struct dwarf_cie *cached_cie;
@@ -300,7 +302,8 @@ static inline int dwarf_entry_len(char *addr, unsigned long *len)
300 */ 302 */
301static struct dwarf_cie *dwarf_lookup_cie(unsigned long cie_ptr) 303static struct dwarf_cie *dwarf_lookup_cie(unsigned long cie_ptr)
302{ 304{
303 struct dwarf_cie *cie; 305 struct rb_node **rb_node = &cie_root.rb_node;
306 struct dwarf_cie *cie = NULL;
304 unsigned long flags; 307 unsigned long flags;
305 308
306 spin_lock_irqsave(&dwarf_cie_lock, flags); 309 spin_lock_irqsave(&dwarf_cie_lock, flags);
@@ -314,16 +317,24 @@ static struct dwarf_cie *dwarf_lookup_cie(unsigned long cie_ptr)
314 goto out; 317 goto out;
315 } 318 }
316 319
317 list_for_each_entry(cie, &dwarf_cie_list, link) { 320 while (*rb_node) {
318 if (cie->cie_pointer == cie_ptr) { 321 struct dwarf_cie *cie_tmp;
319 cached_cie = cie; 322
320 break; 323 cie_tmp = rb_entry(*rb_node, struct dwarf_cie, node);
324 BUG_ON(!cie_tmp);
325
326 if (cie_ptr == cie_tmp->cie_pointer) {
327 cie = cie_tmp;
328 cached_cie = cie_tmp;
329 goto out;
330 } else {
331 if (cie_ptr < cie_tmp->cie_pointer)
332 rb_node = &(*rb_node)->rb_left;
333 else
334 rb_node = &(*rb_node)->rb_right;
321 } 335 }
322 } 336 }
323 337
324 /* Couldn't find the entry in the list. */
325 if (&cie->link == &dwarf_cie_list)
326 cie = NULL;
327out: 338out:
328 spin_unlock_irqrestore(&dwarf_cie_lock, flags); 339 spin_unlock_irqrestore(&dwarf_cie_lock, flags);
329 return cie; 340 return cie;
@@ -335,25 +346,34 @@ out:
335 */ 346 */
336struct dwarf_fde *dwarf_lookup_fde(unsigned long pc) 347struct dwarf_fde *dwarf_lookup_fde(unsigned long pc)
337{ 348{
338 struct dwarf_fde *fde; 349 struct rb_node **rb_node = &fde_root.rb_node;
350 struct dwarf_fde *fde = NULL;
339 unsigned long flags; 351 unsigned long flags;
340 352
341 spin_lock_irqsave(&dwarf_fde_lock, flags); 353 spin_lock_irqsave(&dwarf_fde_lock, flags);
342 354
343 list_for_each_entry(fde, &dwarf_fde_list, link) { 355 while (*rb_node) {
344 unsigned long start, end; 356 struct dwarf_fde *fde_tmp;
357 unsigned long tmp_start, tmp_end;
345 358
346 start = fde->initial_location; 359 fde_tmp = rb_entry(*rb_node, struct dwarf_fde, node);
347 end = fde->initial_location + fde->address_range; 360 BUG_ON(!fde_tmp);
348 361
349 if (pc >= start && pc < end) 362 tmp_start = fde_tmp->initial_location;
350 break; 363 tmp_end = fde_tmp->initial_location + fde_tmp->address_range;
351 }
352 364
353 /* Couldn't find the entry in the list. */ 365 if (pc < tmp_start) {
354 if (&fde->link == &dwarf_fde_list) 366 rb_node = &(*rb_node)->rb_left;
355 fde = NULL; 367 } else {
368 if (pc < tmp_end) {
369 fde = fde_tmp;
370 goto out;
371 } else
372 rb_node = &(*rb_node)->rb_right;
373 }
374 }
356 375
376out:
357 spin_unlock_irqrestore(&dwarf_fde_lock, flags); 377 spin_unlock_irqrestore(&dwarf_fde_lock, flags);
358 378
359 return fde; 379 return fde;
@@ -530,7 +550,20 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start,
530} 550}
531 551
532/** 552/**
533 * dwarf_unwind_stack - recursively unwind the stack 553 * dwarf_free_frame - free the memory allocated for @frame
554 * @frame: the frame to free
555 */
556void dwarf_free_frame(struct dwarf_frame *frame)
557{
558 dwarf_frame_free_regs(frame);
559 mempool_free(frame, dwarf_frame_pool);
560}
561
562extern void ret_from_irq(void);
563
564/**
565 * dwarf_unwind_stack - unwind the stack
566 *
534 * @pc: address of the function to unwind 567 * @pc: address of the function to unwind
535 * @prev: struct dwarf_frame of the previous stackframe on the callstack 568 * @prev: struct dwarf_frame of the previous stackframe on the callstack
536 * 569 *
@@ -538,8 +571,8 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start,
538 * on the callstack. Each of the lower (older) stack frames are 571 * on the callstack. Each of the lower (older) stack frames are
539 * linked via the "prev" member. 572 * linked via the "prev" member.
540 */ 573 */
541struct dwarf_frame * dwarf_unwind_stack(unsigned long pc, 574struct dwarf_frame *dwarf_unwind_stack(unsigned long pc,
542 struct dwarf_frame *prev) 575 struct dwarf_frame *prev)
543{ 576{
544 struct dwarf_frame *frame; 577 struct dwarf_frame *frame;
545 struct dwarf_cie *cie; 578 struct dwarf_cie *cie;
@@ -548,9 +581,9 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
548 unsigned long addr; 581 unsigned long addr;
549 582
550 /* 583 /*
551 * If this is the first invocation of this recursive function we 584 * If we're starting at the top of the stack we need get the
552 * need get the contents of a physical register to get the CFA 585 * contents of a physical register to get the CFA in order to
553 * in order to begin the virtual unwinding of the stack. 586 * begin the virtual unwinding of the stack.
554 * 587 *
555 * NOTE: the return address is guaranteed to be setup by the 588 * NOTE: the return address is guaranteed to be setup by the
556 * time this function makes its first function call. 589 * time this function makes its first function call.
@@ -593,9 +626,8 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
593 fde = dwarf_lookup_fde(pc); 626 fde = dwarf_lookup_fde(pc);
594 if (!fde) { 627 if (!fde) {
595 /* 628 /*
596 * This is our normal exit path - the one that stops the 629 * This is our normal exit path. There are two reasons
597 * recursion. There's two reasons why we might exit 630 * why we might exit here,
598 * here,
599 * 631 *
600 * a) pc has no asscociated DWARF frame info and so 632 * a) pc has no asscociated DWARF frame info and so
601 * we don't know how to unwind this frame. This is 633 * we don't know how to unwind this frame. This is
@@ -637,10 +669,10 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
637 669
638 } else { 670 } else {
639 /* 671 /*
640 * Again, this is the first invocation of this 672 * Again, we're starting from the top of the
641 * recurisve function. We need to physically 673 * stack. We need to physically read
642 * read the contents of a register in order to 674 * the contents of a register in order to get
643 * get the Canonical Frame Address for this 675 * the Canonical Frame Address for this
644 * function. 676 * function.
645 */ 677 */
646 frame->cfa = dwarf_read_arch_reg(frame->cfa_register); 678 frame->cfa = dwarf_read_arch_reg(frame->cfa_register);
@@ -667,17 +699,36 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
667 addr = frame->cfa + reg->addr; 699 addr = frame->cfa + reg->addr;
668 frame->return_addr = __raw_readl(addr); 700 frame->return_addr = __raw_readl(addr);
669 701
702 /*
703 * Ah, the joys of unwinding through interrupts.
704 *
705 * Interrupts are tricky - the DWARF info needs to be _really_
706 * accurate and unfortunately I'm seeing a lot of bogus DWARF
707 * info. For example, I've seen interrupts occur in epilogues
708 * just after the frame pointer (r14) had been restored. The
709 * problem was that the DWARF info claimed that the CFA could be
710 * reached by using the value of the frame pointer before it was
711 * restored.
712 *
713 * So until the compiler can be trusted to produce reliable
714 * DWARF info when it really matters, let's stop unwinding once
715 * we've calculated the function that was interrupted.
716 */
717 if (prev && prev->pc == (unsigned long)ret_from_irq)
718 frame->return_addr = 0;
719
670 return frame; 720 return frame;
671 721
672bail: 722bail:
673 dwarf_frame_free_regs(frame); 723 dwarf_free_frame(frame);
674 mempool_free(frame, dwarf_frame_pool);
675 return NULL; 724 return NULL;
676} 725}
677 726
678static int dwarf_parse_cie(void *entry, void *p, unsigned long len, 727static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
679 unsigned char *end) 728 unsigned char *end, struct module *mod)
680{ 729{
730 struct rb_node **rb_node = &cie_root.rb_node;
731 struct rb_node *parent = *rb_node;
681 struct dwarf_cie *cie; 732 struct dwarf_cie *cie;
682 unsigned long flags; 733 unsigned long flags;
683 int count; 734 int count;
@@ -774,7 +825,28 @@ static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
774 825
775 /* Add to list */ 826 /* Add to list */
776 spin_lock_irqsave(&dwarf_cie_lock, flags); 827 spin_lock_irqsave(&dwarf_cie_lock, flags);
777 list_add_tail(&cie->link, &dwarf_cie_list); 828
829 while (*rb_node) {
830 struct dwarf_cie *cie_tmp;
831
832 cie_tmp = rb_entry(*rb_node, struct dwarf_cie, node);
833
834 parent = *rb_node;
835
836 if (cie->cie_pointer < cie_tmp->cie_pointer)
837 rb_node = &parent->rb_left;
838 else if (cie->cie_pointer >= cie_tmp->cie_pointer)
839 rb_node = &parent->rb_right;
840 else
841 WARN_ON(1);
842 }
843
844 rb_link_node(&cie->node, parent, rb_node);
845 rb_insert_color(&cie->node, &cie_root);
846
847 if (mod != NULL)
848 list_add_tail(&cie->link, &mod->arch.cie_list);
849
778 spin_unlock_irqrestore(&dwarf_cie_lock, flags); 850 spin_unlock_irqrestore(&dwarf_cie_lock, flags);
779 851
780 return 0; 852 return 0;
@@ -782,8 +854,10 @@ static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
782 854
783static int dwarf_parse_fde(void *entry, u32 entry_type, 855static int dwarf_parse_fde(void *entry, u32 entry_type,
784 void *start, unsigned long len, 856 void *start, unsigned long len,
785 unsigned char *end) 857 unsigned char *end, struct module *mod)
786{ 858{
859 struct rb_node **rb_node = &fde_root.rb_node;
860 struct rb_node *parent = *rb_node;
787 struct dwarf_fde *fde; 861 struct dwarf_fde *fde;
788 struct dwarf_cie *cie; 862 struct dwarf_cie *cie;
789 unsigned long flags; 863 unsigned long flags;
@@ -833,7 +907,36 @@ static int dwarf_parse_fde(void *entry, u32 entry_type,
833 907
834 /* Add to list. */ 908 /* Add to list. */
835 spin_lock_irqsave(&dwarf_fde_lock, flags); 909 spin_lock_irqsave(&dwarf_fde_lock, flags);
836 list_add_tail(&fde->link, &dwarf_fde_list); 910
911 while (*rb_node) {
912 struct dwarf_fde *fde_tmp;
913 unsigned long tmp_start, tmp_end;
914 unsigned long start, end;
915
916 fde_tmp = rb_entry(*rb_node, struct dwarf_fde, node);
917
918 start = fde->initial_location;
919 end = fde->initial_location + fde->address_range;
920
921 tmp_start = fde_tmp->initial_location;
922 tmp_end = fde_tmp->initial_location + fde_tmp->address_range;
923
924 parent = *rb_node;
925
926 if (start < tmp_start)
927 rb_node = &parent->rb_left;
928 else if (start >= tmp_end)
929 rb_node = &parent->rb_right;
930 else
931 WARN_ON(1);
932 }
933
934 rb_link_node(&fde->node, parent, rb_node);
935 rb_insert_color(&fde->node, &fde_root);
936
937 if (mod != NULL)
938 list_add_tail(&fde->link, &mod->arch.fde_list);
939
837 spin_unlock_irqrestore(&dwarf_fde_lock, flags); 940 spin_unlock_irqrestore(&dwarf_fde_lock, flags);
838 941
839 return 0; 942 return 0;
@@ -854,10 +957,8 @@ static void dwarf_unwinder_dump(struct task_struct *task,
854 while (1) { 957 while (1) {
855 frame = dwarf_unwind_stack(return_addr, _frame); 958 frame = dwarf_unwind_stack(return_addr, _frame);
856 959
857 if (_frame) { 960 if (_frame)
858 dwarf_frame_free_regs(_frame); 961 dwarf_free_frame(_frame);
859 mempool_free(_frame, dwarf_frame_pool);
860 }
861 962
862 _frame = frame; 963 _frame = frame;
863 964
@@ -867,6 +968,9 @@ static void dwarf_unwinder_dump(struct task_struct *task,
867 return_addr = frame->return_addr; 968 return_addr = frame->return_addr;
868 ops->address(data, return_addr, 1); 969 ops->address(data, return_addr, 1);
869 } 970 }
971
972 if (frame)
973 dwarf_free_frame(frame);
870} 974}
871 975
872static struct unwinder dwarf_unwinder = { 976static struct unwinder dwarf_unwinder = {
@@ -877,67 +981,57 @@ static struct unwinder dwarf_unwinder = {
877 981
878static void dwarf_unwinder_cleanup(void) 982static void dwarf_unwinder_cleanup(void)
879{ 983{
880 struct dwarf_cie *cie; 984 struct rb_node **fde_rb_node = &fde_root.rb_node;
881 struct dwarf_fde *fde; 985 struct rb_node **cie_rb_node = &cie_root.rb_node;
882 986
883 /* 987 /*
884 * Deallocate all the memory allocated for the DWARF unwinder. 988 * Deallocate all the memory allocated for the DWARF unwinder.
885 * Traverse all the FDE/CIE lists and remove and free all the 989 * Traverse all the FDE/CIE lists and remove and free all the
886 * memory associated with those data structures. 990 * memory associated with those data structures.
887 */ 991 */
888 list_for_each_entry(cie, &dwarf_cie_list, link) 992 while (*fde_rb_node) {
889 kfree(cie); 993 struct dwarf_fde *fde;
890 994
891 list_for_each_entry(fde, &dwarf_fde_list, link) 995 fde = rb_entry(*fde_rb_node, struct dwarf_fde, node);
996 rb_erase(*fde_rb_node, &fde_root);
892 kfree(fde); 997 kfree(fde);
998 }
999
1000 while (*cie_rb_node) {
1001 struct dwarf_cie *cie;
1002
1003 cie = rb_entry(*cie_rb_node, struct dwarf_cie, node);
1004 rb_erase(*cie_rb_node, &cie_root);
1005 kfree(cie);
1006 }
893 1007
894 kmem_cache_destroy(dwarf_reg_cachep); 1008 kmem_cache_destroy(dwarf_reg_cachep);
895 kmem_cache_destroy(dwarf_frame_cachep); 1009 kmem_cache_destroy(dwarf_frame_cachep);
896} 1010}
897 1011
898/** 1012/**
899 * dwarf_unwinder_init - initialise the dwarf unwinder 1013 * dwarf_parse_section - parse DWARF section
1014 * @eh_frame_start: start address of the .eh_frame section
1015 * @eh_frame_end: end address of the .eh_frame section
1016 * @mod: the kernel module containing the .eh_frame section
900 * 1017 *
901 * Build the data structures describing the .dwarf_frame section to 1018 * Parse the information in a .eh_frame section.
902 * make it easier to lookup CIE and FDE entries. Because the
903 * .eh_frame section is packed as tightly as possible it is not
904 * easy to lookup the FDE for a given PC, so we build a list of FDE
905 * and CIE entries that make it easier.
906 */ 1019 */
907static int __init dwarf_unwinder_init(void) 1020static int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end,
1021 struct module *mod)
908{ 1022{
909 u32 entry_type; 1023 u32 entry_type;
910 void *p, *entry; 1024 void *p, *entry;
911 int count, err = 0; 1025 int count, err = 0;
912 unsigned long len; 1026 unsigned long len = 0;
913 unsigned int c_entries, f_entries; 1027 unsigned int c_entries, f_entries;
914 unsigned char *end; 1028 unsigned char *end;
915 INIT_LIST_HEAD(&dwarf_cie_list);
916 INIT_LIST_HEAD(&dwarf_fde_list);
917 1029
918 c_entries = 0; 1030 c_entries = 0;
919 f_entries = 0; 1031 f_entries = 0;
920 entry = &__start_eh_frame; 1032 entry = eh_frame_start;
921
922 dwarf_frame_cachep = kmem_cache_create("dwarf_frames",
923 sizeof(struct dwarf_frame), 0,
924 SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
925
926 dwarf_reg_cachep = kmem_cache_create("dwarf_regs",
927 sizeof(struct dwarf_reg), 0,
928 SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
929 1033
930 dwarf_frame_pool = mempool_create(DWARF_FRAME_MIN_REQ, 1034 while ((char *)entry < eh_frame_end) {
931 mempool_alloc_slab,
932 mempool_free_slab,
933 dwarf_frame_cachep);
934
935 dwarf_reg_pool = mempool_create(DWARF_REG_MIN_REQ,
936 mempool_alloc_slab,
937 mempool_free_slab,
938 dwarf_reg_cachep);
939
940 while ((char *)entry < __stop_eh_frame) {
941 p = entry; 1035 p = entry;
942 1036
943 count = dwarf_entry_len(p, &len); 1037 count = dwarf_entry_len(p, &len);
@@ -949,6 +1043,7 @@ static int __init dwarf_unwinder_init(void)
949 * entry and move to the next one because 'len' 1043 * entry and move to the next one because 'len'
950 * tells us where our next entry is. 1044 * tells us where our next entry is.
951 */ 1045 */
1046 err = -EINVAL;
952 goto out; 1047 goto out;
953 } else 1048 } else
954 p += count; 1049 p += count;
@@ -960,13 +1055,14 @@ static int __init dwarf_unwinder_init(void)
960 p += 4; 1055 p += 4;
961 1056
962 if (entry_type == DW_EH_FRAME_CIE) { 1057 if (entry_type == DW_EH_FRAME_CIE) {
963 err = dwarf_parse_cie(entry, p, len, end); 1058 err = dwarf_parse_cie(entry, p, len, end, mod);
964 if (err < 0) 1059 if (err < 0)
965 goto out; 1060 goto out;
966 else 1061 else
967 c_entries++; 1062 c_entries++;
968 } else { 1063 } else {
969 err = dwarf_parse_fde(entry, entry_type, p, len, end); 1064 err = dwarf_parse_fde(entry, entry_type, p, len,
1065 end, mod);
970 if (err < 0) 1066 if (err < 0)
971 goto out; 1067 goto out;
972 else 1068 else
@@ -979,6 +1075,117 @@ static int __init dwarf_unwinder_init(void)
979 printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n", 1075 printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n",
980 c_entries, f_entries); 1076 c_entries, f_entries);
981 1077
1078 return 0;
1079
1080out:
1081 return err;
1082}
1083
1084#ifdef CONFIG_MODULES
1085int module_dwarf_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
1086 struct module *me)
1087{
1088 unsigned int i, err;
1089 unsigned long start, end;
1090 char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
1091
1092 start = end = 0;
1093
1094 for (i = 1; i < hdr->e_shnum; i++) {
1095 /* Alloc bit cleared means "ignore it." */
1096 if ((sechdrs[i].sh_flags & SHF_ALLOC)
1097 && !strcmp(secstrings+sechdrs[i].sh_name, ".eh_frame")) {
1098 start = sechdrs[i].sh_addr;
1099 end = start + sechdrs[i].sh_size;
1100 break;
1101 }
1102 }
1103
1104 /* Did we find the .eh_frame section? */
1105 if (i != hdr->e_shnum) {
1106 INIT_LIST_HEAD(&me->arch.cie_list);
1107 INIT_LIST_HEAD(&me->arch.fde_list);
1108 err = dwarf_parse_section((char *)start, (char *)end, me);
1109 if (err) {
1110 printk(KERN_WARNING "%s: failed to parse DWARF info\n",
1111 me->name);
1112 return err;
1113 }
1114 }
1115
1116 return 0;
1117}
1118
1119/**
1120 * module_dwarf_cleanup - remove FDE/CIEs associated with @mod
1121 * @mod: the module that is being unloaded
1122 *
1123 * Remove any FDEs and CIEs from the global lists that came from
1124 * @mod's .eh_frame section because @mod is being unloaded.
1125 */
1126void module_dwarf_cleanup(struct module *mod)
1127{
1128 struct dwarf_fde *fde, *ftmp;
1129 struct dwarf_cie *cie, *ctmp;
1130 unsigned long flags;
1131
1132 spin_lock_irqsave(&dwarf_cie_lock, flags);
1133
1134 list_for_each_entry_safe(cie, ctmp, &mod->arch.cie_list, link) {
1135 list_del(&cie->link);
1136 rb_erase(&cie->node, &cie_root);
1137 kfree(cie);
1138 }
1139
1140 spin_unlock_irqrestore(&dwarf_cie_lock, flags);
1141
1142 spin_lock_irqsave(&dwarf_fde_lock, flags);
1143
1144 list_for_each_entry_safe(fde, ftmp, &mod->arch.fde_list, link) {
1145 list_del(&fde->link);
1146 rb_erase(&fde->node, &fde_root);
1147 kfree(fde);
1148 }
1149
1150 spin_unlock_irqrestore(&dwarf_fde_lock, flags);
1151}
1152#endif /* CONFIG_MODULES */
1153
1154/**
1155 * dwarf_unwinder_init - initialise the dwarf unwinder
1156 *
1157 * Build the data structures describing the .dwarf_frame section to
1158 * make it easier to lookup CIE and FDE entries. Because the
1159 * .eh_frame section is packed as tightly as possible it is not
1160 * easy to lookup the FDE for a given PC, so we build a list of FDE
1161 * and CIE entries that make it easier.
1162 */
1163static int __init dwarf_unwinder_init(void)
1164{
1165 int err;
1166
1167 dwarf_frame_cachep = kmem_cache_create("dwarf_frames",
1168 sizeof(struct dwarf_frame), 0,
1169 SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
1170
1171 dwarf_reg_cachep = kmem_cache_create("dwarf_regs",
1172 sizeof(struct dwarf_reg), 0,
1173 SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
1174
1175 dwarf_frame_pool = mempool_create(DWARF_FRAME_MIN_REQ,
1176 mempool_alloc_slab,
1177 mempool_free_slab,
1178 dwarf_frame_cachep);
1179
1180 dwarf_reg_pool = mempool_create(DWARF_REG_MIN_REQ,
1181 mempool_alloc_slab,
1182 mempool_free_slab,
1183 dwarf_reg_cachep);
1184
1185 err = dwarf_parse_section(__start_eh_frame, __stop_eh_frame, NULL);
1186 if (err)
1187 goto out;
1188
982 err = unwinder_register(&dwarf_unwinder); 1189 err = unwinder_register(&dwarf_unwinder);
983 if (err) 1190 if (err)
984 goto out; 1191 goto out;
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
deleted file mode 100644
index 81a46145ffa5..000000000000
--- a/arch/sh/kernel/early_printk.c
+++ /dev/null
@@ -1,240 +0,0 @@
1/*
2 * arch/sh/kernel/early_printk.c
3 *
4 * Copyright (C) 1999, 2000 Niibe Yutaka
5 * Copyright (C) 2002 M. R. Brown
6 * Copyright (C) 2004 - 2007 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/console.h>
13#include <linux/tty.h>
14#include <linux/init.h>
15#include <linux/io.h>
16#include <linux/delay.h>
17
18#ifdef CONFIG_SH_STANDARD_BIOS
19#include <asm/sh_bios.h>
20
21/*
22 * Print a string through the BIOS
23 */
24static void sh_console_write(struct console *co, const char *s,
25 unsigned count)
26{
27 sh_bios_console_write(s, count);
28}
29
30/*
31 * Setup initial baud/bits/parity. We do two things here:
32 * - construct a cflag setting for the first rs_open()
33 * - initialize the serial port
34 * Return non-zero if we didn't find a serial port.
35 */
36static int __init sh_console_setup(struct console *co, char *options)
37{
38 int cflag = CREAD | HUPCL | CLOCAL;
39
40 /*
41 * Now construct a cflag setting.
42 * TODO: this is a totally bogus cflag, as we have
43 * no idea what serial settings the BIOS is using, or
44 * even if its using the serial port at all.
45 */
46 cflag |= B115200 | CS8 | /*no parity*/0;
47
48 co->cflag = cflag;
49
50 return 0;
51}
52
53static struct console bios_console = {
54 .name = "bios",
55 .write = sh_console_write,
56 .setup = sh_console_setup,
57 .flags = CON_PRINTBUFFER,
58 .index = -1,
59};
60#endif
61
62#ifdef CONFIG_EARLY_SCIF_CONSOLE
63#include <linux/serial_core.h>
64#include "../../../drivers/serial/sh-sci.h"
65
66#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
67 defined(CONFIG_CPU_SUBTYPE_SH7721)
68#define EPK_SCSMR_VALUE 0x000
69#define EPK_SCBRR_VALUE 0x00C
70#define EPK_FIFO_SIZE 64
71#define EPK_FIFO_BITS (0x7f00 >> 8)
72#else
73#define EPK_FIFO_SIZE 16
74#define EPK_FIFO_BITS (0x1f00 >> 8)
75#endif
76
77static struct uart_port scif_port = {
78 .type = PORT_SCIF,
79 .mapbase = CONFIG_EARLY_SCIF_CONSOLE_PORT,
80 .membase = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT,
81};
82
83static void scif_sercon_putc(int c)
84{
85 while (((sci_in(&scif_port, SCFDR) & EPK_FIFO_BITS) >= EPK_FIFO_SIZE))
86 ;
87
88 sci_in(&scif_port, SCxSR);
89 sci_out(&scif_port, SCxSR, 0xf3 & ~(0x20 | 0x40));
90 sci_out(&scif_port, SCxTDR, c);
91
92 while ((sci_in(&scif_port, SCxSR) & 0x40) == 0)
93 ;
94
95 if (c == '\n')
96 scif_sercon_putc('\r');
97}
98
99static void scif_sercon_write(struct console *con, const char *s,
100 unsigned count)
101{
102 while (count-- > 0)
103 scif_sercon_putc(*s++);
104}
105
106static int __init scif_sercon_setup(struct console *con, char *options)
107{
108 con->cflag = CREAD | HUPCL | CLOCAL | B115200 | CS8;
109
110 return 0;
111}
112
113static struct console scif_console = {
114 .name = "sercon",
115 .write = scif_sercon_write,
116 .setup = scif_sercon_setup,
117 .flags = CON_PRINTBUFFER,
118 .index = -1,
119};
120
121#if !defined(CONFIG_SH_STANDARD_BIOS)
122#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
123 defined(CONFIG_CPU_SUBTYPE_SH7721)
124static void scif_sercon_init(char *s)
125{
126 sci_out(&scif_port, SCSCR, 0x0000); /* clear TE and RE */
127 sci_out(&scif_port, SCFCR, 0x4006); /* reset */
128 sci_out(&scif_port, SCSCR, 0x0000); /* select internal clock */
129 sci_out(&scif_port, SCSMR, EPK_SCSMR_VALUE);
130 sci_out(&scif_port, SCBRR, EPK_SCBRR_VALUE);
131
132 mdelay(1); /* wait 1-bit time */
133
134 sci_out(&scif_port, SCFCR, 0x0030); /* TTRG=b'11 */
135 sci_out(&scif_port, SCSCR, 0x0030); /* TE, RE */
136}
137#elif defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3)
138#define DEFAULT_BAUD 115200
139/*
140 * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4
141 * devices that aren't using sh-ipl+g.
142 */
143static void scif_sercon_init(char *s)
144{
145 struct uart_port *port = &scif_port;
146 unsigned baud = DEFAULT_BAUD;
147 unsigned int status;
148 char *e;
149
150 if (*s == ',')
151 ++s;
152
153 if (*s) {
154 /* ignore ioport/device name */
155 s += strcspn(s, ",");
156 if (*s == ',')
157 s++;
158 }
159
160 if (*s) {
161 baud = simple_strtoul(s, &e, 0);
162 if (baud == 0 || s == e)
163 baud = DEFAULT_BAUD;
164 }
165
166 do {
167 status = sci_in(port, SCxSR);
168 } while (!(status & SCxSR_TEND(port)));
169
170 sci_out(port, SCSCR, 0); /* TE=0, RE=0 */
171 sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
172 sci_out(port, SCSMR, 0);
173
174 /* Set baud rate */
175 sci_out(port, SCBRR, (CONFIG_SH_PCLK_FREQ + 16 * baud) /
176 (32 * baud) - 1);
177 udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
178
179 sci_out(port, SCSPTR, 0);
180 sci_out(port, SCxSR, 0x60);
181 sci_out(port, SCLSR, 0);
182
183 sci_out(port, SCFCR, 0);
184 sci_out(port, SCSCR, 0x30); /* TE=1, RE=1 */
185}
186#endif /* defined(CONFIG_CPU_SUBTYPE_SH7720) */
187#endif /* !defined(CONFIG_SH_STANDARD_BIOS) */
188#endif /* CONFIG_EARLY_SCIF_CONSOLE */
189
190/*
191 * Setup a default console, if more than one is compiled in, rely on the
192 * earlyprintk= parsing to give priority.
193 */
194static struct console *early_console =
195#ifdef CONFIG_SH_STANDARD_BIOS
196 &bios_console
197#elif defined(CONFIG_EARLY_SCIF_CONSOLE)
198 &scif_console
199#else
200 NULL
201#endif
202 ;
203
204static int __init setup_early_printk(char *buf)
205{
206 int keep_early = 0;
207
208 if (!buf)
209 return 0;
210
211 if (strstr(buf, "keep"))
212 keep_early = 1;
213
214#ifdef CONFIG_SH_STANDARD_BIOS
215 if (!strncmp(buf, "bios", 4))
216 early_console = &bios_console;
217#endif
218#if defined(CONFIG_EARLY_SCIF_CONSOLE)
219 if (!strncmp(buf, "serial", 6)) {
220 early_console = &scif_console;
221
222#if !defined(CONFIG_SH_STANDARD_BIOS)
223#if defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3)
224 scif_sercon_init(buf + 6);
225#endif
226#endif
227 }
228#endif
229
230 if (likely(early_console)) {
231 if (keep_early)
232 early_console->flags &= ~CON_BOOT;
233 else
234 early_console->flags |= CON_BOOT;
235 register_console(early_console);
236 }
237
238 return 0;
239}
240early_param("earlyprintk", setup_early_printk);
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 3eb84931d2aa..2b15ae60c3a0 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -70,8 +70,14 @@ ret_from_exception:
70 CFI_STARTPROC simple 70 CFI_STARTPROC simple
71 CFI_DEF_CFA r14, 0 71 CFI_DEF_CFA r14, 0
72 CFI_REL_OFFSET 17, 64 72 CFI_REL_OFFSET 17, 64
73 CFI_REL_OFFSET 15, 0 73 CFI_REL_OFFSET 15, 60
74 CFI_REL_OFFSET 14, 56 74 CFI_REL_OFFSET 14, 56
75 CFI_REL_OFFSET 13, 52
76 CFI_REL_OFFSET 12, 48
77 CFI_REL_OFFSET 11, 44
78 CFI_REL_OFFSET 10, 40
79 CFI_REL_OFFSET 9, 36
80 CFI_REL_OFFSET 8, 32
75 preempt_stop() 81 preempt_stop()
76ENTRY(ret_from_irq) 82ENTRY(ret_from_irq)
77 ! 83 !
@@ -133,7 +139,7 @@ work_pending:
133 ! r8: current_thread_info 139 ! r8: current_thread_info
134 ! t: result of "tst #_TIF_NEED_RESCHED, r0" 140 ! t: result of "tst #_TIF_NEED_RESCHED, r0"
135 bf/s work_resched 141 bf/s work_resched
136 tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0 142 tst #_TIF_SIGPENDING, r0
137work_notifysig: 143work_notifysig:
138 bt/s __restore_all 144 bt/s __restore_all
139 mov r15, r4 145 mov r15, r4
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c
index 2c48e267256e..30e13196d35b 100644
--- a/arch/sh/kernel/ftrace.c
+++ b/arch/sh/kernel/ftrace.c
@@ -62,6 +62,150 @@ static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
62 return ftrace_replaced_code; 62 return ftrace_replaced_code;
63} 63}
64 64
65/*
66 * Modifying code must take extra care. On an SMP machine, if
67 * the code being modified is also being executed on another CPU
68 * that CPU will have undefined results and possibly take a GPF.
69 * We use kstop_machine to stop other CPUS from exectuing code.
70 * But this does not stop NMIs from happening. We still need
71 * to protect against that. We separate out the modification of
72 * the code to take care of this.
73 *
74 * Two buffers are added: An IP buffer and a "code" buffer.
75 *
76 * 1) Put the instruction pointer into the IP buffer
77 * and the new code into the "code" buffer.
78 * 2) Wait for any running NMIs to finish and set a flag that says
79 * we are modifying code, it is done in an atomic operation.
80 * 3) Write the code
81 * 4) clear the flag.
82 * 5) Wait for any running NMIs to finish.
83 *
84 * If an NMI is executed, the first thing it does is to call
85 * "ftrace_nmi_enter". This will check if the flag is set to write
86 * and if it is, it will write what is in the IP and "code" buffers.
87 *
88 * The trick is, it does not matter if everyone is writing the same
89 * content to the code location. Also, if a CPU is executing code
90 * it is OK to write to that code location if the contents being written
91 * are the same as what exists.
92 */
93#define MOD_CODE_WRITE_FLAG (1 << 31) /* set when NMI should do the write */
94static atomic_t nmi_running = ATOMIC_INIT(0);
95static int mod_code_status; /* holds return value of text write */
96static void *mod_code_ip; /* holds the IP to write to */
97static void *mod_code_newcode; /* holds the text to write to the IP */
98
99static unsigned nmi_wait_count;
100static atomic_t nmi_update_count = ATOMIC_INIT(0);
101
102int ftrace_arch_read_dyn_info(char *buf, int size)
103{
104 int r;
105
106 r = snprintf(buf, size, "%u %u",
107 nmi_wait_count,
108 atomic_read(&nmi_update_count));
109 return r;
110}
111
112static void clear_mod_flag(void)
113{
114 int old = atomic_read(&nmi_running);
115
116 for (;;) {
117 int new = old & ~MOD_CODE_WRITE_FLAG;
118
119 if (old == new)
120 break;
121
122 old = atomic_cmpxchg(&nmi_running, old, new);
123 }
124}
125
126static void ftrace_mod_code(void)
127{
128 /*
129 * Yes, more than one CPU process can be writing to mod_code_status.
130 * (and the code itself)
131 * But if one were to fail, then they all should, and if one were
132 * to succeed, then they all should.
133 */
134 mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode,
135 MCOUNT_INSN_SIZE);
136
137 /* if we fail, then kill any new writers */
138 if (mod_code_status)
139 clear_mod_flag();
140}
141
142void ftrace_nmi_enter(void)
143{
144 if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) {
145 smp_rmb();
146 ftrace_mod_code();
147 atomic_inc(&nmi_update_count);
148 }
149 /* Must have previous changes seen before executions */
150 smp_mb();
151}
152
153void ftrace_nmi_exit(void)
154{
155 /* Finish all executions before clearing nmi_running */
156 smp_mb();
157 atomic_dec(&nmi_running);
158}
159
160static void wait_for_nmi_and_set_mod_flag(void)
161{
162 if (!atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG))
163 return;
164
165 do {
166 cpu_relax();
167 } while (atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG));
168
169 nmi_wait_count++;
170}
171
172static void wait_for_nmi(void)
173{
174 if (!atomic_read(&nmi_running))
175 return;
176
177 do {
178 cpu_relax();
179 } while (atomic_read(&nmi_running));
180
181 nmi_wait_count++;
182}
183
184static int
185do_ftrace_mod_code(unsigned long ip, void *new_code)
186{
187 mod_code_ip = (void *)ip;
188 mod_code_newcode = new_code;
189
190 /* The buffers need to be visible before we let NMIs write them */
191 smp_mb();
192
193 wait_for_nmi_and_set_mod_flag();
194
195 /* Make sure all running NMIs have finished before we write the code */
196 smp_mb();
197
198 ftrace_mod_code();
199
200 /* Make sure the write happens before clearing the bit */
201 smp_mb();
202
203 clear_mod_flag();
204 wait_for_nmi();
205
206 return mod_code_status;
207}
208
65static int ftrace_modify_code(unsigned long ip, unsigned char *old_code, 209static int ftrace_modify_code(unsigned long ip, unsigned char *old_code,
66 unsigned char *new_code) 210 unsigned char *new_code)
67{ 211{
@@ -86,7 +230,7 @@ static int ftrace_modify_code(unsigned long ip, unsigned char *old_code,
86 return -EINVAL; 230 return -EINVAL;
87 231
88 /* replace the text with the new text */ 232 /* replace the text with the new text */
89 if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE)) 233 if (do_ftrace_mod_code(ip, new_code))
90 return -EPERM; 234 return -EPERM;
91 235
92 flush_icache_range(ip, ip + MCOUNT_INSN_SIZE); 236 flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
@@ -255,84 +399,3 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
255 } 399 }
256} 400}
257#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 401#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
258
259#ifdef CONFIG_FTRACE_SYSCALLS
260
261extern unsigned long __start_syscalls_metadata[];
262extern unsigned long __stop_syscalls_metadata[];
263extern unsigned long *sys_call_table;
264
265static struct syscall_metadata **syscalls_metadata;
266
267static struct syscall_metadata *find_syscall_meta(unsigned long *syscall)
268{
269 struct syscall_metadata *start;
270 struct syscall_metadata *stop;
271 char str[KSYM_SYMBOL_LEN];
272
273
274 start = (struct syscall_metadata *)__start_syscalls_metadata;
275 stop = (struct syscall_metadata *)__stop_syscalls_metadata;
276 kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str);
277
278 for ( ; start < stop; start++) {
279 if (start->name && !strcmp(start->name, str))
280 return start;
281 }
282
283 return NULL;
284}
285
286struct syscall_metadata *syscall_nr_to_meta(int nr)
287{
288 if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0)
289 return NULL;
290
291 return syscalls_metadata[nr];
292}
293
294int syscall_name_to_nr(char *name)
295{
296 int i;
297
298 if (!syscalls_metadata)
299 return -1;
300 for (i = 0; i < NR_syscalls; i++)
301 if (syscalls_metadata[i])
302 if (!strcmp(syscalls_metadata[i]->name, name))
303 return i;
304 return -1;
305}
306
307void set_syscall_enter_id(int num, int id)
308{
309 syscalls_metadata[num]->enter_id = id;
310}
311
312void set_syscall_exit_id(int num, int id)
313{
314 syscalls_metadata[num]->exit_id = id;
315}
316
317static int __init arch_init_ftrace_syscalls(void)
318{
319 int i;
320 struct syscall_metadata *meta;
321 unsigned long **psys_syscall_table = &sys_call_table;
322
323 syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
324 FTRACE_SYSCALL_MAX, GFP_KERNEL);
325 if (!syscalls_metadata) {
326 WARN_ON(1);
327 return -ENOMEM;
328 }
329
330 for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
331 meta = find_syscall_meta(psys_syscall_table[i]);
332 syscalls_metadata[i] = meta;
333 }
334
335 return 0;
336}
337arch_initcall(arch_init_ftrace_syscalls);
338#endif /* CONFIG_FTRACE_SYSCALLS */
diff --git a/arch/sh/kernel/gpio.c b/arch/sh/kernel/gpio.c
deleted file mode 100644
index d22e5af699f9..000000000000
--- a/arch/sh/kernel/gpio.c
+++ /dev/null
@@ -1,584 +0,0 @@
1/*
2 * Pinmuxed GPIO support for SuperH.
3 *
4 * Copyright (C) 2008 Magnus Damm
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
11#include <linux/errno.h>
12#include <linux/kernel.h>
13#include <linux/list.h>
14#include <linux/module.h>
15#include <linux/clk.h>
16#include <linux/err.h>
17#include <linux/io.h>
18#include <linux/irq.h>
19#include <linux/bitops.h>
20#include <linux/gpio.h>
21
22static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
23{
24 if (enum_id < r->begin)
25 return 0;
26
27 if (enum_id > r->end)
28 return 0;
29
30 return 1;
31}
32
33static unsigned long gpio_read_raw_reg(unsigned long reg,
34 unsigned long reg_width)
35{
36 switch (reg_width) {
37 case 8:
38 return ctrl_inb(reg);
39 case 16:
40 return ctrl_inw(reg);
41 case 32:
42 return ctrl_inl(reg);
43 }
44
45 BUG();
46 return 0;
47}
48
49static void gpio_write_raw_reg(unsigned long reg,
50 unsigned long reg_width,
51 unsigned long data)
52{
53 switch (reg_width) {
54 case 8:
55 ctrl_outb(data, reg);
56 return;
57 case 16:
58 ctrl_outw(data, reg);
59 return;
60 case 32:
61 ctrl_outl(data, reg);
62 return;
63 }
64
65 BUG();
66}
67
68static void gpio_write_bit(struct pinmux_data_reg *dr,
69 unsigned long in_pos, unsigned long value)
70{
71 unsigned long pos;
72
73 pos = dr->reg_width - (in_pos + 1);
74
75#ifdef DEBUG
76 pr_info("write_bit addr = %lx, value = %ld, pos = %ld, "
77 "r_width = %ld\n",
78 dr->reg, !!value, pos, dr->reg_width);
79#endif
80
81 if (value)
82 set_bit(pos, &dr->reg_shadow);
83 else
84 clear_bit(pos, &dr->reg_shadow);
85
86 gpio_write_raw_reg(dr->reg, dr->reg_width, dr->reg_shadow);
87}
88
89static int gpio_read_reg(unsigned long reg, unsigned long reg_width,
90 unsigned long field_width, unsigned long in_pos)
91{
92 unsigned long data, mask, pos;
93
94 data = 0;
95 mask = (1 << field_width) - 1;
96 pos = reg_width - ((in_pos + 1) * field_width);
97
98#ifdef DEBUG
99 pr_info("read_reg: addr = %lx, pos = %ld, "
100 "r_width = %ld, f_width = %ld\n",
101 reg, pos, reg_width, field_width);
102#endif
103
104 data = gpio_read_raw_reg(reg, reg_width);
105 return (data >> pos) & mask;
106}
107
108static void gpio_write_reg(unsigned long reg, unsigned long reg_width,
109 unsigned long field_width, unsigned long in_pos,
110 unsigned long value)
111{
112 unsigned long mask, pos;
113
114 mask = (1 << field_width) - 1;
115 pos = reg_width - ((in_pos + 1) * field_width);
116
117#ifdef DEBUG
118 pr_info("write_reg addr = %lx, value = %ld, pos = %ld, "
119 "r_width = %ld, f_width = %ld\n",
120 reg, value, pos, reg_width, field_width);
121#endif
122
123 mask = ~(mask << pos);
124 value = value << pos;
125
126 switch (reg_width) {
127 case 8:
128 ctrl_outb((ctrl_inb(reg) & mask) | value, reg);
129 break;
130 case 16:
131 ctrl_outw((ctrl_inw(reg) & mask) | value, reg);
132 break;
133 case 32:
134 ctrl_outl((ctrl_inl(reg) & mask) | value, reg);
135 break;
136 }
137}
138
139static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
140{
141 struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
142 struct pinmux_data_reg *data_reg;
143 int k, n;
144
145 if (!enum_in_range(gpiop->enum_id, &gpioc->data))
146 return -1;
147
148 k = 0;
149 while (1) {
150 data_reg = gpioc->data_regs + k;
151
152 if (!data_reg->reg_width)
153 break;
154
155 for (n = 0; n < data_reg->reg_width; n++) {
156 if (data_reg->enum_ids[n] == gpiop->enum_id) {
157 gpiop->flags &= ~PINMUX_FLAG_DREG;
158 gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT);
159 gpiop->flags &= ~PINMUX_FLAG_DBIT;
160 gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT);
161 return 0;
162 }
163 }
164 k++;
165 }
166
167 BUG();
168
169 return -1;
170}
171
172static void setup_data_regs(struct pinmux_info *gpioc)
173{
174 struct pinmux_data_reg *drp;
175 int k;
176
177 for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++)
178 setup_data_reg(gpioc, k);
179
180 k = 0;
181 while (1) {
182 drp = gpioc->data_regs + k;
183
184 if (!drp->reg_width)
185 break;
186
187 drp->reg_shadow = gpio_read_raw_reg(drp->reg, drp->reg_width);
188 k++;
189 }
190}
191
192static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
193 struct pinmux_data_reg **drp, int *bitp)
194{
195 struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
196 int k, n;
197
198 if (!enum_in_range(gpiop->enum_id, &gpioc->data))
199 return -1;
200
201 k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
202 n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
203 *drp = gpioc->data_regs + k;
204 *bitp = n;
205 return 0;
206}
207
208static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
209 struct pinmux_cfg_reg **crp, int *indexp,
210 unsigned long **cntp)
211{
212 struct pinmux_cfg_reg *config_reg;
213 unsigned long r_width, f_width;
214 int k, n;
215
216 k = 0;
217 while (1) {
218 config_reg = gpioc->cfg_regs + k;
219
220 r_width = config_reg->reg_width;
221 f_width = config_reg->field_width;
222
223 if (!r_width)
224 break;
225 for (n = 0; n < (r_width / f_width) * 1 << f_width; n++) {
226 if (config_reg->enum_ids[n] == enum_id) {
227 *crp = config_reg;
228 *indexp = n;
229 *cntp = &config_reg->cnt[n / (1 << f_width)];
230 return 0;
231 }
232 }
233 k++;
234 }
235
236 return -1;
237}
238
239static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
240 int pos, pinmux_enum_t *enum_idp)
241{
242 pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
243 pinmux_enum_t *data = gpioc->gpio_data;
244 int k;
245
246 if (!enum_in_range(enum_id, &gpioc->data)) {
247 if (!enum_in_range(enum_id, &gpioc->mark)) {
248 pr_err("non data/mark enum_id for gpio %d\n", gpio);
249 return -1;
250 }
251 }
252
253 if (pos) {
254 *enum_idp = data[pos + 1];
255 return pos + 1;
256 }
257
258 for (k = 0; k < gpioc->gpio_data_size; k++) {
259 if (data[k] == enum_id) {
260 *enum_idp = data[k + 1];
261 return k + 1;
262 }
263 }
264
265 pr_err("cannot locate data/mark enum_id for gpio %d\n", gpio);
266 return -1;
267}
268
269static void write_config_reg(struct pinmux_info *gpioc,
270 struct pinmux_cfg_reg *crp,
271 int index)
272{
273 unsigned long ncomb, pos, value;
274
275 ncomb = 1 << crp->field_width;
276 pos = index / ncomb;
277 value = index % ncomb;
278
279 gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value);
280}
281
282static int check_config_reg(struct pinmux_info *gpioc,
283 struct pinmux_cfg_reg *crp,
284 int index)
285{
286 unsigned long ncomb, pos, value;
287
288 ncomb = 1 << crp->field_width;
289 pos = index / ncomb;
290 value = index % ncomb;
291
292 if (gpio_read_reg(crp->reg, crp->reg_width,
293 crp->field_width, pos) == value)
294 return 0;
295
296 return -1;
297}
298
299enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
300
301static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
302 int pinmux_type, int cfg_mode)
303{
304 struct pinmux_cfg_reg *cr = NULL;
305 pinmux_enum_t enum_id;
306 struct pinmux_range *range;
307 int in_range, pos, index;
308 unsigned long *cntp;
309
310 switch (pinmux_type) {
311
312 case PINMUX_TYPE_FUNCTION:
313 range = NULL;
314 break;
315
316 case PINMUX_TYPE_OUTPUT:
317 range = &gpioc->output;
318 break;
319
320 case PINMUX_TYPE_INPUT:
321 range = &gpioc->input;
322 break;
323
324 case PINMUX_TYPE_INPUT_PULLUP:
325 range = &gpioc->input_pu;
326 break;
327
328 case PINMUX_TYPE_INPUT_PULLDOWN:
329 range = &gpioc->input_pd;
330 break;
331
332 default:
333 goto out_err;
334 }
335
336 pos = 0;
337 enum_id = 0;
338 index = 0;
339 while (1) {
340 pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
341 if (pos <= 0)
342 goto out_err;
343
344 if (!enum_id)
345 break;
346
347 in_range = enum_in_range(enum_id, &gpioc->function);
348 if (!in_range && range) {
349 in_range = enum_in_range(enum_id, range);
350
351 if (in_range && enum_id == range->force)
352 continue;
353 }
354
355 if (!in_range)
356 continue;
357
358 if (get_config_reg(gpioc, enum_id, &cr, &index, &cntp) != 0)
359 goto out_err;
360
361 switch (cfg_mode) {
362 case GPIO_CFG_DRYRUN:
363 if (!*cntp || !check_config_reg(gpioc, cr, index))
364 continue;
365 break;
366
367 case GPIO_CFG_REQ:
368 write_config_reg(gpioc, cr, index);
369 *cntp = *cntp + 1;
370 break;
371
372 case GPIO_CFG_FREE:
373 *cntp = *cntp - 1;
374 break;
375 }
376 }
377
378 return 0;
379 out_err:
380 return -1;
381}
382
383static DEFINE_SPINLOCK(gpio_lock);
384
385static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
386{
387 return container_of(chip, struct pinmux_info, chip);
388}
389
390static int sh_gpio_request(struct gpio_chip *chip, unsigned offset)
391{
392 struct pinmux_info *gpioc = chip_to_pinmux(chip);
393 struct pinmux_data_reg *dummy;
394 unsigned long flags;
395 int i, ret, pinmux_type;
396
397 ret = -EINVAL;
398
399 if (!gpioc)
400 goto err_out;
401
402 spin_lock_irqsave(&gpio_lock, flags);
403
404 if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
405 goto err_unlock;
406
407 /* setup pin function here if no data is associated with pin */
408
409 if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
410 pinmux_type = PINMUX_TYPE_FUNCTION;
411 else
412 pinmux_type = PINMUX_TYPE_GPIO;
413
414 if (pinmux_type == PINMUX_TYPE_FUNCTION) {
415 if (pinmux_config_gpio(gpioc, offset,
416 pinmux_type,
417 GPIO_CFG_DRYRUN) != 0)
418 goto err_unlock;
419
420 if (pinmux_config_gpio(gpioc, offset,
421 pinmux_type,
422 GPIO_CFG_REQ) != 0)
423 BUG();
424 }
425
426 gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
427 gpioc->gpios[offset].flags |= pinmux_type;
428
429 ret = 0;
430 err_unlock:
431 spin_unlock_irqrestore(&gpio_lock, flags);
432 err_out:
433 return ret;
434}
435
436static void sh_gpio_free(struct gpio_chip *chip, unsigned offset)
437{
438 struct pinmux_info *gpioc = chip_to_pinmux(chip);
439 unsigned long flags;
440 int pinmux_type;
441
442 if (!gpioc)
443 return;
444
445 spin_lock_irqsave(&gpio_lock, flags);
446
447 pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
448 pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
449 gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
450 gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
451
452 spin_unlock_irqrestore(&gpio_lock, flags);
453}
454
455static int pinmux_direction(struct pinmux_info *gpioc,
456 unsigned gpio, int new_pinmux_type)
457{
458 int pinmux_type;
459 int ret = -EINVAL;
460
461 if (!gpioc)
462 goto err_out;
463
464 pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
465
466 switch (pinmux_type) {
467 case PINMUX_TYPE_GPIO:
468 break;
469 case PINMUX_TYPE_OUTPUT:
470 case PINMUX_TYPE_INPUT:
471 case PINMUX_TYPE_INPUT_PULLUP:
472 case PINMUX_TYPE_INPUT_PULLDOWN:
473 pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
474 break;
475 default:
476 goto err_out;
477 }
478
479 if (pinmux_config_gpio(gpioc, gpio,
480 new_pinmux_type,
481 GPIO_CFG_DRYRUN) != 0)
482 goto err_out;
483
484 if (pinmux_config_gpio(gpioc, gpio,
485 new_pinmux_type,
486 GPIO_CFG_REQ) != 0)
487 BUG();
488
489 gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
490 gpioc->gpios[gpio].flags |= new_pinmux_type;
491
492 ret = 0;
493 err_out:
494 return ret;
495}
496
497static int sh_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
498{
499 struct pinmux_info *gpioc = chip_to_pinmux(chip);
500 unsigned long flags;
501 int ret;
502
503 spin_lock_irqsave(&gpio_lock, flags);
504 ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
505 spin_unlock_irqrestore(&gpio_lock, flags);
506
507 return ret;
508}
509
510static void sh_gpio_set_value(struct pinmux_info *gpioc,
511 unsigned gpio, int value)
512{
513 struct pinmux_data_reg *dr = NULL;
514 int bit = 0;
515
516 if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
517 BUG();
518 else
519 gpio_write_bit(dr, bit, value);
520}
521
522static int sh_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
523 int value)
524{
525 struct pinmux_info *gpioc = chip_to_pinmux(chip);
526 unsigned long flags;
527 int ret;
528
529 sh_gpio_set_value(gpioc, offset, value);
530 spin_lock_irqsave(&gpio_lock, flags);
531 ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
532 spin_unlock_irqrestore(&gpio_lock, flags);
533
534 return ret;
535}
536
537static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
538{
539 struct pinmux_data_reg *dr = NULL;
540 int bit = 0;
541
542 if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) {
543 BUG();
544 return 0;
545 }
546
547 return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
548}
549
550static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
551{
552 return sh_gpio_get_value(chip_to_pinmux(chip), offset);
553}
554
555static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
556{
557 sh_gpio_set_value(chip_to_pinmux(chip), offset, value);
558}
559
560int register_pinmux(struct pinmux_info *pip)
561{
562 struct gpio_chip *chip = &pip->chip;
563
564 pr_info("sh pinmux: %s handling gpio %d -> %d\n",
565 pip->name, pip->first_gpio, pip->last_gpio);
566
567 setup_data_regs(pip);
568
569 chip->request = sh_gpio_request;
570 chip->free = sh_gpio_free;
571 chip->direction_input = sh_gpio_direction_input;
572 chip->get = sh_gpio_get;
573 chip->direction_output = sh_gpio_direction_output;
574 chip->set = sh_gpio_set;
575
576 WARN_ON(pip->first_gpio != 0); /* needs testing */
577
578 chip->label = pip->name;
579 chip->owner = THIS_MODULE;
580 chip->base = pip->first_gpio;
581 chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
582
583 return gpiochip_add(chip);
584}
diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index a78be74b8d3e..fe0b743881b0 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -3,6 +3,7 @@
3 * arch/sh/kernel/head.S 3 * arch/sh/kernel/head.S
4 * 4 *
5 * Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima 5 * Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
6 * Copyright (C) 2010 Matt Fleming
6 * 7 *
7 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive 9 * License. See the file "COPYING" in the main directory of this archive
@@ -13,6 +14,8 @@
13#include <linux/init.h> 14#include <linux/init.h>
14#include <linux/linkage.h> 15#include <linux/linkage.h>
15#include <asm/thread_info.h> 16#include <asm/thread_info.h>
17#include <asm/mmu.h>
18#include <cpu/mmu_context.h>
16 19
17#ifdef CONFIG_CPU_SH4A 20#ifdef CONFIG_CPU_SH4A
18#define SYNCO() synco 21#define SYNCO() synco
@@ -82,6 +85,209 @@ ENTRY(_stext)
82 ldc r0, r7_bank ! ... and initial thread_info 85 ldc r0, r7_bank ! ... and initial thread_info
83#endif 86#endif
84 87
88#ifdef CONFIG_PMB
89/*
90 * Reconfigure the initial PMB mappings setup by the hardware.
91 *
92 * When we boot in 32-bit MMU mode there are 2 PMB entries already
93 * setup for us.
94 *
95 * Entry VPN PPN V SZ C UB WT
96 * ---------------------------------------------------------------
97 * 0 0x80000000 0x00000000 1 512MB 1 0 1
98 * 1 0xA0000000 0x00000000 1 512MB 0 0 0
99 *
100 * But we reprogram them here because we want complete control over
101 * our address space and the initial mappings may not map PAGE_OFFSET
102 * to __MEMORY_START (or even map all of our RAM).
103 *
104 * Once we've setup cached and uncached mappings we clear the rest of the
105 * PMB entries. This clearing also deals with the fact that PMB entries
106 * can persist across reboots. The PMB could have been left in any state
107 * when the reboot occurred, so to be safe we clear all entries and start
108 * with with a clean slate.
109 *
110 * The uncached mapping is constructed using the smallest possible
111 * mapping with a single unbufferable page. Only the kernel text needs to
112 * be covered via the uncached mapping so that certain functions can be
113 * run uncached.
114 *
115 * Drivers and the like that have previously abused the 1:1 identity
116 * mapping are unsupported in 32-bit mode and must specify their caching
117 * preference when page tables are constructed.
118 *
119 * This frees up the P2 space for more nefarious purposes.
120 *
121 * Register utilization is as follows:
122 *
123 * r0 = PMB_DATA data field
124 * r1 = PMB_DATA address field
125 * r2 = PMB_ADDR data field
126 * r3 = PMB_ADDR address field
127 * r4 = PMB_E_SHIFT
128 * r5 = remaining amount of RAM to map
129 * r6 = PMB mapping size we're trying to use
130 * r7 = cached_to_uncached
131 * r8 = scratch register
132 * r9 = scratch register
133 * r10 = number of PMB entries we've setup
134 */
135
136 mov.l .LMMUCR, r1 /* Flush the TLB */
137 mov.l @r1, r0
138 or #MMUCR_TI, r0
139 mov.l r0, @r1
140
141 mov.l .LMEMORY_SIZE, r5
142
143 mov #PMB_E_SHIFT, r0
144 mov #0x1, r4
145 shld r0, r4
146
147 mov.l .LFIRST_DATA_ENTRY, r0
148 mov.l .LPMB_DATA, r1
149 mov.l .LFIRST_ADDR_ENTRY, r2
150 mov.l .LPMB_ADDR, r3
151
152 /*
153 * First we need to walk the PMB and figure out if there are any
154 * existing mappings that match the initial mappings VPN/PPN.
155 * If these have already been established by the bootloader, we
156 * don't bother setting up new entries here, and let the late PMB
157 * initialization take care of things instead.
158 *
159 * Note that we may need to coalesce and merge entries in order
160 * to reclaim more available PMB slots, which is much more than
161 * we want to do at this early stage.
162 */
163 mov #0, r10
164 mov #NR_PMB_ENTRIES, r9
165
166 mov r1, r7 /* temporary PMB_DATA iter */
167
168.Lvalidate_existing_mappings:
169
170 mov.l @r7, r8
171 and r0, r8
172 cmp/eq r0, r8 /* Check for valid __MEMORY_START mappings */
173 bt .Lpmb_done
174
175 add #1, r10 /* Increment the loop counter */
176 cmp/eq r9, r10
177 bf/s .Lvalidate_existing_mappings
178 add r4, r7 /* Increment to the next PMB_DATA entry */
179
180 /*
181 * If we've fallen through, continue with setting up the initial
182 * mappings.
183 */
184
185 mov r5, r7 /* cached_to_uncached */
186 mov #0, r10
187
188#ifdef CONFIG_UNCACHED_MAPPING
189 /*
190 * Uncached mapping
191 */
192 mov #(PMB_SZ_16M >> 2), r9
193 shll2 r9
194
195 mov #(PMB_UB >> 8), r8
196 shll8 r8
197
198 or r0, r8
199 or r9, r8
200 mov.l r8, @r1
201 mov r2, r8
202 add r7, r8
203 mov.l r8, @r3
204
205 add r4, r1
206 add r4, r3
207 add #1, r10
208#endif
209
210/*
211 * Iterate over all of the available sizes from largest to
212 * smallest for constructing the cached mapping.
213 */
214#define __PMB_ITER_BY_SIZE(size) \
215.L##size: \
216 mov #(size >> 4), r6; \
217 shll16 r6; \
218 shll8 r6; \
219 \
220 cmp/hi r5, r6; \
221 bt 9999f; \
222 \
223 mov #(PMB_SZ_##size##M >> 2), r9; \
224 shll2 r9; \
225 \
226 /* \
227 * Cached mapping \
228 */ \
229 mov #PMB_C, r8; \
230 or r0, r8; \
231 or r9, r8; \
232 mov.l r8, @r1; \
233 mov.l r2, @r3; \
234 \
235 /* Increment to the next PMB_DATA entry */ \
236 add r4, r1; \
237 /* Increment to the next PMB_ADDR entry */ \
238 add r4, r3; \
239 /* Increment number of PMB entries */ \
240 add #1, r10; \
241 \
242 sub r6, r5; \
243 add r6, r0; \
244 add r6, r2; \
245 \
246 bra .L##size; \
2479999:
248
249 __PMB_ITER_BY_SIZE(512)
250 __PMB_ITER_BY_SIZE(128)
251 __PMB_ITER_BY_SIZE(64)
252 __PMB_ITER_BY_SIZE(16)
253
254#ifdef CONFIG_UNCACHED_MAPPING
255 /*
256 * Now that we can access it, update cached_to_uncached and
257 * uncached_size.
258 */
259 mov.l .Lcached_to_uncached, r0
260 mov.l r7, @r0
261
262 mov.l .Luncached_size, r0
263 mov #1, r7
264 shll16 r7
265 shll8 r7
266 mov.l r7, @r0
267#endif
268
269 /*
270 * Clear the remaining PMB entries.
271 *
272 * r3 = entry to begin clearing from
273 * r10 = number of entries we've setup so far
274 */
275 mov #0, r1
276 mov #NR_PMB_ENTRIES, r0
277
278.Lagain:
279 mov.l r1, @r3 /* Clear PMB_ADDR entry */
280 add #1, r10 /* Increment the loop counter */
281 cmp/eq r0, r10
282 bf/s .Lagain
283 add r4, r3 /* Increment to the next PMB_ADDR entry */
284
285 mov.l 6f, r0
286 icbi @r0
287
288.Lpmb_done:
289#endif /* CONFIG_PMB */
290
85#ifndef CONFIG_SH_NO_BSS_INIT 291#ifndef CONFIG_SH_NO_BSS_INIT
86 /* 292 /*
87 * Don't clear BSS if running on slow platforms such as an RTL simulation, 293 * Don't clear BSS if running on slow platforms such as an RTL simulation,
@@ -131,3 +337,16 @@ ENTRY(stack_start)
1315: .long start_kernel 3375: .long start_kernel
1326: .long sh_cpu_init 3386: .long sh_cpu_init
1337: .long init_thread_union 3397: .long init_thread_union
340
341#ifdef CONFIG_PMB
342.LPMB_ADDR: .long PMB_ADDR
343.LPMB_DATA: .long PMB_DATA
344.LFIRST_ADDR_ENTRY: .long PAGE_OFFSET | PMB_V
345.LFIRST_DATA_ENTRY: .long __MEMORY_START | PMB_V
346.LMMUCR: .long MMUCR
347.LMEMORY_SIZE: .long __MEMORY_SIZE
348#ifdef CONFIG_UNCACHED_MAPPING
349.Lcached_to_uncached: .long cached_to_uncached
350.Luncached_size: .long uncached_size
351#endif
352#endif
diff --git a/arch/sh/kernel/head_64.S b/arch/sh/kernel/head_64.S
index 3ea765844c74..defd851abefa 100644
--- a/arch/sh/kernel/head_64.S
+++ b/arch/sh/kernel/head_64.S
@@ -220,7 +220,6 @@ clear_DTLB:
220 add.l r22, r63, r22 /* Sign extend */ 220 add.l r22, r63, r22 /* Sign extend */
221 putcfg r21, 0, r22 /* Set MMUDR[0].PTEH */ 221 putcfg r21, 0, r22 /* Set MMUDR[0].PTEH */
222 222
223#ifdef CONFIG_EARLY_PRINTK
224 /* 223 /*
225 * Setup a DTLB translation for SCIF phys. 224 * Setup a DTLB translation for SCIF phys.
226 */ 225 */
@@ -231,7 +230,6 @@ clear_DTLB:
231 movi 0xfa03, r22 /* 0xfa030000, fixed SCIF virt */ 230 movi 0xfa03, r22 /* 0xfa030000, fixed SCIF virt */
232 shori 0x0003, r22 231 shori 0x0003, r22
233 putcfg r21, 0, r22 /* PTEH last */ 232 putcfg r21, 0, r22 /* PTEH last */
234#endif
235 233
236 /* 234 /*
237 * Set cache behaviours. 235 * Set cache behaviours.
diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c
new file mode 100644
index 000000000000..675eea7785d9
--- /dev/null
+++ b/arch/sh/kernel/hw_breakpoint.c
@@ -0,0 +1,445 @@
1/*
2 * arch/sh/kernel/hw_breakpoint.c
3 *
4 * Unified kernel/user-space hardware breakpoint facility for the on-chip UBC.
5 *
6 * Copyright (C) 2009 - 2010 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/perf_event.h>
14#include <linux/hw_breakpoint.h>
15#include <linux/percpu.h>
16#include <linux/kallsyms.h>
17#include <linux/notifier.h>
18#include <linux/kprobes.h>
19#include <linux/kdebug.h>
20#include <linux/io.h>
21#include <linux/clk.h>
22#include <asm/hw_breakpoint.h>
23#include <asm/mmu_context.h>
24#include <asm/ptrace.h>
25
26/*
27 * Stores the breakpoints currently in use on each breakpoint address
28 * register for each cpus
29 */
30static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]);
31
32/*
33 * A dummy placeholder for early accesses until the CPUs get a chance to
34 * register their UBCs later in the boot process.
35 */
36static struct sh_ubc ubc_dummy = { .num_events = 0 };
37
38static struct sh_ubc *sh_ubc __read_mostly = &ubc_dummy;
39
40/*
41 * Install a perf counter breakpoint.
42 *
43 * We seek a free UBC channel and use it for this breakpoint.
44 *
45 * Atomic: we hold the counter->ctx->lock and we only handle variables
46 * and registers local to this cpu.
47 */
48int arch_install_hw_breakpoint(struct perf_event *bp)
49{
50 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
51 int i;
52
53 for (i = 0; i < sh_ubc->num_events; i++) {
54 struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
55
56 if (!*slot) {
57 *slot = bp;
58 break;
59 }
60 }
61
62 if (WARN_ONCE(i == sh_ubc->num_events, "Can't find any breakpoint slot"))
63 return -EBUSY;
64
65 clk_enable(sh_ubc->clk);
66 sh_ubc->enable(info, i);
67
68 return 0;
69}
70
71/*
72 * Uninstall the breakpoint contained in the given counter.
73 *
74 * First we search the debug address register it uses and then we disable
75 * it.
76 *
77 * Atomic: we hold the counter->ctx->lock and we only handle variables
78 * and registers local to this cpu.
79 */
80void arch_uninstall_hw_breakpoint(struct perf_event *bp)
81{
82 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
83 int i;
84
85 for (i = 0; i < sh_ubc->num_events; i++) {
86 struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
87
88 if (*slot == bp) {
89 *slot = NULL;
90 break;
91 }
92 }
93
94 if (WARN_ONCE(i == sh_ubc->num_events, "Can't find any breakpoint slot"))
95 return;
96
97 sh_ubc->disable(info, i);
98 clk_disable(sh_ubc->clk);
99}
100
101static int get_hbp_len(u16 hbp_len)
102{
103 unsigned int len_in_bytes = 0;
104
105 switch (hbp_len) {
106 case SH_BREAKPOINT_LEN_1:
107 len_in_bytes = 1;
108 break;
109 case SH_BREAKPOINT_LEN_2:
110 len_in_bytes = 2;
111 break;
112 case SH_BREAKPOINT_LEN_4:
113 len_in_bytes = 4;
114 break;
115 case SH_BREAKPOINT_LEN_8:
116 len_in_bytes = 8;
117 break;
118 }
119 return len_in_bytes;
120}
121
122/*
123 * Check for virtual address in user space.
124 */
125int arch_check_va_in_userspace(unsigned long va, u16 hbp_len)
126{
127 unsigned int len;
128
129 len = get_hbp_len(hbp_len);
130
131 return (va <= TASK_SIZE - len);
132}
133
134/*
135 * Check for virtual address in kernel space.
136 */
137static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
138{
139 unsigned int len;
140
141 len = get_hbp_len(hbp_len);
142
143 return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
144}
145
146int arch_bp_generic_fields(int sh_len, int sh_type,
147 int *gen_len, int *gen_type)
148{
149 /* Len */
150 switch (sh_len) {
151 case SH_BREAKPOINT_LEN_1:
152 *gen_len = HW_BREAKPOINT_LEN_1;
153 break;
154 case SH_BREAKPOINT_LEN_2:
155 *gen_len = HW_BREAKPOINT_LEN_2;
156 break;
157 case SH_BREAKPOINT_LEN_4:
158 *gen_len = HW_BREAKPOINT_LEN_4;
159 break;
160 case SH_BREAKPOINT_LEN_8:
161 *gen_len = HW_BREAKPOINT_LEN_8;
162 break;
163 default:
164 return -EINVAL;
165 }
166
167 /* Type */
168 switch (sh_type) {
169 case SH_BREAKPOINT_READ:
170 *gen_type = HW_BREAKPOINT_R;
171 case SH_BREAKPOINT_WRITE:
172 *gen_type = HW_BREAKPOINT_W;
173 break;
174 case SH_BREAKPOINT_RW:
175 *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
176 break;
177 default:
178 return -EINVAL;
179 }
180
181 return 0;
182}
183
184static int arch_build_bp_info(struct perf_event *bp)
185{
186 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
187
188 info->address = bp->attr.bp_addr;
189
190 /* Len */
191 switch (bp->attr.bp_len) {
192 case HW_BREAKPOINT_LEN_1:
193 info->len = SH_BREAKPOINT_LEN_1;
194 break;
195 case HW_BREAKPOINT_LEN_2:
196 info->len = SH_BREAKPOINT_LEN_2;
197 break;
198 case HW_BREAKPOINT_LEN_4:
199 info->len = SH_BREAKPOINT_LEN_4;
200 break;
201 case HW_BREAKPOINT_LEN_8:
202 info->len = SH_BREAKPOINT_LEN_8;
203 break;
204 default:
205 return -EINVAL;
206 }
207
208 /* Type */
209 switch (bp->attr.bp_type) {
210 case HW_BREAKPOINT_R:
211 info->type = SH_BREAKPOINT_READ;
212 break;
213 case HW_BREAKPOINT_W:
214 info->type = SH_BREAKPOINT_WRITE;
215 break;
216 case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
217 info->type = SH_BREAKPOINT_RW;
218 break;
219 default:
220 return -EINVAL;
221 }
222
223 return 0;
224}
225
226/*
227 * Validate the arch-specific HW Breakpoint register settings
228 */
229int arch_validate_hwbkpt_settings(struct perf_event *bp,
230 struct task_struct *tsk)
231{
232 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
233 unsigned int align;
234 int ret;
235
236 ret = arch_build_bp_info(bp);
237 if (ret)
238 return ret;
239
240 ret = -EINVAL;
241
242 switch (info->len) {
243 case SH_BREAKPOINT_LEN_1:
244 align = 0;
245 break;
246 case SH_BREAKPOINT_LEN_2:
247 align = 1;
248 break;
249 case SH_BREAKPOINT_LEN_4:
250 align = 3;
251 break;
252 case SH_BREAKPOINT_LEN_8:
253 align = 7;
254 break;
255 default:
256 return ret;
257 }
258
259 /*
260 * For kernel-addresses, either the address or symbol name can be
261 * specified.
262 */
263 if (info->name)
264 info->address = (unsigned long)kallsyms_lookup_name(info->name);
265
266 /*
267 * Check that the low-order bits of the address are appropriate
268 * for the alignment implied by len.
269 */
270 if (info->address & align)
271 return -EINVAL;
272
273 /* Check that the virtual address is in the proper range */
274 if (tsk) {
275 if (!arch_check_va_in_userspace(info->address, info->len))
276 return -EFAULT;
277 } else {
278 if (!arch_check_va_in_kernelspace(info->address, info->len))
279 return -EFAULT;
280 }
281
282 return 0;
283}
284
285/*
286 * Release the user breakpoints used by ptrace
287 */
288void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
289{
290 int i;
291 struct thread_struct *t = &tsk->thread;
292
293 for (i = 0; i < sh_ubc->num_events; i++) {
294 unregister_hw_breakpoint(t->ptrace_bps[i]);
295 t->ptrace_bps[i] = NULL;
296 }
297}
298
299static int __kprobes hw_breakpoint_handler(struct die_args *args)
300{
301 int cpu, i, rc = NOTIFY_STOP;
302 struct perf_event *bp;
303 unsigned int cmf, resume_mask;
304
305 /*
306 * Do an early return if none of the channels triggered.
307 */
308 cmf = sh_ubc->triggered_mask();
309 if (unlikely(!cmf))
310 return NOTIFY_DONE;
311
312 /*
313 * By default, resume all of the active channels.
314 */
315 resume_mask = sh_ubc->active_mask();
316
317 /*
318 * Disable breakpoints during exception handling.
319 */
320 sh_ubc->disable_all();
321
322 cpu = get_cpu();
323 for (i = 0; i < sh_ubc->num_events; i++) {
324 unsigned long event_mask = (1 << i);
325
326 if (likely(!(cmf & event_mask)))
327 continue;
328
329 /*
330 * The counter may be concurrently released but that can only
331 * occur from a call_rcu() path. We can then safely fetch
332 * the breakpoint, use its callback, touch its counter
333 * while we are in an rcu_read_lock() path.
334 */
335 rcu_read_lock();
336
337 bp = per_cpu(bp_per_reg[i], cpu);
338 if (bp)
339 rc = NOTIFY_DONE;
340
341 /*
342 * Reset the condition match flag to denote completion of
343 * exception handling.
344 */
345 sh_ubc->clear_triggered_mask(event_mask);
346
347 /*
348 * bp can be NULL due to concurrent perf counter
349 * removing.
350 */
351 if (!bp) {
352 rcu_read_unlock();
353 break;
354 }
355
356 /*
357 * Don't restore the channel if the breakpoint is from
358 * ptrace, as it always operates in one-shot mode.
359 */
360 if (bp->overflow_handler == ptrace_triggered)
361 resume_mask &= ~(1 << i);
362
363 perf_bp_event(bp, args->regs);
364
365 /* Deliver the signal to userspace */
366 if (arch_check_va_in_userspace(bp->attr.bp_addr,
367 bp->attr.bp_len)) {
368 siginfo_t info;
369
370 info.si_signo = args->signr;
371 info.si_errno = notifier_to_errno(rc);
372 info.si_code = TRAP_HWBKPT;
373
374 force_sig_info(args->signr, &info, current);
375 }
376
377 rcu_read_unlock();
378 }
379
380 if (cmf == 0)
381 rc = NOTIFY_DONE;
382
383 sh_ubc->enable_all(resume_mask);
384
385 put_cpu();
386
387 return rc;
388}
389
390BUILD_TRAP_HANDLER(breakpoint)
391{
392 unsigned long ex = lookup_exception_vector();
393 TRAP_HANDLER_DECL;
394
395 notify_die(DIE_BREAKPOINT, "breakpoint", regs, 0, ex, SIGTRAP);
396}
397
398/*
399 * Handle debug exception notifications.
400 */
401int __kprobes hw_breakpoint_exceptions_notify(struct notifier_block *unused,
402 unsigned long val, void *data)
403{
404 struct die_args *args = data;
405
406 if (val != DIE_BREAKPOINT)
407 return NOTIFY_DONE;
408
409 /*
410 * If the breakpoint hasn't been triggered by the UBC, it's
411 * probably from a debugger, so don't do anything more here.
412 *
413 * This also permits the UBC interface clock to remain off for
414 * non-UBC breakpoints, as we don't need to check the triggered
415 * or active channel masks.
416 */
417 if (args->trapnr != sh_ubc->trap_nr)
418 return NOTIFY_DONE;
419
420 return hw_breakpoint_handler(data);
421}
422
423void hw_breakpoint_pmu_read(struct perf_event *bp)
424{
425 /* TODO */
426}
427
428void hw_breakpoint_pmu_unthrottle(struct perf_event *bp)
429{
430 /* TODO */
431}
432
433int register_sh_ubc(struct sh_ubc *ubc)
434{
435 /* Bail if it's already assigned */
436 if (sh_ubc != &ubc_dummy)
437 return -EBUSY;
438 sh_ubc = ubc;
439
440 pr_info("HW Breakpoints: %s UBC support registered\n", ubc->name);
441
442 WARN_ON(ubc->num_events > HBP_NUM);
443
444 return 0;
445}
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index 27ff2dc093c7..273f890b17ae 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -20,10 +20,9 @@
20#include <asm/system.h> 20#include <asm/system.h>
21#include <asm/atomic.h> 21#include <asm/atomic.h>
22 22
23void (*pm_idle)(void) = NULL;
24
23static int hlt_counter; 25static int hlt_counter;
24void (*pm_idle)(void);
25void (*pm_power_off)(void);
26EXPORT_SYMBOL(pm_power_off);
27 26
28static int __init nohlt_setup(char *__unused) 27static int __init nohlt_setup(char *__unused)
29{ 28{
@@ -39,52 +38,107 @@ static int __init hlt_setup(char *__unused)
39} 38}
40__setup("hlt", hlt_setup); 39__setup("hlt", hlt_setup);
41 40
41static inline int hlt_works(void)
42{
43 return !hlt_counter;
44}
45
46/*
47 * On SMP it's slightly faster (but much more power-consuming!)
48 * to poll the ->work.need_resched flag instead of waiting for the
49 * cross-CPU IPI to arrive. Use this option with caution.
50 */
51static void poll_idle(void)
52{
53 local_irq_enable();
54 while (!need_resched())
55 cpu_relax();
56}
57
42void default_idle(void) 58void default_idle(void)
43{ 59{
44 if (!hlt_counter) { 60 if (hlt_works()) {
45 clear_thread_flag(TIF_POLLING_NRFLAG); 61 clear_thread_flag(TIF_POLLING_NRFLAG);
46 smp_mb__after_clear_bit(); 62 smp_mb__after_clear_bit();
47 set_bl_bit();
48 stop_critical_timings();
49 63
50 while (!need_resched()) 64 set_bl_bit();
65 if (!need_resched()) {
66 local_irq_enable();
51 cpu_sleep(); 67 cpu_sleep();
68 } else
69 local_irq_enable();
52 70
53 start_critical_timings();
54 clear_bl_bit();
55 set_thread_flag(TIF_POLLING_NRFLAG); 71 set_thread_flag(TIF_POLLING_NRFLAG);
72 clear_bl_bit();
56 } else 73 } else
57 while (!need_resched()) 74 poll_idle();
58 cpu_relax();
59} 75}
60 76
77/*
78 * The idle thread. There's no useful work to be done, so just try to conserve
79 * power and have a low exit latency (ie sit in a loop waiting for somebody to
80 * say that they'd like to reschedule)
81 */
61void cpu_idle(void) 82void cpu_idle(void)
62{ 83{
84 unsigned int cpu = smp_processor_id();
85
63 set_thread_flag(TIF_POLLING_NRFLAG); 86 set_thread_flag(TIF_POLLING_NRFLAG);
64 87
65 /* endless idle loop with no priority at all */ 88 /* endless idle loop with no priority at all */
66 while (1) { 89 while (1) {
67 void (*idle)(void) = pm_idle; 90 tick_nohz_stop_sched_tick(1);
68 91
69 if (!idle) 92 while (!need_resched() && cpu_online(cpu)) {
70 idle = default_idle; 93 check_pgt_cache();
94 rmb();
71 95
72 tick_nohz_stop_sched_tick(1); 96 local_irq_disable();
73 while (!need_resched()) 97 /* Don't trace irqs off for idle */
74 idle(); 98 stop_critical_timings();
75 tick_nohz_restart_sched_tick(); 99 pm_idle();
100 /*
101 * Sanity check to ensure that pm_idle() returns
102 * with IRQs enabled
103 */
104 WARN_ON(irqs_disabled());
105 start_critical_timings();
106 }
76 107
108 tick_nohz_restart_sched_tick();
77 preempt_enable_no_resched(); 109 preempt_enable_no_resched();
78 schedule(); 110 schedule();
79 preempt_disable(); 111 preempt_disable();
80 check_pgt_cache();
81 } 112 }
82} 113}
83 114
115void __init select_idle_routine(void)
116{
117 /*
118 * If a platform has set its own idle routine, leave it alone.
119 */
120 if (pm_idle)
121 return;
122
123 if (hlt_works())
124 pm_idle = default_idle;
125 else
126 pm_idle = poll_idle;
127}
128
84static void do_nothing(void *unused) 129static void do_nothing(void *unused)
85{ 130{
86} 131}
87 132
133void stop_this_cpu(void *unused)
134{
135 local_irq_disable();
136 cpu_clear(smp_processor_id(), cpu_online_map);
137
138 for (;;)
139 cpu_sleep();
140}
141
88/* 142/*
89 * cpu_idle_wait - Used to ensure that all the CPUs discard old value of 143 * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
90 * pm_idle and update to new pm_idle value. Required while changing pm_idle 144 * pm_idle and update to new pm_idle value. Required while changing pm_idle
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index b8fa6524760a..e1e1dbd19557 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -24,7 +24,7 @@
24#define dummy_read() 24#define dummy_read()
25#endif 25#endif
26 26
27unsigned long generic_io_base; 27unsigned long generic_io_base = 0;
28 28
29u8 generic_inb(unsigned long port) 29u8 generic_inb(unsigned long port)
30{ 30{
@@ -147,8 +147,10 @@ void generic_outsl(unsigned long port, const void *src, unsigned long count)
147 147
148void __iomem *generic_ioport_map(unsigned long addr, unsigned int size) 148void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
149{ 149{
150#ifdef P1SEG
150 if (PXSEG(addr) >= P1SEG) 151 if (PXSEG(addr) >= P1SEG)
151 return (void __iomem *)addr; 152 return (void __iomem *)addr;
153#endif
152 154
153 return (void __iomem *)(addr + generic_io_base); 155 return (void __iomem *)(addr + generic_io_base);
154} 156}
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index 69be603aa2d7..4a8bb4eeb8ad 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -184,31 +184,31 @@ static unsigned long long copy_word(unsigned long src_addr, int src_len,
184 184
185 switch (src_len) { 185 switch (src_len) {
186 case 1: 186 case 1:
187 tmp = ctrl_inb(src_addr); 187 tmp = __raw_readb(src_addr);
188 break; 188 break;
189 case 2: 189 case 2:
190 tmp = ctrl_inw(src_addr); 190 tmp = __raw_readw(src_addr);
191 break; 191 break;
192 case 4: 192 case 4:
193 tmp = ctrl_inl(src_addr); 193 tmp = __raw_readl(src_addr);
194 break; 194 break;
195 case 8: 195 case 8:
196 tmp = ctrl_inq(src_addr); 196 tmp = __raw_readq(src_addr);
197 break; 197 break;
198 } 198 }
199 199
200 switch (dst_len) { 200 switch (dst_len) {
201 case 1: 201 case 1:
202 ctrl_outb(tmp, dst_addr); 202 __raw_writeb(tmp, dst_addr);
203 break; 203 break;
204 case 2: 204 case 2:
205 ctrl_outw(tmp, dst_addr); 205 __raw_writew(tmp, dst_addr);
206 break; 206 break;
207 case 4: 207 case 4:
208 ctrl_outl(tmp, dst_addr); 208 __raw_writel(tmp, dst_addr);
209 break; 209 break;
210 case 8: 210 case 8:
211 ctrl_outq(tmp, dst_addr); 211 __raw_writeq(tmp, dst_addr);
212 break; 212 break;
213 } 213 }
214 214
@@ -271,6 +271,8 @@ int handle_trapped_io(struct pt_regs *regs, unsigned long address)
271 insn_size_t instruction; 271 insn_size_t instruction;
272 int tmp; 272 int tmp;
273 273
274 if (trapped_io_disable)
275 return 0;
274 if (!lookup_tiop(address)) 276 if (!lookup_tiop(address))
275 return 0; 277 return 0;
276 278
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index eac7da772fc2..d2d41d046657 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -37,7 +37,15 @@ void ack_bad_irq(unsigned int irq)
37 */ 37 */
38static int show_other_interrupts(struct seq_file *p, int prec) 38static int show_other_interrupts(struct seq_file *p, int prec)
39{ 39{
40 int j;
41
42 seq_printf(p, "%*s: ", prec, "NMI");
43 for_each_online_cpu(j)
44 seq_printf(p, "%10u ", irq_stat[j].__nmi_count);
45 seq_printf(p, " Non-maskable interrupts\n");
46
40 seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); 47 seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
48
41 return 0; 49 return 0;
42} 50}
43 51
@@ -68,7 +76,7 @@ int show_interrupts(struct seq_file *p, void *v)
68 if (!desc) 76 if (!desc)
69 return 0; 77 return 0;
70 78
71 spin_lock_irqsave(&desc->lock, flags); 79 raw_spin_lock_irqsave(&desc->lock, flags);
72 for_each_online_cpu(j) 80 for_each_online_cpu(j)
73 any_count |= kstat_irqs_cpu(i, j); 81 any_count |= kstat_irqs_cpu(i, j);
74 action = desc->action; 82 action = desc->action;
@@ -89,7 +97,7 @@ int show_interrupts(struct seq_file *p, void *v)
89 97
90 seq_putc(p, '\n'); 98 seq_putc(p, '\n');
91out: 99out:
92 spin_unlock_irqrestore(&desc->lock, flags); 100 raw_spin_unlock_irqrestore(&desc->lock, flags);
93 return 0; 101 return 0;
94} 102}
95#endif 103#endif
@@ -255,6 +263,12 @@ void __init init_IRQ(void)
255{ 263{
256 plat_irq_setup(); 264 plat_irq_setup();
257 265
266 /*
267 * Pin any of the legacy IRQ vectors that haven't already been
268 * grabbed by the platform
269 */
270 reserve_irq_legacy();
271
258 /* Perform the machine specific initialisation */ 272 /* Perform the machine specific initialisation */
259 if (sh_mv.mv_init_irq) 273 if (sh_mv.mv_init_irq)
260 sh_mv.mv_init_irq(); 274 sh_mv.mv_init_irq();
diff --git a/arch/sh/kernel/irq_32.c b/arch/sh/kernel/irq_32.c
new file mode 100644
index 000000000000..e33ab15831f9
--- /dev/null
+++ b/arch/sh/kernel/irq_32.c
@@ -0,0 +1,57 @@
1/*
2 * SHcompact irqflags support
3 *
4 * Copyright (C) 2006 - 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/irqflags.h>
11#include <linux/module.h>
12
13void notrace raw_local_irq_restore(unsigned long flags)
14{
15 unsigned long __dummy0, __dummy1;
16
17 if (flags == RAW_IRQ_DISABLED) {
18 __asm__ __volatile__ (
19 "stc sr, %0\n\t"
20 "or #0xf0, %0\n\t"
21 "ldc %0, sr\n\t"
22 : "=&z" (__dummy0)
23 : /* no inputs */
24 : "memory"
25 );
26 } else {
27 __asm__ __volatile__ (
28 "stc sr, %0\n\t"
29 "and %1, %0\n\t"
30#ifdef CONFIG_CPU_HAS_SR_RB
31 "stc r6_bank, %1\n\t"
32 "or %1, %0\n\t"
33#endif
34 "ldc %0, sr\n\t"
35 : "=&r" (__dummy0), "=r" (__dummy1)
36 : "1" (~RAW_IRQ_DISABLED)
37 : "memory"
38 );
39 }
40}
41EXPORT_SYMBOL(raw_local_irq_restore);
42
43unsigned long notrace __raw_local_save_flags(void)
44{
45 unsigned long flags;
46
47 __asm__ __volatile__ (
48 "stc sr, %0\n\t"
49 "and #0xf0, %0\n\t"
50 : "=&z" (flags)
51 : /* no inputs */
52 : "memory"
53 );
54
55 return flags;
56}
57EXPORT_SYMBOL(__raw_local_save_flags);
diff --git a/arch/sh/kernel/irq_64.c b/arch/sh/kernel/irq_64.c
new file mode 100644
index 000000000000..32365ba0e039
--- /dev/null
+++ b/arch/sh/kernel/irq_64.c
@@ -0,0 +1,51 @@
1/*
2 * SHmedia irqflags support
3 *
4 * Copyright (C) 2006 - 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/irqflags.h>
11#include <linux/module.h>
12#include <cpu/registers.h>
13
14void notrace raw_local_irq_restore(unsigned long flags)
15{
16 unsigned long long __dummy;
17
18 if (flags == RAW_IRQ_DISABLED) {
19 __asm__ __volatile__ (
20 "getcon " __SR ", %0\n\t"
21 "or %0, %1, %0\n\t"
22 "putcon %0, " __SR "\n\t"
23 : "=&r" (__dummy)
24 : "r" (RAW_IRQ_DISABLED)
25 );
26 } else {
27 __asm__ __volatile__ (
28 "getcon " __SR ", %0\n\t"
29 "and %0, %1, %0\n\t"
30 "putcon %0, " __SR "\n\t"
31 : "=&r" (__dummy)
32 : "r" (~RAW_IRQ_DISABLED)
33 );
34 }
35}
36EXPORT_SYMBOL(raw_local_irq_restore);
37
38unsigned long notrace __raw_local_save_flags(void)
39{
40 unsigned long flags;
41
42 __asm__ __volatile__ (
43 "getcon " __SR ", %0\n\t"
44 "and %0, %1, %0"
45 : "=&r" (flags)
46 : "r" (RAW_IRQ_DISABLED)
47 );
48
49 return flags;
50}
51EXPORT_SYMBOL(__raw_local_save_flags);
diff --git a/arch/sh/kernel/kgdb.c b/arch/sh/kernel/kgdb.c
index 3e532d0d4a5c..70c69659b846 100644
--- a/arch/sh/kernel/kgdb.c
+++ b/arch/sh/kernel/kgdb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SuperH KGDB support 2 * SuperH KGDB support
3 * 3 *
4 * Copyright (C) 2008 Paul Mundt 4 * Copyright (C) 2008 - 2009 Paul Mundt
5 * 5 *
6 * Single stepping taken from the old stub by Henry Bell and Jeremy Siegel. 6 * Single stepping taken from the old stub by Henry Bell and Jeremy Siegel.
7 * 7 *
@@ -251,24 +251,60 @@ BUILD_TRAP_HANDLER(singlestep)
251 local_irq_restore(flags); 251 local_irq_restore(flags);
252} 252}
253 253
254static int __kgdb_notify(struct die_args *args, unsigned long cmd)
255{
256 int ret;
257
258 switch (cmd) {
259 case DIE_BREAKPOINT:
260 /*
261 * This means a user thread is single stepping
262 * a system call which should be ignored
263 */
264 if (test_thread_flag(TIF_SINGLESTEP))
265 return NOTIFY_DONE;
266
267 ret = kgdb_handle_exception(args->trapnr & 0xff, args->signr,
268 args->err, args->regs);
269 if (ret)
270 return NOTIFY_DONE;
271
272 break;
273 }
254 274
255BUILD_TRAP_HANDLER(breakpoint) 275 return NOTIFY_STOP;
276}
277
278static int
279kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
256{ 280{
257 unsigned long flags; 281 unsigned long flags;
258 TRAP_HANDLER_DECL; 282 int ret;
259 283
260 local_irq_save(flags); 284 local_irq_save(flags);
261 kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs); 285 ret = __kgdb_notify(ptr, cmd);
262 local_irq_restore(flags); 286 local_irq_restore(flags);
287
288 return ret;
263} 289}
264 290
291static struct notifier_block kgdb_notifier = {
292 .notifier_call = kgdb_notify,
293
294 /*
295 * Lowest-prio notifier priority, we want to be notified last:
296 */
297 .priority = -INT_MAX,
298};
299
265int kgdb_arch_init(void) 300int kgdb_arch_init(void)
266{ 301{
267 return 0; 302 return register_die_notifier(&kgdb_notifier);
268} 303}
269 304
270void kgdb_arch_exit(void) 305void kgdb_arch_exit(void)
271{ 306{
307 unregister_die_notifier(&kgdb_notifier);
272} 308}
273 309
274struct kgdb_arch arch_kgdb_ops = { 310struct kgdb_arch arch_kgdb_ops = {
diff --git a/arch/sh/kernel/kprobes.c b/arch/sh/kernel/kprobes.c
index c96850b061fb..4049d99f76e1 100644
--- a/arch/sh/kernel/kprobes.c
+++ b/arch/sh/kernel/kprobes.c
@@ -13,6 +13,7 @@
13#include <linux/ptrace.h> 13#include <linux/ptrace.h>
14#include <linux/preempt.h> 14#include <linux/preempt.h>
15#include <linux/kdebug.h> 15#include <linux/kdebug.h>
16#include <linux/slab.h>
16#include <asm/cacheflush.h> 17#include <asm/cacheflush.h>
17#include <asm/uaccess.h> 18#include <asm/uaccess.h>
18 19
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index 7ea2704ea033..7672141c841b 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -21,6 +21,8 @@
21#include <asm/mmu_context.h> 21#include <asm/mmu_context.h>
22#include <asm/io.h> 22#include <asm/io.h>
23#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
24#include <asm/sh_bios.h>
25#include <asm/reboot.h>
24 26
25typedef void (*relocate_new_kernel_t)(unsigned long indirection_page, 27typedef void (*relocate_new_kernel_t)(unsigned long indirection_page,
26 unsigned long reboot_code_buffer, 28 unsigned long reboot_code_buffer,
@@ -28,15 +30,11 @@ typedef void (*relocate_new_kernel_t)(unsigned long indirection_page,
28 30
29extern const unsigned char relocate_new_kernel[]; 31extern const unsigned char relocate_new_kernel[];
30extern const unsigned int relocate_new_kernel_size; 32extern const unsigned int relocate_new_kernel_size;
31extern void *gdb_vbr_vector;
32extern void *vbr_base; 33extern void *vbr_base;
33 34
34void machine_shutdown(void) 35void native_machine_crash_shutdown(struct pt_regs *regs)
35{
36}
37
38void machine_crash_shutdown(struct pt_regs *regs)
39{ 36{
37 /* Nothing to do for UP, but definitely broken for SMP.. */
40} 38}
41 39
42/* 40/*
@@ -46,12 +44,6 @@ void machine_crash_shutdown(struct pt_regs *regs)
46 */ 44 */
47int machine_kexec_prepare(struct kimage *image) 45int machine_kexec_prepare(struct kimage *image)
48{ 46{
49 /* older versions of kexec-tools are passing
50 * the zImage entry point as a virtual address.
51 */
52 if (image->start != PHYSADDR(image->start))
53 return -EINVAL; /* upgrade your kexec-tools */
54
55 return 0; 47 return 0;
56} 48}
57 49
@@ -123,11 +115,7 @@ void machine_kexec(struct kimage *image)
123 kexec_info(image); 115 kexec_info(image);
124 flush_cache_all(); 116 flush_cache_all();
125 117
126#if defined(CONFIG_SH_STANDARD_BIOS) 118 sh_bios_vbr_reload();
127 asm volatile("ldc %0, vbr" :
128 : "r" (((unsigned long) gdb_vbr_vector) - 0x100)
129 : "memory");
130#endif
131 119
132 /* now call it */ 120 /* now call it */
133 rnk = (relocate_new_kernel_t) reboot_code_buffer; 121 rnk = (relocate_new_kernel_t) reboot_code_buffer;
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
index cbce639b108a..1652340ba3f2 100644
--- a/arch/sh/kernel/machvec.c
+++ b/arch/sh/kernel/machvec.c
@@ -135,5 +135,9 @@ void __init sh_mv_setup(void)
135 if (!sh_mv.mv_nr_irqs) 135 if (!sh_mv.mv_nr_irqs)
136 sh_mv.mv_nr_irqs = NR_IRQS; 136 sh_mv.mv_nr_irqs = NR_IRQS;
137 137
138#ifdef P2SEG
138 __set_io_port_base(P2SEG); 139 __set_io_port_base(P2SEG);
140#else
141 __set_io_port_base(0);
142#endif
139} 143}
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c
index c2efdcde266f..43adddfe4c04 100644
--- a/arch/sh/kernel/module.c
+++ b/arch/sh/kernel/module.c
@@ -32,6 +32,7 @@
32#include <linux/string.h> 32#include <linux/string.h>
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <asm/unaligned.h> 34#include <asm/unaligned.h>
35#include <asm/dwarf.h>
35 36
36void *module_alloc(unsigned long size) 37void *module_alloc(unsigned long size)
37{ 38{
@@ -145,10 +146,16 @@ int module_finalize(const Elf_Ehdr *hdr,
145 const Elf_Shdr *sechdrs, 146 const Elf_Shdr *sechdrs,
146 struct module *me) 147 struct module *me)
147{ 148{
148 return module_bug_finalize(hdr, sechdrs, me); 149 int ret = 0;
150
151 ret |= module_dwarf_finalize(hdr, sechdrs, me);
152 ret |= module_bug_finalize(hdr, sechdrs, me);
153
154 return ret;
149} 155}
150 156
151void module_arch_cleanup(struct module *mod) 157void module_arch_cleanup(struct module *mod)
152{ 158{
153 module_bug_cleanup(mod); 159 module_bug_cleanup(mod);
160 module_dwarf_cleanup(mod);
154} 161}
diff --git a/arch/sh/kernel/perf_callchain.c b/arch/sh/kernel/perf_callchain.c
new file mode 100644
index 000000000000..a9dd3abde28e
--- /dev/null
+++ b/arch/sh/kernel/perf_callchain.c
@@ -0,0 +1,95 @@
1/*
2 * Performance event callchain support - SuperH architecture code
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/sched.h>
12#include <linux/perf_event.h>
13#include <linux/percpu.h>
14#include <asm/unwinder.h>
15#include <asm/ptrace.h>
16
17static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip)
18{
19 if (entry->nr < PERF_MAX_STACK_DEPTH)
20 entry->ip[entry->nr++] = ip;
21}
22
23static void callchain_warning(void *data, char *msg)
24{
25}
26
27static void
28callchain_warning_symbol(void *data, char *msg, unsigned long symbol)
29{
30}
31
32static int callchain_stack(void *data, char *name)
33{
34 return 0;
35}
36
37static void callchain_address(void *data, unsigned long addr, int reliable)
38{
39 struct perf_callchain_entry *entry = data;
40
41 if (reliable)
42 callchain_store(entry, addr);
43}
44
45static const struct stacktrace_ops callchain_ops = {
46 .warning = callchain_warning,
47 .warning_symbol = callchain_warning_symbol,
48 .stack = callchain_stack,
49 .address = callchain_address,
50};
51
52static void
53perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)
54{
55 callchain_store(entry, PERF_CONTEXT_KERNEL);
56 callchain_store(entry, regs->pc);
57
58 unwind_stack(NULL, regs, NULL, &callchain_ops, entry);
59}
60
61static void
62perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry)
63{
64 int is_user;
65
66 if (!regs)
67 return;
68
69 is_user = user_mode(regs);
70
71 if (is_user && current->state != TASK_RUNNING)
72 return;
73
74 /*
75 * Only the kernel side is implemented for now.
76 */
77 if (!is_user)
78 perf_callchain_kernel(regs, entry);
79}
80
81/*
82 * No need for separate IRQ and NMI entries.
83 */
84static DEFINE_PER_CPU(struct perf_callchain_entry, callchain);
85
86struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
87{
88 struct perf_callchain_entry *entry = &__get_cpu_var(callchain);
89
90 entry->nr = 0;
91
92 perf_do_callchain(regs, entry);
93
94 return entry;
95}
diff --git a/arch/sh/kernel/perf_event.c b/arch/sh/kernel/perf_event.c
new file mode 100644
index 000000000000..81b6de41ae5d
--- /dev/null
+++ b/arch/sh/kernel/perf_event.c
@@ -0,0 +1,330 @@
1/*
2 * Performance event support framework for SuperH hardware counters.
3 *
4 * Copyright (C) 2009 Paul Mundt
5 *
6 * Heavily based on the x86 and PowerPC implementations.
7 *
8 * x86:
9 * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
10 * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
11 * Copyright (C) 2009 Jaswinder Singh Rajput
12 * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
13 * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
14 * Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
15 *
16 * ppc:
17 * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
18 *
19 * This file is subject to the terms and conditions of the GNU General Public
20 * License. See the file "COPYING" in the main directory of this archive
21 * for more details.
22 */
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/io.h>
26#include <linux/irq.h>
27#include <linux/perf_event.h>
28#include <asm/processor.h>
29
30struct cpu_hw_events {
31 struct perf_event *events[MAX_HWEVENTS];
32 unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
33 unsigned long active_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
34};
35
36DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
37
38static struct sh_pmu *sh_pmu __read_mostly;
39
40/* Number of perf_events counting hardware events */
41static atomic_t num_events;
42/* Used to avoid races in calling reserve/release_pmc_hardware */
43static DEFINE_MUTEX(pmc_reserve_mutex);
44
45/*
46 * Stub these out for now, do something more profound later.
47 */
48int reserve_pmc_hardware(void)
49{
50 return 0;
51}
52
53void release_pmc_hardware(void)
54{
55}
56
57static inline int sh_pmu_initialized(void)
58{
59 return !!sh_pmu;
60}
61
62/*
63 * Release the PMU if this is the last perf_event.
64 */
65static void hw_perf_event_destroy(struct perf_event *event)
66{
67 if (!atomic_add_unless(&num_events, -1, 1)) {
68 mutex_lock(&pmc_reserve_mutex);
69 if (atomic_dec_return(&num_events) == 0)
70 release_pmc_hardware();
71 mutex_unlock(&pmc_reserve_mutex);
72 }
73}
74
75static int hw_perf_cache_event(int config, int *evp)
76{
77 unsigned long type, op, result;
78 int ev;
79
80 if (!sh_pmu->cache_events)
81 return -EINVAL;
82
83 /* unpack config */
84 type = config & 0xff;
85 op = (config >> 8) & 0xff;
86 result = (config >> 16) & 0xff;
87
88 if (type >= PERF_COUNT_HW_CACHE_MAX ||
89 op >= PERF_COUNT_HW_CACHE_OP_MAX ||
90 result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
91 return -EINVAL;
92
93 ev = (*sh_pmu->cache_events)[type][op][result];
94 if (ev == 0)
95 return -EOPNOTSUPP;
96 if (ev == -1)
97 return -EINVAL;
98 *evp = ev;
99 return 0;
100}
101
102static int __hw_perf_event_init(struct perf_event *event)
103{
104 struct perf_event_attr *attr = &event->attr;
105 struct hw_perf_event *hwc = &event->hw;
106 int config = -1;
107 int err;
108
109 if (!sh_pmu_initialized())
110 return -ENODEV;
111
112 /*
113 * All of the on-chip counters are "limited", in that they have
114 * no interrupts, and are therefore unable to do sampling without
115 * further work and timer assistance.
116 */
117 if (hwc->sample_period)
118 return -EINVAL;
119
120 /*
121 * See if we need to reserve the counter.
122 *
123 * If no events are currently in use, then we have to take a
124 * mutex to ensure that we don't race with another task doing
125 * reserve_pmc_hardware or release_pmc_hardware.
126 */
127 err = 0;
128 if (!atomic_inc_not_zero(&num_events)) {
129 mutex_lock(&pmc_reserve_mutex);
130 if (atomic_read(&num_events) == 0 &&
131 reserve_pmc_hardware())
132 err = -EBUSY;
133 else
134 atomic_inc(&num_events);
135 mutex_unlock(&pmc_reserve_mutex);
136 }
137
138 if (err)
139 return err;
140
141 event->destroy = hw_perf_event_destroy;
142
143 switch (attr->type) {
144 case PERF_TYPE_RAW:
145 config = attr->config & sh_pmu->raw_event_mask;
146 break;
147 case PERF_TYPE_HW_CACHE:
148 err = hw_perf_cache_event(attr->config, &config);
149 if (err)
150 return err;
151 break;
152 case PERF_TYPE_HARDWARE:
153 if (attr->config >= sh_pmu->max_events)
154 return -EINVAL;
155
156 config = sh_pmu->event_map(attr->config);
157 break;
158 }
159
160 if (config == -1)
161 return -EINVAL;
162
163 hwc->config |= config;
164
165 return 0;
166}
167
168static void sh_perf_event_update(struct perf_event *event,
169 struct hw_perf_event *hwc, int idx)
170{
171 u64 prev_raw_count, new_raw_count;
172 s64 delta;
173 int shift = 0;
174
175 /*
176 * Depending on the counter configuration, they may or may not
177 * be chained, in which case the previous counter value can be
178 * updated underneath us if the lower-half overflows.
179 *
180 * Our tactic to handle this is to first atomically read and
181 * exchange a new raw count - then add that new-prev delta
182 * count to the generic counter atomically.
183 *
184 * As there is no interrupt associated with the overflow events,
185 * this is the simplest approach for maintaining consistency.
186 */
187again:
188 prev_raw_count = atomic64_read(&hwc->prev_count);
189 new_raw_count = sh_pmu->read(idx);
190
191 if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
192 new_raw_count) != prev_raw_count)
193 goto again;
194
195 /*
196 * Now we have the new raw value and have updated the prev
197 * timestamp already. We can now calculate the elapsed delta
198 * (counter-)time and add that to the generic counter.
199 *
200 * Careful, not all hw sign-extends above the physical width
201 * of the count.
202 */
203 delta = (new_raw_count << shift) - (prev_raw_count << shift);
204 delta >>= shift;
205
206 atomic64_add(delta, &event->count);
207}
208
209static void sh_pmu_disable(struct perf_event *event)
210{
211 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
212 struct hw_perf_event *hwc = &event->hw;
213 int idx = hwc->idx;
214
215 clear_bit(idx, cpuc->active_mask);
216 sh_pmu->disable(hwc, idx);
217
218 barrier();
219
220 sh_perf_event_update(event, &event->hw, idx);
221
222 cpuc->events[idx] = NULL;
223 clear_bit(idx, cpuc->used_mask);
224
225 perf_event_update_userpage(event);
226}
227
228static int sh_pmu_enable(struct perf_event *event)
229{
230 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
231 struct hw_perf_event *hwc = &event->hw;
232 int idx = hwc->idx;
233
234 if (test_and_set_bit(idx, cpuc->used_mask)) {
235 idx = find_first_zero_bit(cpuc->used_mask, sh_pmu->num_events);
236 if (idx == sh_pmu->num_events)
237 return -EAGAIN;
238
239 set_bit(idx, cpuc->used_mask);
240 hwc->idx = idx;
241 }
242
243 sh_pmu->disable(hwc, idx);
244
245 cpuc->events[idx] = event;
246 set_bit(idx, cpuc->active_mask);
247
248 sh_pmu->enable(hwc, idx);
249
250 perf_event_update_userpage(event);
251
252 return 0;
253}
254
255static void sh_pmu_read(struct perf_event *event)
256{
257 sh_perf_event_update(event, &event->hw, event->hw.idx);
258}
259
260static const struct pmu pmu = {
261 .enable = sh_pmu_enable,
262 .disable = sh_pmu_disable,
263 .read = sh_pmu_read,
264};
265
266const struct pmu *hw_perf_event_init(struct perf_event *event)
267{
268 int err = __hw_perf_event_init(event);
269 if (unlikely(err)) {
270 if (event->destroy)
271 event->destroy(event);
272 return ERR_PTR(err);
273 }
274
275 return &pmu;
276}
277
278static void sh_pmu_setup(int cpu)
279{
280 struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
281
282 memset(cpuhw, 0, sizeof(struct cpu_hw_events));
283}
284
285static int __cpuinit
286sh_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
287{
288 unsigned int cpu = (long)hcpu;
289
290 switch (action & ~CPU_TASKS_FROZEN) {
291 case CPU_UP_PREPARE:
292 sh_pmu_setup(cpu);
293 break;
294
295 default:
296 break;
297 }
298
299 return NOTIFY_OK;
300}
301
302void hw_perf_enable(void)
303{
304 if (!sh_pmu_initialized())
305 return;
306
307 sh_pmu->enable_all();
308}
309
310void hw_perf_disable(void)
311{
312 if (!sh_pmu_initialized())
313 return;
314
315 sh_pmu->disable_all();
316}
317
318int __cpuinit register_sh_pmu(struct sh_pmu *pmu)
319{
320 if (sh_pmu)
321 return -EBUSY;
322 sh_pmu = pmu;
323
324 pr_info("Performance Events: %s support registered\n", pmu->name);
325
326 WARN_ON(pmu->num_events > MAX_HWEVENTS);
327
328 perf_cpu_notifier(sh_pmu_notifier);
329 return 0;
330}
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
new file mode 100644
index 000000000000..17f89aa4e1b3
--- /dev/null
+++ b/arch/sh/kernel/process.c
@@ -0,0 +1,101 @@
1#include <linux/mm.h>
2#include <linux/kernel.h>
3#include <linux/slab.h>
4#include <linux/sched.h>
5
6struct kmem_cache *task_xstate_cachep = NULL;
7unsigned int xstate_size;
8
9int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
10{
11 *dst = *src;
12
13 if (src->thread.xstate) {
14 dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
15 GFP_KERNEL);
16 if (!dst->thread.xstate)
17 return -ENOMEM;
18 memcpy(dst->thread.xstate, src->thread.xstate, xstate_size);
19 }
20
21 return 0;
22}
23
24void free_thread_xstate(struct task_struct *tsk)
25{
26 if (tsk->thread.xstate) {
27 kmem_cache_free(task_xstate_cachep, tsk->thread.xstate);
28 tsk->thread.xstate = NULL;
29 }
30}
31
32#if THREAD_SHIFT < PAGE_SHIFT
33static struct kmem_cache *thread_info_cache;
34
35struct thread_info *alloc_thread_info(struct task_struct *tsk)
36{
37 struct thread_info *ti;
38
39 ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL);
40 if (unlikely(ti == NULL))
41 return NULL;
42#ifdef CONFIG_DEBUG_STACK_USAGE
43 memset(ti, 0, THREAD_SIZE);
44#endif
45 return ti;
46}
47
48void free_thread_info(struct thread_info *ti)
49{
50 free_thread_xstate(ti->task);
51 kmem_cache_free(thread_info_cache, ti);
52}
53
54void thread_info_cache_init(void)
55{
56 thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE,
57 THREAD_SIZE, SLAB_PANIC, NULL);
58}
59#else
60struct thread_info *alloc_thread_info(struct task_struct *tsk)
61{
62#ifdef CONFIG_DEBUG_STACK_USAGE
63 gfp_t mask = GFP_KERNEL | __GFP_ZERO;
64#else
65 gfp_t mask = GFP_KERNEL;
66#endif
67 return (struct thread_info *)__get_free_pages(mask, THREAD_SIZE_ORDER);
68}
69
70void free_thread_info(struct thread_info *ti)
71{
72 free_thread_xstate(ti->task);
73 free_pages((unsigned long)ti, THREAD_SIZE_ORDER);
74}
75#endif /* THREAD_SHIFT < PAGE_SHIFT */
76
77void arch_task_cache_init(void)
78{
79 if (!xstate_size)
80 return;
81
82 task_xstate_cachep = kmem_cache_create("task_xstate", xstate_size,
83 __alignof__(union thread_xstate),
84 SLAB_PANIC | SLAB_NOTRACK, NULL);
85}
86
87#ifdef CONFIG_SH_FPU_EMU
88# define HAVE_SOFTFP 1
89#else
90# define HAVE_SOFTFP 0
91#endif
92
93void init_thread_xstate(void)
94{
95 if (boot_cpu_data.flags & CPU_HAS_FPU)
96 xstate_size = sizeof(struct sh_fpu_hard_struct);
97 else if (HAVE_SOFTFP)
98 xstate_size = sizeof(struct sh_fpu_soft_struct);
99 else
100 xstate_size = 0;
101}
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 0673c4746be3..052981972ae6 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -15,66 +15,17 @@
15 */ 15 */
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/slab.h>
18#include <linux/elfcore.h> 19#include <linux/elfcore.h>
19#include <linux/pm.h>
20#include <linux/kallsyms.h> 20#include <linux/kallsyms.h>
21#include <linux/kexec.h>
22#include <linux/kdebug.h>
23#include <linux/tick.h>
24#include <linux/reboot.h>
25#include <linux/fs.h> 21#include <linux/fs.h>
26#include <linux/ftrace.h> 22#include <linux/ftrace.h>
27#include <linux/preempt.h> 23#include <linux/hw_breakpoint.h>
28#include <asm/uaccess.h> 24#include <asm/uaccess.h>
29#include <asm/mmu_context.h> 25#include <asm/mmu_context.h>
30#include <asm/pgalloc.h>
31#include <asm/system.h> 26#include <asm/system.h>
32#include <asm/ubc.h>
33#include <asm/fpu.h> 27#include <asm/fpu.h>
34#include <asm/syscalls.h> 28#include <asm/syscalls.h>
35#include <asm/watchdog.h>
36
37int ubc_usercnt = 0;
38
39#ifdef CONFIG_32BIT
40static void watchdog_trigger_immediate(void)
41{
42 sh_wdt_write_cnt(0xFF);
43 sh_wdt_write_csr(0xC2);
44}
45
46void machine_restart(char * __unused)
47{
48 local_irq_disable();
49
50 /* Use watchdog timer to trigger reset */
51 watchdog_trigger_immediate();
52
53 while (1)
54 cpu_sleep();
55}
56#else
57void machine_restart(char * __unused)
58{
59 /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
60 asm volatile("ldc %0, sr\n\t"
61 "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001));
62}
63#endif
64
65void machine_halt(void)
66{
67 local_irq_disable();
68
69 while (1)
70 cpu_sleep();
71}
72
73void machine_power_off(void)
74{
75 if (pm_power_off)
76 pm_power_off();
77}
78 29
79void show_regs(struct pt_regs * regs) 30void show_regs(struct pt_regs * regs)
80{ 31{
@@ -91,7 +42,7 @@ void show_regs(struct pt_regs * regs)
91 printk("PC : %08lx SP : %08lx SR : %08lx ", 42 printk("PC : %08lx SP : %08lx SR : %08lx ",
92 regs->pc, regs->regs[15], regs->sr); 43 regs->pc, regs->regs[15], regs->sr);
93#ifdef CONFIG_MMU 44#ifdef CONFIG_MMU
94 printk("TEA : %08x\n", ctrl_inl(MMU_TEA)); 45 printk("TEA : %08x\n", __raw_readl(MMU_TEA));
95#else 46#else
96 printk("\n"); 47 printk("\n");
97#endif 48#endif
@@ -134,7 +85,10 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
134 regs.regs[5] = (unsigned long)fn; 85 regs.regs[5] = (unsigned long)fn;
135 86
136 regs.pc = (unsigned long)kernel_thread_helper; 87 regs.pc = (unsigned long)kernel_thread_helper;
137 regs.sr = (1 << 30); 88 regs.sr = SR_MD;
89#if defined(CONFIG_SH_FPU)
90 regs.sr |= SR_FD;
91#endif
138 92
139 /* Ok, create the new process.. */ 93 /* Ok, create the new process.. */
140 pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, 94 pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
@@ -142,22 +96,36 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
142 96
143 return pid; 97 return pid;
144} 98}
99EXPORT_SYMBOL(kernel_thread);
100
101void start_thread(struct pt_regs *regs, unsigned long new_pc,
102 unsigned long new_sp)
103{
104 set_fs(USER_DS);
105
106 regs->pr = 0;
107 regs->sr = SR_FD;
108 regs->pc = new_pc;
109 regs->regs[15] = new_sp;
110
111 free_thread_xstate(current);
112}
113EXPORT_SYMBOL(start_thread);
145 114
146/* 115/*
147 * Free current thread data structures etc.. 116 * Free current thread data structures etc..
148 */ 117 */
149void exit_thread(void) 118void exit_thread(void)
150{ 119{
151 if (current->thread.ubc_pc) {
152 current->thread.ubc_pc = 0;
153 ubc_usercnt -= 1;
154 }
155} 120}
156 121
157void flush_thread(void) 122void flush_thread(void)
158{ 123{
159#if defined(CONFIG_SH_FPU)
160 struct task_struct *tsk = current; 124 struct task_struct *tsk = current;
125
126 flush_ptrace_hw_breakpoint(tsk);
127
128#if defined(CONFIG_SH_FPU)
161 /* Forget lazy FPU state */ 129 /* Forget lazy FPU state */
162 clear_fpu(tsk, task_pt_regs(tsk)); 130 clear_fpu(tsk, task_pt_regs(tsk));
163 clear_used_math(); 131 clear_used_math();
@@ -186,6 +154,16 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
186 154
187 return fpvalid; 155 return fpvalid;
188} 156}
157EXPORT_SYMBOL(dump_fpu);
158
159/*
160 * This gets called before we allocate a new thread and copy
161 * the current task into it.
162 */
163void prepare_to_copy(struct task_struct *tsk)
164{
165 unlazy_fpu(tsk, task_pt_regs(tsk));
166}
189 167
190asmlinkage void ret_from_fork(void); 168asmlinkage void ret_from_fork(void);
191 169
@@ -195,17 +173,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
195{ 173{
196 struct thread_info *ti = task_thread_info(p); 174 struct thread_info *ti = task_thread_info(p);
197 struct pt_regs *childregs; 175 struct pt_regs *childregs;
198#if defined(CONFIG_SH_FPU) || defined(CONFIG_SH_DSP)
199 struct task_struct *tsk = current;
200#endif
201
202#if defined(CONFIG_SH_FPU)
203 unlazy_fpu(tsk, regs);
204 p->thread.fpu = tsk->thread.fpu;
205 copy_to_stopped_child_used_math(p);
206#endif
207 176
208#if defined(CONFIG_SH_DSP) 177#if defined(CONFIG_SH_DSP)
178 struct task_struct *tsk = current;
179
209 if (is_dsp_enabled(tsk)) { 180 if (is_dsp_enabled(tsk)) {
210 /* We can use the __save_dsp or just copy the struct: 181 /* We can use the __save_dsp or just copy the struct:
211 * __save_dsp(p); 182 * __save_dsp(p);
@@ -224,6 +195,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
224 } else { 195 } else {
225 childregs->regs[15] = (unsigned long)childregs; 196 childregs->regs[15] = (unsigned long)childregs;
226 ti->addr_limit = KERNEL_DS; 197 ti->addr_limit = KERNEL_DS;
198 ti->status &= ~TS_USEDFPU;
199 p->fpu_counter = 0;
227 } 200 }
228 201
229 if (clone_flags & CLONE_SETTLS) 202 if (clone_flags & CLONE_SETTLS)
@@ -234,53 +207,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
234 p->thread.sp = (unsigned long) childregs; 207 p->thread.sp = (unsigned long) childregs;
235 p->thread.pc = (unsigned long) ret_from_fork; 208 p->thread.pc = (unsigned long) ret_from_fork;
236 209
237 p->thread.ubc_pc = 0; 210 memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
238 211
239 return 0; 212 return 0;
240} 213}
241 214
242/* Tracing by user break controller. */
243static void ubc_set_tracing(int asid, unsigned long pc)
244{
245#if defined(CONFIG_CPU_SH4A)
246 unsigned long val;
247
248 val = (UBC_CBR_ID_INST | UBC_CBR_RW_READ | UBC_CBR_CE);
249 val |= (UBC_CBR_AIE | UBC_CBR_AIV_SET(asid));
250
251 ctrl_outl(val, UBC_CBR0);
252 ctrl_outl(pc, UBC_CAR0);
253 ctrl_outl(0x0, UBC_CAMR0);
254 ctrl_outl(0x0, UBC_CBCR);
255
256 val = (UBC_CRR_RES | UBC_CRR_PCB | UBC_CRR_BIE);
257 ctrl_outl(val, UBC_CRR0);
258
259 /* Read UBC register that we wrote last, for checking update */
260 val = ctrl_inl(UBC_CRR0);
261
262#else /* CONFIG_CPU_SH4A */
263 ctrl_outl(pc, UBC_BARA);
264
265#ifdef CONFIG_MMU
266 ctrl_outb(asid, UBC_BASRA);
267#endif
268
269 ctrl_outl(0, UBC_BAMRA);
270
271 if (current_cpu_data.type == CPU_SH7729 ||
272 current_cpu_data.type == CPU_SH7710 ||
273 current_cpu_data.type == CPU_SH7712 ||
274 current_cpu_data.type == CPU_SH7203){
275 ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
276 ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR);
277 } else {
278 ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
279 ctrl_outw(BRCR_PCBA, UBC_BRCR);
280 }
281#endif /* CONFIG_CPU_SH4A */
282}
283
284/* 215/*
285 * switch_to(x,y) should switch tasks from x to y. 216 * switch_to(x,y) should switch tasks from x to y.
286 * 217 *
@@ -288,9 +219,13 @@ static void ubc_set_tracing(int asid, unsigned long pc)
288__notrace_funcgraph struct task_struct * 219__notrace_funcgraph struct task_struct *
289__switch_to(struct task_struct *prev, struct task_struct *next) 220__switch_to(struct task_struct *prev, struct task_struct *next)
290{ 221{
291#if defined(CONFIG_SH_FPU) 222 struct thread_struct *next_t = &next->thread;
223
292 unlazy_fpu(prev, task_pt_regs(prev)); 224 unlazy_fpu(prev, task_pt_regs(prev));
293#endif 225
226 /* we're going to use this soon, after a few expensive things */
227 if (next->fpu_counter > 5)
228 prefetch(next_t->xstate);
294 229
295#ifdef CONFIG_MMU 230#ifdef CONFIG_MMU
296 /* 231 /*
@@ -302,24 +237,13 @@ __switch_to(struct task_struct *prev, struct task_struct *next)
302 : "r" (task_thread_info(next))); 237 : "r" (task_thread_info(next)));
303#endif 238#endif
304 239
305 /* If no tasks are using the UBC, we're done */ 240 /*
306 if (ubc_usercnt == 0) 241 * If the task has used fpu the last 5 timeslices, just do a full
307 /* If no tasks are using the UBC, we're done */; 242 * restore of the math state immediately to avoid the trap; the
308 else if (next->thread.ubc_pc && next->mm) { 243 * chances of needing FPU soon are obviously high now
309 int asid = 0; 244 */
310#ifdef CONFIG_MMU 245 if (next->fpu_counter > 5)
311 asid |= cpu_asid(smp_processor_id(), next->mm); 246 __fpu_state_restore();
312#endif
313 ubc_set_tracing(asid, next->thread.ubc_pc);
314 } else {
315#if defined(CONFIG_CPU_SH4A)
316 ctrl_outl(UBC_CBR_INIT, UBC_CBR0);
317 ctrl_outl(UBC_CRR_INIT, UBC_CRR0);
318#else
319 ctrl_outw(0, UBC_BBRA);
320 ctrl_outw(0, UBC_BBRB);
321#endif
322 }
323 247
324 return prev; 248 return prev;
325} 249}
@@ -412,20 +336,3 @@ unsigned long get_wchan(struct task_struct *p)
412 336
413 return pc; 337 return pc;
414} 338}
415
416asmlinkage void break_point_trap(void)
417{
418 /* Clear tracing. */
419#if defined(CONFIG_CPU_SH4A)
420 ctrl_outl(UBC_CBR_INIT, UBC_CBR0);
421 ctrl_outl(UBC_CRR_INIT, UBC_CRR0);
422#else
423 ctrl_outw(0, UBC_BBRA);
424 ctrl_outw(0, UBC_BBRB);
425 ctrl_outl(0, UBC_BRCR);
426#endif
427 current->thread.ubc_pc = 0;
428 ubc_usercnt -= 1;
429
430 force_sig(SIGTRAP, current);
431}
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index 1192398ef582..d4ca6480e355 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -21,6 +21,7 @@
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/ptrace.h> 22#include <linux/ptrace.h>
23#include <linux/reboot.h> 23#include <linux/reboot.h>
24#include <linux/slab.h>
24#include <linux/init.h> 25#include <linux/init.h>
25#include <linux/module.h> 26#include <linux/module.h>
26#include <linux/io.h> 27#include <linux/io.h>
@@ -32,30 +33,7 @@
32 33
33struct task_struct *last_task_used_math = NULL; 34struct task_struct *last_task_used_math = NULL;
34 35
35void machine_restart(char * __unused) 36void show_regs(struct pt_regs *regs)
36{
37 extern void phys_stext(void);
38
39 phys_stext();
40}
41
42void machine_halt(void)
43{
44 for (;;);
45}
46
47void machine_power_off(void)
48{
49 __asm__ __volatile__ (
50 "sleep\n\t"
51 "synci\n\t"
52 "nop;nop;nop;nop\n\t"
53 );
54
55 panic("Unexpected wakeup!\n");
56}
57
58void show_regs(struct pt_regs * regs)
59{ 37{
60 unsigned long long ah, al, bh, bl, ch, cl; 38 unsigned long long ah, al, bh, bl, ch, cl;
61 39
@@ -335,6 +313,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
335 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, 313 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
336 &regs, 0, NULL, NULL); 314 &regs, 0, NULL, NULL);
337} 315}
316EXPORT_SYMBOL(kernel_thread);
338 317
339/* 318/*
340 * Free current thread data structures etc.. 319 * Free current thread data structures etc..
@@ -367,7 +346,7 @@ void exit_thread(void)
367void flush_thread(void) 346void flush_thread(void)
368{ 347{
369 348
370 /* Called by fs/exec.c (flush_old_exec) to remove traces of a 349 /* Called by fs/exec.c (setup_new_exec) to remove traces of a
371 * previously running executable. */ 350 * previously running executable. */
372#ifdef CONFIG_SH_FPU 351#ifdef CONFIG_SH_FPU
373 if (last_task_used_math == current) { 352 if (last_task_used_math == current) {
@@ -403,13 +382,13 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
403 if (fpvalid) { 382 if (fpvalid) {
404 if (current == last_task_used_math) { 383 if (current == last_task_used_math) {
405 enable_fpu(); 384 enable_fpu();
406 save_fpu(tsk, regs); 385 save_fpu(tsk);
407 disable_fpu(); 386 disable_fpu();
408 last_task_used_math = 0; 387 last_task_used_math = 0;
409 regs->sr |= SR_FD; 388 regs->sr |= SR_FD;
410 } 389 }
411 390
412 memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu)); 391 memcpy(fpu, &tsk->thread.xstate->hardfpu, sizeof(*fpu));
413 } 392 }
414 393
415 return fpvalid; 394 return fpvalid;
@@ -417,6 +396,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
417 return 0; /* Task didn't use the fpu at all. */ 396 return 0; /* Task didn't use the fpu at all. */
418#endif 397#endif
419} 398}
399EXPORT_SYMBOL(dump_fpu);
420 400
421asmlinkage void ret_from_fork(void); 401asmlinkage void ret_from_fork(void);
422 402
@@ -429,7 +409,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
429#ifdef CONFIG_SH_FPU 409#ifdef CONFIG_SH_FPU
430 if(last_task_used_math == current) { 410 if(last_task_used_math == current) {
431 enable_fpu(); 411 enable_fpu();
432 save_fpu(current, regs); 412 save_fpu(current);
433 disable_fpu(); 413 disable_fpu();
434 last_task_used_math = NULL; 414 last_task_used_math = NULL;
435 regs->sr |= SR_FD; 415 regs->sr |= SR_FD;
@@ -525,13 +505,6 @@ out:
525 return error; 505 return error;
526} 506}
527 507
528/*
529 * These bracket the sleeping functions..
530 */
531extern void interruptible_sleep_on(wait_queue_head_t *q);
532
533#define mid_sched ((unsigned long) interruptible_sleep_on)
534
535#ifdef CONFIG_FRAME_POINTER 508#ifdef CONFIG_FRAME_POINTER
536static int in_sh64_switch_to(unsigned long pc) 509static int in_sh64_switch_to(unsigned long pc)
537{ 510{
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 9be35f348093..7759a9a93211 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -2,7 +2,7 @@
2 * SuperH process tracing 2 * SuperH process tracing
3 * 3 *
4 * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka 4 * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
5 * Copyright (C) 2002 - 2008 Paul Mundt 5 * Copyright (C) 2002 - 2009 Paul Mundt
6 * 6 *
7 * Audit support by Yuichi Nakamura <ynakam@hitachisoft.jp> 7 * Audit support by Yuichi Nakamura <ynakam@hitachisoft.jp>
8 * 8 *
@@ -17,7 +17,6 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/ptrace.h> 18#include <linux/ptrace.h>
19#include <linux/user.h> 19#include <linux/user.h>
20#include <linux/slab.h>
21#include <linux/security.h> 20#include <linux/security.h>
22#include <linux/signal.h> 21#include <linux/signal.h>
23#include <linux/io.h> 22#include <linux/io.h>
@@ -26,6 +25,7 @@
26#include <linux/tracehook.h> 25#include <linux/tracehook.h>
27#include <linux/elf.h> 26#include <linux/elf.h>
28#include <linux/regset.h> 27#include <linux/regset.h>
28#include <linux/hw_breakpoint.h>
29#include <asm/uaccess.h> 29#include <asm/uaccess.h>
30#include <asm/pgtable.h> 30#include <asm/pgtable.h>
31#include <asm/system.h> 31#include <asm/system.h>
@@ -63,33 +63,64 @@ static inline int put_stack_long(struct task_struct *task, int offset,
63 return 0; 63 return 0;
64} 64}
65 65
66void user_enable_single_step(struct task_struct *child) 66void ptrace_triggered(struct perf_event *bp, int nmi,
67 struct perf_sample_data *data, struct pt_regs *regs)
67{ 68{
68 /* Next scheduling will set up UBC */ 69 struct perf_event_attr attr;
69 if (child->thread.ubc_pc == 0) 70
70 ubc_usercnt += 1; 71 /*
72 * Disable the breakpoint request here since ptrace has defined a
73 * one-shot behaviour for breakpoint exceptions.
74 */
75 attr = bp->attr;
76 attr.disabled = true;
77 modify_user_hw_breakpoint(bp, &attr);
78}
79
80static int set_single_step(struct task_struct *tsk, unsigned long addr)
81{
82 struct thread_struct *thread = &tsk->thread;
83 struct perf_event *bp;
84 struct perf_event_attr attr;
85
86 bp = thread->ptrace_bps[0];
87 if (!bp) {
88 hw_breakpoint_init(&attr);
89
90 attr.bp_addr = addr;
91 attr.bp_len = HW_BREAKPOINT_LEN_2;
92 attr.bp_type = HW_BREAKPOINT_R;
93
94 bp = register_user_hw_breakpoint(&attr, ptrace_triggered, tsk);
95 if (IS_ERR(bp))
96 return PTR_ERR(bp);
97
98 thread->ptrace_bps[0] = bp;
99 } else {
100 int err;
101
102 attr = bp->attr;
103 attr.bp_addr = addr;
104 err = modify_user_hw_breakpoint(bp, &attr);
105 if (unlikely(err))
106 return err;
107 }
108
109 return 0;
110}
71 111
72 child->thread.ubc_pc = get_stack_long(child, 112void user_enable_single_step(struct task_struct *child)
73 offsetof(struct pt_regs, pc)); 113{
114 unsigned long pc = get_stack_long(child, offsetof(struct pt_regs, pc));
74 115
75 set_tsk_thread_flag(child, TIF_SINGLESTEP); 116 set_tsk_thread_flag(child, TIF_SINGLESTEP);
117
118 set_single_step(child, pc);
76} 119}
77 120
78void user_disable_single_step(struct task_struct *child) 121void user_disable_single_step(struct task_struct *child)
79{ 122{
80 clear_tsk_thread_flag(child, TIF_SINGLESTEP); 123 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
81
82 /*
83 * Ensure the UBC is not programmed at the next context switch.
84 *
85 * Normally this is not needed but there are sequences such as
86 * singlestep, signal delivery, and continue that leave the
87 * ubc_pc non-zero leading to spurious SIGTRAPs.
88 */
89 if (child->thread.ubc_pc != 0) {
90 ubc_usercnt -= 1;
91 child->thread.ubc_pc = 0;
92 }
93} 124}
94 125
95/* 126/*
@@ -163,10 +194,10 @@ int fpregs_get(struct task_struct *target,
163 194
164 if ((boot_cpu_data.flags & CPU_HAS_FPU)) 195 if ((boot_cpu_data.flags & CPU_HAS_FPU))
165 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, 196 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
166 &target->thread.fpu.hard, 0, -1); 197 &target->thread.xstate->hardfpu, 0, -1);
167 198
168 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, 199 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
169 &target->thread.fpu.soft, 0, -1); 200 &target->thread.xstate->softfpu, 0, -1);
170} 201}
171 202
172static int fpregs_set(struct task_struct *target, 203static int fpregs_set(struct task_struct *target,
@@ -184,10 +215,10 @@ static int fpregs_set(struct task_struct *target,
184 215
185 if ((boot_cpu_data.flags & CPU_HAS_FPU)) 216 if ((boot_cpu_data.flags & CPU_HAS_FPU))
186 return user_regset_copyin(&pos, &count, &kbuf, &ubuf, 217 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
187 &target->thread.fpu.hard, 0, -1); 218 &target->thread.xstate->hardfpu, 0, -1);
188 219
189 return user_regset_copyin(&pos, &count, &kbuf, &ubuf, 220 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
190 &target->thread.fpu.soft, 0, -1); 221 &target->thread.xstate->softfpu, 0, -1);
191} 222}
192 223
193static int fpregs_active(struct task_struct *target, 224static int fpregs_active(struct task_struct *target,
@@ -333,7 +364,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
333 else 364 else
334 tmp = 0; 365 tmp = 0;
335 } else 366 } else
336 tmp = ((long *)&child->thread.fpu) 367 tmp = ((long *)child->thread.xstate)
337 [(addr - (long)&dummy->fpu) >> 2]; 368 [(addr - (long)&dummy->fpu) >> 2];
338 } else if (addr == (long) &dummy->u_fpvalid) 369 } else if (addr == (long) &dummy->u_fpvalid)
339 tmp = !!tsk_used_math(child); 370 tmp = !!tsk_used_math(child);
@@ -362,7 +393,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
362 else if (addr >= (long) &dummy->fpu && 393 else if (addr >= (long) &dummy->fpu &&
363 addr < (long) &dummy->u_fpvalid) { 394 addr < (long) &dummy->u_fpvalid) {
364 set_stopped_child_used_math(child); 395 set_stopped_child_used_math(child);
365 ((long *)&child->thread.fpu) 396 ((long *)child->thread.xstate)
366 [(addr - (long)&dummy->fpu) >> 2] = data; 397 [(addr - (long)&dummy->fpu) >> 2] = data;
367 ret = 0; 398 ret = 0;
368 } else if (addr == (long) &dummy->u_fpvalid) { 399 } else if (addr == (long) &dummy->u_fpvalid) {
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index 952da83903da..5fd644da7f02 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -82,13 +82,13 @@ get_fpu_long(struct task_struct *task, unsigned long addr)
82 82
83 if (last_task_used_math == task) { 83 if (last_task_used_math == task) {
84 enable_fpu(); 84 enable_fpu();
85 save_fpu(task, regs); 85 save_fpu(task);
86 disable_fpu(); 86 disable_fpu();
87 last_task_used_math = 0; 87 last_task_used_math = 0;
88 regs->sr |= SR_FD; 88 regs->sr |= SR_FD;
89 } 89 }
90 90
91 tmp = ((long *)&task->thread.fpu)[addr / sizeof(unsigned long)]; 91 tmp = ((long *)task->thread.xstate)[addr / sizeof(unsigned long)];
92 return tmp; 92 return tmp;
93} 93}
94 94
@@ -114,17 +114,16 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
114 regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1; 114 regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1;
115 115
116 if (!tsk_used_math(task)) { 116 if (!tsk_used_math(task)) {
117 fpinit(&task->thread.fpu.hard); 117 init_fpu(task);
118 set_stopped_child_used_math(task);
119 } else if (last_task_used_math == task) { 118 } else if (last_task_used_math == task) {
120 enable_fpu(); 119 enable_fpu();
121 save_fpu(task, regs); 120 save_fpu(task);
122 disable_fpu(); 121 disable_fpu();
123 last_task_used_math = 0; 122 last_task_used_math = 0;
124 regs->sr |= SR_FD; 123 regs->sr |= SR_FD;
125 } 124 }
126 125
127 ((long *)&task->thread.fpu)[addr / sizeof(unsigned long)] = data; 126 ((long *)task->thread.xstate)[addr / sizeof(unsigned long)] = data;
128 return 0; 127 return 0;
129} 128}
130 129
@@ -133,6 +132,8 @@ void user_enable_single_step(struct task_struct *child)
133 struct pt_regs *regs = child->thread.uregs; 132 struct pt_regs *regs = child->thread.uregs;
134 133
135 regs->sr |= SR_SSTEP; /* auto-resetting upon exception */ 134 regs->sr |= SR_SSTEP; /* auto-resetting upon exception */
135
136 set_tsk_thread_flag(child, TIF_SINGLESTEP);
136} 137}
137 138
138void user_disable_single_step(struct task_struct *child) 139void user_disable_single_step(struct task_struct *child)
@@ -140,6 +141,8 @@ void user_disable_single_step(struct task_struct *child)
140 struct pt_regs *regs = child->thread.uregs; 141 struct pt_regs *regs = child->thread.uregs;
141 142
142 regs->sr &= ~SR_SSTEP; 143 regs->sr &= ~SR_SSTEP;
144
145 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
143} 146}
144 147
145static int genregs_get(struct task_struct *target, 148static int genregs_get(struct task_struct *target,
@@ -222,7 +225,7 @@ int fpregs_get(struct task_struct *target,
222 return ret; 225 return ret;
223 226
224 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, 227 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
225 &target->thread.fpu.hard, 0, -1); 228 &target->thread.xstate->hardfpu, 0, -1);
226} 229}
227 230
228static int fpregs_set(struct task_struct *target, 231static int fpregs_set(struct task_struct *target,
@@ -239,7 +242,7 @@ static int fpregs_set(struct task_struct *target,
239 set_stopped_child_used_math(target); 242 set_stopped_child_used_math(target);
240 243
241 return user_regset_copyin(&pos, &count, &kbuf, &ubuf, 244 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
242 &target->thread.fpu.hard, 0, -1); 245 &target->thread.xstate->hardfpu, 0, -1);
243} 246}
244 247
245static int fpregs_active(struct task_struct *target, 248static int fpregs_active(struct task_struct *target,
@@ -454,6 +457,8 @@ asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs)
454 457
455asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) 458asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
456{ 459{
460 int step;
461
457 if (unlikely(current->audit_context)) 462 if (unlikely(current->audit_context))
458 audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]), 463 audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]),
459 regs->regs[9]); 464 regs->regs[9]);
@@ -461,8 +466,9 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
461 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) 466 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
462 trace_sys_exit(regs, regs->regs[9]); 467 trace_sys_exit(regs, regs->regs[9]);
463 468
464 if (test_thread_flag(TIF_SYSCALL_TRACE)) 469 step = test_thread_flag(TIF_SINGLESTEP);
465 tracehook_report_syscall_exit(regs, 0); 470 if (step || test_thread_flag(TIF_SYSCALL_TRACE))
471 tracehook_report_syscall_exit(regs, step);
466} 472}
467 473
468/* Called with interrupts disabled */ 474/* Called with interrupts disabled */
@@ -479,9 +485,10 @@ asmlinkage void do_single_step(unsigned long long vec, struct pt_regs *regs)
479} 485}
480 486
481/* Called with interrupts disabled */ 487/* Called with interrupts disabled */
482asmlinkage void do_software_break_point(unsigned long long vec, 488BUILD_TRAP_HANDLER(breakpoint)
483 struct pt_regs *regs)
484{ 489{
490 TRAP_HANDLER_DECL;
491
485 /* We need to forward step the PC, to counteract the backstep done 492 /* We need to forward step the PC, to counteract the backstep done
486 in signal.c. */ 493 in signal.c. */
487 local_irq_enable(); 494 local_irq_enable();
diff --git a/arch/sh/kernel/reboot.c b/arch/sh/kernel/reboot.c
new file mode 100644
index 000000000000..b1fca66bb92e
--- /dev/null
+++ b/arch/sh/kernel/reboot.c
@@ -0,0 +1,98 @@
1#include <linux/pm.h>
2#include <linux/kexec.h>
3#include <linux/kernel.h>
4#include <linux/reboot.h>
5#include <linux/module.h>
6#ifdef CONFIG_SUPERH32
7#include <asm/watchdog.h>
8#endif
9#include <asm/addrspace.h>
10#include <asm/reboot.h>
11#include <asm/system.h>
12
13void (*pm_power_off)(void);
14EXPORT_SYMBOL(pm_power_off);
15
16#ifdef CONFIG_SUPERH32
17static void watchdog_trigger_immediate(void)
18{
19 sh_wdt_write_cnt(0xFF);
20 sh_wdt_write_csr(0xC2);
21}
22#endif
23
24static void native_machine_restart(char * __unused)
25{
26 local_irq_disable();
27
28 /* Address error with SR.BL=1 first. */
29 trigger_address_error();
30
31#ifdef CONFIG_SUPERH32
32 /* If that fails or is unsupported, go for the watchdog next. */
33 watchdog_trigger_immediate();
34#endif
35
36 /*
37 * Give up and sleep.
38 */
39 while (1)
40 cpu_sleep();
41}
42
43static void native_machine_shutdown(void)
44{
45 smp_send_stop();
46}
47
48static void native_machine_power_off(void)
49{
50 if (pm_power_off)
51 pm_power_off();
52}
53
54static void native_machine_halt(void)
55{
56 /* stop other cpus */
57 machine_shutdown();
58
59 /* stop this cpu */
60 stop_this_cpu(NULL);
61}
62
63struct machine_ops machine_ops = {
64 .power_off = native_machine_power_off,
65 .shutdown = native_machine_shutdown,
66 .restart = native_machine_restart,
67 .halt = native_machine_halt,
68#ifdef CONFIG_KEXEC
69 .crash_shutdown = native_machine_crash_shutdown,
70#endif
71};
72
73void machine_power_off(void)
74{
75 machine_ops.power_off();
76}
77
78void machine_shutdown(void)
79{
80 machine_ops.shutdown();
81}
82
83void machine_restart(char *cmd)
84{
85 machine_ops.restart(cmd);
86}
87
88void machine_halt(void)
89{
90 machine_ops.halt();
91}
92
93#ifdef CONFIG_KEXEC
94void machine_crash_shutdown(struct pt_regs *regs)
95{
96 machine_ops.crash_shutdown(regs);
97}
98#endif
diff --git a/arch/sh/kernel/return_address.c b/arch/sh/kernel/return_address.c
new file mode 100644
index 000000000000..cbf1dd5372b2
--- /dev/null
+++ b/arch/sh/kernel/return_address.c
@@ -0,0 +1,57 @@
1/*
2 * arch/sh/kernel/return_address.c
3 *
4 * Copyright (C) 2009 Matt Fleming
5 * Copyright (C) 2009 Paul Mundt
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <asm/dwarf.h>
14
15#ifdef CONFIG_DWARF_UNWINDER
16
17void *return_address(unsigned int depth)
18{
19 struct dwarf_frame *frame;
20 unsigned long ra;
21 int i;
22
23 for (i = 0, frame = NULL, ra = 0; i <= depth; i++) {
24 struct dwarf_frame *tmp;
25
26 tmp = dwarf_unwind_stack(ra, frame);
27
28 if (frame)
29 dwarf_free_frame(frame);
30
31 frame = tmp;
32
33 if (!frame || !frame->return_addr)
34 break;
35
36 ra = frame->return_addr;
37 }
38
39 /* Failed to unwind the stack to the specified depth. */
40 WARN_ON(i != depth + 1);
41
42 if (frame)
43 dwarf_free_frame(frame);
44
45 return (void *)ra;
46}
47
48#else
49
50void *return_address(unsigned int depth)
51{
52 return NULL;
53}
54
55#endif
56
57EXPORT_SYMBOL_GPL(return_address);
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 99b4fb553bf1..8870d6ba64bf 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -421,8 +421,13 @@ void __init setup_arch(char **cmdline_p)
421 421
422 parse_early_param(); 422 parse_early_param();
423 423
424 uncached_init();
425
424 plat_early_device_setup(); 426 plat_early_device_setup();
425 427
428 /* Let earlyprintk output early console messages */
429 early_platform_driver_probe("earlyprintk", 1, 1);
430
426 sh_mv_setup(); 431 sh_mv_setup();
427 432
428 /* 433 /*
@@ -438,7 +443,7 @@ void __init setup_arch(char **cmdline_p)
438 443
439 nodes_clear(node_online_map); 444 nodes_clear(node_online_map);
440 445
441 /* Setup bootmem with available RAM */ 446 pmb_init();
442 lmb_init(); 447 lmb_init();
443 setup_memory(); 448 setup_memory();
444 sparse_init(); 449 sparse_init();
@@ -446,13 +451,14 @@ void __init setup_arch(char **cmdline_p)
446#ifdef CONFIG_DUMMY_CONSOLE 451#ifdef CONFIG_DUMMY_CONSOLE
447 conswitchp = &dummy_con; 452 conswitchp = &dummy_con;
448#endif 453#endif
454 paging_init();
455
456 ioremap_fixed_init();
449 457
450 /* Perform the machine specific initialisation */ 458 /* Perform the machine specific initialisation */
451 if (likely(sh_mv.mv_setup)) 459 if (likely(sh_mv.mv_setup))
452 sh_mv.mv_setup(cmdline_p); 460 sh_mv.mv_setup(cmdline_p);
453 461
454 paging_init();
455
456#ifdef CONFIG_SMP 462#ifdef CONFIG_SMP
457 plat_smp_setup(); 463 plat_smp_setup();
458#endif 464#endif
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c
index c852f7805728..47475cca068a 100644
--- a/arch/sh/kernel/sh_bios.c
+++ b/arch/sh/kernel/sh_bios.c
@@ -1,19 +1,30 @@
1/* 1/*
2 * linux/arch/sh/kernel/sh_bios.c
3 * C interface for trapping into the standard LinuxSH BIOS. 2 * C interface for trapping into the standard LinuxSH BIOS.
4 * 3 *
5 * Copyright (C) 2000 Greg Banks, Mitch Davis 4 * Copyright (C) 2000 Greg Banks, Mitch Davis
5 * Copyright (C) 1999, 2000 Niibe Yutaka
6 * Copyright (C) 2002 M. R. Brown
7 * Copyright (C) 2004 - 2010 Paul Mundt
6 * 8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
7 */ 12 */
8#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/console.h>
15#include <linux/tty.h>
16#include <linux/init.h>
17#include <linux/io.h>
18#include <linux/delay.h>
9#include <asm/sh_bios.h> 19#include <asm/sh_bios.h>
10 20
11#define BIOS_CALL_CONSOLE_WRITE 0 21#define BIOS_CALL_CONSOLE_WRITE 0
12#define BIOS_CALL_ETH_NODE_ADDR 10 22#define BIOS_CALL_ETH_NODE_ADDR 10
13#define BIOS_CALL_SHUTDOWN 11 23#define BIOS_CALL_SHUTDOWN 11
14#define BIOS_CALL_CHAR_OUT 0x1f /* TODO: hack */
15#define BIOS_CALL_GDB_DETACH 0xff 24#define BIOS_CALL_GDB_DETACH 0xff
16 25
26void *gdb_vbr_vector = NULL;
27
17static inline long sh_bios_call(long func, long arg0, long arg1, long arg2, 28static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
18 long arg3) 29 long arg3)
19{ 30{
@@ -23,6 +34,9 @@ static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
23 register long r6 __asm__("r6") = arg2; 34 register long r6 __asm__("r6") = arg2;
24 register long r7 __asm__("r7") = arg3; 35 register long r7 __asm__("r7") = arg3;
25 36
37 if (!gdb_vbr_vector)
38 return -ENOSYS;
39
26 __asm__ __volatile__("trapa #0x3f":"=z"(r0) 40 __asm__ __volatile__("trapa #0x3f":"=z"(r0)
27 :"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7) 41 :"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7)
28 :"memory"); 42 :"memory");
@@ -34,11 +48,6 @@ void sh_bios_console_write(const char *buf, unsigned int len)
34 sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0); 48 sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0);
35} 49}
36 50
37void sh_bios_char_out(char ch)
38{
39 sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0);
40}
41
42void sh_bios_gdb_detach(void) 51void sh_bios_gdb_detach(void)
43{ 52{
44 sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0); 53 sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0);
@@ -55,3 +64,109 @@ void sh_bios_shutdown(unsigned int how)
55{ 64{
56 sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0); 65 sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0);
57} 66}
67
68/*
69 * Read the old value of the VBR register to initialise the vector
70 * through which debug and BIOS traps are delegated by the Linux trap
71 * handler.
72 */
73void sh_bios_vbr_init(void)
74{
75 unsigned long vbr;
76
77 if (unlikely(gdb_vbr_vector))
78 return;
79
80 __asm__ __volatile__ ("stc vbr, %0" : "=r" (vbr));
81
82 if (vbr) {
83 gdb_vbr_vector = (void *)(vbr + 0x100);
84 printk(KERN_NOTICE "Setting GDB trap vector to %p\n",
85 gdb_vbr_vector);
86 } else
87 printk(KERN_NOTICE "SH-BIOS not detected\n");
88}
89
90/**
91 * sh_bios_vbr_reload - Re-load the system VBR from the BIOS vector.
92 *
93 * This can be used by save/restore code to reinitialize the system VBR
94 * from the fixed BIOS VBR. A no-op if no BIOS VBR is known.
95 */
96void sh_bios_vbr_reload(void)
97{
98 if (gdb_vbr_vector)
99 __asm__ __volatile__ (
100 "ldc %0, vbr"
101 :
102 : "r" (((unsigned long) gdb_vbr_vector) - 0x100)
103 : "memory"
104 );
105}
106
107/*
108 * Print a string through the BIOS
109 */
110static void sh_console_write(struct console *co, const char *s,
111 unsigned count)
112{
113 sh_bios_console_write(s, count);
114}
115
116/*
117 * Setup initial baud/bits/parity. We do two things here:
118 * - construct a cflag setting for the first rs_open()
119 * - initialize the serial port
120 * Return non-zero if we didn't find a serial port.
121 */
122static int __init sh_console_setup(struct console *co, char *options)
123{
124 int cflag = CREAD | HUPCL | CLOCAL;
125
126 /*
127 * Now construct a cflag setting.
128 * TODO: this is a totally bogus cflag, as we have
129 * no idea what serial settings the BIOS is using, or
130 * even if its using the serial port at all.
131 */
132 cflag |= B115200 | CS8 | /*no parity*/0;
133
134 co->cflag = cflag;
135
136 return 0;
137}
138
139static struct console bios_console = {
140 .name = "bios",
141 .write = sh_console_write,
142 .setup = sh_console_setup,
143 .flags = CON_PRINTBUFFER,
144 .index = -1,
145};
146
147static struct console *early_console;
148
149static int __init setup_early_printk(char *buf)
150{
151 int keep_early = 0;
152
153 if (!buf)
154 return 0;
155
156 if (strstr(buf, "keep"))
157 keep_early = 1;
158
159 if (!strncmp(buf, "bios", 4))
160 early_console = &bios_console;
161
162 if (likely(early_console)) {
163 if (keep_early)
164 early_console->flags &= ~CON_BOOT;
165 else
166 early_console->flags |= CON_BOOT;
167 register_console(early_console);
168 }
169
170 return 0;
171}
172early_param("earlyprintk", setup_early_printk);
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index 444cce3ae921..3896f26efa4a 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -1,37 +1,11 @@
1#include <linux/module.h> 1#include <linux/module.h>
2#include <linux/smp.h> 2#include <linux/string.h>
3#include <linux/user.h> 3#include <linux/uaccess.h>
4#include <linux/elfcore.h> 4#include <linux/delay.h>
5#include <linux/sched.h> 5#include <linux/mm.h>
6#include <linux/in6.h>
7#include <linux/interrupt.h>
8#include <linux/vmalloc.h>
9#include <linux/pci.h>
10#include <linux/irq.h>
11#include <asm/sections.h>
12#include <asm/processor.h>
13#include <asm/uaccess.h>
14#include <asm/checksum.h> 6#include <asm/checksum.h>
15#include <asm/io.h> 7#include <asm/sections.h>
16#include <asm/delay.h>
17#include <asm/tlbflush.h>
18#include <asm/cacheflush.h>
19#include <asm/ftrace.h>
20
21extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
22
23/* platform dependent support */
24EXPORT_SYMBOL(dump_fpu);
25EXPORT_SYMBOL(kernel_thread);
26EXPORT_SYMBOL(strlen);
27
28/* PCI exports */
29#ifdef CONFIG_PCI
30EXPORT_SYMBOL(pci_alloc_consistent);
31EXPORT_SYMBOL(pci_free_consistent);
32#endif
33 8
34/* mem exports */
35EXPORT_SYMBOL(memchr); 9EXPORT_SYMBOL(memchr);
36EXPORT_SYMBOL(memcpy); 10EXPORT_SYMBOL(memcpy);
37EXPORT_SYMBOL(memset); 11EXPORT_SYMBOL(memset);
@@ -40,6 +14,13 @@ EXPORT_SYMBOL(__copy_user);
40EXPORT_SYMBOL(__udelay); 14EXPORT_SYMBOL(__udelay);
41EXPORT_SYMBOL(__ndelay); 15EXPORT_SYMBOL(__ndelay);
42EXPORT_SYMBOL(__const_udelay); 16EXPORT_SYMBOL(__const_udelay);
17EXPORT_SYMBOL(strlen);
18EXPORT_SYMBOL(csum_partial);
19EXPORT_SYMBOL(csum_partial_copy_generic);
20EXPORT_SYMBOL(copy_page);
21EXPORT_SYMBOL(__clear_user);
22EXPORT_SYMBOL(_ebss);
23EXPORT_SYMBOL(empty_zero_page);
43 24
44#define DECLARE_EXPORT(name) \ 25#define DECLARE_EXPORT(name) \
45 extern void name(void);EXPORT_SYMBOL(name) 26 extern void name(void);EXPORT_SYMBOL(name)
@@ -107,30 +88,6 @@ DECLARE_EXPORT(__sdivsi3_i4);
107DECLARE_EXPORT(__udivsi3_i4); 88DECLARE_EXPORT(__udivsi3_i4);
108DECLARE_EXPORT(__sdivsi3_i4i); 89DECLARE_EXPORT(__sdivsi3_i4i);
109DECLARE_EXPORT(__udivsi3_i4i); 90DECLARE_EXPORT(__udivsi3_i4i);
110
111#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
112 defined(CONFIG_SH7705_CACHE_32KB))
113/* needed by some modules */
114EXPORT_SYMBOL(flush_cache_all);
115EXPORT_SYMBOL(flush_cache_range);
116EXPORT_SYMBOL(flush_dcache_page);
117#endif
118
119#ifdef CONFIG_MCOUNT 91#ifdef CONFIG_MCOUNT
120DECLARE_EXPORT(mcount); 92DECLARE_EXPORT(mcount);
121#endif 93#endif
122EXPORT_SYMBOL(csum_partial);
123EXPORT_SYMBOL(csum_partial_copy_generic);
124#ifdef CONFIG_IPV6
125EXPORT_SYMBOL(csum_ipv6_magic);
126#endif
127EXPORT_SYMBOL(copy_page);
128EXPORT_SYMBOL(__clear_user);
129EXPORT_SYMBOL(_ebss);
130EXPORT_SYMBOL(empty_zero_page);
131
132#ifndef CONFIG_CACHE_OFF
133EXPORT_SYMBOL(__flush_purge_region);
134EXPORT_SYMBOL(__flush_wback_region);
135EXPORT_SYMBOL(__flush_invalidate_region);
136#endif
diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c
index d008e17eb257..45afa5c51f67 100644
--- a/arch/sh/kernel/sh_ksyms_64.c
+++ b/arch/sh/kernel/sh_ksyms_64.c
@@ -24,16 +24,6 @@
24#include <asm/delay.h> 24#include <asm/delay.h>
25#include <asm/irq.h> 25#include <asm/irq.h>
26 26
27extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
28
29/* platform dependent support */
30EXPORT_SYMBOL(dump_fpu);
31EXPORT_SYMBOL(kernel_thread);
32
33#ifdef CONFIG_VT
34EXPORT_SYMBOL(screen_info);
35#endif
36
37EXPORT_SYMBOL(__put_user_asm_b); 27EXPORT_SYMBOL(__put_user_asm_b);
38EXPORT_SYMBOL(__put_user_asm_w); 28EXPORT_SYMBOL(__put_user_asm_w);
39EXPORT_SYMBOL(__put_user_asm_l); 29EXPORT_SYMBOL(__put_user_asm_l);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 3db37425210d..579cd2ca358d 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -67,7 +67,8 @@ sys_sigsuspend(old_sigset_t mask,
67 67
68 current->state = TASK_INTERRUPTIBLE; 68 current->state = TASK_INTERRUPTIBLE;
69 schedule(); 69 schedule();
70 set_thread_flag(TIF_RESTORE_SIGMASK); 70 set_restore_sigmask();
71
71 return -ERESTARTNOHAND; 72 return -ERESTARTNOHAND;
72} 73}
73 74
@@ -149,7 +150,7 @@ static inline int restore_sigcontext_fpu(struct sigcontext __user *sc)
149 return 0; 150 return 0;
150 151
151 set_used_math(); 152 set_used_math();
152 return __copy_from_user(&tsk->thread.fpu.hard, &sc->sc_fpregs[0], 153 return __copy_from_user(&tsk->thread.xstate->hardfpu, &sc->sc_fpregs[0],
153 sizeof(long)*(16*2+2)); 154 sizeof(long)*(16*2+2));
154} 155}
155 156
@@ -174,7 +175,7 @@ static inline int save_sigcontext_fpu(struct sigcontext __user *sc,
174 clear_used_math(); 175 clear_used_math();
175 176
176 unlazy_fpu(tsk, regs); 177 unlazy_fpu(tsk, regs);
177 return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard, 178 return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.xstate->hardfpu,
178 sizeof(long)*(16*2+2)); 179 sizeof(long)*(16*2+2));
179} 180}
180#endif /* CONFIG_SH_FPU */ 181#endif /* CONFIG_SH_FPU */
@@ -527,7 +528,7 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs,
527 /* fallthrough */ 528 /* fallthrough */
528 case -ERESTARTNOINTR: 529 case -ERESTARTNOINTR:
529 regs->regs[0] = save_r0; 530 regs->regs[0] = save_r0;
530 regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); 531 regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
531 break; 532 break;
532 } 533 }
533} 534}
@@ -590,7 +591,7 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
590 if (try_to_freeze()) 591 if (try_to_freeze())
591 goto no_signal; 592 goto no_signal;
592 593
593 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 594 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
594 oldset = &current->saved_sigmask; 595 oldset = &current->saved_sigmask;
595 else 596 else
596 oldset = &current->blocked; 597 oldset = &current->blocked;
@@ -602,12 +603,13 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
602 /* Whee! Actually deliver the signal. */ 603 /* Whee! Actually deliver the signal. */
603 if (handle_signal(signr, &ka, &info, oldset, 604 if (handle_signal(signr, &ka, &info, oldset,
604 regs, save_r0) == 0) { 605 regs, save_r0) == 0) {
605 /* a signal was successfully delivered; the saved 606 /*
607 * A signal was successfully delivered; the saved
606 * sigmask will have been stored in the signal frame, 608 * sigmask will have been stored in the signal frame,
607 * and will be restored by sigreturn, so we can simply 609 * and will be restored by sigreturn, so we can simply
608 * clear the TIF_RESTORE_SIGMASK flag */ 610 * clear the TS_RESTORE_SIGMASK flag
609 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 611 */
610 clear_thread_flag(TIF_RESTORE_SIGMASK); 612 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
611 613
612 tracehook_signal_handler(signr, &info, &ka, regs, 614 tracehook_signal_handler(signr, &info, &ka, regs,
613 test_thread_flag(TIF_SINGLESTEP)); 615 test_thread_flag(TIF_SINGLESTEP));
@@ -624,17 +626,19 @@ no_signal:
624 regs->regs[0] == -ERESTARTSYS || 626 regs->regs[0] == -ERESTARTSYS ||
625 regs->regs[0] == -ERESTARTNOINTR) { 627 regs->regs[0] == -ERESTARTNOINTR) {
626 regs->regs[0] = save_r0; 628 regs->regs[0] = save_r0;
627 regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); 629 regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
628 } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) { 630 } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) {
629 regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); 631 regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
630 regs->regs[3] = __NR_restart_syscall; 632 regs->regs[3] = __NR_restart_syscall;
631 } 633 }
632 } 634 }
633 635
634 /* if there's no signal to deliver, we just put the saved sigmask 636 /*
635 * back */ 637 * If there's no signal to deliver, we just put the saved sigmask
636 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 638 * back.
637 clear_thread_flag(TIF_RESTORE_SIGMASK); 639 */
640 if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
641 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
638 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 642 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
639 } 643 }
640} 644}
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 74793c80a57a..5a9f1f10ebf4 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -101,7 +101,7 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
101 if (try_to_freeze()) 101 if (try_to_freeze())
102 goto no_signal; 102 goto no_signal;
103 103
104 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 104 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
105 oldset = &current->saved_sigmask; 105 oldset = &current->saved_sigmask;
106 else if (!oldset) 106 else if (!oldset)
107 oldset = &current->blocked; 107 oldset = &current->blocked;
@@ -115,12 +115,12 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
115 /* 115 /*
116 * If a signal was successfully delivered, the 116 * If a signal was successfully delivered, the
117 * saved sigmask is in its frame, and we can 117 * saved sigmask is in its frame, and we can
118 * clear the TIF_RESTORE_SIGMASK flag. 118 * clear the TS_RESTORE_SIGMASK flag.
119 */ 119 */
120 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 120 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
121 clear_thread_flag(TIF_RESTORE_SIGMASK);
122 121
123 tracehook_signal_handler(signr, &info, &ka, regs, 0); 122 tracehook_signal_handler(signr, &info, &ka, regs,
123 test_thread_flag(TIF_SINGLESTEP));
124 return 1; 124 return 1;
125 } 125 }
126 } 126 }
@@ -146,8 +146,8 @@ no_signal:
146 } 146 }
147 147
148 /* No signal to deliver -- put the saved sigmask back */ 148 /* No signal to deliver -- put the saved sigmask back */
149 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 149 if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
150 clear_thread_flag(TIF_RESTORE_SIGMASK); 150 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
151 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 151 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
152 } 152 }
153 153
@@ -176,6 +176,7 @@ sys_sigsuspend(old_sigset_t mask,
176 while (1) { 176 while (1) {
177 current->state = TASK_INTERRUPTIBLE; 177 current->state = TASK_INTERRUPTIBLE;
178 schedule(); 178 schedule();
179 set_restore_sigmask();
179 regs->pc += 4; /* because sys_sigreturn decrements the pc */ 180 regs->pc += 4; /* because sys_sigreturn decrements the pc */
180 if (do_signal(regs, &saveset)) { 181 if (do_signal(regs, &saveset)) {
181 /* pc now points at signal handler. Need to decrement 182 /* pc now points at signal handler. Need to decrement
@@ -296,7 +297,7 @@ restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
296 regs->sr |= SR_FD; 297 regs->sr |= SR_FD;
297 } 298 }
298 299
299 err |= __copy_from_user(&current->thread.fpu.hard, &sc->sc_fpregs[0], 300 err |= __copy_from_user(&current->thread.xstate->hardfpu, &sc->sc_fpregs[0],
300 (sizeof(long long) * 32) + (sizeof(int) * 1)); 301 (sizeof(long long) * 32) + (sizeof(int) * 1));
301 302
302 return err; 303 return err;
@@ -315,13 +316,13 @@ setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
315 316
316 if (current == last_task_used_math) { 317 if (current == last_task_used_math) {
317 enable_fpu(); 318 enable_fpu();
318 save_fpu(current, regs); 319 save_fpu(current);
319 disable_fpu(); 320 disable_fpu();
320 last_task_used_math = NULL; 321 last_task_used_math = NULL;
321 regs->sr |= SR_FD; 322 regs->sr |= SR_FD;
322 } 323 }
323 324
324 err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.fpu.hard, 325 err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.xstate->hardfpu,
325 (sizeof(long long) * 32) + (sizeof(int) * 1)); 326 (sizeof(long long) * 32) + (sizeof(int) * 1));
326 clear_used_math(); 327 clear_used_math();
327 328
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 160db1003cfb..002cc612deef 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -69,6 +69,7 @@ asmlinkage void __cpuinit start_secondary(void)
69 unsigned int cpu; 69 unsigned int cpu;
70 struct mm_struct *mm = &init_mm; 70 struct mm_struct *mm = &init_mm;
71 71
72 enable_mmu();
72 atomic_inc(&mm->mm_count); 73 atomic_inc(&mm->mm_count);
73 atomic_inc(&mm->mm_users); 74 atomic_inc(&mm->mm_users);
74 current->active_mm = mm; 75 current->active_mm = mm;
@@ -122,7 +123,9 @@ int __cpuinit __cpu_up(unsigned int cpu)
122 stack_start.bss_start = 0; /* don't clear bss for secondary cpus */ 123 stack_start.bss_start = 0; /* don't clear bss for secondary cpus */
123 stack_start.start_kernel_fn = start_secondary; 124 stack_start.start_kernel_fn = start_secondary;
124 125
125 flush_cache_all(); 126 flush_icache_range((unsigned long)&stack_start,
127 (unsigned long)&stack_start + sizeof(stack_start));
128 wmb();
126 129
127 plat_start_cpu(cpu, (unsigned long)_stext); 130 plat_start_cpu(cpu, (unsigned long)_stext);
128 131
@@ -159,15 +162,6 @@ void smp_send_reschedule(int cpu)
159 plat_send_ipi(cpu, SMP_MSG_RESCHEDULE); 162 plat_send_ipi(cpu, SMP_MSG_RESCHEDULE);
160} 163}
161 164
162static void stop_this_cpu(void *unused)
163{
164 cpu_clear(smp_processor_id(), cpu_online_map);
165 local_irq_disable();
166
167 for (;;)
168 cpu_relax();
169}
170
171void smp_send_stop(void) 165void smp_send_stop(void)
172{ 166{
173 smp_call_function(stop_this_cpu, 0, 0); 167 smp_call_function(stop_this_cpu, 0, 0);
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 8aa5d1ceaf14..81f58371613d 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -28,37 +28,13 @@
28#include <asm/cacheflush.h> 28#include <asm/cacheflush.h>
29#include <asm/cachectl.h> 29#include <asm/cachectl.h>
30 30
31static inline long
32do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
33 unsigned long flags, int fd, unsigned long pgoff)
34{
35 int error = -EBADF;
36 struct file *file = NULL;
37
38 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
39 if (!(flags & MAP_ANONYMOUS)) {
40 file = fget(fd);
41 if (!file)
42 goto out;
43 }
44
45 down_write(&current->mm->mmap_sem);
46 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
47 up_write(&current->mm->mmap_sem);
48
49 if (file)
50 fput(file);
51out:
52 return error;
53}
54
55asmlinkage int old_mmap(unsigned long addr, unsigned long len, 31asmlinkage int old_mmap(unsigned long addr, unsigned long len,
56 unsigned long prot, unsigned long flags, 32 unsigned long prot, unsigned long flags,
57 int fd, unsigned long off) 33 int fd, unsigned long off)
58{ 34{
59 if (off & ~PAGE_MASK) 35 if (off & ~PAGE_MASK)
60 return -EINVAL; 36 return -EINVAL;
61 return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT); 37 return sys_mmap_pgoff(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
62} 38}
63 39
64asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, 40asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
@@ -74,111 +50,7 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
74 50
75 pgoff >>= PAGE_SHIFT - 12; 51 pgoff >>= PAGE_SHIFT - 12;
76 52
77 return do_mmap2(addr, len, prot, flags, fd, pgoff); 53 return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
78}
79
80/*
81 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
82 *
83 * This is really horribly ugly.
84 */
85asmlinkage int sys_ipc(uint call, int first, int second,
86 int third, void __user *ptr, long fifth)
87{
88 int version, ret;
89
90 version = call >> 16; /* hack for backward compatibility */
91 call &= 0xffff;
92
93 if (call <= SEMTIMEDOP)
94 switch (call) {
95 case SEMOP:
96 return sys_semtimedop(first,
97 (struct sembuf __user *)ptr,
98 second, NULL);
99 case SEMTIMEDOP:
100 return sys_semtimedop(first,
101 (struct sembuf __user *)ptr, second,
102 (const struct timespec __user *)fifth);
103 case SEMGET:
104 return sys_semget (first, second, third);
105 case SEMCTL: {
106 union semun fourth;
107 if (!ptr)
108 return -EINVAL;
109 if (get_user(fourth.__pad, (void __user * __user *) ptr))
110 return -EFAULT;
111 return sys_semctl (first, second, third, fourth);
112 }
113 default:
114 return -EINVAL;
115 }
116
117 if (call <= MSGCTL)
118 switch (call) {
119 case MSGSND:
120 return sys_msgsnd (first, (struct msgbuf __user *) ptr,
121 second, third);
122 case MSGRCV:
123 switch (version) {
124 case 0:
125 {
126 struct ipc_kludge tmp;
127
128 if (!ptr)
129 return -EINVAL;
130
131 if (copy_from_user(&tmp,
132 (struct ipc_kludge __user *) ptr,
133 sizeof (tmp)))
134 return -EFAULT;
135
136 return sys_msgrcv (first, tmp.msgp, second,
137 tmp.msgtyp, third);
138 }
139 default:
140 return sys_msgrcv (first,
141 (struct msgbuf __user *) ptr,
142 second, fifth, third);
143 }
144 case MSGGET:
145 return sys_msgget ((key_t) first, second);
146 case MSGCTL:
147 return sys_msgctl (first, second,
148 (struct msqid_ds __user *) ptr);
149 default:
150 return -EINVAL;
151 }
152 if (call <= SHMCTL)
153 switch (call) {
154 case SHMAT:
155 switch (version) {
156 default: {
157 ulong raddr;
158 ret = do_shmat (first, (char __user *) ptr,
159 second, &raddr);
160 if (ret)
161 return ret;
162 return put_user (raddr, (ulong __user *) third);
163 }
164 case 1: /* iBCS2 emulator entry point */
165 if (!segment_eq(get_fs(), get_ds()))
166 return -EINVAL;
167 return do_shmat (first, (char __user *) ptr,
168 second, (ulong *) third);
169 }
170 case SHMDT:
171 return sys_shmdt ((char __user *)ptr);
172 case SHMGET:
173 return sys_shmget (first, second, third);
174 case SHMCTL:
175 return sys_shmctl (first, second,
176 (struct shmid_ds __user *) ptr);
177 default:
178 return -EINVAL;
179 }
180
181 return -EINVAL;
182} 54}
183 55
184/* sys_cacheflush -- flush (part of) the processor cache. */ 56/* sys_cacheflush -- flush (part of) the processor cache. */
@@ -221,14 +93,3 @@ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op)
221 up_read(&current->mm->mmap_sem); 93 up_read(&current->mm->mmap_sem);
222 return 0; 94 return 0;
223} 95}
224
225asmlinkage int sys_uname(struct old_utsname __user *name)
226{
227 int err;
228 if (!name)
229 return -EFAULT;
230 down_read(&uts_sem);
231 err = copy_to_user(name, utsname(), sizeof(*name));
232 up_read(&uts_sem);
233 return err?-EFAULT:0;
234}
diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S
index 5bfde6c77498..2048a20d7c80 100644
--- a/arch/sh/kernel/syscalls_64.S
+++ b/arch/sh/kernel/syscalls_64.S
@@ -391,3 +391,5 @@ sys_call_table:
391 .long sys_pwritev 391 .long sys_pwritev
392 .long sys_rt_tgsigqueueinfo 392 .long sys_rt_tgsigqueueinfo
393 .long sys_perf_event_open 393 .long sys_perf_event_open
394 .long sys_recvmmsg /* 365 */
395 .long sys_accept4
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 953fa1613312..8a0072de2bcc 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -39,12 +39,12 @@ static int null_rtc_set_time(const time_t secs)
39void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; 39void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
40int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; 40int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
41 41
42#ifdef CONFIG_GENERIC_CMOS_UPDATE
43void read_persistent_clock(struct timespec *ts) 42void read_persistent_clock(struct timespec *ts)
44{ 43{
45 rtc_sh_get_time(ts); 44 rtc_sh_get_time(ts);
46} 45}
47 46
47#ifdef CONFIG_GENERIC_CMOS_UPDATE
48int update_persistent_clock(struct timespec now) 48int update_persistent_clock(struct timespec now)
49{ 49{
50 return rtc_sh_set_time(now.tv_sec); 50 return rtc_sh_set_time(now.tv_sec);
@@ -113,9 +113,5 @@ void __init time_init(void)
113 hwblk_init(); 113 hwblk_init();
114 clk_init(); 114 clk_init();
115 115
116 rtc_sh_get_time(&xtime);
117 set_normalized_timespec(&wall_to_monotonic,
118 -xtime.tv_sec, -xtime.tv_nsec);
119
120 late_time_init = sh_late_time_init; 116 late_time_init = sh_late_time_init;
121} 117}
diff --git a/arch/sh/kernel/topology.c b/arch/sh/kernel/topology.c
index 0838942b7083..9b0b633b6c92 100644
--- a/arch/sh/kernel/topology.c
+++ b/arch/sh/kernel/topology.c
@@ -16,6 +16,32 @@
16 16
17static DEFINE_PER_CPU(struct cpu, cpu_devices); 17static DEFINE_PER_CPU(struct cpu, cpu_devices);
18 18
19cpumask_t cpu_core_map[NR_CPUS];
20
21static cpumask_t cpu_coregroup_map(unsigned int cpu)
22{
23 /*
24 * Presently all SH-X3 SMP cores are multi-cores, so just keep it
25 * simple until we have a method for determining topology..
26 */
27 return cpu_possible_map;
28}
29
30const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
31{
32 return &cpu_core_map[cpu];
33}
34
35int arch_update_cpu_topology(void)
36{
37 unsigned int cpu;
38
39 for_each_possible_cpu(cpu)
40 cpu_core_map[cpu] = cpu_coregroup_map(cpu);
41
42 return 0;
43}
44
19static int __init topology_init(void) 45static int __init topology_init(void)
20{ 46{
21 int i, ret; 47 int i, ret;
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index a8396f36bd14..0830c2a9f712 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -9,8 +9,8 @@
9#include <asm/unwinder.h> 9#include <asm/unwinder.h>
10#include <asm/system.h> 10#include <asm/system.h>
11 11
12#ifdef CONFIG_BUG 12#ifdef CONFIG_GENERIC_BUG
13void handle_BUG(struct pt_regs *regs) 13static void handle_BUG(struct pt_regs *regs)
14{ 14{
15 const struct bug_entry *bug; 15 const struct bug_entry *bug;
16 unsigned long bugaddr = regs->pc; 16 unsigned long bugaddr = regs->pc;
@@ -58,7 +58,7 @@ BUILD_TRAP_HANDLER(debug)
58 TRAP_HANDLER_DECL; 58 TRAP_HANDLER_DECL;
59 59
60 /* Rewind */ 60 /* Rewind */
61 regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); 61 regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
62 62
63 if (notify_die(DIE_TRAP, "debug trap", regs, 0, vec & 0xff, 63 if (notify_die(DIE_TRAP, "debug trap", regs, 0, vec & 0xff,
64 SIGTRAP) == NOTIFY_STOP) 64 SIGTRAP) == NOTIFY_STOP)
@@ -75,13 +75,13 @@ BUILD_TRAP_HANDLER(bug)
75 TRAP_HANDLER_DECL; 75 TRAP_HANDLER_DECL;
76 76
77 /* Rewind */ 77 /* Rewind */
78 regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); 78 regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
79 79
80 if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff, 80 if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff,
81 SIGTRAP) == NOTIFY_STOP) 81 SIGTRAP) == NOTIFY_STOP)
82 return; 82 return;
83 83
84#ifdef CONFIG_BUG 84#ifdef CONFIG_GENERIC_BUG
85 if (__kernel_text_address(instruction_pointer(regs))) { 85 if (__kernel_text_address(instruction_pointer(regs))) {
86 insn_size_t insn = *(insn_size_t *)instruction_pointer(regs); 86 insn_size_t insn = *(insn_size_t *)instruction_pointer(regs);
87 if (insn == TRAPA_BUG_OPCODE) 87 if (insn == TRAPA_BUG_OPCODE)
@@ -95,9 +95,11 @@ BUILD_TRAP_HANDLER(bug)
95 95
96BUILD_TRAP_HANDLER(nmi) 96BUILD_TRAP_HANDLER(nmi)
97{ 97{
98 unsigned int cpu = smp_processor_id();
98 TRAP_HANDLER_DECL; 99 TRAP_HANDLER_DECL;
99 100
100 nmi_enter(); 101 nmi_enter();
102 nmi_count(cpu)++;
101 103
102 switch (notify_die(DIE_NMI, "NMI", regs, 0, vec & 0xff, SIGINT)) { 104 switch (notify_die(DIE_NMI, "NMI", regs, 0, vec & 0xff, SIGINT)) {
103 case NOTIFY_OK: 105 case NOTIFY_OK:
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 7a2ee3a6b8e7..c3d86fa71ddf 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -24,10 +24,10 @@
24#include <linux/kdebug.h> 24#include <linux/kdebug.h>
25#include <linux/kexec.h> 25#include <linux/kexec.h>
26#include <linux/limits.h> 26#include <linux/limits.h>
27#include <linux/proc_fs.h>
28#include <linux/sysfs.h> 27#include <linux/sysfs.h>
28#include <linux/uaccess.h>
29#include <asm/system.h> 29#include <asm/system.h>
30#include <asm/uaccess.h> 30#include <asm/alignment.h>
31#include <asm/fpu.h> 31#include <asm/fpu.h>
32#include <asm/kprobes.h> 32#include <asm/kprobes.h>
33 33
@@ -46,85 +46,6 @@
46#define TRAP_ILLEGAL_SLOT_INST 13 46#define TRAP_ILLEGAL_SLOT_INST 13
47#endif 47#endif
48 48
49static unsigned long se_user;
50static unsigned long se_sys;
51static unsigned long se_half;
52static unsigned long se_word;
53static unsigned long se_dword;
54static unsigned long se_multi;
55/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not
56 valid! */
57static int se_usermode = 3;
58/* 0: no warning 1: print a warning message, disabled by default */
59static int se_kernmode_warn;
60
61#ifdef CONFIG_PROC_FS
62static const char *se_usermode_action[] = {
63 "ignored",
64 "warn",
65 "fixup",
66 "fixup+warn",
67 "signal",
68 "signal+warn"
69};
70
71static int
72proc_alignment_read(char *page, char **start, off_t off, int count, int *eof,
73 void *data)
74{
75 char *p = page;
76 int len;
77
78 p += sprintf(p, "User:\t\t%lu\n", se_user);
79 p += sprintf(p, "System:\t\t%lu\n", se_sys);
80 p += sprintf(p, "Half:\t\t%lu\n", se_half);
81 p += sprintf(p, "Word:\t\t%lu\n", se_word);
82 p += sprintf(p, "DWord:\t\t%lu\n", se_dword);
83 p += sprintf(p, "Multi:\t\t%lu\n", se_multi);
84 p += sprintf(p, "User faults:\t%i (%s)\n", se_usermode,
85 se_usermode_action[se_usermode]);
86 p += sprintf(p, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn,
87 se_kernmode_warn ? "+warn" : "");
88
89 len = (p - page) - off;
90 if (len < 0)
91 len = 0;
92
93 *eof = (len <= count) ? 1 : 0;
94 *start = page + off;
95
96 return len;
97}
98
99static int proc_alignment_write(struct file *file, const char __user *buffer,
100 unsigned long count, void *data)
101{
102 char mode;
103
104 if (count > 0) {
105 if (get_user(mode, buffer))
106 return -EFAULT;
107 if (mode >= '0' && mode <= '5')
108 se_usermode = mode - '0';
109 }
110 return count;
111}
112
113static int proc_alignment_kern_write(struct file *file, const char __user *buffer,
114 unsigned long count, void *data)
115{
116 char mode;
117
118 if (count > 0) {
119 if (get_user(mode, buffer))
120 return -EFAULT;
121 if (mode >= '0' && mode <= '1')
122 se_kernmode_warn = mode - '0';
123 }
124 return count;
125}
126#endif
127
128static void dump_mem(const char *str, unsigned long bottom, unsigned long top) 49static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
129{ 50{
130 unsigned long p; 51 unsigned long p;
@@ -276,10 +197,10 @@ static int handle_unaligned_ins(insn_size_t instruction, struct pt_regs *regs,
276 count = 1<<(instruction&3); 197 count = 1<<(instruction&3);
277 198
278 switch (count) { 199 switch (count) {
279 case 1: se_half += 1; break; 200 case 1: inc_unaligned_byte_access(); break;
280 case 2: se_word += 1; break; 201 case 2: inc_unaligned_word_access(); break;
281 case 4: se_dword += 1; break; 202 case 4: inc_unaligned_dword_access(); break;
282 case 8: se_multi += 1; break; /* ??? */ 203 case 8: inc_unaligned_multi_access(); break;
283 } 204 }
284 205
285 ret = -EFAULT; 206 ret = -EFAULT;
@@ -463,12 +384,8 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
463 rm = regs->regs[index]; 384 rm = regs->regs[index];
464 385
465 /* shout about fixups */ 386 /* shout about fixups */
466 if (!expected && printk_ratelimit()) 387 if (!expected)
467 printk(KERN_NOTICE "Fixing up unaligned %s access " 388 unaligned_fixups_notify(current, instruction, regs);
468 "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
469 user_mode(regs) ? "userspace" : "kernel",
470 current->comm, task_pid_nr(current),
471 (void *)regs->pc, instruction);
472 389
473 ret = -EFAULT; 390 ret = -EFAULT;
474 switch (instruction&0xF000) { 391 switch (instruction&0xF000) {
@@ -621,10 +538,10 @@ asmlinkage void do_address_error(struct pt_regs *regs,
621 538
622 if (user_mode(regs)) { 539 if (user_mode(regs)) {
623 int si_code = BUS_ADRERR; 540 int si_code = BUS_ADRERR;
541 unsigned int user_action;
624 542
625 local_irq_enable(); 543 local_irq_enable();
626 544 inc_unaligned_user_access();
627 se_user += 1;
628 545
629 set_fs(USER_DS); 546 set_fs(USER_DS);
630 if (copy_from_user(&instruction, (insn_size_t *)(regs->pc & ~1), 547 if (copy_from_user(&instruction, (insn_size_t *)(regs->pc & ~1),
@@ -635,16 +552,12 @@ asmlinkage void do_address_error(struct pt_regs *regs,
635 set_fs(oldfs); 552 set_fs(oldfs);
636 553
637 /* shout about userspace fixups */ 554 /* shout about userspace fixups */
638 if (se_usermode & 1) 555 unaligned_fixups_notify(current, instruction, regs);
639 printk(KERN_NOTICE "Unaligned userspace access "
640 "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
641 current->comm, current->pid, (void *)regs->pc,
642 instruction);
643 556
644 if (se_usermode & 2) 557 user_action = unaligned_user_action();
558 if (user_action & UM_FIXUP)
645 goto fixup; 559 goto fixup;
646 560 if (user_action & UM_SIGNAL)
647 if (se_usermode & 4)
648 goto uspace_segv; 561 goto uspace_segv;
649 else { 562 else {
650 /* ignore */ 563 /* ignore */
@@ -664,7 +577,7 @@ fixup:
664 &user_mem_access, 0); 577 &user_mem_access, 0);
665 set_fs(oldfs); 578 set_fs(oldfs);
666 579
667 if (tmp==0) 580 if (tmp == 0)
668 return; /* sorted */ 581 return; /* sorted */
669uspace_segv: 582uspace_segv:
670 printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned " 583 printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned "
@@ -677,7 +590,7 @@ uspace_segv:
677 info.si_addr = (void __user *)address; 590 info.si_addr = (void __user *)address;
678 force_sig_info(SIGBUS, &info, current); 591 force_sig_info(SIGBUS, &info, current);
679 } else { 592 } else {
680 se_sys += 1; 593 inc_unaligned_kernel_access();
681 594
682 if (regs->pc & 1) 595 if (regs->pc & 1)
683 die("unaligned program counter", regs, error_code); 596 die("unaligned program counter", regs, error_code);
@@ -692,11 +605,7 @@ uspace_segv:
692 die("insn faulting in do_address_error", regs, 0); 605 die("insn faulting in do_address_error", regs, 0);
693 } 606 }
694 607
695 if (se_kernmode_warn) 608 unaligned_fixups_notify(current, instruction, regs);
696 printk(KERN_NOTICE "Unaligned kernel access "
697 "on behalf of \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
698 current->comm, current->pid, (void *)regs->pc,
699 instruction);
700 609
701 handle_unaligned_access(instruction, regs, 610 handle_unaligned_access(instruction, regs,
702 &user_mem_access, 0); 611 &user_mem_access, 0);
@@ -881,35 +790,10 @@ asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
881 die_if_kernel("exception", regs, ex); 790 die_if_kernel("exception", regs, ex);
882} 791}
883 792
884#if defined(CONFIG_SH_STANDARD_BIOS)
885void *gdb_vbr_vector;
886
887static inline void __init gdb_vbr_init(void)
888{
889 register unsigned long vbr;
890
891 /*
892 * Read the old value of the VBR register to initialise
893 * the vector through which debug and BIOS traps are
894 * delegated by the Linux trap handler.
895 */
896 asm volatile("stc vbr, %0" : "=r" (vbr));
897
898 gdb_vbr_vector = (void *)(vbr + 0x100);
899 printk("Setting GDB trap vector to 0x%08lx\n",
900 (unsigned long)gdb_vbr_vector);
901}
902#endif
903
904void __cpuinit per_cpu_trap_init(void) 793void __cpuinit per_cpu_trap_init(void)
905{ 794{
906 extern void *vbr_base; 795 extern void *vbr_base;
907 796
908#ifdef CONFIG_SH_STANDARD_BIOS
909 if (raw_smp_processor_id() == 0)
910 gdb_vbr_init();
911#endif
912
913 /* NOTE: The VBR value should be at P1 797 /* NOTE: The VBR value should be at P1
914 (or P2, virtural "fixed" address space). 798 (or P2, virtural "fixed" address space).
915 It's definitely should not in physical address. */ 799 It's definitely should not in physical address. */
@@ -945,14 +829,9 @@ void __init trap_init(void)
945 set_exception_table_evt(0x800, do_reserved_inst); 829 set_exception_table_evt(0x800, do_reserved_inst);
946 set_exception_table_evt(0x820, do_illegal_slot_inst); 830 set_exception_table_evt(0x820, do_illegal_slot_inst);
947#elif defined(CONFIG_SH_FPU) 831#elif defined(CONFIG_SH_FPU)
948#ifdef CONFIG_CPU_SUBTYPE_SHX3
949 set_exception_table_evt(0xd80, fpu_state_restore_trap_handler);
950 set_exception_table_evt(0xda0, fpu_state_restore_trap_handler);
951#else
952 set_exception_table_evt(0x800, fpu_state_restore_trap_handler); 832 set_exception_table_evt(0x800, fpu_state_restore_trap_handler);
953 set_exception_table_evt(0x820, fpu_state_restore_trap_handler); 833 set_exception_table_evt(0x820, fpu_state_restore_trap_handler);
954#endif 834#endif
955#endif
956 835
957#ifdef CONFIG_CPU_SH2 836#ifdef CONFIG_CPU_SH2
958 set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_trap_handler); 837 set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_trap_handler);
@@ -966,11 +845,8 @@ void __init trap_init(void)
966#endif 845#endif
967 846
968#ifdef TRAP_UBC 847#ifdef TRAP_UBC
969 set_exception_table_vec(TRAP_UBC, break_point_trap); 848 set_exception_table_vec(TRAP_UBC, breakpoint_trap_handler);
970#endif 849#endif
971
972 /* Setup VBR for boot cpu */
973 per_cpu_trap_init();
974} 850}
975 851
976void show_stack(struct task_struct *tsk, unsigned long *sp) 852void show_stack(struct task_struct *tsk, unsigned long *sp)
@@ -995,38 +871,3 @@ void dump_stack(void)
995 show_stack(NULL, NULL); 871 show_stack(NULL, NULL);
996} 872}
997EXPORT_SYMBOL(dump_stack); 873EXPORT_SYMBOL(dump_stack);
998
999#ifdef CONFIG_PROC_FS
1000/*
1001 * This needs to be done after sysctl_init, otherwise sys/ will be
1002 * overwritten. Actually, this shouldn't be in sys/ at all since
1003 * it isn't a sysctl, and it doesn't contain sysctl information.
1004 * We now locate it in /proc/cpu/alignment instead.
1005 */
1006static int __init alignment_init(void)
1007{
1008 struct proc_dir_entry *dir, *res;
1009
1010 dir = proc_mkdir("cpu", NULL);
1011 if (!dir)
1012 return -ENOMEM;
1013
1014 res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, dir);
1015 if (!res)
1016 return -ENOMEM;
1017
1018 res->read_proc = proc_alignment_read;
1019 res->write_proc = proc_alignment_write;
1020
1021 res = create_proc_entry("kernel_alignment", S_IWUSR | S_IRUGO, dir);
1022 if (!res)
1023 return -ENOMEM;
1024
1025 res->read_proc = proc_alignment_read;
1026 res->write_proc = proc_alignment_kern_write;
1027
1028 return 0;
1029}
1030
1031fs_initcall(alignment_init);
1032#endif
diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c
index 267e5ebbb475..e3f92eb05ffd 100644
--- a/arch/sh/kernel/traps_64.c
+++ b/arch/sh/kernel/traps_64.c
@@ -600,7 +600,7 @@ static int misaligned_fpu_load(struct pt_regs *regs,
600 indexed by register number. */ 600 indexed by register number. */
601 if (last_task_used_math == current) { 601 if (last_task_used_math == current) {
602 enable_fpu(); 602 enable_fpu();
603 save_fpu(current, regs); 603 save_fpu(current);
604 disable_fpu(); 604 disable_fpu();
605 last_task_used_math = NULL; 605 last_task_used_math = NULL;
606 regs->sr |= SR_FD; 606 regs->sr |= SR_FD;
@@ -611,19 +611,19 @@ static int misaligned_fpu_load(struct pt_regs *regs,
611 611
612 switch (width_shift) { 612 switch (width_shift) {
613 case 2: 613 case 2:
614 current->thread.fpu.hard.fp_regs[destreg] = buflo; 614 current->thread.xstate->hardfpu.fp_regs[destreg] = buflo;
615 break; 615 break;
616 case 3: 616 case 3:
617 if (do_paired_load) { 617 if (do_paired_load) {
618 current->thread.fpu.hard.fp_regs[destreg] = buflo; 618 current->thread.xstate->hardfpu.fp_regs[destreg] = buflo;
619 current->thread.fpu.hard.fp_regs[destreg+1] = bufhi; 619 current->thread.xstate->hardfpu.fp_regs[destreg+1] = bufhi;
620 } else { 620 } else {
621#if defined(CONFIG_CPU_LITTLE_ENDIAN) 621#if defined(CONFIG_CPU_LITTLE_ENDIAN)
622 current->thread.fpu.hard.fp_regs[destreg] = bufhi; 622 current->thread.xstate->hardfpu.fp_regs[destreg] = bufhi;
623 current->thread.fpu.hard.fp_regs[destreg+1] = buflo; 623 current->thread.xstate->hardfpu.fp_regs[destreg+1] = buflo;
624#else 624#else
625 current->thread.fpu.hard.fp_regs[destreg] = buflo; 625 current->thread.xstate->hardfpu.fp_regs[destreg] = buflo;
626 current->thread.fpu.hard.fp_regs[destreg+1] = bufhi; 626 current->thread.xstate->hardfpu.fp_regs[destreg+1] = bufhi;
627#endif 627#endif
628 } 628 }
629 break; 629 break;
@@ -673,7 +673,7 @@ static int misaligned_fpu_store(struct pt_regs *regs,
673 indexed by register number. */ 673 indexed by register number. */
674 if (last_task_used_math == current) { 674 if (last_task_used_math == current) {
675 enable_fpu(); 675 enable_fpu();
676 save_fpu(current, regs); 676 save_fpu(current);
677 disable_fpu(); 677 disable_fpu();
678 last_task_used_math = NULL; 678 last_task_used_math = NULL;
679 regs->sr |= SR_FD; 679 regs->sr |= SR_FD;
@@ -681,19 +681,19 @@ static int misaligned_fpu_store(struct pt_regs *regs,
681 681
682 switch (width_shift) { 682 switch (width_shift) {
683 case 2: 683 case 2:
684 buflo = current->thread.fpu.hard.fp_regs[srcreg]; 684 buflo = current->thread.xstate->hardfpu.fp_regs[srcreg];
685 break; 685 break;
686 case 3: 686 case 3:
687 if (do_paired_load) { 687 if (do_paired_load) {
688 buflo = current->thread.fpu.hard.fp_regs[srcreg]; 688 buflo = current->thread.xstate->hardfpu.fp_regs[srcreg];
689 bufhi = current->thread.fpu.hard.fp_regs[srcreg+1]; 689 bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg+1];
690 } else { 690 } else {
691#if defined(CONFIG_CPU_LITTLE_ENDIAN) 691#if defined(CONFIG_CPU_LITTLE_ENDIAN)
692 bufhi = current->thread.fpu.hard.fp_regs[srcreg]; 692 bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg];
693 buflo = current->thread.fpu.hard.fp_regs[srcreg+1]; 693 buflo = current->thread.xstate->hardfpu.fp_regs[srcreg+1];
694#else 694#else
695 buflo = current->thread.fpu.hard.fp_regs[srcreg]; 695 buflo = current->thread.xstate->hardfpu.fp_regs[srcreg];
696 bufhi = current->thread.fpu.hard.fp_regs[srcreg+1]; 696 bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg+1];
697#endif 697#endif
698 } 698 }
699 break; 699 break;
@@ -877,44 +877,39 @@ static int misaligned_fixup(struct pt_regs *regs)
877 877
878static ctl_table unaligned_table[] = { 878static ctl_table unaligned_table[] = {
879 { 879 {
880 .ctl_name = CTL_UNNUMBERED,
881 .procname = "kernel_reports", 880 .procname = "kernel_reports",
882 .data = &kernel_mode_unaligned_fixup_count, 881 .data = &kernel_mode_unaligned_fixup_count,
883 .maxlen = sizeof(int), 882 .maxlen = sizeof(int),
884 .mode = 0644, 883 .mode = 0644,
885 .proc_handler = &proc_dointvec 884 .proc_handler = proc_dointvec
886 }, 885 },
887 { 886 {
888 .ctl_name = CTL_UNNUMBERED,
889 .procname = "user_reports", 887 .procname = "user_reports",
890 .data = &user_mode_unaligned_fixup_count, 888 .data = &user_mode_unaligned_fixup_count,
891 .maxlen = sizeof(int), 889 .maxlen = sizeof(int),
892 .mode = 0644, 890 .mode = 0644,
893 .proc_handler = &proc_dointvec 891 .proc_handler = proc_dointvec
894 }, 892 },
895 { 893 {
896 .ctl_name = CTL_UNNUMBERED,
897 .procname = "user_enable", 894 .procname = "user_enable",
898 .data = &user_mode_unaligned_fixup_enable, 895 .data = &user_mode_unaligned_fixup_enable,
899 .maxlen = sizeof(int), 896 .maxlen = sizeof(int),
900 .mode = 0644, 897 .mode = 0644,
901 .proc_handler = &proc_dointvec}, 898 .proc_handler = proc_dointvec},
902 {} 899 {}
903}; 900};
904 901
905static ctl_table unaligned_root[] = { 902static ctl_table unaligned_root[] = {
906 { 903 {
907 .ctl_name = CTL_UNNUMBERED,
908 .procname = "unaligned_fixup", 904 .procname = "unaligned_fixup",
909 .mode = 0555, 905 .mode = 0555,
910 unaligned_table 906 .child = unaligned_table
911 }, 907 },
912 {} 908 {}
913}; 909};
914 910
915static ctl_table sh64_root[] = { 911static ctl_table sh64_root[] = {
916 { 912 {
917 .ctl_name = CTL_UNNUMBERED,
918 .procname = "sh64", 913 .procname = "sh64",
919 .mode = 0555, 914 .mode = 0555,
920 .child = unaligned_root 915 .child = unaligned_root
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index a1e4ec24f1f5..7f8a709c3ada 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -3,7 +3,7 @@
3 * Written by Niibe Yutaka and Paul Mundt 3 * Written by Niibe Yutaka and Paul Mundt
4 */ 4 */
5#ifdef CONFIG_SUPERH64 5#ifdef CONFIG_SUPERH64
6#define LOAD_OFFSET CONFIG_PAGE_OFFSET 6#define LOAD_OFFSET PAGE_OFFSET
7OUTPUT_ARCH(sh:sh5) 7OUTPUT_ARCH(sh:sh5)
8#else 8#else
9#define LOAD_OFFSET 0 9#define LOAD_OFFSET 0
@@ -14,17 +14,16 @@ OUTPUT_ARCH(sh)
14#include <asm/cache.h> 14#include <asm/cache.h>
15#include <asm/vmlinux.lds.h> 15#include <asm/vmlinux.lds.h>
16 16
17#ifdef CONFIG_PMB
18 #define MEMORY_OFFSET 0
19#else
20 #define MEMORY_OFFSET __MEMORY_START
21#endif
22
17ENTRY(_start) 23ENTRY(_start)
18SECTIONS 24SECTIONS
19{ 25{
20#ifdef CONFIG_PMB_FIXED 26 . = PAGE_OFFSET + MEMORY_OFFSET + CONFIG_ZERO_PAGE_OFFSET;
21 . = CONFIG_PAGE_OFFSET + (CONFIG_MEMORY_START & 0x1fffffff) +
22 CONFIG_ZERO_PAGE_OFFSET;
23#elif defined(CONFIG_32BIT)
24 . = CONFIG_PAGE_OFFSET + CONFIG_ZERO_PAGE_OFFSET;
25#else
26 . = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET;
27#endif
28 27
29 _text = .; /* Text and read-only data */ 28 _text = .; /* Text and read-only data */
30 29
@@ -35,12 +34,7 @@ SECTIONS
35 .text : AT(ADDR(.text) - LOAD_OFFSET) { 34 .text : AT(ADDR(.text) - LOAD_OFFSET) {
36 HEAD_TEXT 35 HEAD_TEXT
37 TEXT_TEXT 36 TEXT_TEXT
38 37 EXTRA_TEXT
39#ifdef CONFIG_SUPERH64
40 *(.text64)
41 *(.text..SHmedia32)
42#endif
43
44 SCHED_TEXT 38 SCHED_TEXT
45 LOCK_TEXT 39 LOCK_TEXT
46 KPROBES_TEXT 40 KPROBES_TEXT
@@ -51,24 +45,12 @@ SECTIONS
51 } = 0x0009 45 } = 0x0009
52 46
53 EXCEPTION_TABLE(16) 47 EXCEPTION_TABLE(16)
54
55 NOTES 48 NOTES
56 RO_DATA(PAGE_SIZE)
57
58 /*
59 * Code which must be executed uncached and the associated data
60 */
61 . = ALIGN(PAGE_SIZE);
62 .uncached : AT(ADDR(.uncached) - LOAD_OFFSET) {
63 __uncached_start = .;
64 *(.uncached.text)
65 *(.uncached.data)
66 __uncached_end = .;
67 }
68 49
50 _sdata = .;
51 RO_DATA(PAGE_SIZE)
69 RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) 52 RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
70 53 _edata = .;
71 _edata = .; /* End of data section */
72 54
73 DWARF_EH_FRAME 55 DWARF_EH_FRAME
74 56
diff --git a/arch/sh/kernel/vsyscall/vsyscall.c b/arch/sh/kernel/vsyscall/vsyscall.c
index 3f7e415be86a..242117cbad67 100644
--- a/arch/sh/kernel/vsyscall/vsyscall.c
+++ b/arch/sh/kernel/vsyscall/vsyscall.c
@@ -11,7 +11,6 @@
11 * for more details. 11 * for more details.
12 */ 12 */
13#include <linux/mm.h> 13#include <linux/mm.h>
14#include <linux/slab.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16#include <linux/init.h> 15#include <linux/init.h>
17#include <linux/gfp.h> 16#include <linux/gfp.h>