From dd9cd73246b201af44e90ad98bb3f191faf3ca46 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 12 Feb 2004 23:45:29 -0800 Subject: [PATCH] [PATCH] sh: RTC fixes From: Paul Mundt Re-read RTC registers if MSB of R64CNT was changed while reading them on SH-4 which has unreliable CF bit. Patch from SUGIOKA Toshinobu and Masaki Saitoh. --- arch/sh/kernel/cpu/rtc.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/sh/kernel/cpu/rtc.c b/arch/sh/kernel/cpu/rtc.c index 72b625e9ce073..f8361f5e788bc 100644 --- a/arch/sh/kernel/cpu/rtc.c +++ b/arch/sh/kernel/cpu/rtc.c @@ -23,10 +23,12 @@ void sh_rtc_gettimeofday(struct timespec *ts) { - unsigned int sec128, sec, min, hr, wk, day, mon, yr, yr100; + unsigned int sec128, sec, sec2, min, hr, wk, day, mon, yr, yr100, cf_bit; + unsigned long flags; again: do { + local_irq_save(flags); ctrl_outb(0, RCR1); /* Clear CF-bit */ sec128 = ctrl_inb(R64CNT); sec = ctrl_inb(RSECCNT); @@ -43,15 +45,10 @@ void sh_rtc_gettimeofday(struct timespec *ts) yr = ctrl_inb(RYRCNT); yr100 = (yr == 0x99) ? 0x19 : 0x20; #endif - } while ((ctrl_inb(RCR1) & RCR1_CF) != 0); - -#if RTC_BIT_INVERTED != 0 - /* Work around to avoid reading incorrect value. */ - if (sec128 == RTC_BIT_INVERTED) { - schedule_timeout(1); - goto again; - } -#endif + sec2 = ctrl_inb(R64CNT); + cf_bit = ctrl_inb(RCR1) & RCR1_CF; + local_irq_restore(flags); + } while (cf_bit != 0 || ((sec128 ^ sec2) & RTC_BIT_INVERTED) != 0); BCD_TO_BIN(yr100); BCD_TO_BIN(yr); @@ -65,6 +62,7 @@ void sh_rtc_gettimeofday(struct timespec *ts) hr > 23 || min > 59 || sec > 59) { printk(KERN_ERR "SH RTC: invalid value, resetting to 1 Jan 2000\n"); + local_irq_save(flags); ctrl_outb(RCR2_RESET, RCR2); /* Reset & Stop */ ctrl_outb(0, RSECCNT); ctrl_outb(0, RMINCNT); @@ -99,7 +97,9 @@ int sh_rtc_settimeofday(const time_t secs) { int retval = 0; int real_seconds, real_minutes, cmos_minutes; + unsigned long flags; + local_irq_save(flags); ctrl_outb(RCR2_RESET, RCR2); /* Reset pre-scaler & stop RTC */ cmos_minutes = ctrl_inb(RMINCNT); @@ -130,6 +130,7 @@ int sh_rtc_settimeofday(const time_t secs) } ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start RTC */ + local_irq_restore(flags); return retval; } -- 2.53.0