diff options
-rw-r--r-- | arch/arm/kernel/smp.c | 87 |
1 files changed, 26 insertions, 61 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 7a236db03fb..78d55c681a4 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -48,20 +48,15 @@ struct secondary_data secondary_data; | |||
48 | 48 | ||
49 | /* | 49 | /* |
50 | * structures for inter-processor calls | 50 | * structures for inter-processor calls |
51 | * - A collection of single bit ipi messages. | ||
52 | */ | 51 | */ |
53 | struct ipi_data { | 52 | struct ipi_data { |
54 | spinlock_t lock; | ||
55 | unsigned long ipi_count; | 53 | unsigned long ipi_count; |
56 | unsigned long bits; | ||
57 | }; | 54 | }; |
58 | 55 | ||
59 | static DEFINE_PER_CPU(struct ipi_data, ipi_data) = { | 56 | static DEFINE_PER_CPU(struct ipi_data, ipi_data); |
60 | .lock = SPIN_LOCK_UNLOCKED, | ||
61 | }; | ||
62 | 57 | ||
63 | enum ipi_msg_type { | 58 | enum ipi_msg_type { |
64 | IPI_TIMER, | 59 | IPI_TIMER = 2, |
65 | IPI_RESCHEDULE, | 60 | IPI_RESCHEDULE, |
66 | IPI_CALL_FUNC, | 61 | IPI_CALL_FUNC, |
67 | IPI_CALL_FUNC_SINGLE, | 62 | IPI_CALL_FUNC_SINGLE, |
@@ -389,22 +384,13 @@ void __init smp_prepare_boot_cpu(void) | |||
389 | static void send_ipi_message(const struct cpumask *mask, enum ipi_msg_type msg) | 384 | static void send_ipi_message(const struct cpumask *mask, enum ipi_msg_type msg) |
390 | { | 385 | { |
391 | unsigned long flags; | 386 | unsigned long flags; |
392 | unsigned int cpu; | ||
393 | 387 | ||
394 | local_irq_save(flags); | 388 | local_irq_save(flags); |
395 | 389 | ||
396 | for_each_cpu(cpu, mask) { | ||
397 | struct ipi_data *ipi = &per_cpu(ipi_data, cpu); | ||
398 | |||
399 | spin_lock(&ipi->lock); | ||
400 | ipi->bits |= 1 << msg; | ||
401 | spin_unlock(&ipi->lock); | ||
402 | } | ||
403 | |||
404 | /* | 390 | /* |
405 | * Call the platform specific cross-CPU call function. | 391 | * Call the platform specific cross-CPU call function. |
406 | */ | 392 | */ |
407 | smp_cross_call(mask, 1); | 393 | smp_cross_call(mask, msg); |
408 | 394 | ||
409 | local_irq_restore(flags); | 395 | local_irq_restore(flags); |
410 | } | 396 | } |
@@ -546,56 +532,35 @@ asmlinkage void __exception do_IPI(int ipinr, struct pt_regs *regs) | |||
546 | 532 | ||
547 | ipi->ipi_count++; | 533 | ipi->ipi_count++; |
548 | 534 | ||
549 | for (;;) { | 535 | switch (ipinr) { |
550 | unsigned long msgs; | 536 | case IPI_TIMER: |
551 | 537 | ipi_timer(); | |
552 | spin_lock(&ipi->lock); | 538 | break; |
553 | msgs = ipi->bits; | ||
554 | ipi->bits = 0; | ||
555 | spin_unlock(&ipi->lock); | ||
556 | |||
557 | if (!msgs) | ||
558 | break; | ||
559 | |||
560 | do { | ||
561 | unsigned nextmsg; | ||
562 | |||
563 | nextmsg = msgs & -msgs; | ||
564 | msgs &= ~nextmsg; | ||
565 | nextmsg = ffz(~nextmsg); | ||
566 | |||
567 | switch (nextmsg) { | ||
568 | case IPI_TIMER: | ||
569 | ipi_timer(); | ||
570 | break; | ||
571 | 539 | ||
572 | case IPI_RESCHEDULE: | 540 | case IPI_RESCHEDULE: |
573 | /* | 541 | /* |
574 | * nothing more to do - eveything is | 542 | * nothing more to do - eveything is |
575 | * done on the interrupt return path | 543 | * done on the interrupt return path |
576 | */ | 544 | */ |
577 | break; | 545 | break; |
578 | 546 | ||
579 | case IPI_CALL_FUNC: | 547 | case IPI_CALL_FUNC: |
580 | generic_smp_call_function_interrupt(); | 548 | generic_smp_call_function_interrupt(); |
581 | break; | 549 | break; |
582 | 550 | ||
583 | case IPI_CALL_FUNC_SINGLE: | 551 | case IPI_CALL_FUNC_SINGLE: |
584 | generic_smp_call_function_single_interrupt(); | 552 | generic_smp_call_function_single_interrupt(); |
585 | break; | 553 | break; |
586 | 554 | ||
587 | case IPI_CPU_STOP: | 555 | case IPI_CPU_STOP: |
588 | ipi_cpu_stop(cpu); | 556 | ipi_cpu_stop(cpu); |
589 | break; | 557 | break; |
590 | 558 | ||
591 | default: | 559 | default: |
592 | printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", | 560 | printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", |
593 | cpu, nextmsg); | 561 | cpu, ipinr); |
594 | break; | 562 | break; |
595 | } | ||
596 | } while (msgs); | ||
597 | } | 563 | } |
598 | |||
599 | set_irq_regs(old_regs); | 564 | set_irq_regs(old_regs); |
600 | } | 565 | } |
601 | 566 | ||