add lantiq svip support
[openwrt/staging/chunkeey.git] / target / linux / lantiq / patches-3.3 / 0070-icu-multi-base.patch
1 Index: linux-3.3.8/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
2 ===================================================================
3 --- linux-3.3.8.orig/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h 2012-07-31 08:34:35.000000000 +0200
4 +++ linux-3.3.8/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h 2012-07-31 08:34:46.063369976 +0200
5 @@ -9,6 +9,8 @@
6 #ifndef _LANTIQ_XWAY_IRQ_H__
7 #define _LANTIQ_XWAY_IRQ_H__
8
9 +#define IM_NUM 5
10 +
11 #define INT_NUM_IRQ0 8
12 #define INT_NUM_IM0_IRL0 (INT_NUM_IRQ0 + 0)
13 #define INT_NUM_IM1_IRL0 (INT_NUM_IRQ0 + 32)
14 Index: linux-3.3.8/arch/mips/lantiq/irq.c
15 ===================================================================
16 --- linux-3.3.8.orig/arch/mips/lantiq/irq.c 2012-07-31 08:34:35.000000000 +0200
17 +++ linux-3.3.8/arch/mips/lantiq/irq.c 2012-07-31 08:51:40.203413329 +0200
18 @@ -48,8 +48,8 @@
19 */
20 #define LTQ_ICU_EBU_IRQ 22
21
22 -#define ltq_icu_w32(x, y) ltq_w32((x), ltq_icu_membase + (y))
23 -#define ltq_icu_r32(x) ltq_r32(ltq_icu_membase + (x))
24 +#define ltq_icu_w32(x, y, m) ltq_w32((x), ltq_icu_membase[m] + (y))
25 +#define ltq_icu_r32(x, m) ltq_r32(ltq_icu_membase[m] + (x))
26
27 #define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y))
28 #define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x))
29 @@ -63,11 +63,78 @@
30 LTQ_EIU_IR5,
31 };
32
33 -static struct resource ltq_icu_resource = {
34 - .name = "icu",
35 - .start = LTQ_ICU_BASE_ADDR,
36 - .end = LTQ_ICU_BASE_ADDR + LTQ_ICU_SIZE - 1,
37 - .flags = IORESOURCE_MEM,
38 +static struct resource ltq_icu_resource[IM_NUM] = {
39 +{
40 + .name = "icu_im0",
41 + .start = LTQ_ICU_BASE_ADDR,
42 + .end = LTQ_ICU_BASE_ADDR + LTQ_ICU_OFFSET - 1,
43 + .flags = IORESOURCE_MEM,
44 +},
45 +#if IM_NUM >= 2
46 +{
47 + .name = "icu_im1",
48 +#ifdef LTQ_ICU_BASE_ADDR1
49 + .start = LTQ_ICU_BASE_ADDR1,
50 + .end = LTQ_ICU_BASE_ADDR1 + LTQ_ICU_OFFSET - 1,
51 +#else
52 + .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 1),
53 + .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 2) - 1,
54 +#endif
55 + .flags = IORESOURCE_MEM,
56 +},
57 +#endif
58 +#if IM_NUM >= 3
59 +{
60 + .name = "icu_im2",
61 +#ifdef LTQ_ICU_BASE_ADDR2
62 + .start = LTQ_ICU_BASE_ADDR2,
63 + .end = LTQ_ICU_BASE_ADDR2 + LTQ_ICU_OFFSET - 1,
64 +#else
65 + .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 2),
66 + .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 3) - 1,
67 +#endif
68 + .flags = IORESOURCE_MEM,
69 +},
70 +#endif
71 +#if IM_NUM >= 4
72 +{
73 + .name = "icu_im3",
74 +#ifdef LTQ_ICU_BASE_ADDR3
75 + .start = LTQ_ICU_BASE_ADDR3,
76 + .end = LTQ_ICU_BASE_ADDR3 + LTQ_ICU_OFFSET - 1,
77 +#else
78 + .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 3),
79 + .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 4) - 1,
80 +#endif
81 + .flags = IORESOURCE_MEM,
82 +},
83 +#endif
84 +#if IM_NUM >= 5
85 +{
86 + .name = "icu_im4",
87 +#ifdef LTQ_ICU_BASE_ADDR4
88 + .start = LTQ_ICU_BASE_ADDR4,
89 + .end = LTQ_ICU_BASE_ADDR4 + LTQ_ICU_OFFSET - 1,
90 +#else
91 + .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 4),
92 + .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 5) - 1,
93 +#endif
94 + .flags = IORESOURCE_MEM,
95 +},
96 +#endif
97 +#if IM_NUM >= 6
98 +{
99 + .name = "icu_im5",
100 +#ifdef LTQ_ICU_BASE_ADDR5
101 + .start = LTQ_ICU_BASE_ADDR5,
102 + .end = LTQ_ICU_BASE_ADDR5 + LTQ_ICU_OFFSET - 1,
103 +#else
104 + .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 5),
105 + .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 6) - 1,
106 +#endif
107 + .flags = IORESOURCE_MEM,
108 +},
109 +#endif
110 };
111
112 static struct resource ltq_eiu_resource = {
113 @@ -77,50 +144,56 @@
114 .flags = IORESOURCE_MEM,
115 };
116
117 -static void __iomem *ltq_icu_membase;
118 +static void __iomem *ltq_icu_membase[IM_NUM];
119 static void __iomem *ltq_eiu_membase;
120
121 void ltq_disable_irq(struct irq_data *d)
122 {
123 - u32 ier = LTQ_ICU_IM0_IER;
124 int irq_nr = d->irq - INT_NUM_IRQ0;
125 + unsigned int im_nr;
126
127 - ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
128 + im_nr = (irq_nr / INT_NUM_IM_OFFSET);
129 irq_nr %= INT_NUM_IM_OFFSET;
130 - ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
131 +
132 + ltq_icu_w32(ltq_icu_r32(LTQ_ICU_IM0_IER, im_nr) & ~(1 << irq_nr),
133 + LTQ_ICU_IM0_IER, im_nr);
134 }
135
136 void ltq_mask_and_ack_irq(struct irq_data *d)
137 {
138 - u32 ier = LTQ_ICU_IM0_IER;
139 - u32 isr = LTQ_ICU_IM0_ISR;
140 int irq_nr = d->irq - INT_NUM_IRQ0;
141 + unsigned int im_nr;
142
143 - ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
144 - isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
145 + irq_nr -= INT_NUM_IRQ0;
146 + im_nr = (irq_nr / INT_NUM_IM_OFFSET);
147 irq_nr %= INT_NUM_IM_OFFSET;
148 - ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
149 - ltq_icu_w32((1 << irq_nr), isr);
150 +
151 + ltq_icu_w32(ltq_icu_r32(LTQ_ICU_IM0_IER, im_nr) & ~(1 << irq_nr), LTQ_ICU_IM0_IER, im_nr);
152 + ltq_icu_w32((1 << irq_nr), LTQ_ICU_IM0_ISR, im_nr);
153 }
154
155 static void ltq_ack_irq(struct irq_data *d)
156 {
157 - u32 isr = LTQ_ICU_IM0_ISR;
158 int irq_nr = d->irq - INT_NUM_IRQ0;
159 + unsigned int im_nr;
160
161 - isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
162 + irq_nr -= INT_NUM_IRQ0;
163 + im_nr = (irq_nr / INT_NUM_IM_OFFSET);
164 irq_nr %= INT_NUM_IM_OFFSET;
165 - ltq_icu_w32((1 << irq_nr), isr);
166 +
167 + ltq_icu_w32((1 << irq_nr), LTQ_ICU_IM0_ISR, im_nr);
168 }
169
170 void ltq_enable_irq(struct irq_data *d)
171 {
172 - u32 ier = LTQ_ICU_IM0_IER;
173 int irq_nr = d->irq - INT_NUM_IRQ0;
174 + unsigned int im_nr;
175
176 - ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
177 + irq_nr -= INT_NUM_IRQ0;
178 + im_nr = (irq_nr / INT_NUM_IM_OFFSET);
179 irq_nr %= INT_NUM_IM_OFFSET;
180 - ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier);
181 +
182 + ltq_icu_w32(ltq_icu_r32(LTQ_ICU_IM0_IER, im_nr) | (1 << irq_nr), LTQ_ICU_IM0_IER, im_nr);
183 }
184
185 static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
186 @@ -187,7 +260,7 @@
187 {
188 u32 irq;
189
190 - irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR + (module * LTQ_ICU_OFFSET));
191 + irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR, module);
192 if (irq == 0)
193 return;
194
195 @@ -250,8 +323,19 @@
196 {
197 int i;
198
199 - if (insert_resource(&iomem_resource, &ltq_icu_resource) < 0)
200 - panic("Failed to insert icu memory");
201 + for (i=0; i < IM_NUM; i++) {
202 + if (insert_resource(&iomem_resource, &ltq_icu_resource[i]) < 0)
203 + panic("Failed to insert icu memory\n");
204 +
205 + if (request_mem_region(ltq_icu_resource[i].start,
206 + resource_size(&ltq_icu_resource[i]), "icu") < 0)
207 + panic("Failed to request icu memory\n");
208 +
209 + ltq_icu_membase[i] = ioremap_nocache(ltq_icu_resource[i].start,
210 + resource_size(&ltq_icu_resource[i]));
211 + if (!ltq_icu_membase[i])
212 + panic("Failed to remap icu memory\n");
213 + }
214
215 if (request_mem_region(ltq_icu_resource.start,
216 resource_size(&ltq_icu_resource), "icu") < 0)
217 @@ -277,11 +361,11 @@
218 }
219
220 /* make sure all irqs are turned off by default */
221 - for (i = 0; i < 5; i++)
222 - ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET));
223 -
224 - /* clear all possibly pending interrupts */
225 - ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
226 + for (i = 0; i < IM_NUM; i++)
227 + ltq_icu_w32(0, LTQ_ICU_IM0_IER, i);
228 + /* clear all possibly pending interrupts */
229 + ltq_icu_w32(~0, LTQ_ICU_IM0_ISR, i);
230 + }
231
232 mips_cpu_irq_init();
233