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 | ... | ... |