ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / mips / au1000 / common / irq.c
1 /*
2  * BRIEF MODULE DESCRIPTION
3  *      Au1000 interrupt routines.
4  *
5  * Copyright 2001 MontaVista Software Inc.
6  * Author: MontaVista Software, Inc.
7  *              ppopov@mvista.com or source@mvista.com
8  *
9  *  This program is free software; you can redistribute  it and/or modify it
10  *  under  the terms of  the GNU General  Public License as published by the
11  *  Free Software Foundation;  either version 2 of the  License, or (at your
12  *  option) any later version.
13  *
14  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
15  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
16  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
17  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
18  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
20  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
22  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  *  You should have received a copy of the  GNU General Public License along
26  *  with this program; if not, write  to the Free Software Foundation, Inc.,
27  *  675 Mass Ave, Cambridge, MA 02139, USA.
28  */
29 #include <linux/config.h>
30 #include <linux/errno.h>
31 #include <linux/init.h>
32 #include <linux/irq.h>
33 #include <linux/kernel_stat.h>
34 #include <linux/module.h>
35 #include <linux/signal.h>
36 #include <linux/sched.h>
37 #include <linux/types.h>
38 #include <linux/interrupt.h>
39 #include <linux/ioport.h>
40 #include <linux/timex.h>
41 #include <linux/slab.h>
42 #include <linux/random.h>
43 #include <linux/delay.h>
44
45 #include <asm/bitops.h>
46 #include <asm/bootinfo.h>
47 #include <asm/io.h>
48 #include <asm/mipsregs.h>
49 #include <asm/system.h>
50 #include <asm/mach-au1x00/au1000.h>
51 #ifdef CONFIG_MIPS_PB1000
52 #include <asm/mach-pb1x00/pb1000.h>
53 #endif
54
55 #undef DEBUG_IRQ
56 #ifdef DEBUG_IRQ
57 /* note: prints function name for you */
58 #define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
59 #else
60 #define DPRINTK(fmt, args...)
61 #endif
62
63 #define EXT_INTC0_REQ0 2 /* IP 2 */
64 #define EXT_INTC0_REQ1 3 /* IP 3 */
65 #define EXT_INTC1_REQ0 4 /* IP 4 */
66 #define EXT_INTC1_REQ1 5 /* IP 5 */
67 #define MIPS_TIMER_IP  7 /* IP 7 */
68
69 #ifdef CONFIG_KGDB
70 extern void breakpoint(void);
71 #endif
72
73 extern asmlinkage void au1000_IRQ(void);
74 extern void set_debug_traps(void);
75 extern irq_cpustat_t irq_stat [NR_CPUS];
76
77 static void setup_local_irq(unsigned int irq, int type, int int_req);
78 static unsigned int startup_irq(unsigned int irq);
79 static void end_irq(unsigned int irq_nr);
80 static inline void mask_and_ack_level_irq(unsigned int irq_nr);
81 static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr);
82 static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr);
83 static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr);
84 inline void local_enable_irq(unsigned int irq_nr);
85 inline void local_disable_irq(unsigned int irq_nr);
86
87 extern void __init init_generic_irq(void);
88 void    (*board_init_irq)(void);
89
90 #ifdef CONFIG_PM
91 extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs);
92 #endif
93
94 static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;
95
96
97 static unsigned int startup_irq(unsigned int irq_nr)
98 {
99         local_enable_irq(irq_nr);
100         return 0;
101 }
102
103
104 static void shutdown_irq(unsigned int irq_nr)
105 {
106         local_disable_irq(irq_nr);
107         return;
108 }
109
110
111 inline void local_enable_irq(unsigned int irq_nr)
112 {
113         if (irq_nr > AU1000_LAST_INTC0_INT) {
114                 au_writel(1<<(irq_nr-32), IC1_MASKSET);
115                 au_writel(1<<(irq_nr-32), IC1_WAKESET);
116         }
117         else {
118                 au_writel(1<<irq_nr, IC0_MASKSET);
119                 au_writel(1<<irq_nr, IC0_WAKESET);
120         }
121         au_sync();
122 }
123
124
125 inline void local_disable_irq(unsigned int irq_nr)
126 {
127         if (irq_nr > AU1000_LAST_INTC0_INT) {
128                 au_writel(1<<(irq_nr-32), IC1_MASKCLR);
129                 au_writel(1<<(irq_nr-32), IC1_WAKECLR);
130         }
131         else {
132                 au_writel(1<<irq_nr, IC0_MASKCLR);
133                 au_writel(1<<irq_nr, IC0_WAKECLR);
134         }
135         au_sync();
136 }
137
138
139 static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
140 {
141         if (irq_nr > AU1000_LAST_INTC0_INT) {
142                 au_writel(1<<(irq_nr-32), IC1_RISINGCLR);
143                 au_writel(1<<(irq_nr-32), IC1_MASKCLR);
144         }
145         else {
146                 au_writel(1<<irq_nr, IC0_RISINGCLR);
147                 au_writel(1<<irq_nr, IC0_MASKCLR);
148         }
149         au_sync();
150 }
151
152
153 static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr)
154 {
155         if (irq_nr > AU1000_LAST_INTC0_INT) {
156                 au_writel(1<<(irq_nr-32), IC1_FALLINGCLR);
157                 au_writel(1<<(irq_nr-32), IC1_MASKCLR);
158         }
159         else {
160                 au_writel(1<<irq_nr, IC0_FALLINGCLR);
161                 au_writel(1<<irq_nr, IC0_MASKCLR);
162         }
163         au_sync();
164 }
165
166
167 static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
168 {
169         /* This may assume that we don't get interrupts from
170          * both edges at once, or if we do, that we don't care.
171          */
172         if (irq_nr > AU1000_LAST_INTC0_INT) {
173                 au_writel(1<<(irq_nr-32), IC1_FALLINGCLR);
174                 au_writel(1<<(irq_nr-32), IC1_RISINGCLR);
175                 au_writel(1<<(irq_nr-32), IC1_MASKCLR);
176         }
177         else {
178                 au_writel(1<<irq_nr, IC0_FALLINGCLR);
179                 au_writel(1<<irq_nr, IC0_RISINGCLR);
180                 au_writel(1<<irq_nr, IC0_MASKCLR);
181         }
182         au_sync();
183 }
184
185
186 static inline void mask_and_ack_level_irq(unsigned int irq_nr)
187 {
188
189         local_disable_irq(irq_nr);
190         au_sync();
191 #if defined(CONFIG_MIPS_PB1000)
192         if (irq_nr == AU1000_GPIO_15) {
193                 au_writel(0x8000, PB1000_MDR); /* ack int */
194                 au_sync();
195         }
196 #endif
197         return;
198 }
199
200
201 static void end_irq(unsigned int irq_nr)
202 {
203         if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
204                 local_enable_irq(irq_nr);
205         }
206 #if defined(CONFIG_MIPS_PB1000)
207         if (irq_nr == AU1000_GPIO_15) {
208                 au_writel(0x4000, PB1000_MDR); /* enable int */
209                 au_sync();
210         }
211 #endif
212 }
213
214 unsigned long save_local_and_disable(int controller)
215 {
216         int i;
217         unsigned long flags, mask;
218
219         spin_lock_irqsave(&irq_lock, flags);
220         if (controller) {
221                 mask = au_readl(IC1_MASKSET);
222                 for (i=32; i<64; i++) {
223                         local_disable_irq(i);
224                 }
225         }
226         else {
227                 mask = au_readl(IC0_MASKSET);
228                 for (i=0; i<32; i++) {
229                         local_disable_irq(i);
230                 }
231         }
232         spin_unlock_irqrestore(&irq_lock, flags);
233
234         return mask;
235 }
236
237 void restore_local_and_enable(int controller, unsigned long mask)
238 {
239         int i;
240         unsigned long flags, new_mask;
241
242         spin_lock_irqsave(&irq_lock, flags);
243         for (i=0; i<32; i++) {
244                 if (mask & (1<<i)) {
245                         if (controller)
246                                 local_enable_irq(i+32);
247                         else
248                                 local_enable_irq(i);
249                 }
250         }
251         if (controller)
252                 new_mask = au_readl(IC1_MASKSET);
253         else
254                 new_mask = au_readl(IC0_MASKSET);
255
256         spin_unlock_irqrestore(&irq_lock, flags);
257 }
258
259
260 static struct hw_interrupt_type rise_edge_irq_type = {
261         "Au1000 Rise Edge",
262         startup_irq,
263         shutdown_irq,
264         local_enable_irq,
265         local_disable_irq,
266         mask_and_ack_rise_edge_irq,
267         end_irq,
268         NULL
269 };
270
271 static struct hw_interrupt_type fall_edge_irq_type = {
272         "Au1000 Fall Edge",
273         startup_irq,
274         shutdown_irq,
275         local_enable_irq,
276         local_disable_irq,
277         mask_and_ack_fall_edge_irq,
278         end_irq,
279         NULL
280 };
281
282 static struct hw_interrupt_type either_edge_irq_type = {
283         "Au1000 Rise or Fall Edge",
284         startup_irq,
285         shutdown_irq,
286         local_enable_irq,
287         local_disable_irq,
288         mask_and_ack_either_edge_irq,
289         end_irq,
290         NULL
291 };
292
293 static struct hw_interrupt_type level_irq_type = {
294         "Au1000 Level",
295         startup_irq,
296         shutdown_irq,
297         local_enable_irq,
298         local_disable_irq,
299         mask_and_ack_level_irq,
300         end_irq,
301         NULL
302 };
303
304 #ifdef CONFIG_PM
305 void startup_match20_interrupt(void)
306 {
307         local_enable_irq(AU1000_TOY_MATCH2_INT);
308 }
309 #endif
310
311 static void setup_local_irq(unsigned int irq_nr, int type, int int_req)
312 {
313         if (irq_nr > AU1000_MAX_INTR) return;
314         /* Config2[n], Config1[n], Config0[n] */
315         if (irq_nr > AU1000_LAST_INTC0_INT) {
316                 switch (type) {
317                         case INTC_INT_RISE_EDGE: /* 0:0:1 */
318                                 au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
319                                 au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
320                                 au_writel(1<<(irq_nr-32), IC1_CFG0SET);
321                                 irq_desc[irq_nr].handler = &rise_edge_irq_type;
322                                 break;
323                         case INTC_INT_FALL_EDGE: /* 0:1:0 */
324                                 au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
325                                 au_writel(1<<(irq_nr-32), IC1_CFG1SET);
326                                 au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
327                                 irq_desc[irq_nr].handler = &fall_edge_irq_type;
328                                 break;
329                         case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
330                                 au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
331                                 au_writel(1<<(irq_nr-32), IC1_CFG1SET);
332                                 au_writel(1<<(irq_nr-32), IC1_CFG0SET);
333                                 irq_desc[irq_nr].handler = &either_edge_irq_type;
334                                 break;
335                         case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
336                                 au_writel(1<<(irq_nr-32), IC1_CFG2SET);
337                                 au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
338                                 au_writel(1<<(irq_nr-32), IC1_CFG0SET);
339                                 irq_desc[irq_nr].handler = &level_irq_type;
340                                 break;
341                         case INTC_INT_LOW_LEVEL: /* 1:1:0 */
342                                 au_writel(1<<(irq_nr-32), IC1_CFG2SET);
343                                 au_writel(1<<(irq_nr-32), IC1_CFG1SET);
344                                 au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
345                                 irq_desc[irq_nr].handler = &level_irq_type;
346                                 break;
347                         case INTC_INT_DISABLED: /* 0:0:0 */
348                                 au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
349                                 au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
350                                 au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
351                                 break;
352                         default: /* disable the interrupt */
353                                 printk("unexpected int type %d (irq %d)\n", type, irq_nr);
354                                 au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
355                                 au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
356                                 au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
357                                 return;
358                 }
359                 if (int_req) /* assign to interrupt request 1 */
360                         au_writel(1<<(irq_nr-32), IC1_ASSIGNCLR);
361                 else         /* assign to interrupt request 0 */
362                         au_writel(1<<(irq_nr-32), IC1_ASSIGNSET);
363                 au_writel(1<<(irq_nr-32), IC1_SRCSET);
364                 au_writel(1<<(irq_nr-32), IC1_MASKCLR);
365                 au_writel(1<<(irq_nr-32), IC1_WAKECLR);
366         }
367         else {
368                 switch (type) {
369                         case INTC_INT_RISE_EDGE: /* 0:0:1 */
370                                 au_writel(1<<irq_nr, IC0_CFG2CLR);
371                                 au_writel(1<<irq_nr, IC0_CFG1CLR);
372                                 au_writel(1<<irq_nr, IC0_CFG0SET);
373                                 irq_desc[irq_nr].handler = &rise_edge_irq_type;
374                                 break;
375                         case INTC_INT_FALL_EDGE: /* 0:1:0 */
376                                 au_writel(1<<irq_nr, IC0_CFG2CLR);
377                                 au_writel(1<<irq_nr, IC0_CFG1SET);
378                                 au_writel(1<<irq_nr, IC0_CFG0CLR);
379                                 irq_desc[irq_nr].handler = &fall_edge_irq_type;
380                                 break;
381                         case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
382                                 au_writel(1<<irq_nr, IC0_CFG2CLR);
383                                 au_writel(1<<irq_nr, IC0_CFG1SET);
384                                 au_writel(1<<irq_nr, IC0_CFG0SET);
385                                 irq_desc[irq_nr].handler = &either_edge_irq_type;
386                                 break;
387                         case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
388                                 au_writel(1<<irq_nr, IC0_CFG2SET);
389                                 au_writel(1<<irq_nr, IC0_CFG1CLR);
390                                 au_writel(1<<irq_nr, IC0_CFG0SET);
391                                 irq_desc[irq_nr].handler = &level_irq_type;
392                                 break;
393                         case INTC_INT_LOW_LEVEL: /* 1:1:0 */
394                                 au_writel(1<<irq_nr, IC0_CFG2SET);
395                                 au_writel(1<<irq_nr, IC0_CFG1SET);
396                                 au_writel(1<<irq_nr, IC0_CFG0CLR);
397                                 irq_desc[irq_nr].handler = &level_irq_type;
398                                 break;
399                         case INTC_INT_DISABLED: /* 0:0:0 */
400                                 au_writel(1<<irq_nr, IC0_CFG0CLR);
401                                 au_writel(1<<irq_nr, IC0_CFG1CLR);
402                                 au_writel(1<<irq_nr, IC0_CFG2CLR);
403                                 break;
404                         default: /* disable the interrupt */
405                                 printk("unexpected int type %d (irq %d)\n", type, irq_nr);
406                                 au_writel(1<<irq_nr, IC0_CFG0CLR);
407                                 au_writel(1<<irq_nr, IC0_CFG1CLR);
408                                 au_writel(1<<irq_nr, IC0_CFG2CLR);
409                                 return;
410                 }
411                 if (int_req) /* assign to interrupt request 1 */
412                         au_writel(1<<irq_nr, IC0_ASSIGNCLR);
413                 else         /* assign to interrupt request 0 */
414                         au_writel(1<<irq_nr, IC0_ASSIGNSET);
415                 au_writel(1<<irq_nr, IC0_SRCSET);
416                 au_writel(1<<irq_nr, IC0_MASKCLR);
417                 au_writel(1<<irq_nr, IC0_WAKECLR);
418         }
419         au_sync();
420 }
421
422
423 void __init init_IRQ(void)
424 {
425         int i;
426         unsigned long cp0_status;
427         au1xxx_irq_map_t *imp;
428         extern au1xxx_irq_map_t au1xxx_irq_map[];
429         extern au1xxx_irq_map_t au1xxx_ic0_map[];
430         extern int au1xxx_nr_irqs;
431         extern int au1xxx_ic0_nr_irqs;
432
433         cp0_status = read_c0_status();
434         memset(irq_desc, 0, sizeof(irq_desc));
435         set_except_vector(0, au1000_IRQ);
436
437         init_generic_irq();
438
439         /* Initialize interrupt controllers to a safe state.
440         */
441         au_writel(0xffffffff, IC0_CFG0CLR);
442         au_writel(0xffffffff, IC0_CFG1CLR);
443         au_writel(0xffffffff, IC0_CFG2CLR);
444         au_writel(0xffffffff, IC0_MASKCLR);
445         au_writel(0xffffffff, IC0_ASSIGNSET);
446         au_writel(0xffffffff, IC0_WAKECLR);
447         au_writel(0xffffffff, IC0_SRCSET);
448         au_writel(0xffffffff, IC0_FALLINGCLR);
449         au_writel(0xffffffff, IC0_RISINGCLR);
450         au_writel(0x00000000, IC0_TESTBIT);
451
452         au_writel(0xffffffff, IC1_CFG0CLR);
453         au_writel(0xffffffff, IC1_CFG1CLR);
454         au_writel(0xffffffff, IC1_CFG2CLR);
455         au_writel(0xffffffff, IC1_MASKCLR);
456         au_writel(0xffffffff, IC1_ASSIGNSET);
457         au_writel(0xffffffff, IC1_WAKECLR);
458         au_writel(0xffffffff, IC1_SRCSET);
459         au_writel(0xffffffff, IC1_FALLINGCLR);
460         au_writel(0xffffffff, IC1_RISINGCLR);
461         au_writel(0x00000000, IC1_TESTBIT);
462
463         /* Initialize IC0, which is fixed per processor.
464         */
465         imp = au1xxx_ic0_map;
466         for (i=0; i<au1xxx_ic0_nr_irqs; i++) {
467                 setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
468                 imp++;
469         }
470
471         /* Now set up the irq mapping for the board.
472         */
473         imp = au1xxx_irq_map;
474         for (i=0; i<au1xxx_nr_irqs; i++) {
475                 setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
476                 imp++;
477         }
478
479         set_c0_status(ALLINTS);
480
481         /* Board specific IRQ initialization.
482         */
483         if (board_init_irq)
484                 (*board_init_irq)();
485
486 #ifdef CONFIG_KGDB
487         /* If local serial I/O used for debug port, enter kgdb at once */
488         puts("Waiting for kgdb to connect...");
489         set_debug_traps();
490         breakpoint();
491 #endif
492 }
493
494
495 /*
496  * Interrupts are nested. Even if an interrupt handler is registered
497  * as "fast", we might get another interrupt before we return from
498  * intcX_reqX_irqdispatch().
499  */
500
501 void intc0_req0_irqdispatch(struct pt_regs *regs)
502 {
503         int irq = 0;
504         static unsigned long intc0_req0 = 0;
505
506         intc0_req0 |= au_readl(IC0_REQ0INT);
507
508         if (!intc0_req0) return;
509
510         /*
511          * Because of the tight timing of SETUP token to reply
512          * transactions, the USB devices-side packet complete
513          * interrupt needs the highest priority.
514          */
515         if ((intc0_req0 & (1<<AU1000_USB_DEV_REQ_INT))) {
516                 intc0_req0 &= ~(1<<AU1000_USB_DEV_REQ_INT);
517                 do_IRQ(AU1000_USB_DEV_REQ_INT, regs);
518                 return;
519         }
520
521         irq = au_ffs(intc0_req0) - 1;
522         intc0_req0 &= ~(1<<irq);
523         do_IRQ(irq, regs);
524 }
525
526
527 void intc0_req1_irqdispatch(struct pt_regs *regs)
528 {
529         int irq = 0;
530         static unsigned long intc0_req1 = 0;
531
532         intc0_req1 |= au_readl(IC0_REQ1INT);
533
534         if (!intc0_req1) return;
535
536         irq = au_ffs(intc0_req1) - 1;
537         intc0_req1 &= ~(1<<irq);
538 #ifdef CONFIG_PM
539         if (irq == AU1000_TOY_MATCH2_INT) {
540                 mask_and_ack_rise_edge_irq(irq);
541                 counter0_irq(irq, NULL, regs);
542                 local_enable_irq(irq);
543         }
544         else
545 #endif
546         {
547                 do_IRQ(irq, regs);
548         }
549 }
550
551
552 /*
553  * Interrupt Controller 1:
554  * interrupts 32 - 63
555  */
556 void intc1_req0_irqdispatch(struct pt_regs *regs)
557 {
558         int irq = 0;
559         static unsigned long intc1_req0 = 0;
560
561         intc1_req0 |= au_readl(IC1_REQ0INT);
562
563         if (!intc1_req0) return;
564
565         irq = au_ffs(intc1_req0) - 1;
566         intc1_req0 &= ~(1<<irq);
567         irq += 32;
568         do_IRQ(irq, regs);
569 }
570
571
572 void intc1_req1_irqdispatch(struct pt_regs *regs)
573 {
574         int irq = 0;
575         static unsigned long intc1_req1 = 0;
576
577         intc1_req1 |= au_readl(IC1_REQ1INT);
578
579         if (!intc1_req1) return;
580
581         irq = au_ffs(intc1_req1) - 1;
582         intc1_req1 &= ~(1<<irq);
583         irq += 32;
584         do_IRQ(irq, regs);
585 }
586
587 #ifdef CONFIG_PM
588
589 /* Save/restore the interrupt controller state.
590  * Called from the save/restore core registers as part of the
591  * au_sleep function in power.c.....maybe I should just pm_register()
592  * them instead?
593  */
594 static uint     sleep_intctl_config0[2];
595 static uint     sleep_intctl_config1[2];
596 static uint     sleep_intctl_config2[2];
597 static uint     sleep_intctl_src[2];
598 static uint     sleep_intctl_assign[2];
599 static uint     sleep_intctl_wake[2];
600 static uint     sleep_intctl_mask[2];
601
602 void
603 save_au1xxx_intctl(void)
604 {
605         sleep_intctl_config0[0] = au_readl(IC0_CFG0RD);
606         sleep_intctl_config1[0] = au_readl(IC0_CFG1RD);
607         sleep_intctl_config2[0] = au_readl(IC0_CFG2RD);
608         sleep_intctl_src[0] = au_readl(IC0_SRCRD);
609         sleep_intctl_assign[0] = au_readl(IC0_ASSIGNRD);
610         sleep_intctl_wake[0] = au_readl(IC0_WAKERD);
611         sleep_intctl_mask[0] = au_readl(IC0_MASKRD);
612
613         sleep_intctl_config0[1] = au_readl(IC1_CFG0RD);
614         sleep_intctl_config1[1] = au_readl(IC1_CFG1RD);
615         sleep_intctl_config2[1] = au_readl(IC1_CFG2RD);
616         sleep_intctl_src[1] = au_readl(IC1_SRCRD);
617         sleep_intctl_assign[1] = au_readl(IC1_ASSIGNRD);
618         sleep_intctl_wake[1] = au_readl(IC1_WAKERD);
619         sleep_intctl_mask[1] = au_readl(IC1_MASKRD);
620 }
621
622 /* For most restore operations, we clear the entire register and
623  * then set the bits we found during the save.
624  */
625 void
626 restore_au1xxx_intctl(void)
627 {
628         au_writel(0xffffffff, IC0_MASKCLR); au_sync();
629
630         au_writel(0xffffffff, IC0_CFG0CLR); au_sync();
631         au_writel(sleep_intctl_config0[0], IC0_CFG0SET); au_sync();
632         au_writel(0xffffffff, IC0_CFG1CLR); au_sync();
633         au_writel(sleep_intctl_config1[0], IC0_CFG1SET); au_sync();
634         au_writel(0xffffffff, IC0_CFG2CLR); au_sync();
635         au_writel(sleep_intctl_config2[0], IC0_CFG2SET); au_sync();
636         au_writel(0xffffffff, IC0_SRCCLR); au_sync();
637         au_writel(sleep_intctl_src[0], IC0_SRCSET); au_sync();
638         au_writel(0xffffffff, IC0_ASSIGNCLR); au_sync();
639         au_writel(sleep_intctl_assign[0], IC0_ASSIGNSET); au_sync();
640         au_writel(0xffffffff, IC0_WAKECLR); au_sync();
641         au_writel(sleep_intctl_wake[0], IC0_WAKESET); au_sync();
642         au_writel(0xffffffff, IC0_RISINGCLR); au_sync();
643         au_writel(0xffffffff, IC0_FALLINGCLR); au_sync();
644         au_writel(0x00000000, IC0_TESTBIT); au_sync();
645
646         au_writel(0xffffffff, IC1_MASKCLR); au_sync();
647
648         au_writel(0xffffffff, IC1_CFG0CLR); au_sync();
649         au_writel(sleep_intctl_config0[1], IC1_CFG0SET); au_sync();
650         au_writel(0xffffffff, IC1_CFG1CLR); au_sync();
651         au_writel(sleep_intctl_config1[1], IC1_CFG1SET); au_sync();
652         au_writel(0xffffffff, IC1_CFG2CLR); au_sync();
653         au_writel(sleep_intctl_config2[1], IC1_CFG2SET); au_sync();
654         au_writel(0xffffffff, IC1_SRCCLR); au_sync();
655         au_writel(sleep_intctl_src[1], IC1_SRCSET); au_sync();
656         au_writel(0xffffffff, IC1_ASSIGNCLR); au_sync();
657         au_writel(sleep_intctl_assign[1], IC1_ASSIGNSET); au_sync();
658         au_writel(0xffffffff, IC1_WAKECLR); au_sync();
659         au_writel(sleep_intctl_wake[1], IC1_WAKESET); au_sync();
660         au_writel(0xffffffff, IC1_RISINGCLR); au_sync();
661         au_writel(0xffffffff, IC1_FALLINGCLR); au_sync();
662         au_writel(0x00000000, IC1_TESTBIT); au_sync();
663
664         au_writel(sleep_intctl_mask[1], IC1_MASKSET); au_sync();
665
666         au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync();
667 }
668 #endif /* CONFIG_PM */