aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/class.c3
-rw-r--r--drivers/rtc/rtc-core.h1
-rw-r--r--drivers/rtc/rtc-efi-platform.c1
-rw-r--r--drivers/rtc/rtc-sa1100.h1
-rw-r--r--drivers/rtc/systohc.c53
6 files changed, 45 insertions, 15 deletions
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 7230014c92af..0bf1fc02b82c 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -1,3 +1,4 @@
1# SPDX-License-Identifier: GPL-2.0
1# 2#
2# Makefile for RTC class/drivers. 3# Makefile for RTC class/drivers.
3# 4#
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 2ed970d61da1..722d683e0b0f 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -161,6 +161,9 @@ static struct rtc_device *rtc_allocate_device(void)
161 161
162 device_initialize(&rtc->dev); 162 device_initialize(&rtc->dev);
163 163
164 /* Drivers can revise this default after allocating the device. */
165 rtc->set_offset_nsec = NSEC_PER_SEC / 2;
166
164 rtc->irq_freq = 1; 167 rtc->irq_freq = 1;
165 rtc->max_user_freq = 64; 168 rtc->max_user_freq = 64;
166 rtc->dev.class = rtc_class; 169 rtc->dev.class = rtc_class;
diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h
index ecab76a3207c..513b9bedd2c8 100644
--- a/drivers/rtc/rtc-core.h
+++ b/drivers/rtc/rtc-core.h
@@ -1,3 +1,4 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1#ifdef CONFIG_RTC_INTF_DEV 2#ifdef CONFIG_RTC_INTF_DEV
2 3
3extern void __init rtc_dev_init(void); 4extern void __init rtc_dev_init(void);
diff --git a/drivers/rtc/rtc-efi-platform.c b/drivers/rtc/rtc-efi-platform.c
index 1a7f1d1bc174..6c037dc4e3dc 100644
--- a/drivers/rtc/rtc-efi-platform.c
+++ b/drivers/rtc/rtc-efi-platform.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Moved from arch/ia64/kernel/time.c 3 * Moved from arch/ia64/kernel/time.c
3 * 4 *
diff --git a/drivers/rtc/rtc-sa1100.h b/drivers/rtc/rtc-sa1100.h
index 2c79c0c57822..cc724f5b07bc 100644
--- a/drivers/rtc/rtc-sa1100.h
+++ b/drivers/rtc/rtc-sa1100.h
@@ -1,3 +1,4 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1#ifndef __RTC_SA1100_H__ 2#ifndef __RTC_SA1100_H__
2#define __RTC_SA1100_H__ 3#define __RTC_SA1100_H__
3 4
diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c
index b4a68ffcd06b..0c177647ea6c 100644
--- a/drivers/rtc/systohc.c
+++ b/drivers/rtc/systohc.c
@@ -10,6 +10,7 @@
10/** 10/**
11 * rtc_set_ntp_time - Save NTP synchronized time to the RTC 11 * rtc_set_ntp_time - Save NTP synchronized time to the RTC
12 * @now: Current time of day 12 * @now: Current time of day
13 * @target_nsec: pointer for desired now->tv_nsec value
13 * 14 *
14 * Replacement for the NTP platform function update_persistent_clock64 15 * Replacement for the NTP platform function update_persistent_clock64
15 * that stores time for later retrieval by rtc_hctosys. 16 * that stores time for later retrieval by rtc_hctosys.
@@ -18,30 +19,52 @@
18 * possible at all, and various other -errno for specific temporary failure 19 * possible at all, and various other -errno for specific temporary failure
19 * cases. 20 * cases.
20 * 21 *
22 * -EPROTO is returned if now.tv_nsec is not close enough to *target_nsec.
23 (
21 * If temporary failure is indicated the caller should try again 'soon' 24 * If temporary failure is indicated the caller should try again 'soon'
22 */ 25 */
23int rtc_set_ntp_time(struct timespec64 now) 26int rtc_set_ntp_time(struct timespec64 now, unsigned long *target_nsec)
24{ 27{
25 struct rtc_device *rtc; 28 struct rtc_device *rtc;
26 struct rtc_time tm; 29 struct rtc_time tm;
30 struct timespec64 to_set;
27 int err = -ENODEV; 31 int err = -ENODEV;
28 32 bool ok;
29 if (now.tv_nsec < (NSEC_PER_SEC >> 1))
30 rtc_time64_to_tm(now.tv_sec, &tm);
31 else
32 rtc_time64_to_tm(now.tv_sec + 1, &tm);
33 33
34 rtc = rtc_class_open(CONFIG_RTC_SYSTOHC_DEVICE); 34 rtc = rtc_class_open(CONFIG_RTC_SYSTOHC_DEVICE);
35 if (rtc) { 35 if (!rtc)
36 /* rtc_hctosys exclusively uses UTC, so we call set_time here, 36 goto out_err;
37 * not set_mmss. */ 37
38 if (rtc->ops && 38 if (!rtc->ops || (!rtc->ops->set_time && !rtc->ops->set_mmss64 &&
39 (rtc->ops->set_time || 39 !rtc->ops->set_mmss))
40 rtc->ops->set_mmss64 || 40 goto out_close;
41 rtc->ops->set_mmss)) 41
42 err = rtc_set_time(rtc, &tm); 42 /* Compute the value of tv_nsec we require the caller to supply in
43 rtc_class_close(rtc); 43 * now.tv_nsec. This is the value such that (now +
44 * set_offset_nsec).tv_nsec == 0.
45 */
46 set_normalized_timespec64(&to_set, 0, -rtc->set_offset_nsec);
47 *target_nsec = to_set.tv_nsec;
48
49 /* The ntp code must call this with the correct value in tv_nsec, if
50 * it does not we update target_nsec and return EPROTO to make the ntp
51 * code try again later.
52 */
53 ok = rtc_tv_nsec_ok(rtc->set_offset_nsec, &to_set, &now);
54 if (!ok) {
55 err = -EPROTO;
56 goto out_close;
44 } 57 }
45 58
59 rtc_time64_to_tm(to_set.tv_sec, &tm);
60
61 /* rtc_hctosys exclusively uses UTC, so we call set_time here, not
62 * set_mmss.
63 */
64 err = rtc_set_time(rtc, &tm);
65
66out_close:
67 rtc_class_close(rtc);
68out_err:
46 return err; 69 return err;
47} 70}