diff options
Diffstat (limited to 'arch/ia64/kernel/iosapic.c')
-rw-r--r-- | arch/ia64/kernel/iosapic.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index e647254c2707..c101c8bff27b 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c | |||
@@ -354,11 +354,13 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask) | |||
354 | 354 | ||
355 | irq &= (~IA64_IRQ_REDIRECTED); | 355 | irq &= (~IA64_IRQ_REDIRECTED); |
356 | 356 | ||
357 | /* IRQ migration across domain is not supported yet */ | 357 | cpus_and(mask, mask, cpu_online_map); |
358 | cpus_and(mask, mask, irq_to_domain(irq)); | ||
359 | if (cpus_empty(mask)) | 358 | if (cpus_empty(mask)) |
360 | return; | 359 | return; |
361 | 360 | ||
361 | if (reassign_irq_vector(irq, first_cpu(mask))) | ||
362 | return; | ||
363 | |||
362 | dest = cpu_physical_id(first_cpu(mask)); | 364 | dest = cpu_physical_id(first_cpu(mask)); |
363 | 365 | ||
364 | if (list_empty(&iosapic_intr_info[irq].rtes)) | 366 | if (list_empty(&iosapic_intr_info[irq].rtes)) |
@@ -376,6 +378,8 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask) | |||
376 | else | 378 | else |
377 | /* change delivery mode to fixed */ | 379 | /* change delivery mode to fixed */ |
378 | low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT); | 380 | low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT); |
381 | low32 &= IOSAPIC_VECTOR_MASK; | ||
382 | low32 |= irq_to_vector(irq); | ||
379 | 383 | ||
380 | iosapic_intr_info[irq].low32 = low32; | 384 | iosapic_intr_info[irq].low32 = low32; |
381 | iosapic_intr_info[irq].dest = dest; | 385 | iosapic_intr_info[irq].dest = dest; |
@@ -404,10 +408,20 @@ iosapic_end_level_irq (unsigned int irq) | |||
404 | { | 408 | { |
405 | ia64_vector vec = irq_to_vector(irq); | 409 | ia64_vector vec = irq_to_vector(irq); |
406 | struct iosapic_rte_info *rte; | 410 | struct iosapic_rte_info *rte; |
411 | int do_unmask_irq = 0; | ||
412 | |||
413 | if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) { | ||
414 | do_unmask_irq = 1; | ||
415 | mask_irq(irq); | ||
416 | } | ||
407 | 417 | ||
408 | move_native_irq(irq); | ||
409 | list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) | 418 | list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) |
410 | iosapic_eoi(rte->iosapic->addr, vec); | 419 | iosapic_eoi(rte->iosapic->addr, vec); |
420 | |||
421 | if (unlikely(do_unmask_irq)) { | ||
422 | move_masked_irq(irq); | ||
423 | unmask_irq(irq); | ||
424 | } | ||
411 | } | 425 | } |
412 | 426 | ||
413 | #define iosapic_shutdown_level_irq mask_irq | 427 | #define iosapic_shutdown_level_irq mask_irq |