mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Nigel Cunningham <ncunningham@linuxmail.org>
To: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Cc: Pavel Machek <pavel@ucw.cz>, John Stultz <johnstul@us.ibm.com>,
	David Shaohua <shaohua.li@intel.com>
Subject: Patch 3/3: Reduce number of get_cmos_time_calls.
Date: Sat, 08 Jan 2005 20:42:22 +1100	[thread overview]
Message-ID: <1105177308.5478.43.camel@desktop.cunninghams> (raw)
In-Reply-To: <1105176732.5478.20.camel@desktop.cunninghams>

Create new __get_cmos_time patch, which doesn't wait for the start of a
new second before returning. Adjust timer_suspend to use this as we
don't appear to need the exact start of a second when suspending.

Signed-off-by: Nigel Cunningham <ncunningham@linuxmail.org>

diff -ruNp 913-old/arch/i386/kernel/time.c 913-new/arch/i386/kernel/time.c
--- 913-old/arch/i386/kernel/time.c	2005-01-08 19:40:06.149971536 +1100
+++ 913-new/arch/i386/kernel/time.c	2005-01-08 19:39:51.915135560 +1100
@@ -327,7 +327,7 @@ static int timer_suspend(struct sys_devi
 	/*
 	 * Estimate time zone so that set_time can update the clock
 	 */
-	long cmos_time = get_cmos_time();
+	long cmos_time = __get_cmos_time();
 	
 	clock_cmos_diff = -cmos_time;
 	clock_cmos_diff += get_seconds();
diff -ruNp 913-old/arch/x86_64/kernel/time.c 913-new/arch/x86_64/kernel/time.c
--- 913-old/arch/x86_64/kernel/time.c	2004-12-10 14:27:08.000000000 +1100
+++ 913-new/arch/x86_64/kernel/time.c	2005-01-08 19:39:24.664278320 +1100
@@ -499,11 +499,56 @@ unsigned long long sched_clock(void)
 	return cycles_2_ns(a);
 }
 
+unsigned long __get_cmos_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+
+	/*
+	 * Do we need the spinlock in here too?
+	 *
+	 * If we're called directly (not via get_cmos_time),
+	 * we're in the middle of a sysdev suspend/resume
+	 * and interrupts are disabled, so this 
+	 * should be safe without any locking.
+	 * 				-- NC
+	 */
+
+	do {
+		sec = CMOS_READ(RTC_SECONDS);
+		min = CMOS_READ(RTC_MINUTES);
+		hour = CMOS_READ(RTC_HOURS);
+		day = CMOS_READ(RTC_DAY_OF_MONTH);
+		mon = CMOS_READ(RTC_MONTH);
+		year = CMOS_READ(RTC_YEAR);
+	} while (sec != CMOS_READ(RTC_SECONDS));
+
+	/*
+	 * We know that x86-64 always uses BCD format, no need to check the config
+	 * register.
+	 */
+
+	    BCD_TO_BIN(sec);
+	    BCD_TO_BIN(min);
+	    BCD_TO_BIN(hour);
+	    BCD_TO_BIN(day);
+	    BCD_TO_BIN(mon);
+	    BCD_TO_BIN(year);
+
+	/*
+	 * This will work up to Dec 31, 2069.
+	 */
+
+	if ((year += 1900) < 1970)
+		year += 100;
+
+	return mktime(year, mon, day, hour, min, sec);
+}
+
 unsigned long get_cmos_time(void)
 {
-	unsigned int timeout, year, mon, day, hour, min, sec;
+	unsigned int timeout;
 	unsigned char last, this;
-	unsigned long flags;
+	unsigned long flags, result;
 
 /*
  * The Linux interpretation of the CMOS clock register contents: When the
@@ -524,40 +569,11 @@ unsigned long get_cmos_time(void)
 		timeout--;
 	}
 
-/*
- * Here we are safe to assume the registers won't change for a whole second, so
- * we just go ahead and read them.
-	 */
-
-		sec = CMOS_READ(RTC_SECONDS);
-		min = CMOS_READ(RTC_MINUTES);
-		hour = CMOS_READ(RTC_HOURS);
-		day = CMOS_READ(RTC_DAY_OF_MONTH);
-		mon = CMOS_READ(RTC_MONTH);
-		year = CMOS_READ(RTC_YEAR);
-
+	result =  __get_cmos_time();
 	spin_unlock_irqrestore(&rtc_lock, flags);
 
-/*
- * We know that x86-64 always uses BCD format, no need to check the config
- * register.
- */
-
-	    BCD_TO_BIN(sec);
-	    BCD_TO_BIN(min);
-	    BCD_TO_BIN(hour);
-	    BCD_TO_BIN(day);
-	    BCD_TO_BIN(mon);
-	    BCD_TO_BIN(year);
+	return result;
 
-/*
- * This will work up to Dec 31, 2069.
- */
-
-	if ((year += 1900) < 1970)
-		year += 100;
-
-	return mktime(year, mon, day, hour, min, sec);
 }
 
 #ifdef CONFIG_CPU_FREQ
@@ -962,7 +978,7 @@ static int timer_suspend(struct sys_devi
 	/*
 	 * Estimate time zone so that set_time can update the clock
 	 */
-	clock_cmos_diff = -get_cmos_time();
+	clock_cmos_diff = -__get_cmos_time();
 	clock_cmos_diff += get_seconds();
 	return 0;
 }
diff -ruNp 913-old/include/asm-i386/mach-default/mach_time.h 913-new/include/asm-i386/mach-default/mach_time.h
--- 913-old/include/asm-i386/mach-default/mach_time.h	2004-11-03 21:53:12.000000000 +1100
+++ 913-new/include/asm-i386/mach-default/mach_time.h	2005-01-08 19:39:24.676276496 +1100
@@ -79,24 +79,19 @@ static inline int mach_set_rtc_mmss(unsi
 	return retval;
 }
 
-static inline unsigned long mach_get_cmos_time(void)
+/* __get_cmos_time
+ *
+ * Separated out from mach_get_cmos_time so that we can
+ * quickly get the cmos time when we don't care about
+ * whether the second has just started.
+ *
+ * Used from suspend and resume sysdev calls.
+ */
+static inline unsigned long __get_cmos_time(void)
 {
 	unsigned int year, mon, day, hour, min, sec;
-	int i;
 
-	/* The Linux interpretation of the CMOS clock register contents:
-	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-	 * RTC registers show the second which has precisely just started.
-	 * Let's hope other operating systems interpret the RTC the same way.
-	 */
-	/* read RTC exactly on falling edge of update flag */
-	for (i = 0 ; i < 1000000 ; i++)	/* may take up to 1 second... */
-		if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
-			break;
-	for (i = 0 ; i < 1000000 ; i++)	/* must try at least 2.228 ms */
-		if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
-			break;
-	do { /* Isn't this overkill ? UIP above should guarantee consistency */
+	do {
 		sec = CMOS_READ(RTC_SECONDS);
 		min = CMOS_READ(RTC_MINUTES);
 		hour = CMOS_READ(RTC_HOURS);
@@ -104,6 +99,7 @@ static inline unsigned long mach_get_cmo
 		mon = CMOS_READ(RTC_MONTH);
 		year = CMOS_READ(RTC_YEAR);
 	} while (sec != CMOS_READ(RTC_SECONDS));
+
 	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
 	  {
 	    BCD_TO_BIN(sec);
@@ -119,4 +115,24 @@ static inline unsigned long mach_get_cmo
 	return mktime(year, mon, day, hour, min, sec);
 }
 
+static inline unsigned long mach_get_cmos_time(void)
+{
+	int i;
+
+	/* The Linux interpretation of the CMOS clock register contents:
+	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+	 * RTC registers show the second which has precisely just started.
+	 * Let's hope other operating systems interpret the RTC the same way.
+	 */
+	/* read RTC exactly on falling edge of update flag */
+	for (i = 0 ; i < 1000000 ; i++)	/* may take up to 1 second... */
+		if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
+			break;
+	for (i = 0 ; i < 1000000 ; i++)	/* must try at least 2.228 ms */
+		if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+			break;
+
+	return __get_cmos_time();
+}
+
 #endif /* !_MACH_TIME_H */



  parent reply	other threads:[~2005-01-08  9:48 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-08  9:42 [RFC] Patches to reduce delay in arch/kernel/time.c Nigel Cunningham
2005-01-08  9:42 ` Patch 1/3: Reduce number of get_cmos_time_calls Nigel Cunningham
2005-01-08 13:21   ` Pavel Machek
2005-01-08  9:42 ` Patch 2/3: " Nigel Cunningham
2005-01-08 13:22   ` Pavel Machek
2005-01-08  9:42 ` Nigel Cunningham [this message]
2005-01-08 13:27   ` Patch 3/3: " Pavel Machek

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=1105177308.5478.43.camel@desktop.cunninghams \
    --to=ncunningham@linuxmail.org \
    --cc=johnstul@us.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pavel@ucw.cz \
    --cc=shaohua.li@intel.com \
    /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

Powered by JetHome