diff options
Diffstat (limited to 'arch/powerpc/kernel/time.c')
-rw-r--r-- | arch/powerpc/kernel/time.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 48571ac56fb7..15391c2ab013 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/jiffies.h> | 52 | #include <linux/jiffies.h> |
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 | 56 | ||
56 | #include <asm/io.h> | 57 | #include <asm/io.h> |
57 | #include <asm/processor.h> | 58 | #include <asm/processor.h> |
@@ -109,7 +110,7 @@ static void decrementer_set_mode(enum clock_event_mode mode, | |||
109 | static struct clock_event_device decrementer_clockevent = { | 110 | static struct clock_event_device decrementer_clockevent = { |
110 | .name = "decrementer", | 111 | .name = "decrementer", |
111 | .rating = 200, | 112 | .rating = 200, |
112 | .shift = 16, | 113 | .shift = 0, /* To be filled in */ |
113 | .mult = 0, /* To be filled in */ | 114 | .mult = 0, /* To be filled in */ |
114 | .irq = 0, | 115 | .irq = 0, |
115 | .set_next_event = decrementer_set_next_event, | 116 | .set_next_event = decrementer_set_next_event, |
@@ -843,6 +844,22 @@ static void decrementer_set_mode(enum clock_event_mode mode, | |||
843 | decrementer_set_next_event(DECREMENTER_MAX, dev); | 844 | decrementer_set_next_event(DECREMENTER_MAX, dev); |
844 | } | 845 | } |
845 | 846 | ||
847 | static void __init setup_clockevent_multiplier(unsigned long hz) | ||
848 | { | ||
849 | u64 mult, shift = 32; | ||
850 | |||
851 | while (1) { | ||
852 | mult = div_sc(hz, NSEC_PER_SEC, shift); | ||
853 | if (mult && (mult >> 32UL) == 0UL) | ||
854 | break; | ||
855 | |||
856 | shift--; | ||
857 | } | ||
858 | |||
859 | decrementer_clockevent.shift = shift; | ||
860 | decrementer_clockevent.mult = mult; | ||
861 | } | ||
862 | |||
846 | static void register_decrementer_clockevent(int cpu) | 863 | static void register_decrementer_clockevent(int cpu) |
847 | { | 864 | { |
848 | struct clock_event_device *dec = &per_cpu(decrementers, cpu).event; | 865 | struct clock_event_device *dec = &per_cpu(decrementers, cpu).event; |
@@ -860,8 +877,7 @@ static void __init init_decrementer_clockevent(void) | |||
860 | { | 877 | { |
861 | int cpu = smp_processor_id(); | 878 | int cpu = smp_processor_id(); |
862 | 879 | ||
863 | decrementer_clockevent.mult = div_sc(ppc_tb_freq, NSEC_PER_SEC, | 880 | setup_clockevent_multiplier(ppc_tb_freq); |
864 | decrementer_clockevent.shift); | ||
865 | decrementer_clockevent.max_delta_ns = | 881 | decrementer_clockevent.max_delta_ns = |
866 | clockevent_delta2ns(DECREMENTER_MAX, &decrementer_clockevent); | 882 | clockevent_delta2ns(DECREMENTER_MAX, &decrementer_clockevent); |
867 | decrementer_clockevent.min_delta_ns = | 883 | decrementer_clockevent.min_delta_ns = |
@@ -1128,6 +1144,15 @@ void div128_by_32(u64 dividend_high, u64 dividend_low, | |||
1128 | 1144 | ||
1129 | } | 1145 | } |
1130 | 1146 | ||
1147 | /* We don't need to calibrate delay, we use the CPU timebase for that */ | ||
1148 | void calibrate_delay(void) | ||
1149 | { | ||
1150 | /* Some generic code (such as spinlock debug) use loops_per_jiffy | ||
1151 | * as the number of __delay(1) in a jiffy, so make it so | ||
1152 | */ | ||
1153 | loops_per_jiffy = tb_ticks_per_jiffy; | ||
1154 | } | ||
1155 | |||
1131 | static int __init rtc_init(void) | 1156 | static int __init rtc_init(void) |
1132 | { | 1157 | { |
1133 | struct platform_device *pdev; | 1158 | struct platform_device *pdev; |