summaryrefslogtreecommitdiffstats
path: root/include/asm-mips/mc146818-time.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 11:15:23 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 11:15:23 -0800
commit3f00d3e8fb963968a922d821a9a53b503b687e81 (patch)
treedfac1c73ae63f8d48340f3bbb77ee53b322c59e9 /include/asm-mips/mc146818-time.h
parent407cf84f956ee4b52da5508d5357b8ae212ff77c (diff)
parenta637a114f36b94a1ad8b9867f43bac0414958420 (diff)
downloadtalos-op-linux-3f00d3e8fb963968a922d821a9a53b503b687e81.tar.gz
talos-op-linux-3f00d3e8fb963968a922d821a9a53b503b687e81.zip
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
Diffstat (limited to 'include/asm-mips/mc146818-time.h')
-rw-r--r--include/asm-mips/mc146818-time.h24
1 files changed, 22 insertions, 2 deletions
diff --git a/include/asm-mips/mc146818-time.h b/include/asm-mips/mc146818-time.h
index a2c2d2c24303..47214861093b 100644
--- a/include/asm-mips/mc146818-time.h
+++ b/include/asm-mips/mc146818-time.h
@@ -33,7 +33,9 @@ static inline int mc146818_set_rtc_mmss(unsigned long nowtime)
int real_seconds, real_minutes, cmos_minutes;
unsigned char save_control, save_freq_select;
int retval = 0;
+ unsigned long flags;
+ spin_lock_irqsave(&rtc_lock, flags);
save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
@@ -79,14 +81,30 @@ static inline int mc146818_set_rtc_mmss(unsigned long nowtime)
*/
CMOS_WRITE(save_control, RTC_CONTROL);
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+ spin_unlock_irqrestore(&rtc_lock, flags);
return retval;
}
+/*
+ * Returns true if a clock update is in progress
+ */
+static inline unsigned char rtc_is_updating(void)
+{
+ unsigned char uip;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ return uip;
+}
+
static inline unsigned long mc146818_get_cmos_time(void)
{
unsigned int year, mon, day, hour, min, sec;
int i;
+ unsigned long flags;
/*
* The Linux interpretation of the CMOS clock register contents:
@@ -97,12 +115,13 @@ static inline unsigned long mc146818_get_cmos_time(void)
/* 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)
+ if (rtc_is_updating())
break;
for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
- if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+ if (!rtc_is_updating())
break;
+ spin_lock_irqsave(&rtc_lock, flags);
do { /* Isn't this overkill ? UIP above should guarantee consistency */
sec = CMOS_READ(RTC_SECONDS);
min = CMOS_READ(RTC_MINUTES);
@@ -120,6 +139,7 @@ static inline unsigned long mc146818_get_cmos_time(void)
BCD_TO_BIN(mon);
BCD_TO_BIN(year);
}
+ spin_unlock_irqrestore(&rtc_lock, flags);
year = mc146818_decode_year(year);
return mktime(year, mon, day, hour, min, sec);
OpenPOWER on IntegriCloud