Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzi...
[pandora-kernel.git] / arch / arm / plat-versatile / sched-clock.c
index 9768cf7..3d6a4c2 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <linux/cnt32_to_63.h>
 #include <linux/io.h>
-#include <asm/div64.h>
+#include <linux/sched.h>
 
-#include <mach/hardware.h>
-#include <mach/platform.h>
+#include <asm/sched_clock.h>
+#include <plat/sched_clock.h>
 
-#ifdef VERSATILE_SYS_BASE
-#define REFCOUNTER     (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
-#endif
-
-#ifdef REALVIEW_SYS_BASE
-#define REFCOUNTER     (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
-#endif
+static DEFINE_CLOCK_DATA(cd);
+static void __iomem *ctr;
 
 /*
- * This is the Realview and Versatile sched_clock implementation.  This
- * has a resolution of 41.7ns, and a maximum value of about 35583 days.
- *
- * The return value is guaranteed to be monotonic in that range as
- * long as there is always less than 89 seconds between successive
- * calls to this function.
+ * Constants generated by clocks_calc_mult_shift(m, s, 24MHz, NSEC_PER_SEC, 60).
+ * This gives a resolution of about 41ns and a wrap period of about 178s.
  */
-unsigned long long sched_clock(void)
+#define SC_MULT                2796202667u
+#define SC_SHIFT       26
+
+unsigned long long notrace sched_clock(void)
 {
-       unsigned long long v = cnt32_to_63(readl(REFCOUNTER));
+       if (ctr) {
+               u32 cyc = readl(ctr);
+               return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0,
+                                               SC_MULT, SC_SHIFT);
+       } else
+               return 0;
+}
 
-       /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */
-       v *= 125<<1;
-       do_div(v, 3<<1);
+static void notrace versatile_update_sched_clock(void)
+{
+       u32 cyc = readl(ctr);
+       update_sched_clock(&cd, cyc, (u32)~0);
+}
 
-       return v;
+void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate)
+{
+       ctr = reg;
+       init_fixed_sched_clock(&cd, versatile_update_sched_clock,
+                              32, rate, SC_MULT, SC_SHIFT);
 }