xref: /openbmc/linux/arch/s390/include/asm/cputime.h (revision 7e035230)
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