summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-08-03 14:19:58 +0900
committerPaul Mundt <lethal@linux-sh.org>2007-09-21 11:57:47 +0900
commitad89f87a84040a57c4a78ca2759b364f72f423ab (patch)
treea34207175da4338cc8e4e7b7ea323193e199eb3c
parent7da3b8ef662af6252aa17c55cc0aa6d74cbf02e4 (diff)
downloadlwn-ad89f87a84040a57c4a78ca2759b364f72f423ab.tar.gz
lwn-ad89f87a84040a57c4a78ca2759b364f72f423ab.zip
rtc: rtc-sh: Support 4-digit year on SH7705/SH7710/SH7712.
All SH-4 parts have a 4-digit year, while the SH-3 parts typically only use a 2-digit one. The SH7705, SH7710, and SH7712 SH-3 parts however opted to extend it to 4-digit and still look and act like an SH-3 RTC in all other ways. This adds a capability flag (RTC_CAP_4_DIGIT_YEAR) that these corner-case CPU subtypes can set in their platform data and cleans up some of the ifdef mess in the driver as a result. Reported-by: Markus Brunner <super.firetwister@gmail.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c12
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c10
-rw-r--r--drivers/rtc/rtc-sh.c51
-rw-r--r--include/asm-sh/rtc.h6
4 files changed, 58 insertions, 21 deletions
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index 6fc68e77102f..568cc08c254b 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -1,7 +1,7 @@
/*
* SH7705 Setup
*
- * Copyright (C) 2006 Paul Mundt
+ * Copyright (C) 2006, 2007 Paul Mundt
* Copyright (C) 2007 Nobuhiro Iwamatsu
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -13,8 +13,9 @@
#include <linux/irq.h>
#include <linux/serial.h>
#include <asm/sci.h>
+#include <asm/rtc.h>
-enum{
+enum {
UNUSED = 0,
/* interrupt sources */
@@ -138,11 +139,18 @@ static struct resource rtc_resources[] = {
},
};
+static struct sh_rtc_platform_info rtc_info = {
+ .capabilities = RTC_CAP_4_DIGIT_YEAR,
+};
+
static struct platform_device rtc_device = {
.name = "sh-rtc",
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
+ .dev = {
+ .platform_data = &rtc_info,
+ },
};
static struct platform_device *sh7705_devices[] __initdata = {
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 07f26ab75d97..eb55ac9dbf71 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -1,7 +1,7 @@
/*
* SH3 Setup code for SH7710, SH7712
*
- * Copyright (C) 2006 Paul Mundt
+ * Copyright (C) 2006, 2007 Paul Mundt
* Copyright (C) 2007 Nobuhiro Iwamatsu
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -13,6 +13,7 @@
#include <linux/irq.h>
#include <linux/serial.h>
#include <asm/sci.h>
+#include <asm/rtc.h>
enum {
UNUSED = 0,
@@ -130,11 +131,18 @@ static struct resource rtc_resources[] = {
},
};
+static struct sh_rtc_platform_info rtc_info = {
+ .capabilities = RTC_CAP_4_DIGIT_YEAR,
+};
+
static struct platform_device rtc_device = {
.name = "sh-rtc",
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
+ .dev = {
+ .platform_data = &rtc_info,
+ },
};
static struct plat_sci_port sci_platform_data[] = {
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 93ee05eeaeba..78277a118b67 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -1,7 +1,7 @@
/*
* SuperH On-Chip RTC Support
*
- * Copyright (C) 2006 Paul Mundt
+ * Copyright (C) 2006, 2007 Paul Mundt
* Copyright (C) 2006 Jamie Lenehan
*
* Based on the old arch/sh/kernel/cpu/rtc.c by:
@@ -23,16 +23,19 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/io.h>
+#include <asm/rtc.h>
#define DRV_NAME "sh-rtc"
-#define DRV_VERSION "0.1.2"
+#define DRV_VERSION "0.1.3"
#ifdef CONFIG_CPU_SH3
#define rtc_reg_size sizeof(u16)
#define RTC_BIT_INVERTED 0 /* No bug on SH7708, SH7709A */
+#define RTC_DEF_CAPABILITIES 0UL
#elif defined(CONFIG_CPU_SH4)
#define rtc_reg_size sizeof(u32)
#define RTC_BIT_INVERTED 0x40 /* bug on SH7750, SH7750S */
+#define RTC_DEF_CAPABILITIES RTC_CAP_4_DIGIT_YEAR
#endif
#define RTC_REG(r) ((r) * rtc_reg_size)
@@ -80,6 +83,7 @@ struct sh_rtc {
struct rtc_device *rtc_dev;
spinlock_t lock;
int rearm_aie;
+ unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */
};
static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
@@ -319,14 +323,14 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_mday = BCD2BIN(readb(rtc->regbase + RDAYCNT));
tm->tm_mon = BCD2BIN(readb(rtc->regbase + RMONCNT)) - 1;
-#if defined(CONFIG_CPU_SH4)
- yr = readw(rtc->regbase + RYRCNT);
- yr100 = BCD2BIN(yr >> 8);
- yr &= 0xff;
-#else
- yr = readb(rtc->regbase + RYRCNT);
- yr100 = BCD2BIN((yr == 0x99) ? 0x19 : 0x20);
-#endif
+ if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) {
+ yr = readw(rtc->regbase + RYRCNT);
+ yr100 = BCD2BIN(yr >> 8);
+ yr &= 0xff;
+ } else {
+ yr = readb(rtc->regbase + RYRCNT);
+ yr100 = BCD2BIN((yr == 0x99) ? 0x19 : 0x20);
+ }
tm->tm_year = (yr100 * 100 + BCD2BIN(yr)) - 1900;
@@ -375,14 +379,14 @@ static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm)
writeb(BIN2BCD(tm->tm_mday), rtc->regbase + RDAYCNT);
writeb(BIN2BCD(tm->tm_mon + 1), rtc->regbase + RMONCNT);
-#ifdef CONFIG_CPU_SH3
- year = tm->tm_year % 100;
- writeb(BIN2BCD(year), rtc->regbase + RYRCNT);
-#else
- year = (BIN2BCD((tm->tm_year + 1900) / 100) << 8) |
- BIN2BCD(tm->tm_year % 100);
- writew(year, rtc->regbase + RYRCNT);
-#endif
+ if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) {
+ year = (BIN2BCD((tm->tm_year + 1900) / 100) << 8) |
+ BIN2BCD(tm->tm_year % 100);
+ writew(year, rtc->regbase + RYRCNT);
+ } else {
+ year = tm->tm_year % 100;
+ writeb(BIN2BCD(year), rtc->regbase + RYRCNT);
+ }
/* Start RTC */
tmp = readb(rtc->regbase + RCR2);
@@ -589,6 +593,17 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
goto err_badmap;
}
+ rtc->capabilities = RTC_DEF_CAPABILITIES;
+ if (pdev->dev.platform_data) {
+ struct sh_rtc_platform_info *pinfo = pdev->dev.platform_data;
+
+ /*
+ * Some CPUs have special capabilities in addition to the
+ * default set. Add those in here.
+ */
+ rtc->capabilities |= pinfo->capabilities;
+ }
+
platform_set_drvdata(pdev, rtc);
return 0;
diff --git a/include/asm-sh/rtc.h b/include/asm-sh/rtc.h
index 91aacc96151b..858da99d37e0 100644
--- a/include/asm-sh/rtc.h
+++ b/include/asm-sh/rtc.h
@@ -5,4 +5,10 @@ extern void (*board_time_init)(void);
extern void (*rtc_sh_get_time)(struct timespec *);
extern int (*rtc_sh_set_time)(const time_t);
+#define RTC_CAP_4_DIGIT_YEAR (1 << 0)
+
+struct sh_rtc_platform_info {
+ unsigned long capabilities;
+};
+
#endif /* _ASM_RTC_H */