Merge branches 'at91', 'cache', 'cup', 'ep93xx', 'ixp4xx', 'nuc', 'pending-dma-stream...
[sfrench/cifs-2.6.git] / arch / mips / powertv / asic / irq_asic.c
1 /*
2  * Portions copyright (C) 2005-2009 Scientific Atlanta
3  * Portions copyright (C) 2009 Cisco Systems, Inc.
4  *
5  * Modified from arch/mips/kernel/irq-rm7000.c:
6  * Copyright (C) 2003 Ralf Baechle
7  *
8  * This program is free software; you can redistribute  it and/or modify it
9  * under  the terms of  the GNU General  Public License as published by the
10  * Free Software Foundation;  either version 2 of the  License, or (at your
11  * option) any later version.
12  */
13 #include <linux/init.h>
14 #include <linux/interrupt.h>
15 #include <linux/kernel.h>
16
17 #include <asm/irq_cpu.h>
18 #include <asm/mipsregs.h>
19 #include <asm/system.h>
20
21 #include <asm/mach-powertv/asic_regs.h>
22
23 static inline void unmask_asic_irq(unsigned int irq)
24 {
25         unsigned long enable_bit;
26
27         enable_bit = (1 << (irq & 0x1f));
28
29         switch (irq >> 5) {
30         case 0:
31                 asic_write(asic_read(ien_int_0) | enable_bit, ien_int_0);
32                 break;
33         case 1:
34                 asic_write(asic_read(ien_int_1) | enable_bit, ien_int_1);
35                 break;
36         case 2:
37                 asic_write(asic_read(ien_int_2) | enable_bit, ien_int_2);
38                 break;
39         case 3:
40                 asic_write(asic_read(ien_int_3) | enable_bit, ien_int_3);
41                 break;
42         default:
43                 BUG();
44         }
45 }
46
47 static inline void mask_asic_irq(unsigned int irq)
48 {
49         unsigned long disable_mask;
50
51         disable_mask = ~(1 << (irq & 0x1f));
52
53         switch (irq >> 5) {
54         case 0:
55                 asic_write(asic_read(ien_int_0) & disable_mask, ien_int_0);
56                 break;
57         case 1:
58                 asic_write(asic_read(ien_int_1) & disable_mask, ien_int_1);
59                 break;
60         case 2:
61                 asic_write(asic_read(ien_int_2) & disable_mask, ien_int_2);
62                 break;
63         case 3:
64                 asic_write(asic_read(ien_int_3) & disable_mask, ien_int_3);
65                 break;
66         default:
67                 BUG();
68         }
69 }
70
71 static struct irq_chip asic_irq_chip = {
72         .name = "ASIC Level",
73         .ack = mask_asic_irq,
74         .mask = mask_asic_irq,
75         .mask_ack = mask_asic_irq,
76         .unmask = unmask_asic_irq,
77         .eoi = unmask_asic_irq,
78 };
79
80 void __init asic_irq_init(void)
81 {
82         int i;
83
84         /* set priority to 0 */
85         write_c0_status(read_c0_status() & ~(0x0000fc00));
86
87         asic_write(0, ien_int_0);
88         asic_write(0, ien_int_1);
89         asic_write(0, ien_int_2);
90         asic_write(0, ien_int_3);
91
92         asic_write(0x0fffffff, int_level_3_3);
93         asic_write(0xffffffff, int_level_3_2);
94         asic_write(0xffffffff, int_level_3_1);
95         asic_write(0xffffffff, int_level_3_0);
96         asic_write(0xffffffff, int_level_2_3);
97         asic_write(0xffffffff, int_level_2_2);
98         asic_write(0xffffffff, int_level_2_1);
99         asic_write(0xffffffff, int_level_2_0);
100         asic_write(0xffffffff, int_level_1_3);
101         asic_write(0xffffffff, int_level_1_2);
102         asic_write(0xffffffff, int_level_1_1);
103         asic_write(0xffffffff, int_level_1_0);
104         asic_write(0xffffffff, int_level_0_3);
105         asic_write(0xffffffff, int_level_0_2);
106         asic_write(0xffffffff, int_level_0_1);
107         asic_write(0xffffffff, int_level_0_0);
108
109         asic_write(0xf, int_int_scan);
110
111         /*
112          * Initialize interrupt handlers.
113          */
114         for (i = 0; i < NR_IRQS; i++)
115                 set_irq_chip_and_handler(i, &asic_irq_chip, handle_level_irq);
116 }