1 /* 2 * Copyright IBM Corp. 2004 3 * 4 * Author: Martin Schwidefsky <schwidefsky@de.ibm.com> 5 */ 6 7 #ifndef _S390_CPUTIME_H 8 #define _S390_CPUTIME_H 9 10 #include <linux/types.h> 11 #include <linux/percpu.h> 12 #include <linux/spinlock.h> 13 #include <asm/div64.h> 14 15 /* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */ 16 17 typedef unsigned long long __nocast cputime_t; 18 typedef unsigned long long __nocast cputime64_t; 19 20 static inline unsigned long __div(unsigned long long n, unsigned long base) 21 { 22 #ifndef CONFIG_64BIT 23 register_pair rp; 24 25 rp.pair = n >> 1; 26 asm ("dr %0,%1" : "+d" (rp) : "d" (base >> 1)); 27 return rp.subreg.odd; 28 #else /* CONFIG_64BIT */ 29 return n / base; 30 #endif /* CONFIG_64BIT */ 31 } 32 33 #define cputime_one_jiffy jiffies_to_cputime(1) 34 35 /* 36 * Convert cputime to jiffies and back. 37 */ 38 static inline unsigned long cputime_to_jiffies(const cputime_t cputime) 39 { 40 return __div((__force unsigned long long) cputime, 4096000000ULL / HZ); 41 } 42 43 static inline cputime_t jiffies_to_cputime(const unsigned int jif) 44 { 45 return (__force cputime_t)(jif * (4096000000ULL / HZ)); 46 } 47 48 static inline u64 cputime64_to_jiffies64(cputime64_t cputime) 49 { 50 unsigned long long jif = (__force unsigned long long) cputime; 51 do_div(jif, 4096000000ULL / HZ); 52 return jif; 53 } 54 55 static inline cputime64_t jiffies64_to_cputime64(const u64 jif) 56 { 57 return (__force cputime64_t)(jif * (4096000000ULL / HZ)); 58 } 59 60 /* 61 * Convert cputime to microseconds and back. 62 */ 63 static inline unsigned int cputime_to_usecs(const cputime_t cputime) 64 { 65 return (__force unsigned long long) cputime >> 12; 66 } 67 68 static inline cputime_t usecs_to_cputime(const unsigned int m) 69 { 70 return (__force cputime_t)(m * 4096ULL); 71 } 72 73 #define usecs_to_cputime64(m) usecs_to_cputime(m) 74 75 /* 76 * Convert cputime to milliseconds and back. 77 */ 78 static inline unsigned int cputime_to_secs(const cputime_t cputime) 79 { 80 return __div((__force unsigned long long) cputime, 2048000000) >> 1; 81 } 82 83 static inline cputime_t secs_to_cputime(const unsigned int s) 84 { 85 return (__force cputime_t)(s * 4096000000ULL); 86 } 87 88 /* 89 * Convert cputime to timespec and back. 90 */ 91 static inline cputime_t timespec_to_cputime(const struct timespec *value) 92 { 93 unsigned long long ret = value->tv_sec * 4096000000ULL; 94 return (__force cputime_t)(ret + value->tv_nsec * 4096 / 1000); 95 } 96 97 static inline void cputime_to_timespec(const cputime_t cputime, 98 struct timespec *value) 99 { 100 unsigned long long __cputime = (__force unsigned long long) cputime; 101 #ifndef CONFIG_64BIT 102 register_pair rp; 103 104 rp.pair = __cputime >> 1; 105 asm ("dr %0,%1" : "+d" (rp) : "d" (2048000000UL)); 106 value->tv_nsec = rp.subreg.even * 1000 / 4096; 107 value->tv_sec = rp.subreg.odd; 108 #else 109 value->tv_nsec = (__cputime % 4096000000ULL) * 1000 / 4096; 110 value->tv_sec = __cputime / 4096000000ULL; 111 #endif 112 } 113 114 /* 115 * Convert cputime to timeval and back. 116 * Since cputime and timeval have the same resolution (microseconds) 117 * this is easy. 118 */ 119 static inline cputime_t timeval_to_cputime(const struct timeval *value) 120 { 121 unsigned long long ret = value->tv_sec * 4096000000ULL; 122 return (__force cputime_t)(ret + value->tv_usec * 4096ULL); 123 } 124 125 static inline void cputime_to_timeval(const cputime_t cputime, 126 struct timeval *value) 127 { 128 unsigned long long __cputime = (__force unsigned long long) cputime; 129 #ifndef CONFIG_64BIT 130 register_pair rp; 131 132 rp.pair = __cputime >> 1; 133 asm ("dr %0,%1" : "+d" (rp) : "d" (2048000000UL)); 134 value->tv_usec = rp.subreg.even / 4096; 135 value->tv_sec = rp.subreg.odd; 136 #else 137 value->tv_usec = (__cputime % 4096000000ULL) / 4096; 138 value->tv_sec = __cputime / 4096000000ULL; 139 #endif 140 } 141 142 /* 143 * Convert cputime to clock and back. 144 */ 145 static inline clock_t cputime_to_clock_t(cputime_t cputime) 146 { 147 unsigned long long clock = (__force unsigned long long) cputime; 148 do_div(clock, 4096000000ULL / USER_HZ); 149 return clock; 150 } 151 152 static inline cputime_t clock_t_to_cputime(unsigned long x) 153 { 154 return (__force cputime_t)(x * (4096000000ULL / USER_HZ)); 155 } 156 157 /* 158 * Convert cputime64 to clock. 159 */ 160 static inline clock_t cputime64_to_clock_t(cputime64_t cputime) 161 { 162 unsigned long long clock = (__force unsigned long long) cputime; 163 do_div(clock, 4096000000ULL / USER_HZ); 164 return clock; 165 } 166 167 struct s390_idle_data { 168 int nohz_delay; 169 unsigned int sequence; 170 unsigned long long idle_count; 171 unsigned long long idle_time; 172 unsigned long long clock_idle_enter; 173 unsigned long long clock_idle_exit; 174 unsigned long long timer_idle_enter; 175 unsigned long long timer_idle_exit; 176 }; 177 178 DECLARE_PER_CPU(struct s390_idle_data, s390_idle); 179 180 cputime64_t s390_get_idle_time(int cpu); 181 182 #define arch_idle_time(cpu) s390_get_idle_time(cpu) 183 184 static inline int s390_nohz_delay(int cpu) 185 { 186 return __get_cpu_var(s390_idle).nohz_delay != 0; 187 } 188 189 #define arch_needs_cpu(cpu) s390_nohz_delay(cpu) 190 191 #endif /* _S390_CPUTIME_H */ 192