blob: 023d5ae24482f188b984e269923471649c71502a [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Heiko Carstensa53c8fa2012-07-20 11:15:04 +02002 * Copyright IBM Corp. 2004
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 *
4 * Author: Martin Schwidefsky <schwidefsky@de.ibm.com>
5 */
6
7#ifndef _S390_CPUTIME_H
8#define _S390_CPUTIME_H
9
Martin Schwidefsky76d4e002009-06-12 10:26:21 +020010#include <linux/types.h>
11#include <linux/percpu.h>
12#include <linux/spinlock.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <asm/div64.h>
14
Frederic Weisbeckera7e1a9e2012-09-08 16:14:02 +020015
16#define __ARCH_HAS_VTIME_ACCOUNT
17
Martin Schwidefskyaa5e97c2008-12-31 15:11:39 +010018/* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070019
Martin Schwidefsky64861632011-12-15 14:56:09 +010020typedef unsigned long long __nocast cputime_t;
21typedef unsigned long long __nocast cputime64_t;
Linus Torvalds1da177e2005-04-16 15:20:36 -070022
Martin Schwidefsky64861632011-12-15 14:56:09 +010023static inline unsigned long __div(unsigned long long n, unsigned long base)
Linus Torvalds1da177e2005-04-16 15:20:36 -070024{
Heiko Carstensf4815ac2012-05-23 16:24:51 +020025#ifndef CONFIG_64BIT
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 register_pair rp;
27
28 rp.pair = n >> 1;
29 asm ("dr %0,%1" : "+d" (rp) : "d" (base >> 1));
30 return rp.subreg.odd;
Heiko Carstensf4815ac2012-05-23 16:24:51 +020031#else /* CONFIG_64BIT */
Linus Torvalds1da177e2005-04-16 15:20:36 -070032 return n / base;
Heiko Carstensf4815ac2012-05-23 16:24:51 +020033#endif /* CONFIG_64BIT */
Linus Torvalds1da177e2005-04-16 15:20:36 -070034}
35
Stanislaw Gruszkaa42548a2009-07-29 12:15:29 +020036#define cputime_one_jiffy jiffies_to_cputime(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -070037
Martin Schwidefsky64861632011-12-15 14:56:09 +010038/*
39 * Convert cputime to jiffies and back.
40 */
41static inline unsigned long cputime_to_jiffies(const cputime_t cputime)
Linus Torvalds1da177e2005-04-16 15:20:36 -070042{
Martin Schwidefsky64861632011-12-15 14:56:09 +010043 return __div((__force unsigned long long) cputime, 4096000000ULL / HZ);
44}
45
46static inline cputime_t jiffies_to_cputime(const unsigned int jif)
47{
48 return (__force cputime_t)(jif * (4096000000ULL / HZ));
49}
50
51static inline u64 cputime64_to_jiffies64(cputime64_t cputime)
52{
53 unsigned long long jif = (__force unsigned long long) cputime;
54 do_div(jif, 4096000000ULL / HZ);
55 return jif;
56}
57
58static inline cputime64_t jiffies64_to_cputime64(const u64 jif)
59{
60 return (__force cputime64_t)(jif * (4096000000ULL / HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -070061}
62
63/*
Michael Holzheud57af9b2010-10-27 15:34:45 -070064 * Convert cputime to microseconds and back.
Linus Torvalds1da177e2005-04-16 15:20:36 -070065 */
Martin Schwidefsky64861632011-12-15 14:56:09 +010066static inline unsigned int cputime_to_usecs(const cputime_t cputime)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067{
Martin Schwidefsky64861632011-12-15 14:56:09 +010068 return (__force unsigned long long) cputime >> 12;
Linus Torvalds1da177e2005-04-16 15:20:36 -070069}
70
Martin Schwidefsky64861632011-12-15 14:56:09 +010071static inline cputime_t usecs_to_cputime(const unsigned int m)
Linus Torvalds1da177e2005-04-16 15:20:36 -070072{
Martin Schwidefsky64861632011-12-15 14:56:09 +010073 return (__force cputime_t)(m * 4096ULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -070074}
75
Andreas Schwab34845632011-12-28 15:57:15 -080076#define usecs_to_cputime64(m) usecs_to_cputime(m)
77
Linus Torvalds1da177e2005-04-16 15:20:36 -070078/*
79 * Convert cputime to milliseconds and back.
80 */
Martin Schwidefsky64861632011-12-15 14:56:09 +010081static inline unsigned int cputime_to_secs(const cputime_t cputime)
Linus Torvalds1da177e2005-04-16 15:20:36 -070082{
Martin Schwidefsky64861632011-12-15 14:56:09 +010083 return __div((__force unsigned long long) cputime, 2048000000) >> 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -070084}
85
Martin Schwidefsky64861632011-12-15 14:56:09 +010086static inline cputime_t secs_to_cputime(const unsigned int s)
Linus Torvalds1da177e2005-04-16 15:20:36 -070087{
Martin Schwidefsky64861632011-12-15 14:56:09 +010088 return (__force cputime_t)(s * 4096000000ULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -070089}
90
91/*
92 * Convert cputime to timespec and back.
93 */
Martin Schwidefsky64861632011-12-15 14:56:09 +010094static inline cputime_t timespec_to_cputime(const struct timespec *value)
Linus Torvalds1da177e2005-04-16 15:20:36 -070095{
Martin Schwidefsky64861632011-12-15 14:56:09 +010096 unsigned long long ret = value->tv_sec * 4096000000ULL;
97 return (__force cputime_t)(ret + value->tv_nsec * 4096 / 1000);
Linus Torvalds1da177e2005-04-16 15:20:36 -070098}
99
Martin Schwidefsky64861632011-12-15 14:56:09 +0100100static inline void cputime_to_timespec(const cputime_t cputime,
101 struct timespec *value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102{
Martin Schwidefsky64861632011-12-15 14:56:09 +0100103 unsigned long long __cputime = (__force unsigned long long) cputime;
Heiko Carstensf4815ac2012-05-23 16:24:51 +0200104#ifndef CONFIG_64BIT
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 register_pair rp;
106
Martin Schwidefsky64861632011-12-15 14:56:09 +0100107 rp.pair = __cputime >> 1;
Martin Schwidefskyaa5e97c2008-12-31 15:11:39 +0100108 asm ("dr %0,%1" : "+d" (rp) : "d" (2048000000UL));
109 value->tv_nsec = rp.subreg.even * 1000 / 4096;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110 value->tv_sec = rp.subreg.odd;
111#else
Martin Schwidefsky64861632011-12-15 14:56:09 +0100112 value->tv_nsec = (__cputime % 4096000000ULL) * 1000 / 4096;
113 value->tv_sec = __cputime / 4096000000ULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114#endif
115}
116
117/*
118 * Convert cputime to timeval and back.
119 * Since cputime and timeval have the same resolution (microseconds)
120 * this is easy.
121 */
Martin Schwidefsky64861632011-12-15 14:56:09 +0100122static inline cputime_t timeval_to_cputime(const struct timeval *value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123{
Martin Schwidefsky64861632011-12-15 14:56:09 +0100124 unsigned long long ret = value->tv_sec * 4096000000ULL;
125 return (__force cputime_t)(ret + value->tv_usec * 4096ULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126}
127
Martin Schwidefsky64861632011-12-15 14:56:09 +0100128static inline void cputime_to_timeval(const cputime_t cputime,
129 struct timeval *value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130{
Martin Schwidefsky64861632011-12-15 14:56:09 +0100131 unsigned long long __cputime = (__force unsigned long long) cputime;
Heiko Carstensf4815ac2012-05-23 16:24:51 +0200132#ifndef CONFIG_64BIT
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133 register_pair rp;
134
Martin Schwidefsky64861632011-12-15 14:56:09 +0100135 rp.pair = __cputime >> 1;
Martin Schwidefskyaa5e97c2008-12-31 15:11:39 +0100136 asm ("dr %0,%1" : "+d" (rp) : "d" (2048000000UL));
137 value->tv_usec = rp.subreg.even / 4096;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 value->tv_sec = rp.subreg.odd;
139#else
Martin Schwidefsky64861632011-12-15 14:56:09 +0100140 value->tv_usec = (__cputime % 4096000000ULL) / 4096;
141 value->tv_sec = __cputime / 4096000000ULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142#endif
143}
144
145/*
146 * Convert cputime to clock and back.
147 */
Martin Schwidefsky64861632011-12-15 14:56:09 +0100148static inline clock_t cputime_to_clock_t(cputime_t cputime)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149{
Martin Schwidefsky64861632011-12-15 14:56:09 +0100150 unsigned long long clock = (__force unsigned long long) cputime;
151 do_div(clock, 4096000000ULL / USER_HZ);
152 return clock;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153}
154
Martin Schwidefsky64861632011-12-15 14:56:09 +0100155static inline cputime_t clock_t_to_cputime(unsigned long x)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156{
Martin Schwidefsky64861632011-12-15 14:56:09 +0100157 return (__force cputime_t)(x * (4096000000ULL / USER_HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158}
159
160/*
161 * Convert cputime64 to clock.
162 */
Martin Schwidefsky64861632011-12-15 14:56:09 +0100163static inline clock_t cputime64_to_clock_t(cputime64_t cputime)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164{
Martin Schwidefsky64861632011-12-15 14:56:09 +0100165 unsigned long long clock = (__force unsigned long long) cputime;
166 do_div(clock, 4096000000ULL / USER_HZ);
167 return clock;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168}
169
Martin Schwidefsky76d4e002009-06-12 10:26:21 +0200170struct s390_idle_data {
Heiko Carstens711d2732012-07-13 16:09:04 +0200171 int nohz_delay;
Martin Schwidefskye98bbaa2009-06-22 12:08:20 +0200172 unsigned int sequence;
Martin Schwidefsky76d4e002009-06-12 10:26:21 +0200173 unsigned long long idle_count;
Martin Schwidefsky76d4e002009-06-12 10:26:21 +0200174 unsigned long long idle_time;
Martin Schwidefsky27f6b412012-07-20 11:15:08 +0200175 unsigned long long clock_idle_enter;
176 unsigned long long clock_idle_exit;
177 unsigned long long timer_idle_enter;
178 unsigned long long timer_idle_exit;
Martin Schwidefsky76d4e002009-06-12 10:26:21 +0200179};
180
181DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
182
Martin Schwidefskye1c80532009-04-23 13:58:08 +0200183cputime64_t s390_get_idle_time(int cpu);
184
185#define arch_idle_time(cpu) s390_get_idle_time(cpu)
186
Martin Schwidefsky3c5d92a2009-09-29 14:25:16 +0200187static inline int s390_nohz_delay(int cpu)
188{
Heiko Carstens37e89522011-01-05 12:47:55 +0100189 return __get_cpu_var(s390_idle).nohz_delay != 0;
Martin Schwidefsky3c5d92a2009-09-29 14:25:16 +0200190}
191
192#define arch_needs_cpu(cpu) s390_nohz_delay(cpu)
193
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194#endif /* _S390_CPUTIME_H */