diff options
Diffstat (limited to 'arch/arm/kernel/smp.c')
-rw-r--r-- | arch/arm/kernel/smp.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 421329f5e18e..070bcb7a6306 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #include <linux/module.h> | ||
10 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
12 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
@@ -19,6 +20,7 @@ | |||
19 | #include <linux/cpu.h> | 20 | #include <linux/cpu.h> |
20 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
21 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
23 | #include <linux/irq.h> | ||
22 | 24 | ||
23 | #include <asm/atomic.h> | 25 | #include <asm/atomic.h> |
24 | #include <asm/cacheflush.h> | 26 | #include <asm/cacheflush.h> |
@@ -449,6 +451,7 @@ int smp_call_function(void (*func)(void *info), void *info, int retry, | |||
449 | return smp_call_function_on_cpu(func, info, retry, wait, | 451 | return smp_call_function_on_cpu(func, info, retry, wait, |
450 | cpu_online_map); | 452 | cpu_online_map); |
451 | } | 453 | } |
454 | EXPORT_SYMBOL_GPL(smp_call_function); | ||
452 | 455 | ||
453 | void show_ipi_list(struct seq_file *p) | 456 | void show_ipi_list(struct seq_file *p) |
454 | { | 457 | { |
@@ -474,25 +477,26 @@ void show_local_irqs(struct seq_file *p) | |||
474 | seq_putc(p, '\n'); | 477 | seq_putc(p, '\n'); |
475 | } | 478 | } |
476 | 479 | ||
477 | static void ipi_timer(struct pt_regs *regs) | 480 | static void ipi_timer(void) |
478 | { | 481 | { |
479 | int user = user_mode(regs); | ||
480 | |||
481 | irq_enter(); | 482 | irq_enter(); |
482 | profile_tick(CPU_PROFILING, regs); | 483 | profile_tick(CPU_PROFILING); |
483 | update_process_times(user); | 484 | update_process_times(user_mode(get_irq_regs())); |
484 | irq_exit(); | 485 | irq_exit(); |
485 | } | 486 | } |
486 | 487 | ||
487 | #ifdef CONFIG_LOCAL_TIMERS | 488 | #ifdef CONFIG_LOCAL_TIMERS |
488 | asmlinkage void do_local_timer(struct pt_regs *regs) | 489 | asmlinkage void do_local_timer(struct pt_regs *regs) |
489 | { | 490 | { |
491 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
490 | int cpu = smp_processor_id(); | 492 | int cpu = smp_processor_id(); |
491 | 493 | ||
492 | if (local_timer_ack()) { | 494 | if (local_timer_ack()) { |
493 | irq_stat[cpu].local_timer_irqs++; | 495 | irq_stat[cpu].local_timer_irqs++; |
494 | ipi_timer(regs); | 496 | ipi_timer(); |
495 | } | 497 | } |
498 | |||
499 | set_irq_regs(old_regs); | ||
496 | } | 500 | } |
497 | #endif | 501 | #endif |
498 | 502 | ||
@@ -551,6 +555,7 @@ asmlinkage void do_IPI(struct pt_regs *regs) | |||
551 | { | 555 | { |
552 | unsigned int cpu = smp_processor_id(); | 556 | unsigned int cpu = smp_processor_id(); |
553 | struct ipi_data *ipi = &per_cpu(ipi_data, cpu); | 557 | struct ipi_data *ipi = &per_cpu(ipi_data, cpu); |
558 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
554 | 559 | ||
555 | ipi->ipi_count++; | 560 | ipi->ipi_count++; |
556 | 561 | ||
@@ -574,7 +579,7 @@ asmlinkage void do_IPI(struct pt_regs *regs) | |||
574 | 579 | ||
575 | switch (nextmsg) { | 580 | switch (nextmsg) { |
576 | case IPI_TIMER: | 581 | case IPI_TIMER: |
577 | ipi_timer(regs); | 582 | ipi_timer(); |
578 | break; | 583 | break; |
579 | 584 | ||
580 | case IPI_RESCHEDULE: | 585 | case IPI_RESCHEDULE: |
@@ -599,6 +604,8 @@ asmlinkage void do_IPI(struct pt_regs *regs) | |||
599 | } | 604 | } |
600 | } while (msgs); | 605 | } while (msgs); |
601 | } | 606 | } |
607 | |||
608 | set_irq_regs(old_regs); | ||
602 | } | 609 | } |
603 | 610 | ||
604 | void smp_send_reschedule(int cpu) | 611 | void smp_send_reschedule(int cpu) |