diff options
| author | David Woodhouse <David.Woodhouse@intel.com> | 2008-07-25 10:40:14 -0400 |
|---|---|---|
| committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-07-25 10:40:14 -0400 |
| commit | ff877ea80efa2015b6263766f78ee42c2a1b32f9 (patch) | |
| tree | 85205005c611ab774702148558321c6fb92f1ccd /arch/m32r/kernel | |
| parent | 30821fee4f0cb3e6d241d9f7ddc37742212e3eb7 (diff) | |
| parent | d37e6bf68fc1eb34a4ad21d9ae8890ed37ea80e7 (diff) | |
Merge branch 'linux-next' of git://git.infradead.org/~dedekind/ubi-2.6
Diffstat (limited to 'arch/m32r/kernel')
| -rw-r--r-- | arch/m32r/kernel/m32r_ksyms.c | 3 | ||||
| -rw-r--r-- | arch/m32r/kernel/smp.c | 132 | ||||
| -rw-r--r-- | arch/m32r/kernel/traps.c | 3 |
3 files changed, 17 insertions, 121 deletions
diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c index e6709fe950ba..16bcb189a383 100644 --- a/arch/m32r/kernel/m32r_ksyms.c +++ b/arch/m32r/kernel/m32r_ksyms.c | |||
| @@ -43,9 +43,6 @@ EXPORT_SYMBOL(dcache_dummy); | |||
| 43 | #endif | 43 | #endif |
| 44 | EXPORT_SYMBOL(cpu_data); | 44 | EXPORT_SYMBOL(cpu_data); |
| 45 | 45 | ||
| 46 | /* Global SMP stuff */ | ||
| 47 | EXPORT_SYMBOL(smp_call_function); | ||
| 48 | |||
| 49 | /* TLB flushing */ | 46 | /* TLB flushing */ |
| 50 | EXPORT_SYMBOL(smp_flush_tlb_page); | 47 | EXPORT_SYMBOL(smp_flush_tlb_page); |
| 51 | #endif | 48 | #endif |
diff --git a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c index c837bc13b015..7577f971ea4e 100644 --- a/arch/m32r/kernel/smp.c +++ b/arch/m32r/kernel/smp.c | |||
| @@ -35,22 +35,6 @@ | |||
| 35 | /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ | 35 | /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ |
| 36 | 36 | ||
| 37 | /* | 37 | /* |
| 38 | * Structure and data for smp_call_function(). This is designed to minimise | ||
| 39 | * static memory requirements. It also looks cleaner. | ||
| 40 | */ | ||
| 41 | static DEFINE_SPINLOCK(call_lock); | ||
| 42 | |||
| 43 | struct call_data_struct { | ||
| 44 | void (*func) (void *info); | ||
| 45 | void *info; | ||
| 46 | atomic_t started; | ||
| 47 | atomic_t finished; | ||
| 48 | int wait; | ||
| 49 | } __attribute__ ((__aligned__(SMP_CACHE_BYTES))); | ||
| 50 | |||
| 51 | static struct call_data_struct *call_data; | ||
| 52 | |||
| 53 | /* | ||
| 54 | * For flush_cache_all() | 38 | * For flush_cache_all() |
| 55 | */ | 39 | */ |
| 56 | static DEFINE_SPINLOCK(flushcache_lock); | 40 | static DEFINE_SPINLOCK(flushcache_lock); |
| @@ -96,9 +80,6 @@ void smp_invalidate_interrupt(void); | |||
| 96 | void smp_send_stop(void); | 80 | void smp_send_stop(void); |
| 97 | static void stop_this_cpu(void *); | 81 | static void stop_this_cpu(void *); |
| 98 | 82 | ||
| 99 | int smp_call_function(void (*) (void *), void *, int, int); | ||
| 100 | void smp_call_function_interrupt(void); | ||
| 101 | |||
| 102 | void smp_send_timer(void); | 83 | void smp_send_timer(void); |
| 103 | void smp_ipi_timer_interrupt(struct pt_regs *); | 84 | void smp_ipi_timer_interrupt(struct pt_regs *); |
| 104 | void smp_local_timer_interrupt(void); | 85 | void smp_local_timer_interrupt(void); |
| @@ -231,7 +212,7 @@ void smp_flush_tlb_all(void) | |||
| 231 | local_irq_save(flags); | 212 | local_irq_save(flags); |
| 232 | __flush_tlb_all(); | 213 | __flush_tlb_all(); |
| 233 | local_irq_restore(flags); | 214 | local_irq_restore(flags); |
| 234 | smp_call_function(flush_tlb_all_ipi, NULL, 1, 1); | 215 | smp_call_function(flush_tlb_all_ipi, NULL, 1); |
| 235 | preempt_enable(); | 216 | preempt_enable(); |
| 236 | } | 217 | } |
| 237 | 218 | ||
| @@ -524,7 +505,7 @@ void smp_invalidate_interrupt(void) | |||
| 524 | *==========================================================================*/ | 505 | *==========================================================================*/ |
| 525 | void smp_send_stop(void) | 506 | void smp_send_stop(void) |
| 526 | { | 507 | { |
| 527 | smp_call_function(stop_this_cpu, NULL, 1, 0); | 508 | smp_call_function(stop_this_cpu, NULL, 0); |
| 528 | } | 509 | } |
| 529 | 510 | ||
| 530 | /*==========================================================================* | 511 | /*==========================================================================* |
| @@ -565,86 +546,14 @@ static void stop_this_cpu(void *dummy) | |||
| 565 | for ( ; ; ); | 546 | for ( ; ; ); |
| 566 | } | 547 | } |
| 567 | 548 | ||
| 568 | /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ | 549 | void arch_send_call_function_ipi(cpumask_t mask) |
| 569 | /* Call function Routines */ | ||
| 570 | /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ | ||
| 571 | |||
| 572 | /*==========================================================================* | ||
| 573 | * Name: smp_call_function | ||
| 574 | * | ||
| 575 | * Description: This routine sends a 'CALL_FUNCTION_IPI' to all other CPUs | ||
| 576 | * in the system. | ||
| 577 | * | ||
| 578 | * Born on Date: 2002.02.05 | ||
| 579 | * | ||
| 580 | * Arguments: *func - The function to run. This must be fast and | ||
| 581 | * non-blocking. | ||
| 582 | * *info - An arbitrary pointer to pass to the function. | ||
| 583 | * nonatomic - currently unused. | ||
| 584 | * wait - If true, wait (atomically) until function has | ||
| 585 | * completed on other CPUs. | ||
| 586 | * | ||
| 587 | * Returns: 0 on success, else a negative status code. Does not return | ||
| 588 | * until remote CPUs are nearly ready to execute <<func>> or | ||
| 589 | * are or have executed. | ||
| 590 | * | ||
| 591 | * Cautions: You must not call this function with disabled interrupts or | ||
| 592 | * from a hardware interrupt handler, you may call it from a | ||
| 593 | * bottom half handler. | ||
| 594 | * | ||
| 595 | * Modification log: | ||
| 596 | * Date Who Description | ||
| 597 | * ---------- --- -------------------------------------------------------- | ||
| 598 | * | ||
| 599 | *==========================================================================*/ | ||
| 600 | int smp_call_function(void (*func) (void *info), void *info, int nonatomic, | ||
| 601 | int wait) | ||
| 602 | { | 550 | { |
| 603 | struct call_data_struct data; | 551 | send_IPI_mask(mask, CALL_FUNCTION_IPI, 0); |
| 604 | int cpus; | 552 | } |
| 605 | |||
| 606 | #ifdef DEBUG_SMP | ||
| 607 | unsigned long flags; | ||
| 608 | __save_flags(flags); | ||
| 609 | if (!(flags & 0x0040)) /* Interrupt Disable NONONO */ | ||
| 610 | BUG(); | ||
| 611 | #endif /* DEBUG_SMP */ | ||
| 612 | |||
| 613 | /* Holding any lock stops cpus from going down. */ | ||
| 614 | spin_lock(&call_lock); | ||
| 615 | cpus = num_online_cpus() - 1; | ||
| 616 | |||
| 617 | if (!cpus) { | ||
| 618 | spin_unlock(&call_lock); | ||
| 619 | return 0; | ||
| 620 | } | ||
| 621 | |||
| 622 | /* Can deadlock when called with interrupts disabled */ | ||
| 623 | WARN_ON(irqs_disabled()); | ||
| 624 | |||
| 625 | data.func = func; | ||
| 626 | data.info = info; | ||
| 627 | atomic_set(&data.started, 0); | ||
| 628 | data.wait = wait; | ||
| 629 | if (wait) | ||
| 630 | atomic_set(&data.finished, 0); | ||
| 631 | |||
| 632 | call_data = &data; | ||
| 633 | mb(); | ||
| 634 | |||
| 635 | /* Send a message to all other CPUs and wait for them to respond */ | ||
| 636 | send_IPI_allbutself(CALL_FUNCTION_IPI, 0); | ||
| 637 | |||
| 638 | /* Wait for response */ | ||
| 639 | while (atomic_read(&data.started) != cpus) | ||
| 640 | barrier(); | ||
| 641 | |||
| 642 | if (wait) | ||
| 643 | while (atomic_read(&data.finished) != cpus) | ||
| 644 | barrier(); | ||
| 645 | spin_unlock(&call_lock); | ||
| 646 | 553 | ||
| 647 | return 0; | 554 | void arch_send_call_function_single_ipi(int cpu) |
| 555 | { | ||
| 556 | send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNC_SINGLE_IPI, 0); | ||
| 648 | } | 557 | } |
| 649 | 558 | ||
| 650 | /*==========================================================================* | 559 | /*==========================================================================* |
| @@ -666,27 +575,16 @@ int smp_call_function(void (*func) (void *info), void *info, int nonatomic, | |||
| 666 | *==========================================================================*/ | 575 | *==========================================================================*/ |
| 667 | void smp_call_function_interrupt(void) | 576 | void smp_call_function_interrupt(void) |
| 668 | { | 577 | { |
| 669 | void (*func) (void *info) = call_data->func; | ||
| 670 | void *info = call_data->info; | ||
| 671 | int wait = call_data->wait; | ||
| 672 | |||
| 673 | /* | ||
| 674 | * Notify initiating CPU that I've grabbed the data and am | ||
| 675 | * about to execute the function | ||
| 676 | */ | ||
| 677 | mb(); | ||
| 678 | atomic_inc(&call_data->started); | ||
| 679 | /* | ||
| 680 | * At this point the info structure may be out of scope unless wait==1 | ||
| 681 | */ | ||
| 682 | irq_enter(); | 578 | irq_enter(); |
| 683 | (*func)(info); | 579 | generic_smp_call_function_interrupt(); |
| 684 | irq_exit(); | 580 | irq_exit(); |
| 581 | } | ||
| 685 | 582 | ||
| 686 | if (wait) { | 583 | void smp_call_function_single_interrupt(void) |
| 687 | mb(); | 584 | { |
| 688 | atomic_inc(&call_data->finished); | 585 | irq_enter(); |
| 689 | } | 586 | generic_smp_call_function_single_interrupt(); |
| 587 | irq_exit(); | ||
| 690 | } | 588 | } |
| 691 | 589 | ||
| 692 | /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ | 590 | /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ |
diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c index 89ba4a0b5d51..46159a4e644b 100644 --- a/arch/m32r/kernel/traps.c +++ b/arch/m32r/kernel/traps.c | |||
| @@ -40,6 +40,7 @@ extern void smp_invalidate_interrupt(void); | |||
| 40 | extern void smp_call_function_interrupt(void); | 40 | extern void smp_call_function_interrupt(void); |
| 41 | extern void smp_ipi_timer_interrupt(void); | 41 | extern void smp_ipi_timer_interrupt(void); |
| 42 | extern void smp_flush_cache_all_interrupt(void); | 42 | extern void smp_flush_cache_all_interrupt(void); |
| 43 | extern void smp_call_function_single_interrupt(void); | ||
| 43 | 44 | ||
| 44 | /* | 45 | /* |
| 45 | * for Boot AP function | 46 | * for Boot AP function |
| @@ -103,7 +104,7 @@ void set_eit_vector_entries(void) | |||
| 103 | eit_vector[186] = (unsigned long)smp_call_function_interrupt; | 104 | eit_vector[186] = (unsigned long)smp_call_function_interrupt; |
| 104 | eit_vector[187] = (unsigned long)smp_ipi_timer_interrupt; | 105 | eit_vector[187] = (unsigned long)smp_ipi_timer_interrupt; |
| 105 | eit_vector[188] = (unsigned long)smp_flush_cache_all_interrupt; | 106 | eit_vector[188] = (unsigned long)smp_flush_cache_all_interrupt; |
| 106 | eit_vector[189] = 0; | 107 | eit_vector[189] = (unsigned long)smp_call_function_single_interrupt; |
| 107 | eit_vector[190] = 0; | 108 | eit_vector[190] = 0; |
| 108 | eit_vector[191] = 0; | 109 | eit_vector[191] = 0; |
| 109 | #endif | 110 | #endif |
