summaryrefslogtreecommitdiffstats
path: root/arch/m68k/sun3x
diff options
context:
space:
mode:
authorFinn Thain2018-04-23 03:02:57 +0200
committerGeert Uytterhoeven2018-05-22 10:31:50 +0200
commitb65769fc013edb7c2e5fdcd91ea6124ad76168f5 (patch)
treeb6ad02cfbf7a81d1a4f339d0873fabb71b8b549e /arch/m68k/sun3x
parentm68k: Fix style, spelling, and grammar in siginfo_build_tests() (diff)
downloadkernel-qcow2-linux-b65769fc013edb7c2e5fdcd91ea6124ad76168f5.tar.gz
kernel-qcow2-linux-b65769fc013edb7c2e5fdcd91ea6124ad76168f5.tar.xz
kernel-qcow2-linux-b65769fc013edb7c2e5fdcd91ea6124ad76168f5.zip
m68k: Fix off-by-one calendar month
This fixes a bug in read_persistent_clock() which causes the system clock to lag the Real Time Clock by one month. The problem was noticed on a Mac, but theoretically it must also affect Atari, BVME6000 and Q40. The tm_mon value in the struct rtc_time passed to mach_hwclk() is zero-based, and atari_mste_hwclk(), atari_tt_hwclk(), bvme6000_hwclk(), mac_hwclk() and q40_hwclk() all make this adjustment. Unfortunately, dn_dummy_hwclk(), mvme147_hwclk(), mvme16x_hwclk(), sun3_hwclk() and sun3x_hwclk() fail to decrement tm_mon. Also m68328_hwclk() assumes a one-based tm_mon. Bring these platforms into line and fix read_persistent_clock() so it works correctly on all m68k platforms. The datasheets for the RTC devices found on the affected platforms all confirm that the year is stored as a value in the range 0-99 and the month is stored as a value in the range 1-12. Please refer to the datasheets for MC146818 (Apollo), DS1643 (MVME), ICM7170 (Sun 3) and M48T02 (Sun 3x). Reported-by: Stan Johnson <userm57@yahoo.com> Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Diffstat (limited to 'arch/m68k/sun3x')
-rw-r--r--arch/m68k/sun3x/time.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/arch/m68k/sun3x/time.c b/arch/m68k/sun3x/time.c
index 7a2c53d9f779..047e2bcee3d7 100644
--- a/arch/m68k/sun3x/time.c
+++ b/arch/m68k/sun3x/time.c
@@ -52,8 +52,8 @@ int sun3x_hwclk(int set, struct rtc_time *t)
h->hour = bin2bcd(t->tm_hour);
h->wday = bin2bcd(t->tm_wday);
h->mday = bin2bcd(t->tm_mday);
- h->month = bin2bcd(t->tm_mon);
- h->year = bin2bcd(t->tm_year);
+ h->month = bin2bcd(t->tm_mon + 1);
+ h->year = bin2bcd(t->tm_year % 100);
h->csr &= ~C_WRITE;
} else {
h->csr |= C_READ;
@@ -62,9 +62,11 @@ int sun3x_hwclk(int set, struct rtc_time *t)
t->tm_hour = bcd2bin(h->hour);
t->tm_wday = bcd2bin(h->wday);
t->tm_mday = bcd2bin(h->mday);
- t->tm_mon = bcd2bin(h->month);
+ t->tm_mon = bcd2bin(h->month) - 1;
t->tm_year = bcd2bin(h->year);
h->csr &= ~C_READ;
+ if (t->tm_year < 70)
+ t->tm_year += 100;
}
local_irq_restore(flags);