diff options
Diffstat (limited to 'arch/s390/include/asm/timex.h')
| -rw-r--r-- | arch/s390/include/asm/timex.h | 73 |
1 files changed, 47 insertions, 26 deletions
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index c447a27a7fd..8beee1cceba 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h @@ -1,8 +1,6 @@ /* - * include/asm-s390/timex.h - * * S390 version - * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Copyright IBM Corp. 1999 * * Derived from "include/asm-i386/timex.h" * Copyright (C) 1992, Linus Torvalds @@ -17,7 +15,7 @@ #define TOD_UNIX_EPOCH 0x7d91048bca000000ULL /* Inline functions for clock register access. */ -static inline int set_clock(__u64 time) +static inline int set_tod_clock(__u64 time) { int cc; @@ -29,7 +27,7 @@ static inline int set_clock(__u64 time) return cc; } -static inline int store_clock(__u64 *time) +static inline int store_tod_clock(__u64 *time) { int cc; @@ -73,40 +71,35 @@ static inline void local_tick_enable(unsigned long long comp) typedef unsigned long long cycles_t; -static inline unsigned long long get_clock (void) +static inline void get_tod_clock_ext(char clk[16]) { - unsigned long long clk; + typedef struct { char _[sizeof(clk)]; } addrtype; - asm volatile("stck %0" : "=Q" (clk) : : "cc"); - return clk; + asm volatile("stcke %0" : "=Q" (*(addrtype *) clk) : : "cc"); } -static inline void get_clock_ext(char *clk) +static inline unsigned long long get_tod_clock(void) { - asm volatile("stcke %0" : "=Q" (*clk) : : "cc"); + unsigned char clk[16]; + get_tod_clock_ext(clk); + return *((unsigned long long *)&clk[1]); } -static inline unsigned long long get_clock_fast(void) +static inline unsigned long long get_tod_clock_fast(void) { +#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES unsigned long long clk; - if (MACHINE_HAS_STCKF) - asm volatile(".insn s,0xb27c0000,%0" : "=Q" (clk) : : "cc"); - else - clk = get_clock(); + asm volatile("stckf %0" : "=Q" (clk) : : "cc"); return clk; -} - -static inline unsigned long long get_clock_xt(void) -{ - unsigned char clk[16]; - get_clock_ext(clk); - return *((unsigned long long *)&clk[1]); +#else + return get_tod_clock(); +#endif } static inline cycles_t get_cycles(void) { - return (cycles_t) get_clock() >> 2; + return (cycles_t) get_tod_clock() >> 2; } int get_sync_clock(unsigned long long *clock); @@ -132,9 +125,37 @@ extern u64 sched_clock_base_cc; * function, otherwise the returned value is not guaranteed to * be monotonic. */ -static inline unsigned long long get_clock_monotonic(void) +static inline unsigned long long get_tod_clock_monotonic(void) { - return get_clock_xt() - sched_clock_base_cc; + return get_tod_clock() - sched_clock_base_cc; +} + +/** + * tod_to_ns - convert a TOD format value to nanoseconds + * @todval: to be converted TOD format value + * Returns: number of nanoseconds that correspond to the TOD format value + * + * Converting a 64 Bit TOD format value to nanoseconds means that the value + * must be divided by 4.096. In order to achieve that we multiply with 125 + * and divide by 512: + * + * ns = (todval * 125) >> 9; + * + * In order to avoid an overflow with the multiplication we can rewrite this. + * With a split todval == 2^32 * th + tl (th upper 32 bits, tl lower 32 bits) + * we end up with + * + * ns = ((2^32 * th + tl) * 125 ) >> 9; + * -> ns = (2^23 * th * 125) + ((tl * 125) >> 9); + * + */ +static inline unsigned long long tod_to_ns(unsigned long long todval) +{ + unsigned long long ns; + + ns = ((todval >> 32) << 23) * 125; + ns += ((todval & 0xffffffff) * 125) >> 9; + return ns; } #endif |
