]>
Commit | Line | Data |
---|---|---|
285f5fa7 DW |
1 | /* |
2 | * iop13xx IRQ handling / support functions | |
3 | * Copyright (c) 2005-2006, Intel Corporation. | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms and conditions of the GNU General Public License, | |
7 | * version 2, as published by the Free Software Foundation. | |
8 | * | |
9 | * This program is distributed in the hope it will be useful, but WITHOUT | |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
12 | * more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License along with | |
15 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | |
16 | * Place - Suite 330, Boston, MA 02111-1307 USA. | |
17 | * | |
18 | */ | |
19 | #include <linux/init.h> | |
20 | #include <linux/interrupt.h> | |
21 | #include <linux/list.h> | |
22 | #include <linux/sysctl.h> | |
23 | #include <asm/uaccess.h> | |
24 | #include <asm/mach/irq.h> | |
25 | #include <asm/irq.h> | |
a09e64fb RK |
26 | #include <mach/hardware.h> |
27 | #include <mach/irqs.h> | |
28 | #include <mach/msi.h> | |
285f5fa7 DW |
29 | |
30 | /* INTCTL0 CP6 R0 Page 4 | |
31 | */ | |
d73d8011 | 32 | static u32 read_intctl_0(void) |
285f5fa7 DW |
33 | { |
34 | u32 val; | |
35 | asm volatile("mrc p6, 0, %0, c0, c4, 0":"=r" (val)); | |
36 | return val; | |
37 | } | |
d73d8011 | 38 | static void write_intctl_0(u32 val) |
285f5fa7 DW |
39 | { |
40 | asm volatile("mcr p6, 0, %0, c0, c4, 0"::"r" (val)); | |
41 | } | |
42 | ||
43 | /* INTCTL1 CP6 R1 Page 4 | |
44 | */ | |
d73d8011 | 45 | static u32 read_intctl_1(void) |
285f5fa7 DW |
46 | { |
47 | u32 val; | |
48 | asm volatile("mrc p6, 0, %0, c1, c4, 0":"=r" (val)); | |
49 | return val; | |
50 | } | |
d73d8011 | 51 | static void write_intctl_1(u32 val) |
285f5fa7 DW |
52 | { |
53 | asm volatile("mcr p6, 0, %0, c1, c4, 0"::"r" (val)); | |
54 | } | |
55 | ||
56 | /* INTCTL2 CP6 R2 Page 4 | |
57 | */ | |
d73d8011 | 58 | static u32 read_intctl_2(void) |
285f5fa7 DW |
59 | { |
60 | u32 val; | |
61 | asm volatile("mrc p6, 0, %0, c2, c4, 0":"=r" (val)); | |
62 | return val; | |
63 | } | |
d73d8011 | 64 | static void write_intctl_2(u32 val) |
285f5fa7 DW |
65 | { |
66 | asm volatile("mcr p6, 0, %0, c2, c4, 0"::"r" (val)); | |
67 | } | |
68 | ||
69 | /* INTCTL3 CP6 R3 Page 4 | |
70 | */ | |
d73d8011 | 71 | static u32 read_intctl_3(void) |
285f5fa7 DW |
72 | { |
73 | u32 val; | |
74 | asm volatile("mrc p6, 0, %0, c3, c4, 0":"=r" (val)); | |
75 | return val; | |
76 | } | |
d73d8011 | 77 | static void write_intctl_3(u32 val) |
285f5fa7 DW |
78 | { |
79 | asm volatile("mcr p6, 0, %0, c3, c4, 0"::"r" (val)); | |
80 | } | |
81 | ||
82 | /* INTSTR0 CP6 R0 Page 5 | |
83 | */ | |
d73d8011 | 84 | static void write_intstr_0(u32 val) |
285f5fa7 DW |
85 | { |
86 | asm volatile("mcr p6, 0, %0, c0, c5, 0"::"r" (val)); | |
87 | } | |
88 | ||
89 | /* INTSTR1 CP6 R1 Page 5 | |
90 | */ | |
285f5fa7 DW |
91 | static void write_intstr_1(u32 val) |
92 | { | |
93 | asm volatile("mcr p6, 0, %0, c1, c5, 0"::"r" (val)); | |
94 | } | |
95 | ||
96 | /* INTSTR2 CP6 R2 Page 5 | |
97 | */ | |
285f5fa7 DW |
98 | static void write_intstr_2(u32 val) |
99 | { | |
100 | asm volatile("mcr p6, 0, %0, c2, c5, 0"::"r" (val)); | |
101 | } | |
102 | ||
103 | /* INTSTR3 CP6 R3 Page 5 | |
104 | */ | |
285f5fa7 DW |
105 | static void write_intstr_3(u32 val) |
106 | { | |
107 | asm volatile("mcr p6, 0, %0, c3, c5, 0"::"r" (val)); | |
108 | } | |
109 | ||
110 | /* INTBASE CP6 R0 Page 2 | |
111 | */ | |
285f5fa7 DW |
112 | static void write_intbase(u32 val) |
113 | { | |
114 | asm volatile("mcr p6, 0, %0, c0, c2, 0"::"r" (val)); | |
115 | } | |
116 | ||
117 | /* INTSIZE CP6 R2 Page 2 | |
118 | */ | |
285f5fa7 DW |
119 | static void write_intsize(u32 val) |
120 | { | |
121 | asm volatile("mcr p6, 0, %0, c2, c2, 0"::"r" (val)); | |
122 | } | |
123 | ||
124 | /* 0 = Interrupt Masked and 1 = Interrupt not masked */ | |
125 | static void | |
418c9904 | 126 | iop13xx_irq_mask0 (struct irq_data *d) |
285f5fa7 | 127 | { |
418c9904 | 128 | write_intctl_0(read_intctl_0() & ~(1 << (d->irq - 0))); |
285f5fa7 DW |
129 | } |
130 | ||
131 | static void | |
418c9904 | 132 | iop13xx_irq_mask1 (struct irq_data *d) |
285f5fa7 | 133 | { |
418c9904 | 134 | write_intctl_1(read_intctl_1() & ~(1 << (d->irq - 32))); |
285f5fa7 DW |
135 | } |
136 | ||
137 | static void | |
418c9904 | 138 | iop13xx_irq_mask2 (struct irq_data *d) |
285f5fa7 | 139 | { |
418c9904 | 140 | write_intctl_2(read_intctl_2() & ~(1 << (d->irq - 64))); |
285f5fa7 DW |
141 | } |
142 | ||
143 | static void | |
418c9904 | 144 | iop13xx_irq_mask3 (struct irq_data *d) |
285f5fa7 | 145 | { |
418c9904 | 146 | write_intctl_3(read_intctl_3() & ~(1 << (d->irq - 96))); |
285f5fa7 DW |
147 | } |
148 | ||
149 | static void | |
418c9904 | 150 | iop13xx_irq_unmask0(struct irq_data *d) |
285f5fa7 | 151 | { |
418c9904 | 152 | write_intctl_0(read_intctl_0() | (1 << (d->irq - 0))); |
285f5fa7 DW |
153 | } |
154 | ||
155 | static void | |
418c9904 | 156 | iop13xx_irq_unmask1(struct irq_data *d) |
285f5fa7 | 157 | { |
418c9904 | 158 | write_intctl_1(read_intctl_1() | (1 << (d->irq - 32))); |
285f5fa7 DW |
159 | } |
160 | ||
161 | static void | |
418c9904 | 162 | iop13xx_irq_unmask2(struct irq_data *d) |
285f5fa7 | 163 | { |
418c9904 | 164 | write_intctl_2(read_intctl_2() | (1 << (d->irq - 64))); |
285f5fa7 DW |
165 | } |
166 | ||
167 | static void | |
418c9904 | 168 | iop13xx_irq_unmask3(struct irq_data *d) |
285f5fa7 | 169 | { |
418c9904 | 170 | write_intctl_3(read_intctl_3() | (1 << (d->irq - 96))); |
285f5fa7 DW |
171 | } |
172 | ||
3a2aeda8 | 173 | static struct irq_chip iop13xx_irqchip1 = { |
418c9904 LB |
174 | .name = "IOP13xx-1", |
175 | .irq_ack = iop13xx_irq_mask0, | |
176 | .irq_mask = iop13xx_irq_mask0, | |
177 | .irq_unmask = iop13xx_irq_unmask0, | |
285f5fa7 DW |
178 | }; |
179 | ||
3a2aeda8 | 180 | static struct irq_chip iop13xx_irqchip2 = { |
418c9904 LB |
181 | .name = "IOP13xx-2", |
182 | .irq_ack = iop13xx_irq_mask1, | |
183 | .irq_mask = iop13xx_irq_mask1, | |
184 | .irq_unmask = iop13xx_irq_unmask1, | |
285f5fa7 DW |
185 | }; |
186 | ||
3a2aeda8 | 187 | static struct irq_chip iop13xx_irqchip3 = { |
418c9904 LB |
188 | .name = "IOP13xx-3", |
189 | .irq_ack = iop13xx_irq_mask2, | |
190 | .irq_mask = iop13xx_irq_mask2, | |
191 | .irq_unmask = iop13xx_irq_unmask2, | |
285f5fa7 DW |
192 | }; |
193 | ||
3a2aeda8 | 194 | static struct irq_chip iop13xx_irqchip4 = { |
418c9904 LB |
195 | .name = "IOP13xx-4", |
196 | .irq_ack = iop13xx_irq_mask3, | |
197 | .irq_mask = iop13xx_irq_mask3, | |
198 | .irq_unmask = iop13xx_irq_unmask3, | |
285f5fa7 DW |
199 | }; |
200 | ||
588ef769 DW |
201 | extern void iop_init_cp6_handler(void); |
202 | ||
285f5fa7 DW |
203 | void __init iop13xx_init_irq(void) |
204 | { | |
205 | unsigned int i; | |
206 | ||
588ef769 | 207 | iop_init_cp6_handler(); |
285f5fa7 DW |
208 | |
209 | /* disable all interrupts */ | |
210 | write_intctl_0(0); | |
211 | write_intctl_1(0); | |
212 | write_intctl_2(0); | |
213 | write_intctl_3(0); | |
214 | ||
215 | /* treat all as IRQ */ | |
216 | write_intstr_0(0); | |
217 | write_intstr_1(0); | |
218 | write_intstr_2(0); | |
219 | write_intstr_3(0); | |
220 | ||
221 | /* initialize the interrupt vector generator */ | |
222 | write_intbase(INTBASE); | |
223 | write_intsize(INTSIZE_4); | |
224 | ||
2fd02375 | 225 | for(i = 0; i <= IRQ_IOP13XX_HPI; i++) { |
285f5fa7 | 226 | if (i < 32) |
6845664a | 227 | irq_set_chip(i, &iop13xx_irqchip1); |
3a2aeda8 | 228 | else if (i < 64) |
6845664a | 229 | irq_set_chip(i, &iop13xx_irqchip2); |
3a2aeda8 | 230 | else if (i < 96) |
6845664a | 231 | irq_set_chip(i, &iop13xx_irqchip3); |
3a2aeda8 | 232 | else |
6845664a | 233 | irq_set_chip(i, &iop13xx_irqchip4); |
285f5fa7 | 234 | |
6845664a | 235 | irq_set_handler(i, handle_level_irq); |
285f5fa7 DW |
236 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); |
237 | } | |
2fd02375 DW |
238 | |
239 | iop13xx_msi_init(); | |
285f5fa7 | 240 | } |