diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-08-03 14:19:58 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2007-09-21 11:57:47 +0900 |
commit | ad89f87a84040a57c4a78ca2759b364f72f423ab (patch) | |
tree | a34207175da4338cc8e4e7b7ea323193e199eb3c | |
parent | 7da3b8ef662af6252aa17c55cc0aa6d74cbf02e4 (diff) |
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.c | 12 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/setup-sh7710.c | 10 | ||||
-rw-r--r-- | drivers/rtc/rtc-sh.c | 51 | ||||
-rw-r--r-- | include/asm-sh/rtc.h | 6 |
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 6fc68e77102..568cc08c254 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 07f26ab75d9..eb55ac9dbf7 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 93ee05eeaeb..78277a118b6 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 91aacc96151..858da99d37e 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 */ |