Commit 106627d0a036f9ebe523c648686b087eb8888355
1 parent
577390ff
Rework OMAP1 interrupt handling to allow multiple interrupt banks, by Lauro Ramos Venancio.
Add irq pulse shortcut, by Lauro Ramos Venancio. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3774 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
167 additions
and
134 deletions
hw/irq.h
... | ... | @@ -19,6 +19,12 @@ static inline void qemu_irq_lower(qemu_irq irq) |
19 | 19 | qemu_set_irq(irq, 0); |
20 | 20 | } |
21 | 21 | |
22 | +static inline void qemu_irq_pulse(qemu_irq irq) | |
23 | +{ | |
24 | + qemu_set_irq(irq, 1); | |
25 | + qemu_set_irq(irq, 0); | |
26 | +} | |
27 | + | |
22 | 28 | /* Returns an array of N IRQs. */ |
23 | 29 | qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n); |
24 | 30 | ... | ... |
hw/omap.c
... | ... | @@ -80,71 +80,68 @@ void omap_badwidth_write32(void *opaque, target_phys_addr_t addr, |
80 | 80 | } |
81 | 81 | |
82 | 82 | /* Interrupt Handlers */ |
83 | -struct omap_intr_handler_s { | |
84 | - qemu_irq *pins; | |
85 | - qemu_irq *parent_pic; | |
86 | - target_phys_addr_t base; | |
87 | - | |
88 | - /* state */ | |
83 | +struct omap_intr_handler_bank_s { | |
89 | 84 | uint32_t irqs; |
85 | + uint32_t inputs; | |
90 | 86 | uint32_t mask; |
91 | - uint32_t sens_edge; | |
92 | 87 | uint32_t fiq; |
93 | - int priority[32]; | |
94 | - uint32_t new_irq_agr; | |
95 | - uint32_t new_fiq_agr; | |
96 | - int sir_irq; | |
97 | - int sir_fiq; | |
98 | - int stats[32]; | |
88 | + uint32_t sens_edge; | |
89 | + unsigned char priority[32]; | |
99 | 90 | }; |
100 | 91 | |
101 | -static void omap_inth_update(struct omap_intr_handler_s *s) | |
102 | -{ | |
103 | - uint32_t irq = s->irqs & ~s->mask & ~s->fiq; | |
104 | - uint32_t fiq = s->irqs & ~s->mask & s->fiq; | |
92 | +struct omap_intr_handler_s { | |
93 | + qemu_irq *pins; | |
94 | + qemu_irq parent_intr[2]; | |
95 | + target_phys_addr_t base; | |
96 | + unsigned char nbanks; | |
105 | 97 | |
106 | - if (s->new_irq_agr || !irq) { | |
107 | - qemu_set_irq(s->parent_pic[ARM_PIC_CPU_IRQ], irq); | |
108 | - if (irq) | |
109 | - s->new_irq_agr = 0; | |
110 | - } | |
98 | + /* state */ | |
99 | + uint32_t new_agr[2]; | |
100 | + int sir_intr[2]; | |
101 | + struct omap_intr_handler_bank_s banks[]; | |
102 | +}; | |
111 | 103 | |
112 | - if (s->new_fiq_agr || !irq) { | |
113 | - qemu_set_irq(s->parent_pic[ARM_PIC_CPU_FIQ], fiq); | |
114 | - if (fiq) | |
115 | - s->new_fiq_agr = 0; | |
104 | +static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq) | |
105 | +{ | |
106 | + int i, j, sir_intr, p_intr, p, f; | |
107 | + uint32_t level; | |
108 | + sir_intr = 0; | |
109 | + p_intr = 255; | |
110 | + | |
111 | + /* Find the interrupt line with the highest dynamic priority. | |
112 | + * Note: 0 denotes the hightest priority. | |
113 | + * If all interrupts have the same priority, the default order is IRQ_N, | |
114 | + * IRQ_N-1,...,IRQ_0. */ | |
115 | + for (j = 0; j < s->nbanks; ++j) { | |
116 | + level = s->banks[j].irqs & ~s->banks[j].mask & | |
117 | + (is_fiq ? s->banks[j].fiq : ~s->banks[j].fiq); | |
118 | + for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f, | |
119 | + level >>= f) { | |
120 | + p = s->banks[j].priority[i]; | |
121 | + if (p <= p_intr) { | |
122 | + p_intr = p; | |
123 | + sir_intr = 32 * j + i; | |
124 | + } | |
125 | + f = ffs(level >> 1); | |
126 | + } | |
116 | 127 | } |
128 | + s->sir_intr[is_fiq] = sir_intr; | |
117 | 129 | } |
118 | 130 | |
119 | -static void omap_inth_sir_update(struct omap_intr_handler_s *s) | |
131 | +static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq) | |
120 | 132 | { |
121 | - int i, intr_irq, intr_fiq, p_irq, p_fiq, p, f; | |
122 | - uint32_t level = s->irqs & ~s->mask; | |
133 | + int i; | |
134 | + uint32_t has_intr = 0; | |
123 | 135 | |
124 | - intr_irq = 0; | |
125 | - intr_fiq = 0; | |
126 | - p_irq = -1; | |
127 | - p_fiq = -1; | |
128 | - /* Find the interrupt line with the highest dynamic priority */ | |
129 | - for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f, level >>= f) { | |
130 | - p = s->priority[i]; | |
131 | - if (s->fiq & (1 << i)) { | |
132 | - if (p > p_fiq) { | |
133 | - p_fiq = p; | |
134 | - intr_fiq = i; | |
135 | - } | |
136 | - } else { | |
137 | - if (p > p_irq) { | |
138 | - p_irq = p; | |
139 | - intr_irq = i; | |
140 | - } | |
141 | - } | |
136 | + for (i = 0; i < s->nbanks; ++i) | |
137 | + has_intr |= s->banks[i].irqs & ~s->banks[i].mask & | |
138 | + (is_fiq ? s->banks[i].fiq : ~s->banks[i].fiq); | |
142 | 139 | |
143 | - f = ffs(level >> 1); | |
140 | + if (s->new_agr[is_fiq] && has_intr) { | |
141 | + s->new_agr[is_fiq] = 0; | |
142 | + omap_inth_sir_update(s, is_fiq); | |
143 | + qemu_set_irq(s->parent_intr[is_fiq], 1); | |
144 | 144 | } |
145 | - | |
146 | - s->sir_irq = intr_irq; | |
147 | - s->sir_fiq = intr_fiq; | |
148 | 145 | } |
149 | 146 | |
150 | 147 | #define INT_FALLING_EDGE 0 |
... | ... | @@ -155,19 +152,24 @@ static void omap_set_intr(void *opaque, int irq, int req) |
155 | 152 | struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque; |
156 | 153 | uint32_t rise; |
157 | 154 | |
155 | + struct omap_intr_handler_bank_s *bank = &ih->banks[irq >> 5]; | |
156 | + int n = irq & 31; | |
157 | + | |
158 | 158 | if (req) { |
159 | - rise = ~ih->irqs & (1 << irq); | |
160 | - ih->irqs |= rise; | |
161 | - ih->stats[irq] += !!rise; | |
159 | + rise = ~bank->irqs & (1 << n); | |
160 | + if (~bank->sens_edge & (1 << n)) | |
161 | + rise &= ~bank->inputs & (1 << n); | |
162 | + | |
163 | + bank->inputs |= (1 << n); | |
164 | + if (rise) { | |
165 | + bank->irqs |= rise; | |
166 | + omap_inth_update(ih, 0); | |
167 | + omap_inth_update(ih, 1); | |
168 | + } | |
162 | 169 | } else { |
163 | - rise = ih->sens_edge & ih->irqs & (1 << irq); | |
164 | - ih->irqs &= ~rise; | |
165 | - } | |
166 | - | |
167 | - if (rise & ~ih->mask) { | |
168 | - omap_inth_sir_update(ih); | |
169 | - | |
170 | - omap_inth_update(ih); | |
170 | + rise = bank->sens_edge & bank->irqs & (1 << n); | |
171 | + bank->irqs &= ~rise; | |
172 | + bank->inputs &= ~(1 << n); | |
171 | 173 | } |
172 | 174 | } |
173 | 175 | |
... | ... | @@ -175,33 +177,32 @@ static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr) |
175 | 177 | { |
176 | 178 | struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque; |
177 | 179 | int i, offset = addr - s->base; |
180 | + int bank_no = offset >> 8; | |
181 | + int line_no; | |
182 | + struct omap_intr_handler_bank_s *bank = &s->banks[bank_no]; | |
183 | + offset &= 0xff; | |
178 | 184 | |
179 | 185 | switch (offset) { |
180 | 186 | case 0x00: /* ITR */ |
181 | - return s->irqs; | |
187 | + return bank->irqs; | |
182 | 188 | |
183 | 189 | case 0x04: /* MIR */ |
184 | - return s->mask; | |
190 | + return bank->mask; | |
185 | 191 | |
186 | 192 | case 0x10: /* SIR_IRQ_CODE */ |
187 | - i = s->sir_irq; | |
188 | - if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) { | |
189 | - s->irqs &= ~(1 << i); | |
190 | - omap_inth_sir_update(s); | |
191 | - omap_inth_update(s); | |
192 | - } | |
193 | - return i; | |
194 | - | |
195 | - case 0x14: /* SIR_FIQ_CODE */ | |
196 | - i = s->sir_fiq; | |
197 | - if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) { | |
198 | - s->irqs &= ~(1 << i); | |
199 | - omap_inth_sir_update(s); | |
200 | - omap_inth_update(s); | |
201 | - } | |
193 | + case 0x14: /* SIR_FIQ_CODE */ | |
194 | + if (bank_no != 0) | |
195 | + break; | |
196 | + line_no = s->sir_intr[(offset - 0x10) >> 2]; | |
197 | + bank = &s->banks[line_no >> 5]; | |
198 | + i = line_no & 31; | |
199 | + if (((bank->sens_edge >> i) & 1) == INT_FALLING_EDGE) | |
200 | + bank->irqs &= ~(1 << i); | |
202 | 201 | return i; |
203 | 202 | |
204 | 203 | case 0x18: /* CONTROL_REG */ |
204 | + if (bank_no != 0) | |
205 | + break; | |
205 | 206 | return 0; |
206 | 207 | |
207 | 208 | case 0x1c: /* ILR0 */ |
... | ... | @@ -237,17 +238,15 @@ static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr) |
237 | 238 | case 0x94: /* ILR30 */ |
238 | 239 | case 0x98: /* ILR31 */ |
239 | 240 | i = (offset - 0x1c) >> 2; |
240 | - return (s->priority[i] << 2) | | |
241 | - (((s->sens_edge >> i) & 1) << 1) | | |
242 | - ((s->fiq >> i) & 1); | |
241 | + return (bank->priority[i] << 2) | | |
242 | + (((bank->sens_edge >> i) & 1) << 1) | | |
243 | + ((bank->fiq >> i) & 1); | |
243 | 244 | |
244 | 245 | case 0x9c: /* ISR */ |
245 | 246 | return 0x00000000; |
246 | 247 | |
247 | - default: | |
248 | - OMAP_BAD_REG(addr); | |
249 | - break; | |
250 | 248 | } |
249 | + OMAP_BAD_REG(addr); | |
251 | 250 | return 0; |
252 | 251 | } |
253 | 252 | |
... | ... | @@ -256,18 +255,21 @@ static void omap_inth_write(void *opaque, target_phys_addr_t addr, |
256 | 255 | { |
257 | 256 | struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque; |
258 | 257 | int i, offset = addr - s->base; |
258 | + int bank_no = offset >> 8; | |
259 | + struct omap_intr_handler_bank_s *bank = &s->banks[bank_no]; | |
260 | + offset &= 0xff; | |
259 | 261 | |
260 | 262 | switch (offset) { |
261 | 263 | case 0x00: /* ITR */ |
262 | - s->irqs &= value | 1; | |
263 | - omap_inth_sir_update(s); | |
264 | - omap_inth_update(s); | |
264 | + /* Important: ignore the clearing if the IRQ is level-triggered and | |
265 | + the input bit is 1 */ | |
266 | + bank->irqs &= value | (bank->inputs & bank->sens_edge); | |
265 | 267 | return; |
266 | 268 | |
267 | 269 | case 0x04: /* MIR */ |
268 | - s->mask = value; | |
269 | - omap_inth_sir_update(s); | |
270 | - omap_inth_update(s); | |
270 | + bank->mask = value; | |
271 | + omap_inth_update(s, 0); | |
272 | + omap_inth_update(s, 1); | |
271 | 273 | return; |
272 | 274 | |
273 | 275 | case 0x10: /* SIR_IRQ_CODE */ |
... | ... | @@ -276,11 +278,18 @@ static void omap_inth_write(void *opaque, target_phys_addr_t addr, |
276 | 278 | break; |
277 | 279 | |
278 | 280 | case 0x18: /* CONTROL_REG */ |
279 | - if (value & 2) | |
280 | - s->new_fiq_agr = ~0; | |
281 | - if (value & 1) | |
282 | - s->new_irq_agr = ~0; | |
283 | - omap_inth_update(s); | |
281 | + if (bank_no != 0) | |
282 | + break; | |
283 | + if (value & 2) { | |
284 | + qemu_set_irq(s->parent_intr[1], 0); | |
285 | + s->new_agr[1] = ~0; | |
286 | + omap_inth_update(s, 1); | |
287 | + } | |
288 | + if (value & 1) { | |
289 | + qemu_set_irq(s->parent_intr[0], 0); | |
290 | + s->new_agr[0] = ~0; | |
291 | + omap_inth_update(s, 0); | |
292 | + } | |
284 | 293 | return; |
285 | 294 | |
286 | 295 | case 0x1c: /* ILR0 */ |
... | ... | @@ -316,24 +325,22 @@ static void omap_inth_write(void *opaque, target_phys_addr_t addr, |
316 | 325 | case 0x94: /* ILR30 */ |
317 | 326 | case 0x98: /* ILR31 */ |
318 | 327 | i = (offset - 0x1c) >> 2; |
319 | - s->priority[i] = (value >> 2) & 0x1f; | |
320 | - s->sens_edge &= ~(1 << i); | |
321 | - s->sens_edge |= ((value >> 1) & 1) << i; | |
322 | - s->fiq &= ~(1 << i); | |
323 | - s->fiq |= (value & 1) << i; | |
328 | + bank->priority[i] = (value >> 2) & 0x1f; | |
329 | + bank->sens_edge &= ~(1 << i); | |
330 | + bank->sens_edge |= ((value >> 1) & 1) << i; | |
331 | + bank->fiq &= ~(1 << i); | |
332 | + bank->fiq |= (value & 1) << i; | |
324 | 333 | return; |
325 | 334 | |
326 | 335 | case 0x9c: /* ISR */ |
327 | 336 | for (i = 0; i < 32; i ++) |
328 | 337 | if (value & (1 << i)) { |
329 | - omap_set_intr(s, i, 1); | |
338 | + omap_set_intr(s, 32 * bank_no + i, 1); | |
330 | 339 | return; |
331 | 340 | } |
332 | 341 | return; |
333 | - | |
334 | - default: | |
335 | - OMAP_BAD_REG(addr); | |
336 | 342 | } |
343 | + OMAP_BAD_REG(addr); | |
337 | 344 | } |
338 | 345 | |
339 | 346 | static CPUReadMemoryFunc *omap_inth_readfn[] = { |
... | ... | @@ -348,31 +355,43 @@ static CPUWriteMemoryFunc *omap_inth_writefn[] = { |
348 | 355 | omap_inth_write, |
349 | 356 | }; |
350 | 357 | |
351 | -static void omap_inth_reset(struct omap_intr_handler_s *s) | |
358 | +void omap_inth_reset(struct omap_intr_handler_s *s) | |
352 | 359 | { |
353 | - s->irqs = 0x00000000; | |
354 | - s->mask = 0xffffffff; | |
355 | - s->sens_edge = 0x00000000; | |
356 | - s->fiq = 0x00000000; | |
357 | - memset(s->priority, 0, sizeof(s->priority)); | |
358 | - s->new_irq_agr = ~0; | |
359 | - s->new_fiq_agr = ~0; | |
360 | - s->sir_irq = 0; | |
361 | - s->sir_fiq = 0; | |
360 | + int i; | |
361 | + | |
362 | + for (i = 0; i < s->nbanks; ++i){ | |
363 | + s->banks[i].irqs = 0x00000000; | |
364 | + s->banks[i].mask = 0xffffffff; | |
365 | + s->banks[i].sens_edge = 0x00000000; | |
366 | + s->banks[i].fiq = 0x00000000; | |
367 | + s->banks[i].inputs = 0x00000000; | |
368 | + memset(s->banks[i].priority, 0, sizeof(s->banks[i].priority)); | |
369 | + } | |
362 | 370 | |
363 | - omap_inth_update(s); | |
371 | + s->new_agr[0] = ~0; | |
372 | + s->new_agr[1] = ~0; | |
373 | + s->sir_intr[0] = 0; | |
374 | + s->sir_intr[1] = 0; | |
375 | + | |
376 | + qemu_set_irq(s->parent_intr[0], 0); | |
377 | + qemu_set_irq(s->parent_intr[1], 0); | |
364 | 378 | } |
365 | 379 | |
366 | 380 | struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, |
367 | - unsigned long size, qemu_irq parent[2], omap_clk clk) | |
381 | + unsigned long size, unsigned char nbanks, | |
382 | + qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk) | |
368 | 383 | { |
369 | 384 | int iomemtype; |
370 | 385 | struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) |
371 | - qemu_mallocz(sizeof(struct omap_intr_handler_s)); | |
386 | + qemu_mallocz(sizeof(struct omap_intr_handler_s) + | |
387 | + sizeof(struct omap_intr_handler_bank_s) * nbanks); | |
372 | 388 | |
373 | - s->parent_pic = parent; | |
389 | + s->parent_intr[0] = parent_irq; | |
390 | + s->parent_intr[1] = parent_fiq; | |
374 | 391 | s->base = base; |
375 | - s->pins = qemu_allocate_irqs(omap_set_intr, s, 32); | |
392 | + s->nbanks = nbanks; | |
393 | + s->pins = qemu_allocate_irqs(omap_set_intr, s, nbanks * 32); | |
394 | + | |
376 | 395 | omap_inth_reset(s); |
377 | 396 | |
378 | 397 | iomemtype = cpu_register_io_memory(0, omap_inth_readfn, |
... | ... | @@ -1144,7 +1163,8 @@ static inline void omap_timer_update(struct omap_mpu_timer_s *timer) |
1144 | 1163 | timer->val = 0; |
1145 | 1164 | timer->st = 0; |
1146 | 1165 | if (timer->it_ena) |
1147 | - qemu_irq_raise(timer->irq); | |
1166 | + /* Edge-triggered irq */ | |
1167 | + qemu_irq_pulse(timer->irq); | |
1148 | 1168 | } |
1149 | 1169 | } else |
1150 | 1170 | qemu_del_timer(timer->timer); |
... | ... | @@ -1161,7 +1181,8 @@ static void omap_timer_tick(void *opaque) |
1161 | 1181 | } |
1162 | 1182 | |
1163 | 1183 | if (timer->it_ena) |
1164 | - qemu_irq_raise(timer->irq); | |
1184 | + /* Edge-triggered irq */ | |
1185 | + qemu_irq_pulse(timer->irq); | |
1165 | 1186 | omap_timer_update(timer); |
1166 | 1187 | } |
1167 | 1188 | |
... | ... | @@ -3678,6 +3699,7 @@ struct omap_rtc_s { |
3678 | 3699 | |
3679 | 3700 | static void omap_rtc_interrupts_update(struct omap_rtc_s *s) |
3680 | 3701 | { |
3702 | + /* s->alarm is level-triggered */ | |
3681 | 3703 | qemu_set_irq(s->alarm, (s->status >> 6) & 1); |
3682 | 3704 | } |
3683 | 3705 | |
... | ... | @@ -4000,26 +4022,26 @@ static void omap_rtc_tick(void *opaque) |
4000 | 4022 | switch (s->interrupts & 3) { |
4001 | 4023 | case 0: |
4002 | 4024 | s->status |= 0x04; |
4003 | - qemu_irq_raise(s->irq); | |
4025 | + qemu_irq_pulse(s->irq); | |
4004 | 4026 | break; |
4005 | 4027 | case 1: |
4006 | 4028 | if (s->current_tm.tm_sec) |
4007 | 4029 | break; |
4008 | 4030 | s->status |= 0x08; |
4009 | - qemu_irq_raise(s->irq); | |
4031 | + qemu_irq_pulse(s->irq); | |
4010 | 4032 | break; |
4011 | 4033 | case 2: |
4012 | 4034 | if (s->current_tm.tm_sec || s->current_tm.tm_min) |
4013 | 4035 | break; |
4014 | 4036 | s->status |= 0x10; |
4015 | - qemu_irq_raise(s->irq); | |
4037 | + qemu_irq_pulse(s->irq); | |
4016 | 4038 | break; |
4017 | 4039 | case 3: |
4018 | 4040 | if (s->current_tm.tm_sec || |
4019 | 4041 | s->current_tm.tm_min || s->current_tm.tm_hour) |
4020 | 4042 | break; |
4021 | 4043 | s->status |= 0x20; |
4022 | - qemu_irq_raise(s->irq); | |
4044 | + qemu_irq_pulse(s->irq); | |
4023 | 4045 | break; |
4024 | 4046 | } |
4025 | 4047 | |
... | ... | @@ -4121,7 +4143,8 @@ static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s) |
4121 | 4143 | break; |
4122 | 4144 | } |
4123 | 4145 | |
4124 | - qemu_set_irq(s->rxirq, irq); | |
4146 | + if (irq) | |
4147 | + qemu_irq_pulse(s->rxirq); | |
4125 | 4148 | |
4126 | 4149 | switch ((s->spcr[1] >> 4) & 3) { /* XINTM */ |
4127 | 4150 | case 0: |
... | ... | @@ -4135,7 +4158,8 @@ static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s) |
4135 | 4158 | break; |
4136 | 4159 | } |
4137 | 4160 | |
4138 | - qemu_set_irq(s->txirq, irq); | |
4161 | + if (irq) | |
4162 | + qemu_irq_pulse(s->txirq); | |
4139 | 4163 | } |
4140 | 4164 | |
4141 | 4165 | static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s) |
... | ... | @@ -4901,8 +4925,9 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, |
4901 | 4925 | struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) |
4902 | 4926 | qemu_mallocz(sizeof(struct omap_mpu_state_s)); |
4903 | 4927 | ram_addr_t imif_base, emiff_base; |
4928 | + qemu_irq *cpu_irq; | |
4904 | 4929 | int sdindex; |
4905 | - | |
4930 | + | |
4906 | 4931 | if (!core) |
4907 | 4932 | core = "ti925t"; |
4908 | 4933 | |
... | ... | @@ -4929,11 +4954,12 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, |
4929 | 4954 | |
4930 | 4955 | omap_clkm_init(0xfffece00, 0xe1008000, s); |
4931 | 4956 | |
4932 | - s->ih[0] = omap_inth_init(0xfffecb00, 0x100, | |
4933 | - arm_pic_init_cpu(s->env), | |
4957 | + cpu_irq = arm_pic_init_cpu(s->env); | |
4958 | + s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1, | |
4959 | + cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ], | |
4934 | 4960 | omap_findclk(s, "arminth_ck")); |
4935 | - s->ih[1] = omap_inth_init(0xfffe0000, 0x800, | |
4936 | - &s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ], | |
4961 | + s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1, | |
4962 | + s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ], NULL, | |
4937 | 4963 | omap_findclk(s, "arminth_ck")); |
4938 | 4964 | s->irq[0] = s->ih[0]->pins; |
4939 | 4965 | s->irq[1] = s->ih[1]->pins; | ... | ... |
hw/omap.h
... | ... | @@ -57,7 +57,8 @@ void omap_clk_reparent(omap_clk clk, omap_clk parent); |
57 | 57 | /* omap.c */ |
58 | 58 | struct omap_intr_handler_s; |
59 | 59 | struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, |
60 | - unsigned long size, qemu_irq parent[2], omap_clk clk); | |
60 | + unsigned long size, unsigned char nbanks, | |
61 | + qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk); | |
61 | 62 | |
62 | 63 | /* |
63 | 64 | * Common IRQ numbers for level 1 interrupt handler | ... | ... |