aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu')
-rw-r--r--arch/sh/kernel/cpu/init.c15
-rw-r--r--arch/sh/kernel/cpu/irq/intc2.c63
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c59
-rw-r--r--arch/sh/kernel/cpu/sh2/entry.S1
-rw-r--r--arch/sh/kernel/cpu/sh2/probe.c13
-rw-r--r--arch/sh/kernel/cpu/sh2/setup-sh7619.c24
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7206.c24
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S19
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c40
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7709.c112
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c42
-rw-r--r--arch/sh/kernel/cpu/sh4/Makefile4
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c8
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c58
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7760.c45
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-shx3.c135
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c29
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7780.c15
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c16
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-shx3.c85
21 files changed, 596 insertions, 213 deletions
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 6451ad630174..9172e97dc26a 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -21,8 +21,7 @@
21#include <asm/cacheflush.h> 21#include <asm/cacheflush.h>
22#include <asm/cache.h> 22#include <asm/cache.h>
23#include <asm/io.h> 23#include <asm/io.h>
24 24#include <asm/ubc.h>
25extern void detect_cpu_and_cache_system(void);
26 25
27/* 26/*
28 * Generic wrapper for command line arguments to disable on-chip 27 * Generic wrapper for command line arguments to disable on-chip
@@ -152,15 +151,6 @@ static void __init cache_init(void)
152 flags |= CCR_CACHE_CB; 151 flags |= CCR_CACHE_CB;
153#endif 152#endif
154 153
155#ifdef CONFIG_SH_OCRAM
156 /* Turn on OCRAM -- halve the OC */
157 flags |= CCR_CACHE_ORA;
158 current_cpu_data.dcache.sets >>= 1;
159
160 current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets *
161 current_cpu_data.dcache.linesz;
162#endif
163
164 ctrl_outl(flags, CCR); 154 ctrl_outl(flags, CCR);
165 back_to_P1(); 155 back_to_P1();
166} 156}
@@ -269,7 +259,6 @@ asmlinkage void __init sh_cpu_init(void)
269 } 259 }
270#endif 260#endif
271 261
272#ifdef CONFIG_UBC_WAKEUP
273 /* 262 /*
274 * Some brain-damaged loaders decided it would be a good idea to put 263 * Some brain-damaged loaders decided it would be a good idea to put
275 * the UBC to sleep. This causes some issues when it comes to things 264 * the UBC to sleep. This causes some issues when it comes to things
@@ -277,7 +266,5 @@ asmlinkage void __init sh_cpu_init(void)
277 * we wake it up and hope that all is well. 266 * we wake it up and hope that all is well.
278 */ 267 */
279 ubc_wakeup(); 268 ubc_wakeup();
280#endif
281
282 speculative_execution_init(); 269 speculative_execution_init();
283} 270}
diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c
index d8e22f4ff0f0..cc5221390e09 100644
--- a/arch/sh/kernel/cpu/irq/intc2.c
+++ b/arch/sh/kernel/cpu/irq/intc2.c
@@ -13,36 +13,31 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <asm/smp.h>
16 17
17#if defined(CONFIG_CPU_SUBTYPE_SH7760) 18static inline struct intc2_desc *get_intc2_desc(unsigned int irq)
18#define INTC2_BASE 0xfe080000 19{
19#define INTC2_INTMSK (INTC2_BASE + 0x40) 20 struct irq_chip *chip = get_irq_chip(irq);
20#define INTC2_INTMSKCLR (INTC2_BASE + 0x60) 21 return (void *)((char *)chip - offsetof(struct intc2_desc, chip));
21#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || \ 22}
22 defined(CONFIG_CPU_SUBTYPE_SH7785)
23#define INTC2_BASE 0xffd40000
24#define INTC2_INTMSK (INTC2_BASE + 0x38)
25#define INTC2_INTMSKCLR (INTC2_BASE + 0x3c)
26#endif
27 23
28static void disable_intc2_irq(unsigned int irq) 24static void disable_intc2_irq(unsigned int irq)
29{ 25{
30 struct intc2_data *p = get_irq_chip_data(irq); 26 struct intc2_data *p = get_irq_chip_data(irq);
31 ctrl_outl(1 << p->msk_shift, INTC2_INTMSK + p->msk_offset); 27 struct intc2_desc *d = get_intc2_desc(irq);
28
29 ctrl_outl(1 << p->msk_shift, d->msk_base + p->msk_offset +
30 (hard_smp_processor_id() * 4));
32} 31}
33 32
34static void enable_intc2_irq(unsigned int irq) 33static void enable_intc2_irq(unsigned int irq)
35{ 34{
36 struct intc2_data *p = get_irq_chip_data(irq); 35 struct intc2_data *p = get_irq_chip_data(irq);
37 ctrl_outl(1 << p->msk_shift, INTC2_INTMSKCLR + p->msk_offset); 36 struct intc2_desc *d = get_intc2_desc(irq);
38}
39 37
40static struct irq_chip intc2_irq_chip = { 38 ctrl_outl(1 << p->msk_shift, d->mskclr_base + p->msk_offset +
41 .name = "INTC2", 39 (hard_smp_processor_id() * 4));
42 .mask = disable_intc2_irq, 40}
43 .unmask = enable_intc2_irq,
44 .mask_ack = disable_intc2_irq,
45};
46 41
47/* 42/*
48 * Setup an INTC2 style interrupt. 43 * Setup an INTC2 style interrupt.
@@ -56,30 +51,36 @@ static struct irq_chip intc2_irq_chip = {
56 * 51 *
57 * in the intc2_data table. 52 * in the intc2_data table.
58 */ 53 */
59void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs) 54void register_intc2_controller(struct intc2_desc *desc)
60{ 55{
61 int i; 56 int i;
62 57
63 for (i = 0; i < nr_irqs; i++) { 58 desc->chip.mask = disable_intc2_irq;
59 desc->chip.unmask = enable_intc2_irq;
60 desc->chip.mask_ack = disable_intc2_irq;
61
62 for (i = 0; i < desc->nr_irqs; i++) {
64 unsigned long ipr, flags; 63 unsigned long ipr, flags;
65 struct intc2_data *p = table + i; 64 struct intc2_data *p = desc->intc2_data + i;
66 65
67 disable_irq_nosync(p->irq); 66 disable_irq_nosync(p->irq);
68 67
69 /* Set the priority level */ 68 if (desc->prio_base) {
70 local_irq_save(flags); 69 /* Set the priority level */
70 local_irq_save(flags);
71 71
72 ipr = ctrl_inl(INTC2_BASE + p->ipr_offset); 72 ipr = ctrl_inl(desc->prio_base + p->ipr_offset);
73 ipr &= ~(0xf << p->ipr_shift); 73 ipr &= ~(0xf << p->ipr_shift);
74 ipr |= p->priority << p->ipr_shift; 74 ipr |= p->priority << p->ipr_shift;
75 ctrl_outl(ipr, INTC2_BASE + p->ipr_offset); 75 ctrl_outl(ipr, desc->prio_base + p->ipr_offset);
76 76
77 local_irq_restore(flags); 77 local_irq_restore(flags);
78 }
78 79
79 set_irq_chip_and_handler_name(p->irq, &intc2_irq_chip, 80 set_irq_chip_and_handler_name(p->irq, &desc->chip,
80 handle_level_irq, "level"); 81 handle_level_irq, "level");
81 set_irq_chip_data(p->irq, p); 82 set_irq_chip_data(p->irq, p);
82 83
83 enable_intc2_irq(p->irq); 84 disable_intc2_irq(p->irq);
84 } 85 }
85} 86}
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index 210280b6fddf..98e84f40c713 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -22,58 +22,57 @@
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24 24
25static inline struct ipr_desc *get_ipr_desc(unsigned int irq)
26{
27 struct irq_chip *chip = get_irq_chip(irq);
28 return (void *)((char *)chip - offsetof(struct ipr_desc, chip));
29}
30
25static void disable_ipr_irq(unsigned int irq) 31static void disable_ipr_irq(unsigned int irq)
26{ 32{
27 struct ipr_data *p = get_irq_chip_data(irq); 33 struct ipr_data *p = get_irq_chip_data(irq);
34 unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx];
28 /* Set the priority in IPR to 0 */ 35 /* Set the priority in IPR to 0 */
29 ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr); 36 ctrl_outw(ctrl_inw(addr) & (0xffff ^ (0xf << p->shift)), addr);
30} 37}
31 38
32static void enable_ipr_irq(unsigned int irq) 39static void enable_ipr_irq(unsigned int irq)
33{ 40{
34 struct ipr_data *p = get_irq_chip_data(irq); 41 struct ipr_data *p = get_irq_chip_data(irq);
42 unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx];
35 /* Set priority in IPR back to original value */ 43 /* Set priority in IPR back to original value */
36 ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr); 44 ctrl_outw(ctrl_inw(addr) | (p->priority << p->shift), addr);
37} 45}
38 46
39static struct irq_chip ipr_irq_chip = { 47/*
40 .name = "IPR", 48 * The shift value is now the number of bits to shift, not the number of
41 .mask = disable_ipr_irq, 49 * bits/4. This is to make it easier to read the value directly from the
42 .unmask = enable_ipr_irq, 50 * datasheets. The IPR address is calculated using the ipr_offset table.
43 .mask_ack = disable_ipr_irq, 51 */
44};
45
46unsigned int map_ipridx_to_addr(int idx) __attribute__ ((weak));
47unsigned int map_ipridx_to_addr(int idx)
48{
49 return 0;
50}
51 52
52void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) 53void register_ipr_controller(struct ipr_desc *desc)
53{ 54{
54 int i; 55 int i;
55 56
56 for (i = 0; i < nr_irqs; i++) { 57 desc->chip.mask = disable_ipr_irq;
57 unsigned int irq = table[i].irq; 58 desc->chip.unmask = enable_ipr_irq;
59 desc->chip.mask_ack = disable_ipr_irq;
58 60
59 if (!irq) 61 for (i = 0; i < desc->nr_irqs; i++) {
60 irq = table[i].irq = i; 62 struct ipr_data *p = desc->ipr_data + i;
61 63
62 /* could the IPR index be mapped, if not we ignore this */ 64 BUG_ON(p->ipr_idx >= desc->nr_offsets);
63 if (!table[i].addr) { 65 BUG_ON(!desc->ipr_offsets[p->ipr_idx]);
64 table[i].addr = map_ipridx_to_addr(table[i].ipr_idx);
65 if (!table[i].addr)
66 continue;
67 }
68 66
69 disable_irq_nosync(irq); 67 disable_irq_nosync(p->irq);
70 set_irq_chip_and_handler_name(irq, &ipr_irq_chip, 68 set_irq_chip_and_handler_name(p->irq, &desc->chip,
71 handle_level_irq, "level"); 69 handle_level_irq, "level");
72 set_irq_chip_data(irq, &table[i]); 70 set_irq_chip_data(p->irq, p);
73 enable_ipr_irq(irq); 71 disable_ipr_irq(p->irq);
74 } 72 }
75} 73}
76EXPORT_SYMBOL(make_ipr_irq); 74
75EXPORT_SYMBOL(register_ipr_controller);
77 76
78#if !defined(CONFIG_CPU_HAS_PINT_IRQ) 77#if !defined(CONFIG_CPU_HAS_PINT_IRQ)
79int ipr_irq_demux(int irq) 78int ipr_irq_demux(int irq)
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index c16dc8fec489..ee8f1fe84b08 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -311,6 +311,7 @@ restore_all:
311 rte 311 rte
312 nop 312 nop
313 313
314 .align 2
314#ifdef CONFIG_TRACE_IRQFLAGS 315#ifdef CONFIG_TRACE_IRQFLAGS
3151: .long trace_hardirqs_off 3161: .long trace_hardirqs_off
316#endif 317#endif
diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c
index 108e81b682ed..abbf17427e52 100644
--- a/arch/sh/kernel/cpu/sh2/probe.c
+++ b/arch/sh/kernel/cpu/sh2/probe.c
@@ -9,23 +9,14 @@
9 * 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
10 * for more details. 10 * for more details.
11 */ 11 */
12
13
14#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/smp.h>
15#include <asm/processor.h> 14#include <asm/processor.h>
16#include <asm/cache.h> 15#include <asm/cache.h>
17 16
18int __init detect_cpu_and_cache_system(void) 17int __init detect_cpu_and_cache_system(void)
19{ 18{
20#if defined(CONFIG_CPU_SUBTYPE_SH7604) 19#if defined(CONFIG_CPU_SUBTYPE_SH7619)
21 current_cpu_data.type = CPU_SH7604;
22 current_cpu_data.dcache.ways = 4;
23 current_cpu_data.dcache.way_incr = (1<<10);
24 current_cpu_data.dcache.sets = 64;
25 current_cpu_data.dcache.entry_shift = 4;
26 current_cpu_data.dcache.linesz = L1_CACHE_BYTES;
27 current_cpu_data.dcache.flags = 0;
28#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
29 current_cpu_data.type = CPU_SH7619; 20 current_cpu_data.type = CPU_SH7619;
30 current_cpu_data.dcache.ways = 4; 21 current_cpu_data.dcache.ways = 4;
31 current_cpu_data.dcache.way_incr = (1<<12); 22 current_cpu_data.dcache.way_incr = (1<<12);
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index f83ff8a68f35..1a107fe22dde 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -52,7 +52,7 @@ static int __init sh7619_devices_setup(void)
52} 52}
53__initcall(sh7619_devices_setup); 53__initcall(sh7619_devices_setup);
54 54
55static struct ipr_data sh7619_ipr_map[] = { 55static struct ipr_data ipr_irq_table[] = {
56 { 86, 0, 4, 2 }, /* CMI0 */ 56 { 86, 0, 4, 2 }, /* CMI0 */
57 { 88, 1, 12, 3 }, /* SCIF0_ERI */ 57 { 88, 1, 12, 3 }, /* SCIF0_ERI */
58 { 89, 1, 12, 3 }, /* SCIF0_RXI */ 58 { 89, 1, 12, 3 }, /* SCIF0_RXI */
@@ -68,7 +68,7 @@ static struct ipr_data sh7619_ipr_map[] = {
68 { 99, 1, 4, 3 }, /* SCIF2_TXI */ 68 { 99, 1, 4, 3 }, /* SCIF2_TXI */
69}; 69};
70 70
71static unsigned int ipr_offsets[] = { 71static unsigned long ipr_offsets[] = {
72 0xf8080000, /* IPRC */ 72 0xf8080000, /* IPRC */
73 0xf8080002, /* IPRD */ 73 0xf8080002, /* IPRD */
74 0xf8080004, /* IPRE */ 74 0xf8080004, /* IPRE */
@@ -76,15 +76,19 @@ static unsigned int ipr_offsets[] = {
76 0xf8080008, /* IPRG */ 76 0xf8080008, /* IPRG */
77}; 77};
78 78
79/* given the IPR index return the address of the IPR register */ 79static struct ipr_desc ipr_irq_desc = {
80unsigned int map_ipridx_to_addr(int idx) 80 .ipr_offsets = ipr_offsets,
81{ 81 .nr_offsets = ARRAY_SIZE(ipr_offsets),
82 if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) 82
83 return 0; 83 .ipr_data = ipr_irq_table,
84 return ipr_offsets[idx]; 84 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
85} 85
86 .chip = {
87 .name = "IPR-sh7619",
88 },
89};
86 90
87void __init init_IRQ_ipr(void) 91void __init init_IRQ_ipr(void)
88{ 92{
89 make_ipr_irq(sh7619_ipr_map, ARRAY_SIZE(sh7619_ipr_map)); 93 register_ipr_controller(&ipr_irq_desc);
90} 94}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index 4ed9110632bc..b6e3a6351fa6 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -57,7 +57,7 @@ static int __init sh7206_devices_setup(void)
57} 57}
58__initcall(sh7206_devices_setup); 58__initcall(sh7206_devices_setup);
59 59
60static struct ipr_data sh7206_ipr_map[] = { 60static struct ipr_data ipr_irq_table[] = {
61 { 140, 7, 12, 2 }, /* CMI0 */ 61 { 140, 7, 12, 2 }, /* CMI0 */
62 { 164, 8, 4, 2 }, /* MTU2_TGI1A */ 62 { 164, 8, 4, 2 }, /* MTU2_TGI1A */
63 { 240, 13, 12, 3 }, /* SCIF0_BRI */ 63 { 240, 13, 12, 3 }, /* SCIF0_BRI */
@@ -78,7 +78,7 @@ static struct ipr_data sh7206_ipr_map[] = {
78 { 255, 13, 0, 3 }, /* SCIF3_TXI */ 78 { 255, 13, 0, 3 }, /* SCIF3_TXI */
79}; 79};
80 80
81static unsigned int ipr_offsets[] = { 81static unsigned long ipr_offsets[] = {
82 0xfffe0818, /* IPR01 */ 82 0xfffe0818, /* IPR01 */
83 0xfffe081a, /* IPR02 */ 83 0xfffe081a, /* IPR02 */
84 0, /* unused */ 84 0, /* unused */
@@ -95,15 +95,19 @@ static unsigned int ipr_offsets[] = {
95 0xfffe0c10, /* IPR14 */ 95 0xfffe0c10, /* IPR14 */
96}; 96};
97 97
98/* given the IPR index return the address of the IPR register */ 98static struct ipr_desc ipr_irq_desc = {
99unsigned int map_ipridx_to_addr(int idx) 99 .ipr_offsets = ipr_offsets,
100{ 100 .nr_offsets = ARRAY_SIZE(ipr_offsets),
101 if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) 101
102 return 0; 102 .ipr_data = ipr_irq_table,
103 return ipr_offsets[idx]; 103 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
104} 104
105 .chip = {
106 .name = "IPR-sh7206",
107 },
108};
105 109
106void __init init_IRQ_ipr(void) 110void __init init_IRQ_ipr(void)
107{ 111{
108 make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map)); 112 register_ipr_controller(&ipr_irq_desc);
109} 113}
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index b0b59d4a33ca..d8e122971c3e 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -340,8 +340,27 @@ ENTRY(vbr_base)
340general_exception: 340general_exception:
341 mov.l 1f, k2 341 mov.l 1f, k2
342 mov.l 2f, k3 342 mov.l 2f, k3
343#ifdef CONFIG_CPU_SUBTYPE_SHX3
344 mov.l @k2, k2
345
346 ! Is EXPEVT larger than 0x800?
347 mov #0x8, k0
348 shll8 k0
349 cmp/hs k0, k2
350 bf 0f
351
352 ! then add 0x580 (k2 is 0xd80 or 0xda0)
353 mov #0x58, k0
354 shll2 k0
355 shll2 k0
356 add k0, k2
3570:
358 bra handle_exception
359 nop
360#else
343 bra handle_exception 361 bra handle_exception
344 mov.l @k2, k2 362 mov.l @k2, k2
363#endif
345 .align 2 364 .align 2
3461: .long EXPEVT 3651: .long EXPEVT
3472: .long ret_from_exception 3662: .long ret_from_exception
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index 1983fb7ad6ea..a55b8ce2c54c 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -48,7 +48,7 @@ static int __init sh7705_devices_setup(void)
48} 48}
49__initcall(sh7705_devices_setup); 49__initcall(sh7705_devices_setup);
50 50
51static struct ipr_data sh7705_ipr_map[] = { 51static struct ipr_data ipr_irq_table[] = {
52 /* IRQ, IPR-idx, shift, priority */ 52 /* IRQ, IPR-idx, shift, priority */
53 { 16, 0, 12, 2 }, /* TMU0 TUNI*/ 53 { 16, 0, 12, 2 }, /* TMU0 TUNI*/
54 { 17, 0, 8, 2 }, /* TMU1 TUNI */ 54 { 17, 0, 8, 2 }, /* TMU1 TUNI */
@@ -70,25 +70,29 @@ static struct ipr_data sh7705_ipr_map[] = {
70}; 70};
71 71
72static unsigned long ipr_offsets[] = { 72static unsigned long ipr_offsets[] = {
73 0xFFFFFEE2 /* 0: IPRA */ 73 0xFFFFFEE2, /* 0: IPRA */
74, 0xFFFFFEE4 /* 1: IPRB */ 74 0xFFFFFEE4, /* 1: IPRB */
75, 0xA4000016 /* 2: IPRC */ 75 0xA4000016, /* 2: IPRC */
76, 0xA4000018 /* 3: IPRD */ 76 0xA4000018, /* 3: IPRD */
77, 0xA400001A /* 4: IPRE */ 77 0xA400001A, /* 4: IPRE */
78, 0xA4080000 /* 5: IPRF */ 78 0xA4080000, /* 5: IPRF */
79, 0xA4080002 /* 6: IPRG */ 79 0xA4080002, /* 6: IPRG */
80, 0xA4080004 /* 7: IPRH */ 80 0xA4080004, /* 7: IPRH */
81}; 81};
82 82
83/* given the IPR index return the address of the IPR register */ 83static struct ipr_desc ipr_irq_desc = {
84unsigned int map_ipridx_to_addr(int idx) 84 .ipr_offsets = ipr_offsets,
85{ 85 .nr_offsets = ARRAY_SIZE(ipr_offsets),
86 if (idx >= ARRAY_SIZE(ipr_offsets)) 86
87 return 0; 87 .ipr_data = ipr_irq_table,
88 return ipr_offsets[idx]; 88 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
89} 89
90 .chip = {
91 .name = "IPR-sh7705",
92 },
93};
90 94
91void __init init_IRQ_ipr() 95void __init init_IRQ_ipr(void)
92{ 96{
93 make_ipr_irq(sh7705_ipr_map, ARRAY_SIZE(sh7705_ipr_map)); 97 register_ipr_controller(&ipr_irq_desc);
94} 98}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/arch/sh/kernel/cpu/sh3/setup-sh7709.c
index c7d7c35fc834..d79ec0c0522f 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7709.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7709.c
@@ -12,6 +12,26 @@
12#include <linux/serial.h> 12#include <linux/serial.h>
13#include <asm/sci.h> 13#include <asm/sci.h>
14 14
15static struct resource rtc_resources[] = {
16 [0] = {
17 .start = 0xfffffec0,
18 .end = 0xfffffec0 + 0x1e,
19 .flags = IORESOURCE_IO,
20 },
21 [1] = {
22 .start = 20,
23 .flags = IORESOURCE_IRQ,
24 },
25 [2] = {
26 .start = 21,
27 .flags = IORESOURCE_IRQ,
28 },
29 [3] = {
30 .start = 22,
31 .flags = IORESOURCE_IRQ,
32 },
33};
34
15static struct plat_sci_port sci_platform_data[] = { 35static struct plat_sci_port sci_platform_data[] = {
16 { 36 {
17 .mapbase = 0xfffffe80, 37 .mapbase = 0xfffffe80,
@@ -41,8 +61,16 @@ static struct platform_device sci_device = {
41 }, 61 },
42}; 62};
43 63
64static struct platform_device rtc_device = {
65 .name = "sh-rtc",
66 .id = -1,
67 .num_resources = ARRAY_SIZE(rtc_resources),
68 .resource = rtc_resources,
69};
70
44static struct platform_device *sh7709_devices[] __initdata = { 71static struct platform_device *sh7709_devices[] __initdata = {
45 &sci_device, 72 &sci_device,
73 &rtc_device,
46}; 74};
47 75
48static int __init sh7709_devices_setup(void) 76static int __init sh7709_devices_setup(void)
@@ -52,32 +80,66 @@ static int __init sh7709_devices_setup(void)
52} 80}
53__initcall(sh7709_devices_setup); 81__initcall(sh7709_devices_setup);
54 82
55#define IPRx(A,N) .addr=A, .shift=N 83static struct ipr_data ipr_irq_table[] = {
56#define IPRA(N) IPRx(0xfffffee2UL,N) 84 { 16, 0, 12, 2 }, /* TMU TUNI0 */
57#define IPRB(N) IPRx(0xfffffee4UL,N) 85 { 17, 0, 8, 4 }, /* TMU TUNI1 */
58#define IPRC(N) IPRx(0xa4000016UL,N) 86 { 18, 0, 4, 1 }, /* TMU TUNI1 */
59#define IPRD(N) IPRx(0xa4000018UL,N) 87 { 19, 0, 4, 1 }, /* TMU TUNI1 */
60#define IPRE(N) IPRx(0xa400001aUL,N) 88 { 20, 0, 0, 2 }, /* RTC CUI */
61 89 { 21, 0, 0, 2 }, /* RTC CUI */
62static struct ipr_data sh7709_ipr_map[] = { 90 { 22, 0, 0, 2 }, /* RTC CUI */
63 [16] = { IPRA(12), 2 }, /* TMU TUNI0 */ 91
64 [17] = { IPRA(8), 4 }, /* TMU TUNI1 */ 92 { 23, 1, 4, 3 }, /* SCI */
65 [18 ... 19] = { IPRA(4), 1 }, /* TMU TUNI1 */ 93 { 24, 1, 4, 3 }, /* SCI */
66 [20 ... 22] = { IPRA(0), 2 }, /* RTC CUI */ 94 { 25, 1, 4, 3 }, /* SCI */
67 [23 ... 26] = { IPRB(4), 3 }, /* SCI */ 95 { 26, 1, 4, 3 }, /* SCI */
68 [27] = { IPRB(12), 2 }, /* WDT ITI */ 96 { 27, 1, 12, 3 }, /* WDT ITI */
69 [32] = { IPRC(0), 1 }, /* IRQ 0 */ 97
70 [33] = { IPRC(4), 1 }, /* IRQ 1 */ 98 { 32, 2, 0, 1 }, /* IRQ 0 */
71 [34] = { IPRC(8), 1 }, /* IRQ 2 APM */ 99 { 33, 2, 4, 1 }, /* IRQ 1 */
72 [35] = { IPRC(12), 1 }, /* IRQ 3 TOUCHSCREEN */ 100 { 34, 2, 8, 1 }, /* IRQ 2 APM */
73 [36] = { IPRD(0), 1 }, /* IRQ 4 */ 101 { 35, 2, 12, 1 }, /* IRQ 3 TOUCHSCREEN */
74 [37] = { IPRD(4), 1 }, /* IRQ 5 */ 102
75 [48 ... 51] = { IPRE(12), 7 }, /* DMA */ 103 { 36, 3, 0, 1 }, /* IRQ 4 */
76 [52 ... 55] = { IPRE(8), 3 }, /* IRDA */ 104 { 37, 3, 4, 1 }, /* IRQ 5 */
77 [56 ... 59] = { IPRE(4), 3 }, /* SCIF */ 105
106 { 48, 4, 12, 7 }, /* DMA */
107 { 49, 4, 12, 7 }, /* DMA */
108 { 50, 4, 12, 7 }, /* DMA */
109 { 51, 4, 12, 7 }, /* DMA */
110
111 { 52, 4, 8, 3 }, /* IRDA */
112 { 53, 4, 8, 3 }, /* IRDA */
113 { 54, 4, 8, 3 }, /* IRDA */
114 { 55, 4, 8, 3 }, /* IRDA */
115
116 { 56, 4, 4, 3 }, /* SCIF */
117 { 57, 4, 4, 3 }, /* SCIF */
118 { 58, 4, 4, 3 }, /* SCIF */
119 { 59, 4, 4, 3 }, /* SCIF */
120};
121
122static unsigned long ipr_offsets[] = {
123 0xfffffee2, /* 0: IPRA */
124 0xfffffee4, /* 1: IPRB */
125 0xa4000016, /* 2: IPRC */
126 0xa4000018, /* 3: IPRD */
127 0xa400001a, /* 4: IPRE */
128};
129
130static struct ipr_desc ipr_irq_desc = {
131 .ipr_offsets = ipr_offsets,
132 .nr_offsets = ARRAY_SIZE(ipr_offsets),
133
134 .ipr_data = ipr_irq_table,
135 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
136
137 .chip = {
138 .name = "IPR-sh7709",
139 },
78}; 140};
79 141
80void __init init_IRQ_ipr() 142void __init init_IRQ_ipr(void)
81{ 143{
82 make_ipr_irq(sh7709_ipr_map, ARRAY_SIZE(sh7709_ipr_map)); 144 register_ipr_controller(&ipr_irq_desc);
83} 145}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 51760a7e7f1c..f40e6dac337d 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -49,7 +49,7 @@ static int __init sh7710_devices_setup(void)
49} 49}
50__initcall(sh7710_devices_setup); 50__initcall(sh7710_devices_setup);
51 51
52static struct ipr_data sh7710_ipr_map[] = { 52static struct ipr_data ipr_irq_table[] = {
53 /* IRQ, IPR-idx, shift, priority */ 53 /* IRQ, IPR-idx, shift, priority */
54 { 16, 0, 12, 2 }, /* TMU0 TUNI*/ 54 { 16, 0, 12, 2 }, /* TMU0 TUNI*/
55 { 17, 0, 8, 2 }, /* TMU1 TUNI */ 55 { 17, 0, 8, 2 }, /* TMU1 TUNI */
@@ -78,26 +78,30 @@ static struct ipr_data sh7710_ipr_map[] = {
78}; 78};
79 79
80static unsigned long ipr_offsets[] = { 80static unsigned long ipr_offsets[] = {
81 0xA414FEE2 /* 0: IPRA */ 81 0xA414FEE2, /* 0: IPRA */
82, 0xA414FEE4 /* 1: IPRB */ 82 0xA414FEE4, /* 1: IPRB */
83, 0xA4140016 /* 2: IPRC */ 83 0xA4140016, /* 2: IPRC */
84, 0xA4140018 /* 3: IPRD */ 84 0xA4140018, /* 3: IPRD */
85, 0xA414001A /* 4: IPRE */ 85 0xA414001A, /* 4: IPRE */
86, 0xA4080000 /* 5: IPRF */ 86 0xA4080000, /* 5: IPRF */
87, 0xA4080002 /* 6: IPRG */ 87 0xA4080002, /* 6: IPRG */
88, 0xA4080004 /* 7: IPRH */ 88 0xA4080004, /* 7: IPRH */
89, 0xA4080006 /* 8: IPRI */ 89 0xA4080006, /* 8: IPRI */
90}; 90};
91 91
92/* given the IPR index return the address of the IPR register */ 92static struct ipr_desc ipr_irq_desc = {
93unsigned int map_ipridx_to_addr(int idx) 93 .ipr_offsets = ipr_offsets,
94{ 94 .nr_offsets = ARRAY_SIZE(ipr_offsets),
95 if (idx >= ARRAY_SIZE(ipr_offsets)) 95
96 return 0; 96 .ipr_data = ipr_irq_table,
97 return ipr_offsets[idx]; 97 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
98} 98
99 .chip = {
100 .name = "IPR-sh7710",
101 },
102};
99 103
100void __init init_IRQ_ipr() 104void __init init_IRQ_ipr(void)
101{ 105{
102 make_ipr_irq(sh7710_ipr_map, ARRAY_SIZE(sh7710_ipr_map)); 106 register_ipr_controller(&ipr_irq_desc);
103} 107}
diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile
index 8add10bd8268..dadd6bffc128 100644
--- a/arch/sh/kernel/cpu/sh4/Makefile
+++ b/arch/sh/kernel/cpu/sh4/Makefile
@@ -10,7 +10,11 @@ obj-$(CONFIG_SH_STORE_QUEUES) += sq.o
10 10
11# CPU subtype setup 11# CPU subtype setup
12obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o 12obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o
13obj-$(CONFIG_CPU_SUBTYPE_SH7750R) += setup-sh7750.o
14obj-$(CONFIG_CPU_SUBTYPE_SH7750S) += setup-sh7750.o
15obj-$(CONFIG_CPU_SUBTYPE_SH7091) += setup-sh7750.o
13obj-$(CONFIG_CPU_SUBTYPE_SH7751) += setup-sh7750.o 16obj-$(CONFIG_CPU_SUBTYPE_SH7751) += setup-sh7750.o
17obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += setup-sh7750.o
14obj-$(CONFIG_CPU_SUBTYPE_SH7760) += setup-sh7760.o 18obj-$(CONFIG_CPU_SUBTYPE_SH7760) += setup-sh7760.o
15obj-$(CONFIG_CPU_SUBTYPE_SH4_202) += setup-sh4-202.o 19obj-$(CONFIG_CPU_SUBTYPE_SH4_202) += setup-sh4-202.o
16 20
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index fab2eb07196b..66c3f75647b2 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -141,6 +141,14 @@ int __init detect_cpu_and_cache_system(void)
141 current_cpu_data.flags |= CPU_HAS_LLSC; 141 current_cpu_data.flags |= CPU_HAS_LLSC;
142 } 142 }
143 break; 143 break;
144 case 0x4000: /* 1st cut */
145 case 0x4001: /* 2nd cut */
146 current_cpu_data.type = CPU_SHX3;
147 current_cpu_data.icache.ways = 4;
148 current_cpu_data.dcache.ways = 4;
149 current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
150 CPU_HAS_LLSC;
151 break;
144 case 0x8000: 152 case 0x8000:
145 current_cpu_data.type = CPU_ST40RA; 153 current_cpu_data.type = CPU_ST40RA;
146 current_cpu_data.flags |= CPU_HAS_FPU; 154 current_cpu_data.flags |= CPU_HAS_FPU;
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index 03b14cf78ddf..da153bcdfeb2 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -82,7 +82,7 @@ static int __init sh7750_devices_setup(void)
82} 82}
83__initcall(sh7750_devices_setup); 83__initcall(sh7750_devices_setup);
84 84
85static struct ipr_data sh7750_ipr_map[] = { 85static struct ipr_data ipr_irq_table[] = {
86 /* IRQ, IPR-idx, shift, priority */ 86 /* IRQ, IPR-idx, shift, priority */
87 { 16, 0, 12, 2 }, /* TMU0 TUNI*/ 87 { 16, 0, 12, 2 }, /* TMU0 TUNI*/
88 { 17, 0, 12, 2 }, /* TMU1 TUNI */ 88 { 17, 0, 12, 2 }, /* TMU1 TUNI */
@@ -106,8 +106,27 @@ static struct ipr_data sh7750_ipr_map[] = {
106 { 38, 2, 8, 7 }, /* DMAC DMAE */ 106 { 38, 2, 8, 7 }, /* DMAC DMAE */
107}; 107};
108 108
109static unsigned long ipr_offsets[] = {
110 0xffd00004UL, /* 0: IPRA */
111 0xffd00008UL, /* 1: IPRB */
112 0xffd0000cUL, /* 2: IPRC */
113 0xffd00010UL, /* 3: IPRD */
114};
115
116static struct ipr_desc ipr_irq_desc = {
117 .ipr_offsets = ipr_offsets,
118 .nr_offsets = ARRAY_SIZE(ipr_offsets),
119
120 .ipr_data = ipr_irq_table,
121 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
122
123 .chip = {
124 .name = "IPR-sh7750",
125 },
126};
127
109#ifdef CONFIG_CPU_SUBTYPE_SH7751 128#ifdef CONFIG_CPU_SUBTYPE_SH7751
110static struct ipr_data sh7751_ipr_map[] = { 129static struct ipr_data ipr_irq_table_sh7751[] = {
111 { 44, 2, 8, 7 }, /* DMAC DMTE4 */ 130 { 44, 2, 8, 7 }, /* DMAC DMTE4 */
112 { 45, 2, 8, 7 }, /* DMAC DMTE5 */ 131 { 45, 2, 8, 7 }, /* DMAC DMTE5 */
113 { 46, 2, 8, 7 }, /* DMAC DMTE6 */ 132 { 46, 2, 8, 7 }, /* DMAC DMTE6 */
@@ -118,21 +137,26 @@ static struct ipr_data sh7751_ipr_map[] = {
118 /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */ 137 /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */
119 /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */ 138 /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */
120}; 139};
121#endif
122 140
123static unsigned long ipr_offsets[] = { 141static struct ipr_desc ipr_irq_desc_sh7751 = {
124 0xffd00004UL, /* 0: IPRA */ 142 .ipr_offsets = ipr_offsets,
125 0xffd00008UL, /* 1: IPRB */ 143 .nr_offsets = ARRAY_SIZE(ipr_offsets),
126 0xffd0000cUL, /* 2: IPRC */ 144
127 0xffd00010UL, /* 3: IPRD */ 145 .ipr_data = ipr_irq_table_sh7751,
146 .nr_irqs = ARRAY_SIZE(ipr_irq_table_sh7751),
147
148 .chip = {
149 .name = "IPR-sh7751",
150 },
128}; 151};
152#endif
129 153
130/* given the IPR index return the address of the IPR register */ 154void __init init_IRQ_ipr(void)
131unsigned int map_ipridx_to_addr(int idx)
132{ 155{
133 if (idx >= ARRAY_SIZE(ipr_offsets)) 156 register_ipr_controller(&ipr_irq_desc);
134 return 0; 157#ifdef CONFIG_CPU_SUBTYPE_SH7751
135 return ipr_offsets[idx]; 158 register_ipr_controller(&ipr_irq_desc_sh7751);
159#endif
136} 160}
137 161
138#define INTC_ICR 0xffd00000UL 162#define INTC_ICR 0xffd00000UL
@@ -143,11 +167,3 @@ void ipr_irq_enable_irlm(void)
143{ 167{
144 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); 168 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
145} 169}
146
147void __init init_IRQ_ipr()
148{
149 make_ipr_irq(sh7750_ipr_map, ARRAY_SIZE(sh7750_ipr_map));
150#ifdef CONFIG_CPU_SUBTYPE_SH7751
151 make_ipr_irq(sh7751_ipr_map, ARRAY_SIZE(sh7751_ipr_map));
152#endif
153}
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index b7c702821e6f..3df169755673 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -96,7 +96,25 @@ static struct intc2_data intc2_irq_table[] = {
96 {109,12, 0, 4, 0, 3}, /* CMTI */ 96 {109,12, 0, 4, 0, 3}, /* CMTI */
97}; 97};
98 98
99static struct ipr_data sh7760_ipr_map[] = { 99static struct intc2_desc intc2_irq_desc __read_mostly = {
100 .prio_base = 0xfe080000,
101 .msk_base = 0xfe080040,
102 .mskclr_base = 0xfe080060,
103
104 .intc2_data = intc2_irq_table,
105 .nr_irqs = ARRAY_SIZE(intc2_irq_table),
106
107 .chip = {
108 .name = "INTC2-sh7760",
109 },
110};
111
112void __init init_IRQ_intc2(void)
113{
114 register_intc2_controller(&intc2_irq_desc);
115}
116
117static struct ipr_data ipr_irq_table[] = {
100 /* IRQ, IPR-idx, shift, priority */ 118 /* IRQ, IPR-idx, shift, priority */
101 { 16, 0, 12, 2 }, /* TMU0 TUNI*/ 119 { 16, 0, 12, 2 }, /* TMU0 TUNI*/
102 { 17, 0, 8, 2 }, /* TMU1 TUNI */ 120 { 17, 0, 8, 2 }, /* TMU1 TUNI */
@@ -133,20 +151,19 @@ static unsigned long ipr_offsets[] = {
133 0xffd00010UL, /* 3: IPRD */ 151 0xffd00010UL, /* 3: IPRD */
134}; 152};
135 153
136/* given the IPR index return the address of the IPR register */ 154static struct ipr_desc ipr_irq_desc = {
137unsigned int map_ipridx_to_addr(int idx) 155 .ipr_offsets = ipr_offsets,
138{ 156 .nr_offsets = ARRAY_SIZE(ipr_offsets),
139 if (idx >= ARRAY_SIZE(ipr_offsets))
140 return 0;
141 return ipr_offsets[idx];
142}
143 157
144void __init init_IRQ_intc2(void) 158 .ipr_data = ipr_irq_table,
145{ 159 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
146 make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); 160
147} 161 .chip = {
162 .name = "IPR-sh7760",
163 },
164};
148 165
149void __init init_IRQ_ipr(void) 166void __init init_IRQ_ipr(void)
150{ 167{
151 make_ipr_irq(sh7760_ipr_map, ARRAY_SIZE(sh7760_ipr_map)); 168 register_ipr_controller(&ipr_irq_desc);
152} 169}
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index ab7422f8f820..400623286487 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o
9obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o 9obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o
10obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o 10obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
11obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o 11obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
12obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o
12 13
13# Primary on-chip clocks (common) 14# Primary on-chip clocks (common)
14clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o 15clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o
@@ -17,5 +18,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
17clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o 18clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
18clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o 19clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o
19clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o 20clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o
21clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o
20 22
21obj-y += $(clock-y) 23obj-y += $(clock-y)
diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
new file mode 100644
index 000000000000..c630b29e06a8
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
@@ -0,0 +1,135 @@
1/*
2 * arch/sh/kernel/cpu/sh4/clock-shx3.c
3 *
4 * SH-X3 support for the clock framework
5 *
6 * Copyright (C) 2006-2007 Renesas Technology Corp.
7 * Copyright (C) 2006-2007 Renesas Solutions Corp.
8 * Copyright (C) 2006-2007 Paul Mundt
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
13 */
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <asm/clock.h>
17#include <asm/freq.h>
18#include <asm/io.h>
19
20static int ifc_divisors[] = { 1, 2, 4 ,6 };
21static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18, 24, 32, 36, 48 };
22static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18, 24, 32, 36, 48 };
23static int cfc_divisors[] = { 1, 1, 4, 6 };
24
25#define IFC_POS 28
26#define IFC_MSK 0x0003
27#define BFC_MSK 0x000f
28#define PFC_MSK 0x000f
29#define CFC_MSK 0x0003
30#define BFC_POS 16
31#define PFC_POS 0
32#define CFC_POS 20
33
34static void master_clk_init(struct clk *clk)
35{
36 clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK];
37}
38
39static struct clk_ops shx3_master_clk_ops = {
40 .init = master_clk_init,
41};
42
43static void module_clk_recalc(struct clk *clk)
44{
45 int idx = ((ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK);
46 clk->rate = clk->parent->rate / pfc_divisors[idx];
47}
48
49static struct clk_ops shx3_module_clk_ops = {
50 .recalc = module_clk_recalc,
51};
52
53static void bus_clk_recalc(struct clk *clk)
54{
55 int idx = ((ctrl_inl(FRQCR) >> BFC_POS) & BFC_MSK);
56 clk->rate = clk->parent->rate / bfc_divisors[idx];
57}
58
59static struct clk_ops shx3_bus_clk_ops = {
60 .recalc = bus_clk_recalc,
61};
62
63static void cpu_clk_recalc(struct clk *clk)
64{
65 int idx = ((ctrl_inl(FRQCR) >> IFC_POS) & IFC_MSK);
66 clk->rate = clk->parent->rate / ifc_divisors[idx];
67}
68
69static struct clk_ops shx3_cpu_clk_ops = {
70 .recalc = cpu_clk_recalc,
71};
72
73static struct clk_ops *shx3_clk_ops[] = {
74 &shx3_master_clk_ops,
75 &shx3_module_clk_ops,
76 &shx3_bus_clk_ops,
77 &shx3_cpu_clk_ops,
78};
79
80void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
81{
82 if (idx < ARRAY_SIZE(shx3_clk_ops))
83 *ops = shx3_clk_ops[idx];
84}
85
86static void shyway_clk_recalc(struct clk *clk)
87{
88 int idx = ((ctrl_inl(FRQCR) >> CFC_POS) & CFC_MSK);
89 clk->rate = clk->parent->rate / cfc_divisors[idx];
90}
91
92static struct clk_ops shx3_shyway_clk_ops = {
93 .recalc = shyway_clk_recalc,
94};
95
96static struct clk shx3_shyway_clk = {
97 .name = "shyway_clk",
98 .flags = CLK_ALWAYS_ENABLED,
99 .ops = &shx3_shyway_clk_ops,
100};
101
102/*
103 * Additional SHx3-specific on-chip clocks that aren't already part of the
104 * clock framework
105 */
106static struct clk *shx3_onchip_clocks[] = {
107 &shx3_shyway_clk,
108};
109
110static int __init shx3_clk_init(void)
111{
112 struct clk *clk = clk_get(NULL, "master_clk");
113 int i;
114
115 for (i = 0; i < ARRAY_SIZE(shx3_onchip_clocks); i++) {
116 struct clk *clkp = shx3_onchip_clocks[i];
117
118 clkp->parent = clk;
119 clk_register(clkp);
120 clk_enable(clkp);
121 }
122
123 /*
124 * Now that we have the rest of the clocks registered, we need to
125 * force the parent clock to propagate so that these clocks will
126 * automatically figure out their rate. We cheat by handing the
127 * parent clock its current rate and forcing child propagation.
128 */
129 clk_set_rate(clk, clk_get_rate(clk));
130
131 clk_put(clk);
132
133 return 0;
134}
135arch_initcall(shx3_clk_init);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index 1143fbf65faf..a3e159ef6dfe 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SH7722 Setup 2 * SH7722 Setup
3 * 3 *
4 * Copyright (C) 2006 Paul Mundt 4 * Copyright (C) 2006 - 2007 Paul Mundt
5 * 5 *
6 * This file is subject to the terms and conditions of the GNU General Public 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 7 * License. See the file "COPYING" in the main directory of this archive
@@ -10,6 +10,8 @@
10#include <linux/platform_device.h> 10#include <linux/platform_device.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/serial.h> 12#include <linux/serial.h>
13#include <linux/mm.h>
14#include <asm/mmzone.h>
13#include <asm/sci.h> 15#include <asm/sci.h>
14 16
15static struct plat_sci_port sci_platform_data[] = { 17static struct plat_sci_port sci_platform_data[] = {
@@ -42,7 +44,7 @@ static int __init sh7722_devices_setup(void)
42} 44}
43__initcall(sh7722_devices_setup); 45__initcall(sh7722_devices_setup);
44 46
45static struct ipr_data sh7722_ipr_map[] = { 47static struct ipr_data ipr_irq_table[] = {
46 /* IRQ, IPR-idx, shift, prio */ 48 /* IRQ, IPR-idx, shift, prio */
47 { 16, 0, 12, 2 }, /* TMU0 */ 49 { 16, 0, 12, 2 }, /* TMU0 */
48 { 17, 0, 8, 2 }, /* TMU1 */ 50 { 17, 0, 8, 2 }, /* TMU1 */
@@ -67,14 +69,25 @@ static unsigned long ipr_offsets[] = {
67 0xa408002c, /* 11: IPRL */ 69 0xa408002c, /* 11: IPRL */
68}; 70};
69 71
70unsigned int map_ipridx_to_addr(int idx) 72static struct ipr_desc ipr_irq_desc = {
73 .ipr_offsets = ipr_offsets,
74 .nr_offsets = ARRAY_SIZE(ipr_offsets),
75
76 .ipr_data = ipr_irq_table,
77 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
78
79 .chip = {
80 .name = "IPR-sh7722",
81 },
82};
83
84void __init init_IRQ_ipr(void)
71{ 85{
72 if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) 86 register_ipr_controller(&ipr_irq_desc);
73 return 0;
74 return ipr_offsets[idx];
75} 87}
76 88
77void __init init_IRQ_ipr(void) 89void __init plat_mem_setup(void)
78{ 90{
79 make_ipr_irq(sh7722_ipr_map, ARRAY_SIZE(sh7722_ipr_map)); 91 /* Register the URAM space as Node 1 */
92 setup_bootmem_node(1, 0x055f0000, 0x05610000);
80} 93}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index 9aeaa2ddaa28..b57c760bffde 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -102,7 +102,20 @@ static struct intc2_data intc2_irq_table[] = {
102 { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */ 102 { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */
103}; 103};
104 104
105static struct intc2_desc intc2_irq_desc __read_mostly = {
106 .prio_base = 0xffd40000,
107 .msk_base = 0xffd40038,
108 .mskclr_base = 0xffd4003c,
109
110 .intc2_data = intc2_irq_table,
111 .nr_irqs = ARRAY_SIZE(intc2_irq_table),
112
113 .chip = {
114 .name = "INTC2-sh7780",
115 },
116};
117
105void __init init_IRQ_intc2(void) 118void __init init_IRQ_intc2(void)
106{ 119{
107 make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); 120 register_intc2_controller(&intc2_irq_desc);
108} 121}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index 07b0de82cfe6..ce10ec5d6914 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -97,7 +97,21 @@ static struct intc2_data intc2_irq_table[] = {
97 { 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */ 97 { 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */
98}; 98};
99 99
100static struct intc2_desc intc2_irq_desc __read_mostly = {
101 .prio_base = 0xffd40000,
102 .msk_base = 0xffd40038,
103 .mskclr_base = 0xffd4003c,
104
105 .intc2_data = intc2_irq_table,
106 .nr_irqs = ARRAY_SIZE(intc2_irq_table),
107
108 .chip = {
109 .name = "INTC2-sh7785",
110 },
111};
112
100void __init init_IRQ_intc2(void) 113void __init init_IRQ_intc2(void)
101{ 114{
102 make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); 115 register_intc2_controller(&intc2_irq_desc);
103} 116}
117
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
new file mode 100644
index 000000000000..70683ea12b83
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -0,0 +1,85 @@
1/*
2 * SH-X3 Setup
3 *
4 * Copyright (C) 2007 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/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <linux/io.h>
14#include <asm/sci.h>
15
16static struct plat_sci_port sci_platform_data[] = {
17 {
18 .mapbase = 0xffc30000,
19 .flags = UPF_BOOT_AUTOCONF,
20 .type = PORT_SCIF,
21 .irqs = { 40, 41, 43, 42 },
22 }, {
23 .mapbase = 0xffc40000,
24 .flags = UPF_BOOT_AUTOCONF,
25 .type = PORT_SCIF,
26 .irqs = { 44, 45, 47, 46 },
27 }, {
28 .mapbase = 0xffc50000,
29 .flags = UPF_BOOT_AUTOCONF,
30 .type = PORT_SCIF,
31 .irqs = { 48, 49, 51, 50 },
32 }, {
33 .mapbase = 0xffc60000,
34 .flags = UPF_BOOT_AUTOCONF,
35 .type = PORT_SCIF,
36 .irqs = { 52, 53, 55, 54 },
37 }, {
38 .flags = 0,
39 }
40};
41
42static struct platform_device sci_device = {
43 .name = "sh-sci",
44 .id = -1,
45 .dev = {
46 .platform_data = sci_platform_data,
47 },
48};
49
50static struct platform_device *shx3_devices[] __initdata = {
51 &sci_device,
52};
53
54static int __init shx3_devices_setup(void)
55{
56 return platform_add_devices(shx3_devices,
57 ARRAY_SIZE(shx3_devices));
58}
59__initcall(shx3_devices_setup);
60
61static struct intc2_data intc2_irq_table[] = {
62 { 16, 0, 0, 0, 1, 2 }, /* TMU0 */
63 { 40, 4, 0, 0x20, 0, 3 }, /* SCIF0 ERI */
64 { 41, 4, 0, 0x20, 1, 3 }, /* SCIF0 RXI */
65 { 42, 4, 0, 0x20, 2, 3 }, /* SCIF0 BRI */
66 { 43, 4, 0, 0x20, 3, 3 }, /* SCIF0 TXI */
67};
68
69static struct intc2_desc intc2_irq_desc __read_mostly = {
70 .prio_base = 0xfe410000,
71 .msk_base = 0xfe410820,
72 .mskclr_base = 0xfe410850,
73
74 .intc2_data = intc2_irq_table,
75 .nr_irqs = ARRAY_SIZE(intc2_irq_table),
76
77 .chip = {
78 .name = "INTC2-SHX3",
79 },
80};
81
82void __init init_IRQ_intc2(void)
83{
84 register_intc2_controller(&intc2_irq_desc);
85}