aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/hrtimer.h9
-rw-r--r--include/linux/time.h2
-rw-r--r--kernel/time/hrtimer.c19
-rw-r--r--kernel/time/timekeeping.c36
4 files changed, 37 insertions, 29 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index bb4ffff31c69..e84eb4f228cd 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -331,9 +331,12 @@ extern ktime_t ktime_get_real(void);
331extern ktime_t ktime_get_boottime(void); 331extern ktime_t ktime_get_boottime(void);
332extern ktime_t ktime_get_monotonic_offset(void); 332extern ktime_t ktime_get_monotonic_offset(void);
333extern ktime_t ktime_get_clocktai(void); 333extern ktime_t ktime_get_clocktai(void);
334extern ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot, 334extern ktime_t ktime_get_update_offsets_tick(ktime_t *offs_real,
335 ktime_t *offs_tai); 335 ktime_t *offs_boot,
336 336 ktime_t *offs_tai);
337extern ktime_t ktime_get_update_offsets_now(ktime_t *offs_real,
338 ktime_t *offs_boot,
339 ktime_t *offs_tai);
337DECLARE_PER_CPU(struct tick_device, tick_cpu_device); 340DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
338 341
339 342
diff --git a/include/linux/time.h b/include/linux/time.h
index d5d229b2e5af..f6d990d1c79a 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -133,8 +133,6 @@ unsigned long get_seconds(void);
133struct timespec current_kernel_time(void); 133struct timespec current_kernel_time(void);
134struct timespec __current_kernel_time(void); /* does not take xtime_lock */ 134struct timespec __current_kernel_time(void); /* does not take xtime_lock */
135struct timespec get_monotonic_coarse(void); 135struct timespec get_monotonic_coarse(void);
136void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim,
137 struct timespec *wtom, struct timespec *sleep);
138void timekeeping_inject_sleeptime(struct timespec *delta); 136void timekeeping_inject_sleeptime(struct timespec *delta);
139 137
140#define CURRENT_TIME (current_kernel_time()) 138#define CURRENT_TIME (current_kernel_time())
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 66a6dc1075ad..2f4ef8a1e5ff 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -114,21 +114,18 @@ static inline int hrtimer_clockid_to_base(clockid_t clock_id)
114 */ 114 */
115static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) 115static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)
116{ 116{
117 ktime_t xtim, mono, boot; 117 ktime_t xtim, mono, boot, tai;
118 struct timespec xts, tom, slp; 118 ktime_t off_real, off_boot, off_tai;
119 s32 tai_offset;
120 119
121 get_xtime_and_monotonic_and_sleep_offset(&xts, &tom, &slp); 120 mono = ktime_get_update_offsets_tick(&off_real, &off_boot, &off_tai);
122 tai_offset = timekeeping_get_tai_offset(); 121 boot = ktime_add(mono, off_boot);
122 xtim = ktime_add(mono, off_real);
123 tai = ktime_add(xtim, off_tai);
123 124
124 xtim = timespec_to_ktime(xts);
125 mono = ktime_add(xtim, timespec_to_ktime(tom));
126 boot = ktime_add(mono, timespec_to_ktime(slp));
127 base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim; 125 base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim;
128 base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono; 126 base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono;
129 base->clock_base[HRTIMER_BASE_BOOTTIME].softirq_time = boot; 127 base->clock_base[HRTIMER_BASE_BOOTTIME].softirq_time = boot;
130 base->clock_base[HRTIMER_BASE_TAI].softirq_time = 128 base->clock_base[HRTIMER_BASE_TAI].softirq_time = tai;
131 ktime_add(xtim, ktime_set(tai_offset, 0));
132} 129}
133 130
134/* 131/*
@@ -673,7 +670,7 @@ static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base)
673 ktime_t *offs_boot = &base->clock_base[HRTIMER_BASE_BOOTTIME].offset; 670 ktime_t *offs_boot = &base->clock_base[HRTIMER_BASE_BOOTTIME].offset;
674 ktime_t *offs_tai = &base->clock_base[HRTIMER_BASE_TAI].offset; 671 ktime_t *offs_tai = &base->clock_base[HRTIMER_BASE_TAI].offset;
675 672
676 return ktime_get_update_offsets(offs_real, offs_boot, offs_tai); 673 return ktime_get_update_offsets_now(offs_real, offs_boot, offs_tai);
677} 674}
678 675
679/* 676/*
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 908861c58e62..b94fa3652aaa 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1581,29 +1581,39 @@ void do_timer(unsigned long ticks)
1581} 1581}
1582 1582
1583/** 1583/**
1584 * get_xtime_and_monotonic_and_sleep_offset() - get xtime, wall_to_monotonic, 1584 * ktime_get_update_offsets_tick - hrtimer helper
1585 * and sleep offsets. 1585 * @offs_real: pointer to storage for monotonic -> realtime offset
1586 * @xtim: pointer to timespec to be set with xtime 1586 * @offs_boot: pointer to storage for monotonic -> boottime offset
1587 * @wtom: pointer to timespec to be set with wall_to_monotonic 1587 * @offs_tai: pointer to storage for monotonic -> clock tai offset
1588 * @sleep: pointer to timespec to be set with time in suspend 1588 *
1589 * Returns monotonic time at last tick and various offsets
1589 */ 1590 */
1590void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, 1591ktime_t ktime_get_update_offsets_tick(ktime_t *offs_real, ktime_t *offs_boot,
1591 struct timespec *wtom, struct timespec *sleep) 1592 ktime_t *offs_tai)
1592{ 1593{
1593 struct timekeeper *tk = &timekeeper; 1594 struct timekeeper *tk = &timekeeper;
1594 unsigned long seq; 1595 struct timespec ts;
1596 ktime_t now;
1597 unsigned int seq;
1595 1598
1596 do { 1599 do {
1597 seq = read_seqcount_begin(&timekeeper_seq); 1600 seq = read_seqcount_begin(&timekeeper_seq);
1598 *xtim = tk_xtime(tk); 1601
1599 *wtom = tk->wall_to_monotonic; 1602 ts = tk_xtime(tk);
1600 *sleep = tk->total_sleep_time; 1603
1604 *offs_real = tk->offs_real;
1605 *offs_boot = tk->offs_boot;
1606 *offs_tai = tk->offs_tai;
1601 } while (read_seqcount_retry(&timekeeper_seq, seq)); 1607 } while (read_seqcount_retry(&timekeeper_seq, seq));
1608
1609 now = ktime_set(ts.tv_sec, ts.tv_nsec);
1610 now = ktime_sub(now, *offs_real);
1611 return now;
1602} 1612}
1603 1613
1604#ifdef CONFIG_HIGH_RES_TIMERS 1614#ifdef CONFIG_HIGH_RES_TIMERS
1605/** 1615/**
1606 * ktime_get_update_offsets - hrtimer helper 1616 * ktime_get_update_offsets_now - hrtimer helper
1607 * @offs_real: pointer to storage for monotonic -> realtime offset 1617 * @offs_real: pointer to storage for monotonic -> realtime offset
1608 * @offs_boot: pointer to storage for monotonic -> boottime offset 1618 * @offs_boot: pointer to storage for monotonic -> boottime offset
1609 * @offs_tai: pointer to storage for monotonic -> clock tai offset 1619 * @offs_tai: pointer to storage for monotonic -> clock tai offset
@@ -1611,7 +1621,7 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim,
1611 * Returns current monotonic time and updates the offsets 1621 * Returns current monotonic time and updates the offsets
1612 * Called from hrtimer_interrupt() or retrigger_next_event() 1622 * Called from hrtimer_interrupt() or retrigger_next_event()
1613 */ 1623 */
1614ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot, 1624ktime_t ktime_get_update_offsets_now(ktime_t *offs_real, ktime_t *offs_boot,
1615 ktime_t *offs_tai) 1625 ktime_t *offs_tai)
1616{ 1626{
1617 struct timekeeper *tk = &timekeeper; 1627 struct timekeeper *tk = &timekeeper;