Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab...
[pandora-kernel.git] / kernel / time.c
index 2f47888..ffe1914 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/timex.h>
 #include <linux/capability.h>
 #include <linux/errno.h>
-#include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/security.h>
 #include <linux/fs.h>
@@ -58,14 +57,17 @@ EXPORT_SYMBOL(sys_tz);
  */
 asmlinkage long sys_time(time_t __user * tloc)
 {
-       time_t i;
-       struct timeval tv;
+       /*
+        * We read xtime.tv_sec atomically - it's updated
+        * atomically by update_wall_time(), so no need to
+        * even read-lock the xtime seqlock:
+        */
+       time_t i = xtime.tv_sec;
 
-       do_gettimeofday(&tv);
-       i = tv.tv_sec;
+       smp_rmb(); /* sys_time() results are coherent */
 
        if (tloc) {
-               if (put_user(i,tloc))
+               if (put_user(i, tloc))
                        i = -EFAULT;
        }
        return i;
@@ -247,6 +249,36 @@ struct timespec current_fs_time(struct super_block *sb)
 }
 EXPORT_SYMBOL(current_fs_time);
 
+/*
+ * Convert jiffies to milliseconds and back.
+ *
+ * Avoid unnecessary multiplications/divisions in the
+ * two most common HZ cases:
+ */
+unsigned int inline jiffies_to_msecs(const unsigned long j)
+{
+#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+       return (MSEC_PER_SEC / HZ) * j;
+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
+       return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
+#else
+       return (j * MSEC_PER_SEC) / HZ;
+#endif
+}
+EXPORT_SYMBOL(jiffies_to_msecs);
+
+unsigned int inline jiffies_to_usecs(const unsigned long j)
+{
+#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
+       return (USEC_PER_SEC / HZ) * j;
+#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
+       return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
+#else
+       return (j * USEC_PER_SEC) / HZ;
+#endif
+}
+EXPORT_SYMBOL(jiffies_to_usecs);
+
 /**
  * timespec_trunc - Truncate timespec to a granularity
  * @t: Timespec
@@ -344,12 +376,25 @@ void do_gettimeofday (struct timeval *tv)
 
        tv->tv_sec = sec;
        tv->tv_usec = usec;
-}
 
+       /*
+        * Make sure xtime.tv_sec [returned by sys_time()] always
+        * follows the gettimeofday() result precisely. This
+        * condition is extremely unlikely, it can hit at most
+        * once per second:
+        */
+       if (unlikely(xtime.tv_sec != tv->tv_sec)) {
+               unsigned long flags;
+
+               write_seqlock_irqsave(&xtime_lock, flags);
+               update_wall_time();
+               write_sequnlock_irqrestore(&xtime_lock, flags);
+       }
+}
 EXPORT_SYMBOL(do_gettimeofday);
 
+#else  /* CONFIG_TIME_INTERPOLATION */
 
-#else
 #ifndef CONFIG_GENERIC_TIME
 /*
  * Simulate gettimeofday using do_gettimeofday which only allows a timeval
@@ -365,7 +410,7 @@ void getnstimeofday(struct timespec *tv)
 }
 EXPORT_SYMBOL_GPL(getnstimeofday);
 #endif
-#endif
+#endif /* CONFIG_TIME_INTERPOLATION */
 
 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
  * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
@@ -452,6 +497,7 @@ struct timespec ns_to_timespec(const s64 nsec)
 
        return ts;
 }
+EXPORT_SYMBOL(ns_to_timespec);
 
 /**
  * ns_to_timeval - Convert nanoseconds to timeval
@@ -469,36 +515,7 @@ struct timeval ns_to_timeval(const s64 nsec)
 
        return tv;
 }
-
-/*
- * Convert jiffies to milliseconds and back.
- *
- * Avoid unnecessary multiplications/divisions in the
- * two most common HZ cases:
- */
-unsigned int jiffies_to_msecs(const unsigned long j)
-{
-#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
-       return (MSEC_PER_SEC / HZ) * j;
-#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
-       return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
-#else
-       return (j * MSEC_PER_SEC) / HZ;
-#endif
-}
-EXPORT_SYMBOL(jiffies_to_msecs);
-
-unsigned int jiffies_to_usecs(const unsigned long j)
-{
-#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
-       return (USEC_PER_SEC / HZ) * j;
-#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
-       return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
-#else
-       return (j * USEC_PER_SEC) / HZ;
-#endif
-}
-EXPORT_SYMBOL(jiffies_to_usecs);
+EXPORT_SYMBOL(ns_to_timeval);
 
 /*
  * When we convert to jiffies then we interpret incoming values