diff options
Diffstat (limited to 'arch/powerpc/kernel/time.c')
-rw-r--r-- | arch/powerpc/kernel/time.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 15391c2ab013..eae4511ceeac 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <linux/posix-timers.h> | 53 | #include <linux/posix-timers.h> |
54 | #include <linux/irq.h> | 54 | #include <linux/irq.h> |
55 | #include <linux/delay.h> | 55 | #include <linux/delay.h> |
56 | #include <linux/perf_counter.h> | ||
56 | 57 | ||
57 | #include <asm/io.h> | 58 | #include <asm/io.h> |
58 | #include <asm/processor.h> | 59 | #include <asm/processor.h> |
@@ -525,6 +526,26 @@ void __init iSeries_time_init_early(void) | |||
525 | } | 526 | } |
526 | #endif /* CONFIG_PPC_ISERIES */ | 527 | #endif /* CONFIG_PPC_ISERIES */ |
527 | 528 | ||
529 | #if defined(CONFIG_PERF_COUNTERS) && defined(CONFIG_PPC32) | ||
530 | DEFINE_PER_CPU(u8, perf_counter_pending); | ||
531 | |||
532 | void set_perf_counter_pending(void) | ||
533 | { | ||
534 | get_cpu_var(perf_counter_pending) = 1; | ||
535 | set_dec(1); | ||
536 | put_cpu_var(perf_counter_pending); | ||
537 | } | ||
538 | |||
539 | #define test_perf_counter_pending() __get_cpu_var(perf_counter_pending) | ||
540 | #define clear_perf_counter_pending() __get_cpu_var(perf_counter_pending) = 0 | ||
541 | |||
542 | #else /* CONFIG_PERF_COUNTERS && CONFIG_PPC32 */ | ||
543 | |||
544 | #define test_perf_counter_pending() 0 | ||
545 | #define clear_perf_counter_pending() | ||
546 | |||
547 | #endif /* CONFIG_PERF_COUNTERS && CONFIG_PPC32 */ | ||
548 | |||
528 | /* | 549 | /* |
529 | * For iSeries shared processors, we have to let the hypervisor | 550 | * For iSeries shared processors, we have to let the hypervisor |
530 | * set the hardware decrementer. We set a virtual decrementer | 551 | * set the hardware decrementer. We set a virtual decrementer |
@@ -551,6 +572,10 @@ void timer_interrupt(struct pt_regs * regs) | |||
551 | set_dec(DECREMENTER_MAX); | 572 | set_dec(DECREMENTER_MAX); |
552 | 573 | ||
553 | #ifdef CONFIG_PPC32 | 574 | #ifdef CONFIG_PPC32 |
575 | if (test_perf_counter_pending()) { | ||
576 | clear_perf_counter_pending(); | ||
577 | perf_counter_do_pending(); | ||
578 | } | ||
554 | if (atomic_read(&ppc_n_lost_interrupts) != 0) | 579 | if (atomic_read(&ppc_n_lost_interrupts) != 0) |
555 | do_IRQ(regs); | 580 | do_IRQ(regs); |
556 | #endif | 581 | #endif |