[S390] introduce vdso on s390
[pandora-kernel.git] / arch / s390 / kernel / time.c
index b94e9e3..b73bbf3 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/delay.h>
 #include <asm/s390_ext.h>
 #include <asm/div64.h>
+#include <asm/vdso.h>
 #include <asm/irq.h>
 #include <asm/irq_regs.h>
 #include <asm/timer.h>
@@ -59,7 +60,7 @@
 
 static ext_int_info_t ext_int_info_cc;
 static ext_int_info_t ext_int_etr_cc;
-static u64 jiffies_timer_cc;
+static u64 sched_clock_base_cc;
 
 static DEFINE_PER_CPU(struct clock_event_device, comparators);
 
@@ -68,7 +69,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators);
  */
 unsigned long long sched_clock(void)
 {
-       return ((get_clock_xt() - jiffies_timer_cc) * 125) >> 9;
+       return ((get_clock_xt() - sched_clock_base_cc) * 125) >> 9;
 }
 
 /*
@@ -223,19 +224,46 @@ static struct clocksource clocksource_tod = {
 };
 
 
+void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
+{
+       if (clock != &clocksource_tod)
+               return;
+
+       /* Make userspace gettimeofday spin until we're done. */
+       ++vdso_data->tb_update_count;
+       smp_wmb();
+       vdso_data->xtime_tod_stamp = clock->cycle_last;
+       vdso_data->xtime_clock_sec = xtime.tv_sec;
+       vdso_data->xtime_clock_nsec = xtime.tv_nsec;
+       vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
+       vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
+       smp_wmb();
+       ++vdso_data->tb_update_count;
+}
+
+extern struct timezone sys_tz;
+
+void update_vsyscall_tz(void)
+{
+       /* Make userspace gettimeofday spin until we're done. */
+       ++vdso_data->tb_update_count;
+       smp_wmb();
+       vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
+       vdso_data->tz_dsttime = sys_tz.tz_dsttime;
+       smp_wmb();
+       ++vdso_data->tb_update_count;
+}
+
 /*
  * Initialize the TOD clock and the CPU timer of
  * the boot cpu.
  */
 void __init time_init(void)
 {
-       u64 init_timer_cc;
-
-       init_timer_cc = reset_tod_clock();
-       jiffies_timer_cc = init_timer_cc - jiffies_64 * CLK_TICKS_PER_JIFFY;
+       sched_clock_base_cc = reset_tod_clock();
 
        /* set xtime */
-       tod_to_timeval(init_timer_cc - TOD_UNIX_EPOCH, &xtime);
+       tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &xtime);
         set_normalized_timespec(&wall_to_monotonic,
                                 -xtime.tv_sec, -xtime.tv_nsec);
 
@@ -289,7 +317,7 @@ static unsigned long long adjust_time(unsigned long long old,
                delta = -delta;
                adjust.offset = -ticks * (1000000 / HZ);
        }
-       jiffies_timer_cc += delta;
+       sched_clock_base_cc += delta;
        if (adjust.offset != 0) {
                printk(KERN_NOTICE "etr: time adjusted by %li micro-seconds\n",
                       adjust.offset);