sh: rework ipr code
[linux-2.6] / arch / sh / kernel / cpu / sh4 / setup-sh7750.c
1 /*
2  * SH7750/SH7751 Setup
3  *
4  *  Copyright (C) 2006  Paul Mundt
5  *  Copyright (C) 2006  Jamie Lenehan
6  *
7  * This file is subject to the terms and conditions of the GNU General Public
8  * License.  See the file "COPYING" in the main directory of this archive
9  * for more details.
10  */
11 #include <linux/platform_device.h>
12 #include <linux/init.h>
13 #include <linux/serial.h>
14 #include <linux/io.h>
15 #include <asm/sci.h>
16
17 static struct resource rtc_resources[] = {
18         [0] = {
19                 .start  = 0xffc80000,
20                 .end    = 0xffc80000 + 0x58 - 1,
21                 .flags  = IORESOURCE_IO,
22         },
23         [1] = {
24                 /* Period IRQ */
25                 .start  = 21,
26                 .flags  = IORESOURCE_IRQ,
27         },
28         [2] = {
29                 /* Carry IRQ */
30                 .start  = 22,
31                 .flags  = IORESOURCE_IRQ,
32         },
33         [3] = {
34                 /* Alarm IRQ */
35                 .start  = 20,
36                 .flags  = IORESOURCE_IRQ,
37         },
38 };
39
40 static struct platform_device rtc_device = {
41         .name           = "sh-rtc",
42         .id             = -1,
43         .num_resources  = ARRAY_SIZE(rtc_resources),
44         .resource       = rtc_resources,
45 };
46
47 static struct plat_sci_port sci_platform_data[] = {
48         {
49 #ifndef CONFIG_SH_RTS7751R2D
50                 .mapbase        = 0xffe00000,
51                 .flags          = UPF_BOOT_AUTOCONF,
52                 .type           = PORT_SCI,
53                 .irqs           = { 23, 24, 25, 0 },
54         }, {
55 #endif
56                 .mapbase        = 0xffe80000,
57                 .flags          = UPF_BOOT_AUTOCONF,
58                 .type           = PORT_SCIF,
59                 .irqs           = { 40, 41, 43, 42 },
60         }, {
61                 .flags = 0,
62         }
63 };
64
65 static struct platform_device sci_device = {
66         .name           = "sh-sci",
67         .id             = -1,
68         .dev            = {
69                 .platform_data  = sci_platform_data,
70         },
71 };
72
73 static struct platform_device *sh7750_devices[] __initdata = {
74         &rtc_device,
75         &sci_device,
76 };
77
78 static int __init sh7750_devices_setup(void)
79 {
80         return platform_add_devices(sh7750_devices,
81                                     ARRAY_SIZE(sh7750_devices));
82 }
83 __initcall(sh7750_devices_setup);
84
85 static struct ipr_data ipr_irq_table[] = {
86         /* IRQ, IPR-idx, shift, priority */
87         { 16, 0, 12, 2 }, /* TMU0 TUNI*/
88         { 17, 0, 12, 2 }, /* TMU1 TUNI */
89         { 18, 0,  4, 2 }, /* TMU2 TUNI */
90         { 19, 0,  4, 2 }, /* TMU2 TIPCI */
91         { 27, 1, 12, 2 }, /* WDT ITI */
92         { 20, 0,  0, 2 }, /* RTC ATI (alarm) */
93         { 21, 0,  0, 2 }, /* RTC PRI (period) */
94         { 22, 0,  0, 2 }, /* RTC CUI (carry) */
95         { 23, 1,  4, 3 }, /* SCI ERI */
96         { 24, 1,  4, 3 }, /* SCI RXI */
97         { 25, 1,  4, 3 }, /* SCI TXI */
98         { 40, 2,  4, 3 }, /* SCIF ERI */
99         { 41, 2,  4, 3 }, /* SCIF RXI */
100         { 42, 2,  4, 3 }, /* SCIF BRI */
101         { 43, 2,  4, 3 }, /* SCIF TXI */
102         { 34, 2,  8, 7 }, /* DMAC DMTE0 */
103         { 35, 2,  8, 7 }, /* DMAC DMTE1 */
104         { 36, 2,  8, 7 }, /* DMAC DMTE2 */
105         { 37, 2,  8, 7 }, /* DMAC DMTE3 */
106         { 38, 2,  8, 7 }, /* DMAC DMAE */
107 };
108
109 static unsigned long ipr_offsets[] = {
110         0xffd00004UL,   /* 0: IPRA */
111         0xffd00008UL,   /* 1: IPRB */
112         0xffd0000cUL,   /* 2: IPRC */
113         0xffd00010UL,   /* 3: IPRD */
114 };
115
116 static 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
128 #ifdef CONFIG_CPU_SUBTYPE_SH7751
129 static struct ipr_data ipr_irq_table_sh7751[] = {
130         { 44, 2,  8, 7 }, /* DMAC DMTE4 */
131         { 45, 2,  8, 7 }, /* DMAC DMTE5 */
132         { 46, 2,  8, 7 }, /* DMAC DMTE6 */
133         { 47, 2,  8, 7 }, /* DMAC DMTE7 */
134         /* The following use INTC_INPRI00 for masking, which is a 32-bit
135            register, not a 16-bit register like the IPRx registers, so it
136            would need special support */
137         /*{ 72, INTPRI00,  8, ? },*/ /* TMU3 TUNI */
138         /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */
139 };
140
141 static struct ipr_desc ipr_irq_desc_sh7751 = {
142         .ipr_offsets    = ipr_offsets,
143         .nr_offsets     = ARRAY_SIZE(ipr_offsets),
144
145         .ipr_data       = ipr_irq_table_sh7751,
146         .nr_irqs        = ARRAY_SIZE(ipr_irq_table_sh7751),
147
148         .chip = {
149                 .name   = "IPR-sh7751",
150         },
151 };
152 #endif
153
154 void __init init_IRQ_ipr(void)
155 {
156         register_ipr_controller(&ipr_irq_desc);
157 #ifdef CONFIG_CPU_SUBTYPE_SH7751
158         register_ipr_controller(&ipr_irq_desc_sh7751);
159 #endif
160 }
161
162 #define INTC_ICR        0xffd00000UL
163 #define INTC_ICR_IRLM   (1<<7)
164
165 /* enable individual interrupt mode for external interupts */
166 void ipr_irq_enable_irlm(void)
167 {
168         ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
169 }