aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/sh2a
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu/sh2a')
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7201.c26
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7203.c25
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7206.c26
-rw-r--r--arch/sh/kernel/cpu/sh2a/entry.S3
-rw-r--r--arch/sh/kernel/cpu/sh2a/fpu.c110
-rw-r--r--arch/sh/kernel/cpu/sh2a/probe.c6
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-mxg.c38
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7201.c224
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7203.c119
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7206.c122
10 files changed, 367 insertions, 332 deletions
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
index 7814c76159a7..1174e2d96c03 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
@@ -22,19 +22,12 @@ static const int pll1rate[]={1,2,3,4,6,8};
22static const int pfc_divisors[]={1,2,3,4,6,8,12}; 22static const int pfc_divisors[]={1,2,3,4,6,8,12};
23#define ifc_divisors pfc_divisors 23#define ifc_divisors pfc_divisors
24 24
25#if (CONFIG_SH_CLK_MD == 0) 25static unsigned int pll2_mult;
26#define PLL2 (4)
27#elif (CONFIG_SH_CLK_MD == 2)
28#define PLL2 (2)
29#elif (CONFIG_SH_CLK_MD == 3)
30#define PLL2 (1)
31#else
32#error "Illegal Clock Mode!"
33#endif
34 26
35static void master_clk_init(struct clk *clk) 27static void master_clk_init(struct clk *clk)
36{ 28{
37 return 10000000 * PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; 29 clk->rate = 10000000 * pll2_mult *
30 pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
38} 31}
39 32
40static struct clk_ops sh7201_master_clk_ops = { 33static struct clk_ops sh7201_master_clk_ops = {
@@ -43,7 +36,7 @@ static struct clk_ops sh7201_master_clk_ops = {
43 36
44static unsigned long module_clk_recalc(struct clk *clk) 37static unsigned long module_clk_recalc(struct clk *clk)
45{ 38{
46 int idx = (ctrl_inw(FREQCR) & 0x0007); 39 int idx = (__raw_readw(FREQCR) & 0x0007);
47 return clk->parent->rate / pfc_divisors[idx]; 40 return clk->parent->rate / pfc_divisors[idx];
48} 41}
49 42
@@ -53,7 +46,7 @@ static struct clk_ops sh7201_module_clk_ops = {
53 46
54static unsigned long bus_clk_recalc(struct clk *clk) 47static unsigned long bus_clk_recalc(struct clk *clk)
55{ 48{
56 int idx = (ctrl_inw(FREQCR) & 0x0007); 49 int idx = (__raw_readw(FREQCR) & 0x0007);
57 return clk->parent->rate / pfc_divisors[idx]; 50 return clk->parent->rate / pfc_divisors[idx];
58} 51}
59 52
@@ -63,7 +56,7 @@ static struct clk_ops sh7201_bus_clk_ops = {
63 56
64static unsigned long cpu_clk_recalc(struct clk *clk) 57static unsigned long cpu_clk_recalc(struct clk *clk)
65{ 58{
66 int idx = ((ctrl_inw(FREQCR) >> 4) & 0x0007); 59 int idx = ((__raw_readw(FREQCR) >> 4) & 0x0007);
67 return clk->parent->rate / ifc_divisors[idx]; 60 return clk->parent->rate / ifc_divisors[idx];
68} 61}
69 62
@@ -80,6 +73,13 @@ static struct clk_ops *sh7201_clk_ops[] = {
80 73
81void __init arch_init_clk_ops(struct clk_ops **ops, int idx) 74void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
82{ 75{
76 if (test_mode_pin(MODE_PIN1 | MODE_PIN0))
77 pll2_mult = 1;
78 else if (test_mode_pin(MODE_PIN1))
79 pll2_mult = 2;
80 else
81 pll2_mult = 4;
82
83 if (idx < ARRAY_SIZE(sh7201_clk_ops)) 83 if (idx < ARRAY_SIZE(sh7201_clk_ops))
84 *ops = sh7201_clk_ops[idx]; 84 *ops = sh7201_clk_ops[idx];
85} 85}
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
index 940986965102..95a008e8b735 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
@@ -25,21 +25,11 @@ static const int pll1rate[]={8,12,16,0};
25static const int pfc_divisors[]={1,2,3,4,6,8,12}; 25static const int pfc_divisors[]={1,2,3,4,6,8,12};
26#define ifc_divisors pfc_divisors 26#define ifc_divisors pfc_divisors
27 27
28#if (CONFIG_SH_CLK_MD == 0) 28static unsigned int pll2_mult;
29#define PLL2 (1)
30#elif (CONFIG_SH_CLK_MD == 1)
31#define PLL2 (2)
32#elif (CONFIG_SH_CLK_MD == 2)
33#define PLL2 (4)
34#elif (CONFIG_SH_CLK_MD == 3)
35#define PLL2 (4)
36#else
37#error "Illegal Clock Mode!"
38#endif
39 29
40static void master_clk_init(struct clk *clk) 30static void master_clk_init(struct clk *clk)
41{ 31{
42 clk->rate *= pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0003] * PLL2 ; 32 clk->rate *= pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0003] * pll2_mult;
43} 33}
44 34
45static struct clk_ops sh7203_master_clk_ops = { 35static struct clk_ops sh7203_master_clk_ops = {
@@ -48,7 +38,7 @@ static struct clk_ops sh7203_master_clk_ops = {
48 38
49static unsigned long module_clk_recalc(struct clk *clk) 39static unsigned long module_clk_recalc(struct clk *clk)
50{ 40{
51 int idx = (ctrl_inw(FREQCR) & 0x0007); 41 int idx = (__raw_readw(FREQCR) & 0x0007);
52 return clk->parent->rate / pfc_divisors[idx]; 42 return clk->parent->rate / pfc_divisors[idx];
53} 43}
54 44
@@ -58,7 +48,7 @@ static struct clk_ops sh7203_module_clk_ops = {
58 48
59static unsigned long bus_clk_recalc(struct clk *clk) 49static unsigned long bus_clk_recalc(struct clk *clk)
60{ 50{
61 int idx = (ctrl_inw(FREQCR) & 0x0007); 51 int idx = (__raw_readw(FREQCR) & 0x0007);
62 return clk->parent->rate / pfc_divisors[idx-2]; 52 return clk->parent->rate / pfc_divisors[idx-2];
63} 53}
64 54
@@ -79,6 +69,13 @@ static struct clk_ops *sh7203_clk_ops[] = {
79 69
80void __init arch_init_clk_ops(struct clk_ops **ops, int idx) 70void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
81{ 71{
72 if (test_mode_pin(MODE_PIN1))
73 pll2_mult = 4;
74 else if (test_mode_pin(MODE_PIN0))
75 pll2_mult = 2;
76 else
77 pll2_mult = 1;
78
82 if (idx < ARRAY_SIZE(sh7203_clk_ops)) 79 if (idx < ARRAY_SIZE(sh7203_clk_ops))
83 *ops = sh7203_clk_ops[idx]; 80 *ops = sh7203_clk_ops[idx];
84} 81}
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
index c2268bdeceeb..3c314d7cd6e6 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
@@ -22,19 +22,11 @@ static const int pll1rate[]={1,2,3,4,6,8};
22static const int pfc_divisors[]={1,2,3,4,6,8,12}; 22static const int pfc_divisors[]={1,2,3,4,6,8,12};
23#define ifc_divisors pfc_divisors 23#define ifc_divisors pfc_divisors
24 24
25#if (CONFIG_SH_CLK_MD == 2) 25static unsigned int pll2_mult;
26#define PLL2 (4)
27#elif (CONFIG_SH_CLK_MD == 6)
28#define PLL2 (2)
29#elif (CONFIG_SH_CLK_MD == 7)
30#define PLL2 (1)
31#else
32#error "Illigal Clock Mode!"
33#endif
34 26
35static void master_clk_init(struct clk *clk) 27static void master_clk_init(struct clk *clk)
36{ 28{
37 clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; 29 clk->rate *= pll2_mult * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
38} 30}
39 31
40static struct clk_ops sh7206_master_clk_ops = { 32static struct clk_ops sh7206_master_clk_ops = {
@@ -43,7 +35,7 @@ static struct clk_ops sh7206_master_clk_ops = {
43 35
44static unsigned long module_clk_recalc(struct clk *clk) 36static unsigned long module_clk_recalc(struct clk *clk)
45{ 37{
46 int idx = (ctrl_inw(FREQCR) & 0x0007); 38 int idx = (__raw_readw(FREQCR) & 0x0007);
47 return clk->parent->rate / pfc_divisors[idx]; 39 return clk->parent->rate / pfc_divisors[idx];
48} 40}
49 41
@@ -53,7 +45,7 @@ static struct clk_ops sh7206_module_clk_ops = {
53 45
54static unsigned long bus_clk_recalc(struct clk *clk) 46static unsigned long bus_clk_recalc(struct clk *clk)
55{ 47{
56 return clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; 48 return clk->parent->rate / pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
57} 49}
58 50
59static struct clk_ops sh7206_bus_clk_ops = { 51static struct clk_ops sh7206_bus_clk_ops = {
@@ -62,7 +54,7 @@ static struct clk_ops sh7206_bus_clk_ops = {
62 54
63static unsigned long cpu_clk_recalc(struct clk *clk) 55static unsigned long cpu_clk_recalc(struct clk *clk)
64{ 56{
65 int idx = (ctrl_inw(FREQCR) & 0x0007); 57 int idx = (__raw_readw(FREQCR) & 0x0007);
66 return clk->parent->rate / ifc_divisors[idx]; 58 return clk->parent->rate / ifc_divisors[idx];
67} 59}
68 60
@@ -79,7 +71,13 @@ static struct clk_ops *sh7206_clk_ops[] = {
79 71
80void __init arch_init_clk_ops(struct clk_ops **ops, int idx) 72void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
81{ 73{
74 if (test_mode_pin(MODE_PIN2 | MODE_PIN1 | MODE_PIN0))
75 pll2_mult = 1;
76 else if (test_mode_pin(MODE_PIN2 | MODE_PIN1))
77 pll2_mult = 2;
78 else if (test_mode_pin(MODE_PIN1))
79 pll2_mult = 4;
80
82 if (idx < ARRAY_SIZE(sh7206_clk_ops)) 81 if (idx < ARRAY_SIZE(sh7206_clk_ops))
83 *ops = sh7206_clk_ops[idx]; 82 *ops = sh7206_clk_ops[idx];
84} 83}
85
diff --git a/arch/sh/kernel/cpu/sh2a/entry.S b/arch/sh/kernel/cpu/sh2a/entry.S
index ab3903eeda5c..222742ddc0d6 100644
--- a/arch/sh/kernel/cpu/sh2a/entry.S
+++ b/arch/sh/kernel/cpu/sh2a/entry.S
@@ -176,8 +176,9 @@ ENTRY(sh_bios_handler)
176 movml.l @r15+,r14 176 movml.l @r15+,r14
177 add #8,r15 177 add #8,r15
178 lds.l @r15+, pr 178 lds.l @r15+, pr
179 mov.l @r15+,r15
179 rte 180 rte
180 mov.l @r15+,r15 181 nop
181 .align 2 182 .align 2
1821: .long gdb_vbr_vector 1831: .long gdb_vbr_vector
183#endif /* CONFIG_SH_STANDARD_BIOS */ 184#endif /* CONFIG_SH_STANDARD_BIOS */
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/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c
index e098e2f6aa08..48e97a2a0c8d 100644
--- a/arch/sh/kernel/cpu/sh2a/probe.c
+++ b/arch/sh/kernel/cpu/sh2a/probe.c
@@ -13,8 +13,10 @@
13#include <asm/processor.h> 13#include <asm/processor.h>
14#include <asm/cache.h> 14#include <asm/cache.h>
15 15
16int __init detect_cpu_and_cache_system(void) 16void __cpuinit cpu_probe(void)
17{ 17{
18 boot_cpu_data.family = CPU_FAMILY_SH2A;
19
18 /* All SH-2A CPUs have support for 16 and 32-bit opcodes.. */ 20 /* All SH-2A CPUs have support for 16 and 32-bit opcodes.. */
19 boot_cpu_data.flags |= CPU_HAS_OP32; 21 boot_cpu_data.flags |= CPU_HAS_OP32;
20 22
@@ -49,6 +51,4 @@ int __init detect_cpu_and_cache_system(void)
49 * on the cache info. 51 * on the cache info.
50 */ 52 */
51 boot_cpu_data.icache = boot_cpu_data.dcache; 53 boot_cpu_data.icache = boot_cpu_data.dcache;
52
53 return 0;
54} 54}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
index b2c3bcc01190..949bf2bac28c 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
@@ -115,16 +115,13 @@ static DECLARE_INTC_DESC(intc_desc, "mxg", vectors, groups,
115 mask_registers, prio_registers, NULL); 115 mask_registers, prio_registers, NULL);
116 116
117static struct sh_timer_config mtu2_0_platform_data = { 117static struct sh_timer_config mtu2_0_platform_data = {
118 .name = "MTU2_0",
119 .channel_offset = -0x80, 118 .channel_offset = -0x80,
120 .timer_bit = 0, 119 .timer_bit = 0,
121 .clk = "peripheral_clk",
122 .clockevent_rating = 200, 120 .clockevent_rating = 200,
123}; 121};
124 122
125static struct resource mtu2_0_resources[] = { 123static struct resource mtu2_0_resources[] = {
126 [0] = { 124 [0] = {
127 .name = "MTU2_0",
128 .start = 0xff801300, 125 .start = 0xff801300,
129 .end = 0xff801326, 126 .end = 0xff801326,
130 .flags = IORESOURCE_MEM, 127 .flags = IORESOURCE_MEM,
@@ -146,16 +143,13 @@ static struct platform_device mtu2_0_device = {
146}; 143};
147 144
148static struct sh_timer_config mtu2_1_platform_data = { 145static struct sh_timer_config mtu2_1_platform_data = {
149 .name = "MTU2_1",
150 .channel_offset = -0x100, 146 .channel_offset = -0x100,
151 .timer_bit = 1, 147 .timer_bit = 1,
152 .clk = "peripheral_clk",
153 .clockevent_rating = 200, 148 .clockevent_rating = 200,
154}; 149};
155 150
156static struct resource mtu2_1_resources[] = { 151static struct resource mtu2_1_resources[] = {
157 [0] = { 152 [0] = {
158 .name = "MTU2_1",
159 .start = 0xff801380, 153 .start = 0xff801380,
160 .end = 0xff801390, 154 .end = 0xff801390,
161 .flags = IORESOURCE_MEM, 155 .flags = IORESOURCE_MEM,
@@ -177,16 +171,13 @@ static struct platform_device mtu2_1_device = {
177}; 171};
178 172
179static struct sh_timer_config mtu2_2_platform_data = { 173static struct sh_timer_config mtu2_2_platform_data = {
180 .name = "MTU2_2",
181 .channel_offset = 0x80, 174 .channel_offset = 0x80,
182 .timer_bit = 2, 175 .timer_bit = 2,
183 .clk = "peripheral_clk",
184 .clockevent_rating = 200, 176 .clockevent_rating = 200,
185}; 177};
186 178
187static struct resource mtu2_2_resources[] = { 179static struct resource mtu2_2_resources[] = {
188 [0] = { 180 [0] = {
189 .name = "MTU2_2",
190 .start = 0xff801000, 181 .start = 0xff801000,
191 .end = 0xff80100a, 182 .end = 0xff80100a,
192 .flags = IORESOURCE_MEM, 183 .flags = IORESOURCE_MEM,
@@ -207,29 +198,25 @@ static struct platform_device mtu2_2_device = {
207 .num_resources = ARRAY_SIZE(mtu2_2_resources), 198 .num_resources = ARRAY_SIZE(mtu2_2_resources),
208}; 199};
209 200
210static struct plat_sci_port sci_platform_data[] = { 201static struct plat_sci_port scif0_platform_data = {
211 { 202 .mapbase = 0xff804000,
212 .mapbase = 0xff804000, 203 .flags = UPF_BOOT_AUTOCONF,
213 .flags = UPF_BOOT_AUTOCONF, 204 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
214 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 205 .scbrr_algo_id = SCBRR_ALGO_2,
215 .scbrr_algo_id = SCBRR_ALGO_2, 206 .type = PORT_SCIF,
216 .type = PORT_SCIF, 207 .irqs = { 220, 220, 220, 220 },
217 .irqs = { 220, 220, 220, 220 },
218 }, {
219 .flags = 0,
220 }
221}; 208};
222 209
223static struct platform_device sci_device = { 210static struct platform_device scif0_device = {
224 .name = "sh-sci", 211 .name = "sh-sci",
225 .id = -1, 212 .id = 0,
226 .dev = { 213 .dev = {
227 .platform_data = sci_platform_data, 214 .platform_data = &scif0_platform_data,
228 }, 215 },
229}; 216};
230 217
231static struct platform_device *mxg_devices[] __initdata = { 218static struct platform_device *mxg_devices[] __initdata = {
232 &sci_device, 219 &scif0_device,
233 &mtu2_0_device, 220 &mtu2_0_device,
234 &mtu2_1_device, 221 &mtu2_1_device,
235 &mtu2_2_device, 222 &mtu2_2_device,
@@ -240,7 +227,7 @@ static int __init mxg_devices_setup(void)
240 return platform_add_devices(mxg_devices, 227 return platform_add_devices(mxg_devices,
241 ARRAY_SIZE(mxg_devices)); 228 ARRAY_SIZE(mxg_devices));
242} 229}
243__initcall(mxg_devices_setup); 230arch_initcall(mxg_devices_setup);
244 231
245void __init plat_irq_setup(void) 232void __init plat_irq_setup(void)
246{ 233{
@@ -248,6 +235,7 @@ void __init plat_irq_setup(void)
248} 235}
249 236
250static struct platform_device *mxg_early_devices[] __initdata = { 237static struct platform_device *mxg_early_devices[] __initdata = {
238 &scif0_device,
251 &mtu2_0_device, 239 &mtu2_0_device,
252 &mtu2_1_device, 240 &mtu2_1_device,
253 &mtu2_2_device, 241 &mtu2_2_device,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
index 8d44917ce50b..9df558dcdb86 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
@@ -177,73 +177,139 @@ 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 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
184 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 184 .scbrr_algo_id = SCBRR_ALGO_2,
185 .scbrr_algo_id = SCBRR_ALGO_2, 185 .type = PORT_SCIF,
186 .type = PORT_SCIF, 186 .irqs = { 180, 180, 180, 180 }
187 .irqs = { 180, 180, 180, 180 } 187};
188 }, { 188
189 .mapbase = 0xfffe8800, 189static struct platform_device scif0_device = {
190 .flags = UPF_BOOT_AUTOCONF,
191 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
192 .scbrr_algo_id = SCBRR_ALGO_2,
193 .type = PORT_SCIF,
194 .irqs = { 184, 184, 184, 184 }
195 }, {
196 .mapbase = 0xfffe9000,
197 .flags = UPF_BOOT_AUTOCONF,
198 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
199 .scbrr_algo_id = SCBRR_ALGO_2,
200 .type = PORT_SCIF,
201 .irqs = { 188, 188, 188, 188 }
202 }, {
203 .mapbase = 0xfffe9800,
204 .flags = UPF_BOOT_AUTOCONF,
205 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
206 .scbrr_algo_id = SCBRR_ALGO_2,
207 .type = PORT_SCIF,
208 .irqs = { 192, 192, 192, 192 }
209 }, {
210 .mapbase = 0xfffea000,
211 .flags = UPF_BOOT_AUTOCONF,
212 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
213 .scbrr_algo_id = SCBRR_ALGO_2,
214 .type = PORT_SCIF,
215 .irqs = { 196, 196, 196, 196 }
216 }, {
217 .mapbase = 0xfffea800,
218 .flags = UPF_BOOT_AUTOCONF,
219 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
220 .scbrr_algo_id = SCBRR_ALGO_2,
221 .type = PORT_SCIF,
222 .irqs = { 200, 200, 200, 200 }
223 }, {
224 .mapbase = 0xfffeb000,
225 .flags = UPF_BOOT_AUTOCONF,
226 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
227 .scbrr_algo_id = SCBRR_ALGO_2,
228 .type = PORT_SCIF,
229 .irqs = { 204, 204, 204, 204 }
230 }, {
231 .mapbase = 0xfffeb800,
232 .flags = UPF_BOOT_AUTOCONF,
233 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
234 .scbrr_algo_id = SCBRR_ALGO_2,
235 .type = PORT_SCIF,
236 .irqs = { 208, 208, 208, 208 }
237 }, {
238 .flags = 0,
239 }
240};
241
242static struct platform_device sci_device = {
243 .name = "sh-sci", 190 .name = "sh-sci",
244 .id = -1, 191 .id = 0,
192 .dev = {
193 .platform_data = &scif0_platform_data,
194 },
195};
196
197static struct plat_sci_port scif1_platform_data = {
198 .mapbase = 0xfffe8800,
199 .flags = UPF_BOOT_AUTOCONF,
200 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
201 .scbrr_algo_id = SCBRR_ALGO_2,
202 .type = PORT_SCIF,
203 .irqs = { 184, 184, 184, 184 }
204};
205
206static struct platform_device scif1_device = {
207 .name = "sh-sci",
208 .id = 1,
209 .dev = {
210 .platform_data = &scif1_platform_data,
211 },
212};
213
214static struct plat_sci_port scif2_platform_data = {
215 .mapbase = 0xfffe9000,
216 .flags = UPF_BOOT_AUTOCONF,
217 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
218 .scbrr_algo_id = SCBRR_ALGO_2,
219 .type = PORT_SCIF,
220 .irqs = { 188, 188, 188, 188 }
221};
222
223static struct platform_device scif2_device = {
224 .name = "sh-sci",
225 .id = 2,
226 .dev = {
227 .platform_data = &scif2_platform_data,
228 },
229};
230
231static struct plat_sci_port scif3_platform_data = {
232 .mapbase = 0xfffe9800,
233 .flags = UPF_BOOT_AUTOCONF,
234 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
235 .scbrr_algo_id = SCBRR_ALGO_2,
236 .type = PORT_SCIF,
237 .irqs = { 192, 192, 192, 192 }
238};
239
240static struct platform_device scif3_device = {
241 .name = "sh-sci",
242 .id = 3,
243 .dev = {
244 .platform_data = &scif3_platform_data,
245 },
246};
247
248static struct plat_sci_port scif4_platform_data = {
249 .mapbase = 0xfffea000,
250 .flags = UPF_BOOT_AUTOCONF,
251 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
252 .scbrr_algo_id = SCBRR_ALGO_2,
253 .type = PORT_SCIF,
254 .irqs = { 196, 196, 196, 196 }
255};
256
257static struct platform_device scif4_device = {
258 .name = "sh-sci",
259 .id = 4,
260 .dev = {
261 .platform_data = &scif4_platform_data,
262 },
263};
264
265static struct plat_sci_port scif5_platform_data = {
266 .mapbase = 0xfffea800,
267 .flags = UPF_BOOT_AUTOCONF,
268 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
269 .scbrr_algo_id = SCBRR_ALGO_2,
270 .type = PORT_SCIF,
271 .irqs = { 200, 200, 200, 200 }
272};
273
274static struct platform_device scif5_device = {
275 .name = "sh-sci",
276 .id = 5,
277 .dev = {
278 .platform_data = &scif5_platform_data,
279 },
280};
281
282static struct plat_sci_port scif6_platform_data = {
283 .mapbase = 0xfffeb000,
284 .flags = UPF_BOOT_AUTOCONF,
285 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
286 .scbrr_algo_id = SCBRR_ALGO_2,
287 .type = PORT_SCIF,
288 .irqs = { 204, 204, 204, 204 }
289};
290
291static struct platform_device scif6_device = {
292 .name = "sh-sci",
293 .id = 6,
294 .dev = {
295 .platform_data = &scif6_platform_data,
296 },
297};
298
299static struct plat_sci_port scif7_platform_data = {
300 .mapbase = 0xfffeb800,
301 .flags = UPF_BOOT_AUTOCONF,
302 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
303 .scbrr_algo_id = SCBRR_ALGO_2,
304 .type = PORT_SCIF,
305 .irqs = { 208, 208, 208, 208 }
306};
307
308static struct platform_device scif7_device = {
309 .name = "sh-sci",
310 .id = 7,
245 .dev = { 311 .dev = {
246 .platform_data = sci_platform_data, 312 .platform_data = &scif7_platform_data,
247 }, 313 },
248}; 314};
249 315
@@ -268,16 +334,13 @@ static struct platform_device rtc_device = {
268}; 334};
269 335
270static struct sh_timer_config mtu2_0_platform_data = { 336static struct sh_timer_config mtu2_0_platform_data = {
271 .name = "MTU2_0",
272 .channel_offset = -0x80, 337 .channel_offset = -0x80,
273 .timer_bit = 0, 338 .timer_bit = 0,
274 .clk = "peripheral_clk",
275 .clockevent_rating = 200, 339 .clockevent_rating = 200,
276}; 340};
277 341
278static struct resource mtu2_0_resources[] = { 342static struct resource mtu2_0_resources[] = {
279 [0] = { 343 [0] = {
280 .name = "MTU2_0",
281 .start = 0xfffe4300, 344 .start = 0xfffe4300,
282 .end = 0xfffe4326, 345 .end = 0xfffe4326,
283 .flags = IORESOURCE_MEM, 346 .flags = IORESOURCE_MEM,
@@ -299,16 +362,13 @@ static struct platform_device mtu2_0_device = {
299}; 362};
300 363
301static struct sh_timer_config mtu2_1_platform_data = { 364static struct sh_timer_config mtu2_1_platform_data = {
302 .name = "MTU2_1",
303 .channel_offset = -0x100, 365 .channel_offset = -0x100,
304 .timer_bit = 1, 366 .timer_bit = 1,
305 .clk = "peripheral_clk",
306 .clockevent_rating = 200, 367 .clockevent_rating = 200,
307}; 368};
308 369
309static struct resource mtu2_1_resources[] = { 370static struct resource mtu2_1_resources[] = {
310 [0] = { 371 [0] = {
311 .name = "MTU2_1",
312 .start = 0xfffe4380, 372 .start = 0xfffe4380,
313 .end = 0xfffe4390, 373 .end = 0xfffe4390,
314 .flags = IORESOURCE_MEM, 374 .flags = IORESOURCE_MEM,
@@ -330,16 +390,13 @@ static struct platform_device mtu2_1_device = {
330}; 390};
331 391
332static struct sh_timer_config mtu2_2_platform_data = { 392static struct sh_timer_config mtu2_2_platform_data = {
333 .name = "MTU2_2",
334 .channel_offset = 0x80, 393 .channel_offset = 0x80,
335 .timer_bit = 2, 394 .timer_bit = 2,
336 .clk = "peripheral_clk",
337 .clockevent_rating = 200, 395 .clockevent_rating = 200,
338}; 396};
339 397
340static struct resource mtu2_2_resources[] = { 398static struct resource mtu2_2_resources[] = {
341 [0] = { 399 [0] = {
342 .name = "MTU2_2",
343 .start = 0xfffe4000, 400 .start = 0xfffe4000,
344 .end = 0xfffe400a, 401 .end = 0xfffe400a,
345 .flags = IORESOURCE_MEM, 402 .flags = IORESOURCE_MEM,
@@ -361,7 +418,14 @@ static struct platform_device mtu2_2_device = {
361}; 418};
362 419
363static struct platform_device *sh7201_devices[] __initdata = { 420static struct platform_device *sh7201_devices[] __initdata = {
364 &sci_device, 421 &scif0_device,
422 &scif1_device,
423 &scif2_device,
424 &scif3_device,
425 &scif4_device,
426 &scif5_device,
427 &scif6_device,
428 &scif7_device,
365 &rtc_device, 429 &rtc_device,
366 &mtu2_0_device, 430 &mtu2_0_device,
367 &mtu2_1_device, 431 &mtu2_1_device,
@@ -373,7 +437,7 @@ static int __init sh7201_devices_setup(void)
373 return platform_add_devices(sh7201_devices, 437 return platform_add_devices(sh7201_devices,
374 ARRAY_SIZE(sh7201_devices)); 438 ARRAY_SIZE(sh7201_devices));
375} 439}
376__initcall(sh7201_devices_setup); 440arch_initcall(sh7201_devices_setup);
377 441
378void __init plat_irq_setup(void) 442void __init plat_irq_setup(void)
379{ 443{
@@ -381,6 +445,14 @@ void __init plat_irq_setup(void)
381} 445}
382 446
383static struct platform_device *sh7201_early_devices[] __initdata = { 447static struct platform_device *sh7201_early_devices[] __initdata = {
448 &scif0_device,
449 &scif1_device,
450 &scif2_device,
451 &scif3_device,
452 &scif4_device,
453 &scif5_device,
454 &scif6_device,
455 &scif7_device,
384 &mtu2_0_device, 456 &mtu2_0_device,
385 &mtu2_1_device, 457 &mtu2_1_device,
386 &mtu2_2_device, 458 &mtu2_2_device,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
index a78d2a219f3b..a43124e608c3 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
@@ -173,60 +173,83 @@ 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 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
180 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 180 .scbrr_algo_id = SCBRR_ALGO_2,
181 .scbrr_algo_id = SCBRR_ALGO_2, 181 .type = PORT_SCIF,
182 .type = PORT_SCIF, 182 .irqs = { 192, 192, 192, 192 },
183 .irqs = { 192, 192, 192, 192 },
184 }, {
185 .mapbase = 0xfffe8800,
186 .flags = UPF_BOOT_AUTOCONF,
187 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
188 .scbrr_algo_id = SCBRR_ALGO_2,
189 .type = PORT_SCIF,
190 .irqs = { 196, 196, 196, 196 },
191 }, {
192 .mapbase = 0xfffe9000,
193 .flags = UPF_BOOT_AUTOCONF,
194 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
195 .scbrr_algo_id = SCBRR_ALGO_2,
196 .type = PORT_SCIF,
197 .irqs = { 200, 200, 200, 200 },
198 }, {
199 .mapbase = 0xfffe9800,
200 .flags = UPF_BOOT_AUTOCONF,
201 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
202 .scbrr_algo_id = SCBRR_ALGO_2,
203 .type = PORT_SCIF,
204 .irqs = { 204, 204, 204, 204 },
205 }, {
206 .flags = 0,
207 }
208}; 183};
209 184
210static struct platform_device sci_device = { 185static struct platform_device scif0_device = {
211 .name = "sh-sci", 186 .name = "sh-sci",
212 .id = -1, 187 .id = 0,
188 .dev = {
189 .platform_data = &scif0_platform_data,
190 },
191};
192
193static struct plat_sci_port scif1_platform_data = {
194 .mapbase = 0xfffe8800,
195 .flags = UPF_BOOT_AUTOCONF,
196 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
197 .scbrr_algo_id = SCBRR_ALGO_2,
198 .type = PORT_SCIF,
199 .irqs = { 196, 196, 196, 196 },
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 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
214 .scbrr_algo_id = SCBRR_ALGO_2,
215 .type = PORT_SCIF,
216 .irqs = { 200, 200, 200, 200 },
217};
218
219static struct platform_device scif2_device = {
220 .name = "sh-sci",
221 .id = 2,
222 .dev = {
223 .platform_data = &scif2_platform_data,
224 },
225};
226
227static struct plat_sci_port scif3_platform_data = {
228 .mapbase = 0xfffe9800,
229 .flags = UPF_BOOT_AUTOCONF,
230 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
231 .scbrr_algo_id = SCBRR_ALGO_2,
232 .type = PORT_SCIF,
233 .irqs = { 204, 204, 204, 204 },
234};
235
236static struct platform_device scif3_device = {
237 .name = "sh-sci",
238 .id = 3,
213 .dev = { 239 .dev = {
214 .platform_data = sci_platform_data, 240 .platform_data = &scif3_platform_data,
215 }, 241 },
216}; 242};
217 243
218static struct sh_timer_config cmt0_platform_data = { 244static struct sh_timer_config cmt0_platform_data = {
219 .name = "CMT0",
220 .channel_offset = 0x02, 245 .channel_offset = 0x02,
221 .timer_bit = 0, 246 .timer_bit = 0,
222 .clk = "peripheral_clk",
223 .clockevent_rating = 125, 247 .clockevent_rating = 125,
224 .clocksource_rating = 0, /* disabled due to code generation issues */ 248 .clocksource_rating = 0, /* disabled due to code generation issues */
225}; 249};
226 250
227static struct resource cmt0_resources[] = { 251static struct resource cmt0_resources[] = {
228 [0] = { 252 [0] = {
229 .name = "CMT0",
230 .start = 0xfffec002, 253 .start = 0xfffec002,
231 .end = 0xfffec007, 254 .end = 0xfffec007,
232 .flags = IORESOURCE_MEM, 255 .flags = IORESOURCE_MEM,
@@ -248,17 +271,14 @@ static struct platform_device cmt0_device = {
248}; 271};
249 272
250static struct sh_timer_config cmt1_platform_data = { 273static struct sh_timer_config cmt1_platform_data = {
251 .name = "CMT1",
252 .channel_offset = 0x08, 274 .channel_offset = 0x08,
253 .timer_bit = 1, 275 .timer_bit = 1,
254 .clk = "peripheral_clk",
255 .clockevent_rating = 125, 276 .clockevent_rating = 125,
256 .clocksource_rating = 0, /* disabled due to code generation issues */ 277 .clocksource_rating = 0, /* disabled due to code generation issues */
257}; 278};
258 279
259static struct resource cmt1_resources[] = { 280static struct resource cmt1_resources[] = {
260 [0] = { 281 [0] = {
261 .name = "CMT1",
262 .start = 0xfffec008, 282 .start = 0xfffec008,
263 .end = 0xfffec00d, 283 .end = 0xfffec00d,
264 .flags = IORESOURCE_MEM, 284 .flags = IORESOURCE_MEM,
@@ -280,16 +300,13 @@ static struct platform_device cmt1_device = {
280}; 300};
281 301
282static struct sh_timer_config mtu2_0_platform_data = { 302static struct sh_timer_config mtu2_0_platform_data = {
283 .name = "MTU2_0",
284 .channel_offset = -0x80, 303 .channel_offset = -0x80,
285 .timer_bit = 0, 304 .timer_bit = 0,
286 .clk = "peripheral_clk",
287 .clockevent_rating = 200, 305 .clockevent_rating = 200,
288}; 306};
289 307
290static struct resource mtu2_0_resources[] = { 308static struct resource mtu2_0_resources[] = {
291 [0] = { 309 [0] = {
292 .name = "MTU2_0",
293 .start = 0xfffe4300, 310 .start = 0xfffe4300,
294 .end = 0xfffe4326, 311 .end = 0xfffe4326,
295 .flags = IORESOURCE_MEM, 312 .flags = IORESOURCE_MEM,
@@ -311,16 +328,13 @@ static struct platform_device mtu2_0_device = {
311}; 328};
312 329
313static struct sh_timer_config mtu2_1_platform_data = { 330static struct sh_timer_config mtu2_1_platform_data = {
314 .name = "MTU2_1",
315 .channel_offset = -0x100, 331 .channel_offset = -0x100,
316 .timer_bit = 1, 332 .timer_bit = 1,
317 .clk = "peripheral_clk",
318 .clockevent_rating = 200, 333 .clockevent_rating = 200,
319}; 334};
320 335
321static struct resource mtu2_1_resources[] = { 336static struct resource mtu2_1_resources[] = {
322 [0] = { 337 [0] = {
323 .name = "MTU2_1",
324 .start = 0xfffe4380, 338 .start = 0xfffe4380,
325 .end = 0xfffe4390, 339 .end = 0xfffe4390,
326 .flags = IORESOURCE_MEM, 340 .flags = IORESOURCE_MEM,
@@ -362,7 +376,10 @@ static struct platform_device rtc_device = {
362}; 376};
363 377
364static struct platform_device *sh7203_devices[] __initdata = { 378static struct platform_device *sh7203_devices[] __initdata = {
365 &sci_device, 379 &scif0_device,
380 &scif1_device,
381 &scif2_device,
382 &scif3_device,
366 &cmt0_device, 383 &cmt0_device,
367 &cmt1_device, 384 &cmt1_device,
368 &mtu2_0_device, 385 &mtu2_0_device,
@@ -375,7 +392,7 @@ static int __init sh7203_devices_setup(void)
375 return platform_add_devices(sh7203_devices, 392 return platform_add_devices(sh7203_devices,
376 ARRAY_SIZE(sh7203_devices)); 393 ARRAY_SIZE(sh7203_devices));
377} 394}
378__initcall(sh7203_devices_setup); 395arch_initcall(sh7203_devices_setup);
379 396
380void __init plat_irq_setup(void) 397void __init plat_irq_setup(void)
381{ 398{
@@ -383,6 +400,10 @@ void __init plat_irq_setup(void)
383} 400}
384 401
385static struct platform_device *sh7203_early_devices[] __initdata = { 402static struct platform_device *sh7203_early_devices[] __initdata = {
403 &scif0_device,
404 &scif1_device,
405 &scif2_device,
406 &scif3_device,
386 &cmt0_device, 407 &cmt0_device,
387 &cmt1_device, 408 &cmt1_device,
388 &mtu2_0_device, 409 &mtu2_0_device,
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index 68b93ed44cc2..5d14f849aea3 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -133,60 +133,83 @@ 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 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
140 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 140 .scbrr_algo_id = SCBRR_ALGO_2,
141 .scbrr_algo_id = SCBRR_ALGO_2, 141 .type = PORT_SCIF,
142 .type = PORT_SCIF, 142 .irqs = { 240, 240, 240, 240 },
143 .irqs = { 240, 240, 240, 240 },
144 }, {
145 .mapbase = 0xfffe8800,
146 .flags = UPF_BOOT_AUTOCONF,
147 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
148 .scbrr_algo_id = SCBRR_ALGO_2,
149 .type = PORT_SCIF,
150 .irqs = { 244, 244, 244, 244 },
151 }, {
152 .mapbase = 0xfffe9000,
153 .flags = UPF_BOOT_AUTOCONF,
154 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
155 .scbrr_algo_id = SCBRR_ALGO_2,
156 .type = PORT_SCIF,
157 .irqs = { 248, 248, 248, 248 },
158 }, {
159 .mapbase = 0xfffe9800,
160 .flags = UPF_BOOT_AUTOCONF,
161 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
162 .scbrr_algo_id = SCBRR_ALGO_2,
163 .type = PORT_SCIF,
164 .irqs = { 252, 252, 252, 252 },
165 }, {
166 .flags = 0,
167 }
168}; 143};
169 144
170static struct platform_device sci_device = { 145static struct platform_device scif0_device = {
171 .name = "sh-sci", 146 .name = "sh-sci",
172 .id = -1, 147 .id = 0,
148 .dev = {
149 .platform_data = &scif0_platform_data,
150 },
151};
152
153static struct plat_sci_port scif1_platform_data = {
154 .mapbase = 0xfffe8800,
155 .flags = UPF_BOOT_AUTOCONF,
156 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
157 .scbrr_algo_id = SCBRR_ALGO_2,
158 .type = PORT_SCIF,
159 .irqs = { 244, 244, 244, 244 },
160};
161
162static struct platform_device scif1_device = {
163 .name = "sh-sci",
164 .id = 1,
165 .dev = {
166 .platform_data = &scif1_platform_data,
167 },
168};
169
170static struct plat_sci_port scif2_platform_data = {
171 .mapbase = 0xfffe9000,
172 .flags = UPF_BOOT_AUTOCONF,
173 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
174 .scbrr_algo_id = SCBRR_ALGO_2,
175 .type = PORT_SCIF,
176 .irqs = { 248, 248, 248, 248 },
177};
178
179static struct platform_device scif2_device = {
180 .name = "sh-sci",
181 .id = 2,
182 .dev = {
183 .platform_data = &scif2_platform_data,
184 },
185};
186
187static struct plat_sci_port scif3_platform_data = {
188 .mapbase = 0xfffe9800,
189 .flags = UPF_BOOT_AUTOCONF,
190 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
191 .scbrr_algo_id = SCBRR_ALGO_2,
192 .type = PORT_SCIF,
193 .irqs = { 252, 252, 252, 252 },
194};
195
196static struct platform_device scif3_device = {
197 .name = "sh-sci",
198 .id = 3,
173 .dev = { 199 .dev = {
174 .platform_data = sci_platform_data, 200 .platform_data = &scif3_platform_data,
175 }, 201 },
176}; 202};
177 203
178static struct sh_timer_config cmt0_platform_data = { 204static struct sh_timer_config cmt0_platform_data = {
179 .name = "CMT0",
180 .channel_offset = 0x02, 205 .channel_offset = 0x02,
181 .timer_bit = 0, 206 .timer_bit = 0,
182 .clk = "peripheral_clk",
183 .clockevent_rating = 125, 207 .clockevent_rating = 125,
184 .clocksource_rating = 0, /* disabled due to code generation issues */ 208 .clocksource_rating = 0, /* disabled due to code generation issues */
185}; 209};
186 210
187static struct resource cmt0_resources[] = { 211static struct resource cmt0_resources[] = {
188 [0] = { 212 [0] = {
189 .name = "CMT0",
190 .start = 0xfffec002, 213 .start = 0xfffec002,
191 .end = 0xfffec007, 214 .end = 0xfffec007,
192 .flags = IORESOURCE_MEM, 215 .flags = IORESOURCE_MEM,
@@ -208,17 +231,14 @@ static struct platform_device cmt0_device = {
208}; 231};
209 232
210static struct sh_timer_config cmt1_platform_data = { 233static struct sh_timer_config cmt1_platform_data = {
211 .name = "CMT1",
212 .channel_offset = 0x08, 234 .channel_offset = 0x08,
213 .timer_bit = 1, 235 .timer_bit = 1,
214 .clk = "peripheral_clk",
215 .clockevent_rating = 125, 236 .clockevent_rating = 125,
216 .clocksource_rating = 0, /* disabled due to code generation issues */ 237 .clocksource_rating = 0, /* disabled due to code generation issues */
217}; 238};
218 239
219static struct resource cmt1_resources[] = { 240static struct resource cmt1_resources[] = {
220 [0] = { 241 [0] = {
221 .name = "CMT1",
222 .start = 0xfffec008, 242 .start = 0xfffec008,
223 .end = 0xfffec00d, 243 .end = 0xfffec00d,
224 .flags = IORESOURCE_MEM, 244 .flags = IORESOURCE_MEM,
@@ -240,16 +260,13 @@ static struct platform_device cmt1_device = {
240}; 260};
241 261
242static struct sh_timer_config mtu2_0_platform_data = { 262static struct sh_timer_config mtu2_0_platform_data = {
243 .name = "MTU2_0",
244 .channel_offset = -0x80, 263 .channel_offset = -0x80,
245 .timer_bit = 0, 264 .timer_bit = 0,
246 .clk = "peripheral_clk",
247 .clockevent_rating = 200, 265 .clockevent_rating = 200,
248}; 266};
249 267
250static struct resource mtu2_0_resources[] = { 268static struct resource mtu2_0_resources[] = {
251 [0] = { 269 [0] = {
252 .name = "MTU2_0",
253 .start = 0xfffe4300, 270 .start = 0xfffe4300,
254 .end = 0xfffe4326, 271 .end = 0xfffe4326,
255 .flags = IORESOURCE_MEM, 272 .flags = IORESOURCE_MEM,
@@ -271,16 +288,13 @@ static struct platform_device mtu2_0_device = {
271}; 288};
272 289
273static struct sh_timer_config mtu2_1_platform_data = { 290static struct sh_timer_config mtu2_1_platform_data = {
274 .name = "MTU2_1",
275 .channel_offset = -0x100, 291 .channel_offset = -0x100,
276 .timer_bit = 1, 292 .timer_bit = 1,
277 .clk = "peripheral_clk",
278 .clockevent_rating = 200, 293 .clockevent_rating = 200,
279}; 294};
280 295
281static struct resource mtu2_1_resources[] = { 296static struct resource mtu2_1_resources[] = {
282 [0] = { 297 [0] = {
283 .name = "MTU2_1",
284 .start = 0xfffe4380, 298 .start = 0xfffe4380,
285 .end = 0xfffe4390, 299 .end = 0xfffe4390,
286 .flags = IORESOURCE_MEM, 300 .flags = IORESOURCE_MEM,
@@ -302,16 +316,13 @@ static struct platform_device mtu2_1_device = {
302}; 316};
303 317
304static struct sh_timer_config mtu2_2_platform_data = { 318static struct sh_timer_config mtu2_2_platform_data = {
305 .name = "MTU2_2",
306 .channel_offset = 0x80, 319 .channel_offset = 0x80,
307 .timer_bit = 2, 320 .timer_bit = 2,
308 .clk = "peripheral_clk",
309 .clockevent_rating = 200, 321 .clockevent_rating = 200,
310}; 322};
311 323
312static struct resource mtu2_2_resources[] = { 324static struct resource mtu2_2_resources[] = {
313 [0] = { 325 [0] = {
314 .name = "MTU2_2",
315 .start = 0xfffe4000, 326 .start = 0xfffe4000,
316 .end = 0xfffe400a, 327 .end = 0xfffe400a,
317 .flags = IORESOURCE_MEM, 328 .flags = IORESOURCE_MEM,
@@ -333,7 +344,10 @@ static struct platform_device mtu2_2_device = {
333}; 344};
334 345
335static struct platform_device *sh7206_devices[] __initdata = { 346static struct platform_device *sh7206_devices[] __initdata = {
336 &sci_device, 347 &scif0_device,
348 &scif1_device,
349 &scif2_device,
350 &scif3_device,
337 &cmt0_device, 351 &cmt0_device,
338 &cmt1_device, 352 &cmt1_device,
339 &mtu2_0_device, 353 &mtu2_0_device,
@@ -346,7 +360,7 @@ static int __init sh7206_devices_setup(void)
346 return platform_add_devices(sh7206_devices, 360 return platform_add_devices(sh7206_devices,
347 ARRAY_SIZE(sh7206_devices)); 361 ARRAY_SIZE(sh7206_devices));
348} 362}
349__initcall(sh7206_devices_setup); 363arch_initcall(sh7206_devices_setup);
350 364
351void __init plat_irq_setup(void) 365void __init plat_irq_setup(void)
352{ 366{
@@ -354,6 +368,10 @@ void __init plat_irq_setup(void)
354} 368}
355 369
356static struct platform_device *sh7206_early_devices[] __initdata = { 370static struct platform_device *sh7206_early_devices[] __initdata = {
371 &scif0_device,
372 &scif1_device,
373 &scif2_device,
374 &scif3_device,
357 &cmt0_device, 375 &cmt0_device,
358 &cmt1_device, 376 &cmt1_device,
359 &mtu2_0_device, 377 &mtu2_0_device,