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.c105
1 files changed, 30 insertions, 75 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 522bb1dfc353..567dd7c3ac2a 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -86,8 +86,6 @@ static struct clocksource clocksource_rtc = {
86 .rating = 400, 86 .rating = 400,
87 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 87 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
88 .mask = CLOCKSOURCE_MASK(64), 88 .mask = CLOCKSOURCE_MASK(64),
89 .shift = 22,
90 .mult = 0, /* To be filled in */
91 .read = rtc_read, 89 .read = rtc_read,
92}; 90};
93 91
@@ -97,8 +95,6 @@ static struct clocksource clocksource_timebase = {
97 .rating = 400, 95 .rating = 400,
98 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 96 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
99 .mask = CLOCKSOURCE_MASK(64), 97 .mask = CLOCKSOURCE_MASK(64),
100 .shift = 22,
101 .mult = 0, /* To be filled in */
102 .read = timebase_read, 98 .read = timebase_read,
103}; 99};
104 100
@@ -110,22 +106,16 @@ static void decrementer_set_mode(enum clock_event_mode mode,
110 struct clock_event_device *dev); 106 struct clock_event_device *dev);
111 107
112static struct clock_event_device decrementer_clockevent = { 108static struct clock_event_device decrementer_clockevent = {
113 .name = "decrementer", 109 .name = "decrementer",
114 .rating = 200, 110 .rating = 200,
115 .shift = 0, /* To be filled in */ 111 .irq = 0,
116 .mult = 0, /* To be filled in */ 112 .set_next_event = decrementer_set_next_event,
117 .irq = 0, 113 .set_mode = decrementer_set_mode,
118 .set_next_event = decrementer_set_next_event, 114 .features = CLOCK_EVT_FEAT_ONESHOT,
119 .set_mode = decrementer_set_mode,
120 .features = CLOCK_EVT_FEAT_ONESHOT,
121}; 115};
122 116
123struct decrementer_clock { 117DEFINE_PER_CPU(u64, decrementers_next_tb);
124 struct clock_event_device event; 118static DEFINE_PER_CPU(struct clock_event_device, decrementers);
125 u64 next_tb;
126};
127
128static DEFINE_PER_CPU(struct decrementer_clock, decrementers);
129 119
130#ifdef CONFIG_PPC_ISERIES 120#ifdef CONFIG_PPC_ISERIES
131static unsigned long __initdata iSeries_recal_titan; 121static unsigned long __initdata iSeries_recal_titan;
@@ -168,13 +158,13 @@ EXPORT_SYMBOL_GPL(ppc_tb_freq);
168#ifdef CONFIG_VIRT_CPU_ACCOUNTING 158#ifdef CONFIG_VIRT_CPU_ACCOUNTING
169/* 159/*
170 * Factors for converting from cputime_t (timebase ticks) to 160 * Factors for converting from cputime_t (timebase ticks) to
171 * jiffies, milliseconds, seconds, and clock_t (1/USER_HZ seconds). 161 * jiffies, microseconds, seconds, and clock_t (1/USER_HZ seconds).
172 * These are all stored as 0.64 fixed-point binary fractions. 162 * These are all stored as 0.64 fixed-point binary fractions.
173 */ 163 */
174u64 __cputime_jiffies_factor; 164u64 __cputime_jiffies_factor;
175EXPORT_SYMBOL(__cputime_jiffies_factor); 165EXPORT_SYMBOL(__cputime_jiffies_factor);
176u64 __cputime_msec_factor; 166u64 __cputime_usec_factor;
177EXPORT_SYMBOL(__cputime_msec_factor); 167EXPORT_SYMBOL(__cputime_usec_factor);
178u64 __cputime_sec_factor; 168u64 __cputime_sec_factor;
179EXPORT_SYMBOL(__cputime_sec_factor); 169EXPORT_SYMBOL(__cputime_sec_factor);
180u64 __cputime_clockt_factor; 170u64 __cputime_clockt_factor;
@@ -192,8 +182,8 @@ static void calc_cputime_factors(void)
192 182
193 div128_by_32(HZ, 0, tb_ticks_per_sec, &res); 183 div128_by_32(HZ, 0, tb_ticks_per_sec, &res);
194 __cputime_jiffies_factor = res.result_low; 184 __cputime_jiffies_factor = res.result_low;
195 div128_by_32(1000, 0, tb_ticks_per_sec, &res); 185 div128_by_32(1000000, 0, tb_ticks_per_sec, &res);
196 __cputime_msec_factor = res.result_low; 186 __cputime_usec_factor = res.result_low;
197 div128_by_32(1, 0, tb_ticks_per_sec, &res); 187 div128_by_32(1, 0, tb_ticks_per_sec, &res);
198 __cputime_sec_factor = res.result_low; 188 __cputime_sec_factor = res.result_low;
199 div128_by_32(USER_HZ, 0, tb_ticks_per_sec, &res); 189 div128_by_32(USER_HZ, 0, tb_ticks_per_sec, &res);
@@ -441,7 +431,7 @@ EXPORT_SYMBOL(profile_pc);
441/* 431/*
442 * This function recalibrates the timebase based on the 49-bit time-of-day 432 * This function recalibrates the timebase based on the 49-bit time-of-day
443 * value in the Titan chip. The Titan is much more accurate than the value 433 * value in the Titan chip. The Titan is much more accurate than the value
444 * returned by the service processor for the timebase frequency. 434 * returned by the service processor for the timebase frequency.
445 */ 435 */
446 436
447static int __init iSeries_tb_recal(void) 437static int __init iSeries_tb_recal(void)
@@ -576,9 +566,8 @@ void arch_irq_work_raise(void)
576void timer_interrupt(struct pt_regs * regs) 566void timer_interrupt(struct pt_regs * regs)
577{ 567{
578 struct pt_regs *old_regs; 568 struct pt_regs *old_regs;
579 struct decrementer_clock *decrementer = &__get_cpu_var(decrementers); 569 u64 *next_tb = &__get_cpu_var(decrementers_next_tb);
580 struct clock_event_device *evt = &decrementer->event; 570 struct clock_event_device *evt = &__get_cpu_var(decrementers);
581 u64 now;
582 571
583 /* Ensure a positive value is written to the decrementer, or else 572 /* Ensure a positive value is written to the decrementer, or else
584 * some CPUs will continue to take decrementer exceptions. 573 * some CPUs will continue to take decrementer exceptions.
@@ -613,16 +602,9 @@ void timer_interrupt(struct pt_regs * regs)
613 get_lppaca()->int_dword.fields.decr_int = 0; 602 get_lppaca()->int_dword.fields.decr_int = 0;
614#endif 603#endif
615 604
616 now = get_tb_or_rtc(); 605 *next_tb = ~(u64)0;
617 if (now >= decrementer->next_tb) { 606 if (evt->event_handler)
618 decrementer->next_tb = ~(u64)0; 607 evt->event_handler(evt);
619 if (evt->event_handler)
620 evt->event_handler(evt);
621 } else {
622 now = decrementer->next_tb - now;
623 if (now <= DECREMENTER_MAX)
624 set_dec((int)now);
625 }
626 608
627#ifdef CONFIG_PPC_ISERIES 609#ifdef CONFIG_PPC_ISERIES
628 if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending()) 610 if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending())
@@ -650,9 +632,9 @@ static void generic_suspend_disable_irqs(void)
650 * with suspending. 632 * with suspending.
651 */ 633 */
652 634
653 set_dec(0x7fffffff); 635 set_dec(DECREMENTER_MAX);
654 local_irq_disable(); 636 local_irq_disable();
655 set_dec(0x7fffffff); 637 set_dec(DECREMENTER_MAX);
656} 638}
657 639
658static void generic_suspend_enable_irqs(void) 640static void generic_suspend_enable_irqs(void)
@@ -824,9 +806,8 @@ void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
824 ++vdso_data->tb_update_count; 806 ++vdso_data->tb_update_count;
825 smp_mb(); 807 smp_mb();
826 808
827 /* XXX this assumes clock->shift == 22 */ 809 /* 19342813113834067 ~= 2^(20+64) / 1e9 */
828 /* 4611686018 ~= 2^(20+64-22) / 1e9 */ 810 new_tb_to_xs = (u64) mult * (19342813113834067ULL >> clock->shift);
829 new_tb_to_xs = (u64) mult * 4611686018ULL;
830 new_stamp_xsec = (u64) wall_time->tv_nsec * XSEC_PER_SEC; 811 new_stamp_xsec = (u64) wall_time->tv_nsec * XSEC_PER_SEC;
831 do_div(new_stamp_xsec, 1000000000); 812 do_div(new_stamp_xsec, 1000000000);
832 new_stamp_xsec += (u64) wall_time->tv_sec * XSEC_PER_SEC; 813 new_stamp_xsec += (u64) wall_time->tv_sec * XSEC_PER_SEC;
@@ -877,9 +858,7 @@ static void __init clocksource_init(void)
877 else 858 else
878 clock = &clocksource_timebase; 859 clock = &clocksource_timebase;
879 860
880 clock->mult = clocksource_hz2mult(tb_ticks_per_sec, clock->shift); 861 if (clocksource_register_hz(clock, tb_ticks_per_sec)) {
881
882 if (clocksource_register(clock)) {
883 printk(KERN_ERR "clocksource: %s is already registered\n", 862 printk(KERN_ERR "clocksource: %s is already registered\n",
884 clock->name); 863 clock->name);
885 return; 864 return;
@@ -892,7 +871,7 @@ static void __init clocksource_init(void)
892static int decrementer_set_next_event(unsigned long evt, 871static int decrementer_set_next_event(unsigned long evt,
893 struct clock_event_device *dev) 872 struct clock_event_device *dev)
894{ 873{
895 __get_cpu_var(decrementers).next_tb = get_tb_or_rtc() + evt; 874 __get_cpu_var(decrementers_next_tb) = get_tb_or_rtc() + evt;
896 set_dec(evt); 875 set_dec(evt);
897 return 0; 876 return 0;
898} 877}
@@ -904,34 +883,9 @@ static void decrementer_set_mode(enum clock_event_mode mode,
904 decrementer_set_next_event(DECREMENTER_MAX, dev); 883 decrementer_set_next_event(DECREMENTER_MAX, dev);
905} 884}
906 885
907static inline uint64_t div_sc64(unsigned long ticks, unsigned long nsec,
908 int shift)
909{
910 uint64_t tmp = ((uint64_t)ticks) << shift;
911
912 do_div(tmp, nsec);
913 return tmp;
914}
915
916static void __init setup_clockevent_multiplier(unsigned long hz)
917{
918 u64 mult, shift = 32;
919
920 while (1) {
921 mult = div_sc64(hz, NSEC_PER_SEC, shift);
922 if (mult && (mult >> 32UL) == 0UL)
923 break;
924
925 shift--;
926 }
927
928 decrementer_clockevent.shift = shift;
929 decrementer_clockevent.mult = mult;
930}
931
932static void register_decrementer_clockevent(int cpu) 886static void register_decrementer_clockevent(int cpu)
933{ 887{
934 struct clock_event_device *dec = &per_cpu(decrementers, cpu).event; 888 struct clock_event_device *dec = &per_cpu(decrementers, cpu);
935 889
936 *dec = decrementer_clockevent; 890 *dec = decrementer_clockevent;
937 dec->cpumask = cpumask_of(cpu); 891 dec->cpumask = cpumask_of(cpu);
@@ -946,7 +900,8 @@ static void __init init_decrementer_clockevent(void)
946{ 900{
947 int cpu = smp_processor_id(); 901 int cpu = smp_processor_id();
948 902
949 setup_clockevent_multiplier(ppc_tb_freq); 903 clockevents_calc_mult_shift(&decrementer_clockevent, ppc_tb_freq, 4);
904
950 decrementer_clockevent.max_delta_ns = 905 decrementer_clockevent.max_delta_ns =
951 clockevent_delta2ns(DECREMENTER_MAX, &decrementer_clockevent); 906 clockevent_delta2ns(DECREMENTER_MAX, &decrementer_clockevent);
952 decrementer_clockevent.min_delta_ns = 907 decrementer_clockevent.min_delta_ns =
@@ -1014,10 +969,10 @@ void __init time_init(void)
1014 boot_tb = get_tb_or_rtc(); 969 boot_tb = get_tb_or_rtc();
1015 970
1016 /* If platform provided a timezone (pmac), we correct the time */ 971 /* If platform provided a timezone (pmac), we correct the time */
1017 if (timezone_offset) { 972 if (timezone_offset) {
1018 sys_tz.tz_minuteswest = -timezone_offset / 60; 973 sys_tz.tz_minuteswest = -timezone_offset / 60;
1019 sys_tz.tz_dsttime = 0; 974 sys_tz.tz_dsttime = 0;
1020 } 975 }
1021 976
1022 vdso_data->tb_update_count = 0; 977 vdso_data->tb_update_count = 0;
1023 vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; 978 vdso_data->tb_ticks_per_sec = tb_ticks_per_sec;