diff mbox

rtc: add rtc_systohc for ntp use

Message ID 1233018262.14510.111.camel@localhost.localdomain
State Superseded
Headers show

Commit Message

Ed Swierk Jan. 27, 2009, 1:04 a.m. UTC
Following up to Alessandro's RFC of 10 Nov 2008, this patch implements
rtc_systohc() to update the configured rtc device (cmos, i2c, etc.) from
the ntp-synchronized system clock.  It changes the ntp update code to
call rtc_systohc() rather than update_persistent_clock() which (at least
on x86) always updates the cmos rtc.

No attempt is made to compensate for the 500-ms delay imposed when
setting a cmos rtc chip.  If you actually have a cmos rtc you can stick
with the existing code, but at some point it would be nice to unify
these.

Signed-off-by: Ed Swierk <eswierk@aristanetworks.com>

---



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
-~----------~----~----~----~------~----~------~--~---

Comments

Andrew Morton Feb. 2, 2009, 10:26 p.m. UTC | #1
On Mon, 26 Jan 2009 17:04:22 -0800
Ed Swierk <eswierk@aristanetworks.com> wrote:

> Following up to Alessandro's RFC of 10 Nov 2008, this patch implements
> rtc_systohc() to update the configured rtc device (cmos, i2c, etc.) from
> the ntp-synchronized system clock.  It changes the ntp update code to
> call rtc_systohc() rather than update_persistent_clock() which (at least
> on x86) always updates the cmos rtc.
> 
> No attempt is made to compensate for the 500-ms delay imposed when
> setting a cmos rtc chip.  If you actually have a cmos rtc you can stick
> with the existing code, but at some point it would be nice to unify
> these.

I don't get this.  Do we not currently update the cmos clock in
response to NTP controls?  Does the patch now alter this policy, by now
updating the RTC?

IOW: what effect does this patch actually have upon the kernel?


Please cc Roman on NTP changes.  Roman, please consider sending in a
MAINTAINERS patch for this.


Please use scripts/checkpatch.pl.

Please fix the checkpatch warnings which this patch emits.

When fixing the extern-declaration-in-C warning, please consider
dropping the ifdefs around the rtc_systohc() declaration in the header
file.  They're not really needed.


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
-~----------~----~----~----~------~----~------~--~---
Alessandro Zummo Feb. 3, 2009, 6:09 a.m. UTC | #2
On Mon, 2 Feb 2009 14:26:13 -0800
Andrew Morton <akpm@linux-foundation.org> wrote:

> > No attempt is made to compensate for the 500-ms delay imposed when
> > setting a cmos rtc chip.  If you actually have a cmos rtc you can stick
> > with the existing code, but at some point it would be nice to unify
> > these.
> 
> I don't get this.  Do we not currently update the cmos clock in
> response to NTP controls?  Does the patch now alter this policy, by now
> updating the RTC?

 Hi Andrew, please do not apply yet. It's still experimental.
 The clock is not currently updated in ntp mode and my original patch
 plus Ed's work is meant to fix this.
diff mbox

Patch

Index: linux-2.6.28.2/drivers/rtc/Kconfig
===================================================================
--- linux-2.6.28.2.orig/drivers/rtc/Kconfig
+++ linux-2.6.28.2/drivers/rtc/Kconfig
@@ -30,7 +30,7 @@  config RTC_HCTOSYS
 	  unnecessary fsck runs at boot time, and to network better.
 
 config RTC_HCTOSYS_DEVICE
-	string "RTC used to set the system time"
+	string "RTC used to set the system time on startup and resume"
 	depends on RTC_HCTOSYS = y
 	default "rtc0"
 	help
@@ -52,6 +52,23 @@  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 RTC from system time in NTP sync mode"
+	depends on RTC_CLASS = y
+	default y
+	help
+	  If you say yes here, the system time (wall clock) will be written
+	  to the hardware clock every 11 minutes, if the kernel is in NTP
+	  mode and your platforms supports it.
+
+config RTC_SYSTOHC_DEVICE
+	string "RTC used to save the system time in NTP sync mode"
+	depends on RTC_SYSTOHC = y
+	default "rtc0"
+	help
+	  The RTC device that will get written with the system time
+	  in NTP mode.
+
 config RTC_DEBUG
 	bool "RTC debug support"
 	depends on RTC_CLASS = y
Index: linux-2.6.28.2/drivers/rtc/Makefile
===================================================================
--- linux-2.6.28.2.orig/drivers/rtc/Makefile
+++ linux-2.6.28.2/drivers/rtc/Makefile
@@ -8,6 +8,7 @@  endif
 
 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
 
Index: linux-2.6.28.2/drivers/rtc/systohc.c
===================================================================
--- /dev/null
+++ linux-2.6.28.2/drivers/rtc/systohc.c
@@ -0,0 +1,36 @@ 
+/*
+ * RTC subsystem, systohc for ntp use
+ *
+ * Copyright (C) 2008 Tower Technologies
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ *
+ * 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>
+
+int rtc_systohc(void)
+{
+	int err;
+	struct rtc_time tm;
+	struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_SYSTOHC_DEVICE);
+
+	if (rtc == NULL) {
+		printk("%s: unable to open rtc device (%s)\n",
+			__FILE__, CONFIG_RTC_SYSTOHC_DEVICE);
+		return -ENODEV;
+	}
+
+	rtc_time_to_tm(get_seconds(), &tm);
+	err = rtc_set_time(rtc, &tm);
+	if (err != 0)
+		dev_err(rtc->dev.parent,
+			"systohc: unable to set the hardware clock\n");
+
+	rtc_class_close(rtc);
+
+	return err;
+}
+EXPORT_SYMBOL(rtc_systohc);
Index: linux-2.6.28.2/kernel/time/ntp.c
===================================================================
--- linux-2.6.28.2.orig/kernel/time/ntp.c
+++ linux-2.6.28.2/kernel/time/ntp.c
@@ -221,17 +221,20 @@  static void sync_cmos_clock(struct work_
 
 static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock);
 
+#ifdef CONFIG_RTC_SYSTOHC
+extern int rtc_systohc(void);
+#endif
+
 static void sync_cmos_clock(struct work_struct *work)
 {
+#ifndef CONFIG_RTC_SYSTOHC
 	struct timespec now, next;
 	int fail = 1;
+#endif
 
 	/*
 	 * If we have an externally synchronized Linux clock, then update
-	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-	 * called as close as possible to 500 ms before the new second starts.
-	 * This code is run on a timer.  If the clock is set, that timer
-	 * may not expire at the correct time.  Thus, we adjust...
+	 * CMOS clock accordingly every ~11 minutes.
 	 */
 	if (!ntp_synced())
 		/*
@@ -240,6 +243,19 @@  static void sync_cmos_clock(struct work_
 		 */
 		return;
 
+#ifdef CONFIG_RTC_SYSTOHC
+
+	rtc_systohc();
+	schedule_delayed_work(&sync_cmos_work, 660*HZ);
+
+#else
+
+	/*
+	 * Set_rtc_mmss() has to be called as close as possible to 500 ms
+	 * before the new second starts.  This code is run on a timer.
+	 * If the clock is set, that timer may not expire at the correct
+	 * time.  Thus, we adjust...
+	 */
 	getnstimeofday(&now);
 	if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2)
 		fail = update_persistent_clock(now);
@@ -258,6 +274,8 @@  static void sync_cmos_clock(struct work_
 		next.tv_nsec -= NSEC_PER_SEC;
 	}
 	schedule_delayed_work(&sync_cmos_work, timespec_to_jiffies(&next));
+
+#endif
 }
 
 static void notify_cmos_timer(void)