aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/alchemy/common/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/alchemy/common/irq.c')
-rw-r--r--arch/mips/alchemy/common/irq.c785
1 files changed, 422 insertions, 363 deletions
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c
index 40c6ceceb5f9..c54384779fb9 100644
--- a/arch/mips/alchemy/common/irq.c
+++ b/arch/mips/alchemy/common/irq.c
@@ -24,6 +24,7 @@
24 * with this program; if not, write to the Free Software Foundation, Inc., 24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 675 Mass Ave, Cambridge, MA 02139, USA. 25 * 675 Mass Ave, Cambridge, MA 02139, USA.
26 */ 26 */
27
27#include <linux/bitops.h> 28#include <linux/bitops.h>
28#include <linux/init.h> 29#include <linux/init.h>
29#include <linux/interrupt.h> 30#include <linux/interrupt.h>
@@ -36,15 +37,174 @@
36#include <asm/mach-pb1x00/pb1000.h> 37#include <asm/mach-pb1x00/pb1000.h>
37#endif 38#endif
38 39
39#define EXT_INTC0_REQ0 2 /* IP 2 */ 40static DEFINE_SPINLOCK(irq_lock);
40#define EXT_INTC0_REQ1 3 /* IP 3 */
41#define EXT_INTC1_REQ0 4 /* IP 4 */
42#define EXT_INTC1_REQ1 5 /* IP 5 */
43#define MIPS_TIMER_IP 7 /* IP 7 */
44 41
45void (*board_init_irq)(void) __initdata = NULL; 42static int au1x_ic_settype(unsigned int irq, unsigned int flow_type);
43
44/* per-processor fixed function irqs */
45struct au1xxx_irqmap au1xxx_ic0_map[] __initdata = {
46
47#if defined(CONFIG_SOC_AU1000)
48 { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
49 { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
50 { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
51 { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
52 { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
53 { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
54 { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
55 { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
56 { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
57 { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
58 { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
59 { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
60 { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
61 { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
62 { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
63 { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
64 { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
65 { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
66 { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
67 { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
68 { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
69 { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
70 { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
71 { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
72 { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
73 { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
74 { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
75 { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
76 { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
77 { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
78 { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
79
80#elif defined(CONFIG_SOC_AU1500)
81
82 { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
83 { AU1000_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
84 { AU1000_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
85 { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
86 { AU1000_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
87 { AU1000_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
88 { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
89 { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
90 { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
91 { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
92 { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
93 { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
94 { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
95 { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
96 { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
97 { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
98 { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
99 { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
100 { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
101 { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
102 { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
103 { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
104 { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
105 { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
106 { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
107 { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
108 { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
109 { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
110 { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
111
112#elif defined(CONFIG_SOC_AU1100)
113
114 { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
115 { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
116 { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
117 { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
118 { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
119 { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
120 { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
121 { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
122 { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
123 { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
124 { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
125 { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
126 { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
127 { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
128 { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
129 { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
130 { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
131 { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
132 { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
133 { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
134 { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
135 { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
136 { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
137 { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
138 { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
139 { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
140 { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
141 { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
142 { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
143 { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
144 { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
145
146#elif defined(CONFIG_SOC_AU1550)
147
148 { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
149 { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
150 { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
151 { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
152 { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
153 { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
154 { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
155 { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
156 { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
157 { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
158 { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
159 { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
160 { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
161 { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
162 { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
163 { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
164 { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
165 { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
166 { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
167 { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
168 { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
169 { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
170 { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
171 { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
172 { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
173 { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
174 { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
175 { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
176
177#elif defined(CONFIG_SOC_AU1200)
178
179 { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
180 { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 },
181 { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
182 { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
183 { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
184 { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
185 { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
186 { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
187 { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
188 { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
189 { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
190 { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
191 { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
192 { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
193 { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
194 { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
195 { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
196 { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
197 { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
198 { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
199 { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
200 { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
201 { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
202
203#else
204#error "Error: Unknown Alchemy SOC"
205#endif
206};
46 207
47static DEFINE_SPINLOCK(irq_lock);
48 208
49#ifdef CONFIG_PM 209#ifdef CONFIG_PM
50 210
@@ -130,67 +290,47 @@ void restore_au1xxx_intctl(void)
130#endif /* CONFIG_PM */ 290#endif /* CONFIG_PM */
131 291
132 292
133inline void local_enable_irq(unsigned int irq_nr) 293static void au1x_ic0_unmask(unsigned int irq_nr)
134{ 294{
135 unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; 295 unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
136 296 au_writel(1 << bit, IC0_MASKSET);
137 if (bit >= 32) { 297 au_writel(1 << bit, IC0_WAKESET);
138 au_writel(1 << (bit - 32), IC1_MASKSET);
139 au_writel(1 << (bit - 32), IC1_WAKESET);
140 } else {
141 au_writel(1 << bit, IC0_MASKSET);
142 au_writel(1 << bit, IC0_WAKESET);
143 }
144 au_sync(); 298 au_sync();
145} 299}
146 300
147 301static void au1x_ic1_unmask(unsigned int irq_nr)
148inline void local_disable_irq(unsigned int irq_nr)
149{ 302{
150 unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; 303 unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
304 au_writel(1 << bit, IC1_MASKSET);
305 au_writel(1 << bit, IC1_WAKESET);
151 306
152 if (bit >= 32) { 307/* very hacky. does the pb1000 cpld auto-disable this int?
153 au_writel(1 << (bit - 32), IC1_MASKCLR); 308 * nowhere in the current kernel sources is it disabled. --mlau
154 au_writel(1 << (bit - 32), IC1_WAKECLR); 309 */
155 } else { 310#if defined(CONFIG_MIPS_PB1000)
156 au_writel(1 << bit, IC0_MASKCLR); 311 if (irq_nr == AU1000_GPIO_15)
157 au_writel(1 << bit, IC0_WAKECLR); 312 au_writel(0x4000, PB1000_MDR); /* enable int */
158 } 313#endif
159 au_sync(); 314 au_sync();
160} 315}
161 316
162 317static void au1x_ic0_mask(unsigned int irq_nr)
163static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
164{ 318{
165 unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; 319 unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
166 320 au_writel(1 << bit, IC0_MASKCLR);
167 if (bit >= 32) { 321 au_writel(1 << bit, IC0_WAKECLR);
168 au_writel(1 << (bit - 32), IC1_RISINGCLR);
169 au_writel(1 << (bit - 32), IC1_MASKCLR);
170 } else {
171 au_writel(1 << bit, IC0_RISINGCLR);
172 au_writel(1 << bit, IC0_MASKCLR);
173 }
174 au_sync(); 322 au_sync();
175} 323}
176 324
177 325static void au1x_ic1_mask(unsigned int irq_nr)
178static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr)
179{ 326{
180 unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; 327 unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
181 328 au_writel(1 << bit, IC1_MASKCLR);
182 if (bit >= 32) { 329 au_writel(1 << bit, IC1_WAKECLR);
183 au_writel(1 << (bit - 32), IC1_FALLINGCLR);
184 au_writel(1 << (bit - 32), IC1_MASKCLR);
185 } else {
186 au_writel(1 << bit, IC0_FALLINGCLR);
187 au_writel(1 << bit, IC0_MASKCLR);
188 }
189 au_sync(); 330 au_sync();
190} 331}
191 332
192 333static void au1x_ic0_ack(unsigned int irq_nr)
193static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
194{ 334{
195 unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; 335 unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
196 336
@@ -198,349 +338,229 @@ static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
198 * This may assume that we don't get interrupts from 338 * This may assume that we don't get interrupts from
199 * both edges at once, or if we do, that we don't care. 339 * both edges at once, or if we do, that we don't care.
200 */ 340 */
201 if (bit >= 32) { 341 au_writel(1 << bit, IC0_FALLINGCLR);
202 au_writel(1 << (bit - 32), IC1_FALLINGCLR); 342 au_writel(1 << bit, IC0_RISINGCLR);
203 au_writel(1 << (bit - 32), IC1_RISINGCLR);
204 au_writel(1 << (bit - 32), IC1_MASKCLR);
205 } else {
206 au_writel(1 << bit, IC0_FALLINGCLR);
207 au_writel(1 << bit, IC0_RISINGCLR);
208 au_writel(1 << bit, IC0_MASKCLR);
209 }
210 au_sync(); 343 au_sync();
211} 344}
212 345
213static inline void mask_and_ack_level_irq(unsigned int irq_nr) 346static void au1x_ic1_ack(unsigned int irq_nr)
214{
215 local_disable_irq(irq_nr);
216 au_sync();
217#if defined(CONFIG_MIPS_PB1000)
218 if (irq_nr == AU1000_GPIO_15) {
219 au_writel(0x8000, PB1000_MDR); /* ack int */
220 au_sync();
221 }
222#endif
223}
224
225static void end_irq(unsigned int irq_nr)
226{ 347{
227 if (!(irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS))) 348 unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
228 local_enable_irq(irq_nr);
229
230#if defined(CONFIG_MIPS_PB1000)
231 if (irq_nr == AU1000_GPIO_15) {
232 au_writel(0x4000, PB1000_MDR); /* enable int */
233 au_sync();
234 }
235#endif
236}
237
238unsigned long save_local_and_disable(int controller)
239{
240 int i;
241 unsigned long flags, mask;
242
243 spin_lock_irqsave(&irq_lock, flags);
244 if (controller) {
245 mask = au_readl(IC1_MASKSET);
246 for (i = 32; i < 64; i++)
247 local_disable_irq(i);
248 } else {
249 mask = au_readl(IC0_MASKSET);
250 for (i = 0; i < 32; i++)
251 local_disable_irq(i);
252 }
253 spin_unlock_irqrestore(&irq_lock, flags);
254 349
255 return mask; 350 /*
351 * This may assume that we don't get interrupts from
352 * both edges at once, or if we do, that we don't care.
353 */
354 au_writel(1 << bit, IC1_FALLINGCLR);
355 au_writel(1 << bit, IC1_RISINGCLR);
356 au_sync();
256} 357}
257 358
258void restore_local_and_enable(int controller, unsigned long mask) 359static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
259{ 360{
260 int i; 361 unsigned int bit = irq - AU1000_INTC1_INT_BASE;
261 unsigned long flags, new_mask; 362 unsigned long wakemsk, flags;
262 363
263 spin_lock_irqsave(&irq_lock, flags); 364 /* only GPIO 0-7 can act as wakeup source: */
264 for (i = 0; i < 32; i++) 365 if ((irq < AU1000_GPIO_0) || (irq > AU1000_GPIO_7))
265 if (mask & (1 << i)) { 366 return -EINVAL;
266 if (controller)
267 local_enable_irq(i + 32);
268 else
269 local_enable_irq(i);
270 }
271 367
272 if (controller) 368 local_irq_save(flags);
273 new_mask = au_readl(IC1_MASKSET); 369 wakemsk = au_readl(SYS_WAKEMSK);
370 if (on)
371 wakemsk |= 1 << bit;
274 else 372 else
275 new_mask = au_readl(IC0_MASKSET); 373 wakemsk &= ~(1 << bit);
374 au_writel(wakemsk, SYS_WAKEMSK);
375 au_sync();
376 local_irq_restore(flags);
276 377
277 spin_unlock_irqrestore(&irq_lock, flags); 378 return 0;
278} 379}
279 380
280 381/*
281static struct irq_chip rise_edge_irq_type = { 382 * irq_chips for both ICs; this way the mask handlers can be
282 .name = "Au1000 Rise Edge", 383 * as short as possible.
283 .ack = mask_and_ack_rise_edge_irq, 384 *
284 .mask = local_disable_irq, 385 * NOTE: the ->ack() callback is used by the handle_edge_irq
285 .mask_ack = mask_and_ack_rise_edge_irq, 386 * flowhandler only, the ->mask_ack() one by handle_level_irq,
286 .unmask = local_enable_irq, 387 * so no need for an irq_chip for each type of irq (level/edge).
287 .end = end_irq, 388 */
288}; 389static struct irq_chip au1x_ic0_chip = {
289 390 .name = "Alchemy-IC0",
290static struct irq_chip fall_edge_irq_type = { 391 .ack = au1x_ic0_ack, /* edge */
291 .name = "Au1000 Fall Edge", 392 .mask = au1x_ic0_mask,
292 .ack = mask_and_ack_fall_edge_irq, 393 .mask_ack = au1x_ic0_mask, /* level */
293 .mask = local_disable_irq, 394 .unmask = au1x_ic0_unmask,
294 .mask_ack = mask_and_ack_fall_edge_irq, 395 .set_type = au1x_ic_settype,
295 .unmask = local_enable_irq,
296 .end = end_irq,
297};
298
299static struct irq_chip either_edge_irq_type = {
300 .name = "Au1000 Rise or Fall Edge",
301 .ack = mask_and_ack_either_edge_irq,
302 .mask = local_disable_irq,
303 .mask_ack = mask_and_ack_either_edge_irq,
304 .unmask = local_enable_irq,
305 .end = end_irq,
306}; 396};
307 397
308static struct irq_chip level_irq_type = { 398static struct irq_chip au1x_ic1_chip = {
309 .name = "Au1000 Level", 399 .name = "Alchemy-IC1",
310 .ack = mask_and_ack_level_irq, 400 .ack = au1x_ic1_ack, /* edge */
311 .mask = local_disable_irq, 401 .mask = au1x_ic1_mask,
312 .mask_ack = mask_and_ack_level_irq, 402 .mask_ack = au1x_ic1_mask, /* level */
313 .unmask = local_enable_irq, 403 .unmask = au1x_ic1_unmask,
314 .end = end_irq, 404 .set_type = au1x_ic_settype,
405 .set_wake = au1x_ic1_setwake,
315}; 406};
316 407
317static void __init setup_local_irq(unsigned int irq_nr, int type, int int_req) 408static int au1x_ic_settype(unsigned int irq, unsigned int flow_type)
318{ 409{
319 unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; 410 struct irq_chip *chip;
320 411 unsigned long icr[6];
321 if (irq_nr > AU1000_MAX_INTR) 412 unsigned int bit, ic;
322 return; 413 int ret;
323 414
324 /* Config2[n], Config1[n], Config0[n] */ 415 if (irq >= AU1000_INTC1_INT_BASE) {
325 if (bit >= 32) { 416 bit = irq - AU1000_INTC1_INT_BASE;
326 switch (type) { 417 chip = &au1x_ic1_chip;
327 case INTC_INT_RISE_EDGE: /* 0:0:1 */ 418 ic = 1;
328 au_writel(1 << (bit - 32), IC1_CFG2CLR);
329 au_writel(1 << (bit - 32), IC1_CFG1CLR);
330 au_writel(1 << (bit - 32), IC1_CFG0SET);
331 set_irq_chip(irq_nr, &rise_edge_irq_type);
332 break;
333 case INTC_INT_FALL_EDGE: /* 0:1:0 */
334 au_writel(1 << (bit - 32), IC1_CFG2CLR);
335 au_writel(1 << (bit - 32), IC1_CFG1SET);
336 au_writel(1 << (bit - 32), IC1_CFG0CLR);
337 set_irq_chip(irq_nr, &fall_edge_irq_type);
338 break;
339 case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
340 au_writel(1 << (bit - 32), IC1_CFG2CLR);
341 au_writel(1 << (bit - 32), IC1_CFG1SET);
342 au_writel(1 << (bit - 32), IC1_CFG0SET);
343 set_irq_chip(irq_nr, &either_edge_irq_type);
344 break;
345 case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
346 au_writel(1 << (bit - 32), IC1_CFG2SET);
347 au_writel(1 << (bit - 32), IC1_CFG1CLR);
348 au_writel(1 << (bit - 32), IC1_CFG0SET);
349 set_irq_chip(irq_nr, &level_irq_type);
350 break;
351 case INTC_INT_LOW_LEVEL: /* 1:1:0 */
352 au_writel(1 << (bit - 32), IC1_CFG2SET);
353 au_writel(1 << (bit - 32), IC1_CFG1SET);
354 au_writel(1 << (bit - 32), IC1_CFG0CLR);
355 set_irq_chip(irq_nr, &level_irq_type);
356 break;
357 case INTC_INT_DISABLED: /* 0:0:0 */
358 au_writel(1 << (bit - 32), IC1_CFG0CLR);
359 au_writel(1 << (bit - 32), IC1_CFG1CLR);
360 au_writel(1 << (bit - 32), IC1_CFG2CLR);
361 break;
362 default: /* disable the interrupt */
363 printk(KERN_WARNING "unexpected int type %d (irq %d)\n",
364 type, irq_nr);
365 au_writel(1 << (bit - 32), IC1_CFG0CLR);
366 au_writel(1 << (bit - 32), IC1_CFG1CLR);
367 au_writel(1 << (bit - 32), IC1_CFG2CLR);
368 return;
369 }
370 if (int_req) /* assign to interrupt request 1 */
371 au_writel(1 << (bit - 32), IC1_ASSIGNCLR);
372 else /* assign to interrupt request 0 */
373 au_writel(1 << (bit - 32), IC1_ASSIGNSET);
374 au_writel(1 << (bit - 32), IC1_SRCSET);
375 au_writel(1 << (bit - 32), IC1_MASKCLR);
376 au_writel(1 << (bit - 32), IC1_WAKECLR);
377 } else { 419 } else {
378 switch (type) { 420 bit = irq - AU1000_INTC0_INT_BASE;
379 case INTC_INT_RISE_EDGE: /* 0:0:1 */ 421 chip = &au1x_ic0_chip;
380 au_writel(1 << bit, IC0_CFG2CLR); 422 ic = 0;
381 au_writel(1 << bit, IC0_CFG1CLR); 423 }
382 au_writel(1 << bit, IC0_CFG0SET); 424
383 set_irq_chip(irq_nr, &rise_edge_irq_type); 425 if (bit > 31)
384 break; 426 return -EINVAL;
385 case INTC_INT_FALL_EDGE: /* 0:1:0 */ 427
386 au_writel(1 << bit, IC0_CFG2CLR); 428 icr[0] = ic ? IC1_CFG0SET : IC0_CFG0SET;
387 au_writel(1 << bit, IC0_CFG1SET); 429 icr[1] = ic ? IC1_CFG1SET : IC0_CFG1SET;
388 au_writel(1 << bit, IC0_CFG0CLR); 430 icr[2] = ic ? IC1_CFG2SET : IC0_CFG2SET;
389 set_irq_chip(irq_nr, &fall_edge_irq_type); 431 icr[3] = ic ? IC1_CFG0CLR : IC0_CFG0CLR;
390 break; 432 icr[4] = ic ? IC1_CFG1CLR : IC0_CFG1CLR;
391 case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ 433 icr[5] = ic ? IC1_CFG2CLR : IC0_CFG2CLR;
392 au_writel(1 << bit, IC0_CFG2CLR); 434
393 au_writel(1 << bit, IC0_CFG1SET); 435 ret = 0;
394 au_writel(1 << bit, IC0_CFG0SET); 436
395 set_irq_chip(irq_nr, &either_edge_irq_type); 437 switch (flow_type) { /* cfgregs 2:1:0 */
396 break; 438 case IRQ_TYPE_EDGE_RISING: /* 0:0:1 */
397 case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ 439 au_writel(1 << bit, icr[5]);
398 au_writel(1 << bit, IC0_CFG2SET); 440 au_writel(1 << bit, icr[4]);
399 au_writel(1 << bit, IC0_CFG1CLR); 441 au_writel(1 << bit, icr[0]);
400 au_writel(1 << bit, IC0_CFG0SET); 442 set_irq_chip_and_handler_name(irq, chip,
401 set_irq_chip(irq_nr, &level_irq_type); 443 handle_edge_irq, "riseedge");
402 break; 444 break;
403 case INTC_INT_LOW_LEVEL: /* 1:1:0 */ 445 case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */
404 au_writel(1 << bit, IC0_CFG2SET); 446 au_writel(1 << bit, icr[5]);
405 au_writel(1 << bit, IC0_CFG1SET); 447 au_writel(1 << bit, icr[1]);
406 au_writel(1 << bit, IC0_CFG0CLR); 448 au_writel(1 << bit, icr[3]);
407 set_irq_chip(irq_nr, &level_irq_type); 449 set_irq_chip_and_handler_name(irq, chip,
408 break; 450 handle_edge_irq, "falledge");
409 case INTC_INT_DISABLED: /* 0:0:0 */ 451 break;
410 au_writel(1 << bit, IC0_CFG0CLR); 452 case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */
411 au_writel(1 << bit, IC0_CFG1CLR); 453 au_writel(1 << bit, icr[5]);
412 au_writel(1 << bit, IC0_CFG2CLR); 454 au_writel(1 << bit, icr[1]);
413 break; 455 au_writel(1 << bit, icr[0]);
414 default: /* disable the interrupt */ 456 set_irq_chip_and_handler_name(irq, chip,
415 printk(KERN_WARNING "unexpected int type %d (irq %d)\n", 457 handle_edge_irq, "bothedge");
416 type, irq_nr); 458 break;
417 au_writel(1 << bit, IC0_CFG0CLR); 459 case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */
418 au_writel(1 << bit, IC0_CFG1CLR); 460 au_writel(1 << bit, icr[2]);
419 au_writel(1 << bit, IC0_CFG2CLR); 461 au_writel(1 << bit, icr[4]);
420 return; 462 au_writel(1 << bit, icr[0]);
421 } 463 set_irq_chip_and_handler_name(irq, chip,
422 if (int_req) /* assign to interrupt request 1 */ 464 handle_level_irq, "hilevel");
423 au_writel(1 << bit, IC0_ASSIGNCLR); 465 break;
424 else /* assign to interrupt request 0 */ 466 case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */
425 au_writel(1 << bit, IC0_ASSIGNSET); 467 au_writel(1 << bit, icr[2]);
426 au_writel(1 << bit, IC0_SRCSET); 468 au_writel(1 << bit, icr[1]);
427 au_writel(1 << bit, IC0_MASKCLR); 469 au_writel(1 << bit, icr[3]);
428 au_writel(1 << bit, IC0_WAKECLR); 470 set_irq_chip_and_handler_name(irq, chip,
471 handle_level_irq, "lowlevel");
472 break;
473 case IRQ_TYPE_NONE: /* 0:0:0 */
474 au_writel(1 << bit, icr[5]);
475 au_writel(1 << bit, icr[4]);
476 au_writel(1 << bit, icr[3]);
477 /* set at least chip so we can call set_irq_type() on it */
478 set_irq_chip(irq, chip);
479 break;
480 default:
481 ret = -EINVAL;
429 } 482 }
430 au_sync(); 483 au_sync();
431}
432 484
433/* 485 return ret;
434 * Interrupts are nested. Even if an interrupt handler is registered 486}
435 * as "fast", we might get another interrupt before we return from
436 * intcX_reqX_irqdispatch().
437 */
438 487
439static void intc0_req0_irqdispatch(void) 488asmlinkage void plat_irq_dispatch(void)
440{ 489{
441 static unsigned long intc0_req0; 490 unsigned int pending = read_c0_status() & read_c0_cause();
442 unsigned int bit; 491 unsigned long s, off, bit;
443
444 intc0_req0 |= au_readl(IC0_REQ0INT);
445 492
446 if (!intc0_req0) 493 if (pending & CAUSEF_IP7) {
494 do_IRQ(MIPS_CPU_IRQ_BASE + 7);
447 return; 495 return;
448 496 } else if (pending & CAUSEF_IP2) {
497 s = IC0_REQ0INT;
498 off = AU1000_INTC0_INT_BASE;
499 } else if (pending & CAUSEF_IP3) {
500 s = IC0_REQ1INT;
501 off = AU1000_INTC0_INT_BASE;
502 } else if (pending & CAUSEF_IP4) {
503 s = IC1_REQ0INT;
504 off = AU1000_INTC1_INT_BASE;
505 } else if (pending & CAUSEF_IP5) {
506 s = IC1_REQ1INT;
507 off = AU1000_INTC1_INT_BASE;
508 } else
509 goto spurious;
510
511 bit = 0;
512 s = au_readl(s);
513 if (unlikely(!s)) {
514spurious:
515 spurious_interrupt();
516 return;
517 }
449#ifdef AU1000_USB_DEV_REQ_INT 518#ifdef AU1000_USB_DEV_REQ_INT
450 /* 519 /*
451 * Because of the tight timing of SETUP token to reply 520 * Because of the tight timing of SETUP token to reply
452 * transactions, the USB devices-side packet complete 521 * transactions, the USB devices-side packet complete
453 * interrupt needs the highest priority. 522 * interrupt needs the highest priority.
454 */ 523 */
455 if ((intc0_req0 & (1 << AU1000_USB_DEV_REQ_INT))) { 524 bit = 1 << (AU1000_USB_DEV_REQ_INT - AU1000_INTC0_INT_BASE);
456 intc0_req0 &= ~(1 << AU1000_USB_DEV_REQ_INT); 525 if ((pending & CAUSEF_IP2) && (s & bit)) {
457 do_IRQ(AU1000_USB_DEV_REQ_INT); 526 do_IRQ(AU1000_USB_DEV_REQ_INT);
458 return; 527 return;
459 } 528 }
460#endif 529#endif
461 bit = __ffs(intc0_req0); 530 do_IRQ(__ffs(s) + off);
462 intc0_req0 &= ~(1 << bit);
463 do_IRQ(AU1000_INTC0_INT_BASE + bit);
464} 531}
465 532
466 533/* setup edge/level and assign request 0/1 */
467static void intc0_req1_irqdispatch(void) 534void __init au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count)
468{ 535{
469 static unsigned long intc0_req1; 536 unsigned int bit, irq_nr;
470 unsigned int bit; 537
471 538 while (count--) {
472 intc0_req1 |= au_readl(IC0_REQ1INT); 539 irq_nr = map[count].im_irq;
473 540
474 if (!intc0_req1) 541 if (((irq_nr < AU1000_INTC0_INT_BASE) ||
475 return; 542 (irq_nr >= AU1000_INTC0_INT_BASE + 32)) &&
476 543 ((irq_nr < AU1000_INTC1_INT_BASE) ||
477 bit = __ffs(intc0_req1); 544 (irq_nr >= AU1000_INTC1_INT_BASE + 32)))
478 intc0_req1 &= ~(1 << bit); 545 continue;
479 do_IRQ(AU1000_INTC0_INT_BASE + bit); 546
480} 547 if (irq_nr >= AU1000_INTC1_INT_BASE) {
481 548 bit = irq_nr - AU1000_INTC1_INT_BASE;
482 549 if (map[count].im_request)
483/* 550 au_writel(1 << bit, IC1_ASSIGNCLR);
484 * Interrupt Controller 1: 551 } else {
485 * interrupts 32 - 63 552 bit = irq_nr - AU1000_INTC0_INT_BASE;
486 */ 553 if (map[count].im_request)
487static void intc1_req0_irqdispatch(void) 554 au_writel(1 << bit, IC0_ASSIGNCLR);
488{ 555 }
489 static unsigned long intc1_req0;
490 unsigned int bit;
491
492 intc1_req0 |= au_readl(IC1_REQ0INT);
493
494 if (!intc1_req0)
495 return;
496
497 bit = __ffs(intc1_req0);
498 intc1_req0 &= ~(1 << bit);
499 do_IRQ(AU1000_INTC1_INT_BASE + bit);
500}
501
502
503static void intc1_req1_irqdispatch(void)
504{
505 static unsigned long intc1_req1;
506 unsigned int bit;
507
508 intc1_req1 |= au_readl(IC1_REQ1INT);
509
510 if (!intc1_req1)
511 return;
512
513 bit = __ffs(intc1_req1);
514 intc1_req1 &= ~(1 << bit);
515 do_IRQ(AU1000_INTC1_INT_BASE + bit);
516}
517
518asmlinkage void plat_irq_dispatch(void)
519{
520 unsigned int pending = read_c0_status() & read_c0_cause();
521 556
522 if (pending & CAUSEF_IP7) 557 au1x_ic_settype(irq_nr, map[count].im_type);
523 do_IRQ(MIPS_CPU_IRQ_BASE + 7); 558 }
524 else if (pending & CAUSEF_IP2)
525 intc0_req0_irqdispatch();
526 else if (pending & CAUSEF_IP3)
527 intc0_req1_irqdispatch();
528 else if (pending & CAUSEF_IP4)
529 intc1_req0_irqdispatch();
530 else if (pending & CAUSEF_IP5)
531 intc1_req1_irqdispatch();
532 else
533 spurious_interrupt();
534} 559}
535 560
536void __init arch_init_irq(void) 561void __init arch_init_irq(void)
537{ 562{
538 int i; 563 int i;
539 struct au1xxx_irqmap *imp;
540 extern struct au1xxx_irqmap au1xxx_irq_map[];
541 extern struct au1xxx_irqmap au1xxx_ic0_map[];
542 extern int au1xxx_nr_irqs;
543 extern int au1xxx_ic0_nr_irqs;
544 564
545 /* 565 /*
546 * Initialize interrupt controllers to a safe state. 566 * Initialize interrupt controllers to a safe state.
@@ -569,28 +589,67 @@ void __init arch_init_irq(void)
569 589
570 mips_cpu_irq_init(); 590 mips_cpu_irq_init();
571 591
572 /* 592 /* register all 64 possible IC0+IC1 irq sources as type "none".
573 * Initialize IC0, which is fixed per processor. 593 * Use set_irq_type() to set edge/level behaviour at runtime.
574 */ 594 */
575 imp = au1xxx_ic0_map; 595 for (i = AU1000_INTC0_INT_BASE;
576 for (i = 0; i < au1xxx_ic0_nr_irqs; i++) { 596 (i < AU1000_INTC0_INT_BASE + 32); i++)
577 setup_local_irq(imp->im_irq, imp->im_type, imp->im_request); 597 au1x_ic_settype(i, IRQ_TYPE_NONE);
578 imp++; 598
579 } 599 for (i = AU1000_INTC1_INT_BASE;
600 (i < AU1000_INTC1_INT_BASE + 32); i++)
601 au1x_ic_settype(i, IRQ_TYPE_NONE);
580 602
581 /* 603 /*
582 * Now set up the irq mapping for the board. 604 * Initialize IC0, which is fixed per processor.
583 */ 605 */
584 imp = au1xxx_irq_map; 606 au1xxx_setup_irqmap(au1xxx_ic0_map, ARRAY_SIZE(au1xxx_ic0_map));
585 for (i = 0; i < au1xxx_nr_irqs; i++) { 607
586 setup_local_irq(imp->im_irq, imp->im_type, imp->im_request); 608 /* Boards can register additional (GPIO-based) IRQs.
587 imp++; 609 */
610 board_init_irq();
611
612 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3);
613}
614
615unsigned long save_local_and_disable(int controller)
616{
617 int i;
618 unsigned long flags, mask;
619
620 spin_lock_irqsave(&irq_lock, flags);
621 if (controller) {
622 mask = au_readl(IC1_MASKSET);
623 for (i = 0; i < 32; i++)
624 au1x_ic1_mask(i + AU1000_INTC1_INT_BASE);
625 } else {
626 mask = au_readl(IC0_MASKSET);
627 for (i = 0; i < 32; i++)
628 au1x_ic0_mask(i + AU1000_INTC0_INT_BASE);
588 } 629 }
630 spin_unlock_irqrestore(&irq_lock, flags);
589 631
590 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4); 632 return mask;
633}
591 634
592 /* Board specific IRQ initialization. 635void restore_local_and_enable(int controller, unsigned long mask)
593 */ 636{
594 if (board_init_irq) 637 int i;
595 board_init_irq(); 638 unsigned long flags, new_mask;
639
640 spin_lock_irqsave(&irq_lock, flags);
641 for (i = 0; i < 32; i++)
642 if (mask & (1 << i)) {
643 if (controller)
644 au1x_ic1_unmask(i + AU1000_INTC1_INT_BASE);
645 else
646 au1x_ic0_unmask(i + AU1000_INTC0_INT_BASE);
647 }
648
649 if (controller)
650 new_mask = au_readl(IC1_MASKSET);
651 else
652 new_mask = au_readl(IC0_MASKSET);
653
654 spin_unlock_irqrestore(&irq_lock, flags);
596} 655}