aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/time.c')
-rw-r--r--arch/powerpc/kernel/time.c31
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,
109static struct clock_event_device decrementer_clockevent = { 110static 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
847static 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
846static void register_decrementer_clockevent(int cpu) 863static 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 */
1148void 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
1131static int __init rtc_init(void) 1156static int __init rtc_init(void)
1132{ 1157{
1133 struct platform_device *pdev; 1158 struct platform_device *pdev;