linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: jgunthorpe@obsidianresearch.com (Jason Gunthorpe)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] NTP: Add a CONFIG_RTC_SYSTOHC configuration
Date: Tue, 11 Dec 2012 22:56:43 -0700	[thread overview]
Message-ID: <20121212055643.GA18078@obsidianresearch.com> (raw)

The purpose of this option is to allow ARM/etc systems that rely on the
class RTC subsystem to have the same kind of automatic NTP based
synchronization that we have on PC platforms. Today ARM does not
implement update_persistent_clock and makes extensive use of the
class RTC system.

When enabled CONFIG_RTC_SYSTOHC will provide a generic
rtc_update_persistent_clock that stores the current time in the RTC
and is intended complement the existing CONFIG_RTC_HCTOSYS option that
loads the RTC at boot.

The option also overrides the call to any platform update_persistent_clock
so that the RTC subsystem completely and generically replaces this
functionality.

Tested on ARM kirkwood and PPC405

Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
---
 drivers/rtc/Kconfig   |    8 ++++++++
 drivers/rtc/Makefile  |    1 +
 drivers/rtc/systohc.c |   30 ++++++++++++++++++++++++++++++
 include/linux/time.h  |    1 +
 kernel/time/ntp.c     |   12 ++++++++++--
 5 files changed, 50 insertions(+), 2 deletions(-)
 create mode 100644 drivers/rtc/systohc.c

I saw on Google an older version of a similar patch to this, but I
couldn't find any indication what happened to it. So here is a
slightly different take, tested on 3.7.

I've been running basically this idea buried in PPC platform specific
code since 2.6.16..

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 19c03ab..30a866a 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -48,6 +48,14 @@ config RTC_HCTOSYS_DEVICE
 	  sleep states. Do not specify an RTC here unless it stays powered
 	  during all this system's supported sleep states.
 
+config RTC_SYSTOHC
+	bool "Set the RTC time based on NTP synchronization"
+	default y
+	help
+	  If you say yes here, the system time (wall clock) will be stored
+          in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 11
+  	  minutes if the NTP status is synchronized.
+
 config RTC_DEBUG
 	bool "RTC debug support"
 	help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 56297f0..69d11f1 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -6,6 +6,7 @@ ccflags-$(CONFIG_RTC_DEBUG)	:= -DDEBUG
 
 obj-$(CONFIG_RTC_LIB)		+= rtc-lib.o
 obj-$(CONFIG_RTC_HCTOSYS)	+= hctosys.o
+obj-$(CONFIG_RTC_SYSTOHC)	+= systohc.o
 obj-$(CONFIG_RTC_CLASS)		+= rtc-core.o
 rtc-core-y			:= class.o interface.o
 
diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c
new file mode 100644
index 0000000..0536cae
--- /dev/null
+++ b/drivers/rtc/systohc.c
@@ -0,0 +1,30 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ */
+#include <linux/rtc.h>
+#include <linux/time.h>
+
+/* Replacement for the NTP platform function 'update_persistent_clock'
+ * that does the opposite of rtc_hctosys.c */
+int rtc_update_persistent_clock(struct timespec now)
+{
+	struct rtc_device *rtc;
+	struct rtc_time tm;
+	int err = -ENODEV;
+
+	if (now.tv_nsec < (NSEC_PER_SEC >> 1))
+		rtc_time_to_tm(now.tv_sec, &tm);
+	else
+		rtc_time_to_tm(now.tv_sec + 1, &tm);
+
+	rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+	if (rtc) {
+		err = rtc_set_mmss(rtc, now.tv_sec);
+		rtc_class_close(rtc);
+	}
+
+	return err;
+}
diff --git a/include/linux/time.h b/include/linux/time.h
index 4d358e9..d668f9c 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -118,6 +118,7 @@ static inline bool timespec_valid_strict(const struct timespec *ts)
 extern void read_persistent_clock(struct timespec *ts);
 extern void read_boot_clock(struct timespec *ts);
 extern int update_persistent_clock(struct timespec now);
+extern int rtc_update_persistent_clock(struct timespec now);
 void timekeeping_init(void);
 extern int timekeeping_suspended;
 
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 24174b4..f79ab16 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -483,7 +483,15 @@ out:
 	return leap;
 }
 
-#ifdef CONFIG_GENERIC_CMOS_UPDATE
+#if defined(CONFIG_GENERIC_CMOS_UPDATE) || defined(CONFIG_RTC_SYSTOHC)
+
+/* Only do one, if using CONFIG_RTC_SYSTOHC then the platform function
+ * might be mapped to the RTC code already. */
+#ifdef CONFIG_RTC_SYSTOHC
+#define __update_persistent_clock rtc_update_persistent_clock
+#else
+#define __update_persistent_clock update_persistent_clock
+#endif
 
 static void sync_cmos_clock(struct work_struct *work);
 
@@ -511,7 +519,7 @@ static void sync_cmos_clock(struct work_struct *work)
 
 	getnstimeofday(&now);
 	if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2)
-		fail = update_persistent_clock(now);
+		fail = __update_persistent_clock(now);
 
 	next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2);
 	if (next.tv_nsec <= 0)
-- 
1.7.5.4

             reply	other threads:[~2012-12-12  5:56 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-12  5:56 Jason Gunthorpe [this message]
2012-12-12 19:40 ` [PATCH] NTP: Add a CONFIG_RTC_SYSTOHC configuration John Stultz
2012-12-12 21:04   ` Jason Gunthorpe
2012-12-13  0:18     ` John Stultz
2012-12-13  5:21       ` Jason Gunthorpe
2012-12-14  1:29         ` John Stultz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20121212055643.GA18078@obsidianresearch.com \
    --to=jgunthorpe@obsidianresearch.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).