aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorMatt Mackall <mpm@selenic.com>2006-03-28 04:56:06 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-28 12:16:01 -0500
commitddcabb4fc7f2f4a70f35aa72827888a4c549d355 (patch)
treea730f9c35f76d88ec5f586dc415e427f618589a5 /arch/mips
parentda2468b6a81884a696fd6c7ab66dcc62d7233d32 (diff)
[PATCH] RTC: Remove RTC UIP synchronization on MIPS-based DEC
Move real_year inside the read loop and move the spinlock up as well Signed-off-by: Matt Mackall <mpm@selenic.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Alessandro Zummo <a.zummo@towertech.it> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/dec/time.c47
1 files changed, 11 insertions, 36 deletions
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index f17d3378e9a6..74cb055d4bf6 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -36,41 +36,13 @@
36#include <asm/dec/ioasic_addrs.h> 36#include <asm/dec/ioasic_addrs.h>
37#include <asm/dec/machtype.h> 37#include <asm/dec/machtype.h>
38 38
39
40/*
41 * Returns true if a clock update is in progress
42 */
43static inline unsigned char dec_rtc_is_updating(void)
44{
45 unsigned char uip;
46 unsigned long flags;
47
48 spin_lock_irqsave(&rtc_lock, flags);
49 uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
50 spin_unlock_irqrestore(&rtc_lock, flags);
51 return uip;
52}
53
54static unsigned long dec_rtc_get_time(void) 39static unsigned long dec_rtc_get_time(void)
55{ 40{
56 unsigned int year, mon, day, hour, min, sec, real_year; 41 unsigned int year, mon, day, hour, min, sec, real_year;
57 int i;
58 unsigned long flags; 42 unsigned long flags;
59 43
60 /* The Linux interpretation of the DS1287 clock register contents:
61 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
62 * RTC registers show the second which has precisely just started.
63 * Let's hope other operating systems interpret the RTC the same way.
64 */
65 /* read RTC exactly on falling edge of update flag */
66 for (i = 0; i < 1000000; i++) /* may take up to 1 second... */
67 if (dec_rtc_is_updating())
68 break;
69 for (i = 0; i < 1000000; i++) /* must try at least 2.228 ms */
70 if (!dec_rtc_is_updating())
71 break;
72 spin_lock_irqsave(&rtc_lock, flags); 44 spin_lock_irqsave(&rtc_lock, flags);
73 /* Isn't this overkill? UIP above should guarantee consistency */ 45
74 do { 46 do {
75 sec = CMOS_READ(RTC_SECONDS); 47 sec = CMOS_READ(RTC_SECONDS);
76 min = CMOS_READ(RTC_MINUTES); 48 min = CMOS_READ(RTC_MINUTES);
@@ -78,7 +50,16 @@ static unsigned long dec_rtc_get_time(void)
78 day = CMOS_READ(RTC_DAY_OF_MONTH); 50 day = CMOS_READ(RTC_DAY_OF_MONTH);
79 mon = CMOS_READ(RTC_MONTH); 51 mon = CMOS_READ(RTC_MONTH);
80 year = CMOS_READ(RTC_YEAR); 52 year = CMOS_READ(RTC_YEAR);
53 /*
54 * The PROM will reset the year to either '72 or '73.
55 * Therefore we store the real year separately, in one
56 * of unused BBU RAM locations.
57 */
58 real_year = CMOS_READ(RTC_DEC_YEAR);
81 } while (sec != CMOS_READ(RTC_SECONDS)); 59 } while (sec != CMOS_READ(RTC_SECONDS));
60
61 spin_unlock_irqrestore(&rtc_lock, flags);
62
82 if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 63 if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
83 sec = BCD2BIN(sec); 64 sec = BCD2BIN(sec);
84 min = BCD2BIN(min); 65 min = BCD2BIN(min);
@@ -87,13 +68,7 @@ static unsigned long dec_rtc_get_time(void)
87 mon = BCD2BIN(mon); 68 mon = BCD2BIN(mon);
88 year = BCD2BIN(year); 69 year = BCD2BIN(year);
89 } 70 }
90 /* 71
91 * The PROM will reset the year to either '72 or '73.
92 * Therefore we store the real year separately, in one
93 * of unused BBU RAM locations.
94 */
95 real_year = CMOS_READ(RTC_DEC_YEAR);
96 spin_unlock_irqrestore(&rtc_lock, flags);
97 year += real_year - 72 + 2000; 72 year += real_year - 72 + 2000;
98 73
99 return mktime(year, mon, day, hour, min, sec); 74 return mktime(year, mon, day, hour, min, sec);