diff options
-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 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 @@ | |||
1 | /* | 1 | /* |
2 | * SH7705 Setup | 2 | * SH7705 Setup |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Paul Mundt | 4 | * Copyright (C) 2006, 2007 Paul Mundt |
5 | * Copyright (C) 2007 Nobuhiro Iwamatsu | 5 | * Copyright (C) 2007 Nobuhiro Iwamatsu |
6 | * | 6 | * |
7 | * This file is subject to the terms and conditions of the GNU General Public | 7 | * This file is subject to the terms and conditions of the GNU General Public |
@@ -13,8 +13,9 @@ | |||
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/serial.h> | 14 | #include <linux/serial.h> |
15 | #include <asm/sci.h> | 15 | #include <asm/sci.h> |
16 | #include <asm/rtc.h> | ||
16 | 17 | ||
17 | enum{ | 18 | enum { |
18 | UNUSED = 0, | 19 | UNUSED = 0, |
19 | 20 | ||
20 | /* interrupt sources */ | 21 | /* interrupt sources */ |
@@ -138,11 +139,18 @@ static struct resource rtc_resources[] = { | |||
138 | }, | 139 | }, |
139 | }; | 140 | }; |
140 | 141 | ||
142 | static struct sh_rtc_platform_info rtc_info = { | ||
143 | .capabilities = RTC_CAP_4_DIGIT_YEAR, | ||
144 | }; | ||
145 | |||
141 | static struct platform_device rtc_device = { | 146 | static struct platform_device rtc_device = { |
142 | .name = "sh-rtc", | 147 | .name = "sh-rtc", |
143 | .id = -1, | 148 | .id = -1, |
144 | .num_resources = ARRAY_SIZE(rtc_resources), | 149 | .num_resources = ARRAY_SIZE(rtc_resources), |
145 | .resource = rtc_resources, | 150 | .resource = rtc_resources, |
151 | .dev = { | ||
152 | .platform_data = &rtc_info, | ||
153 | }, | ||
146 | }; | 154 | }; |
147 | 155 | ||
148 | static struct platform_device *sh7705_devices[] __initdata = { | 156 | 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 @@ | |||
1 | /* | 1 | /* |
2 | * SH3 Setup code for SH7710, SH7712 | 2 | * SH3 Setup code for SH7710, SH7712 |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Paul Mundt | 4 | * Copyright (C) 2006, 2007 Paul Mundt |
5 | * Copyright (C) 2007 Nobuhiro Iwamatsu | 5 | * Copyright (C) 2007 Nobuhiro Iwamatsu |
6 | * | 6 | * |
7 | * This file is subject to the terms and conditions of the GNU General Public | 7 | * This file is subject to the terms and conditions of the GNU General Public |
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/serial.h> | 14 | #include <linux/serial.h> |
15 | #include <asm/sci.h> | 15 | #include <asm/sci.h> |
16 | #include <asm/rtc.h> | ||
16 | 17 | ||
17 | enum { | 18 | enum { |
18 | UNUSED = 0, | 19 | UNUSED = 0, |
@@ -130,11 +131,18 @@ static struct resource rtc_resources[] = { | |||
130 | }, | 131 | }, |
131 | }; | 132 | }; |
132 | 133 | ||
134 | static struct sh_rtc_platform_info rtc_info = { | ||
135 | .capabilities = RTC_CAP_4_DIGIT_YEAR, | ||
136 | }; | ||
137 | |||
133 | static struct platform_device rtc_device = { | 138 | static struct platform_device rtc_device = { |
134 | .name = "sh-rtc", | 139 | .name = "sh-rtc", |
135 | .id = -1, | 140 | .id = -1, |
136 | .num_resources = ARRAY_SIZE(rtc_resources), | 141 | .num_resources = ARRAY_SIZE(rtc_resources), |
137 | .resource = rtc_resources, | 142 | .resource = rtc_resources, |
143 | .dev = { | ||
144 | .platform_data = &rtc_info, | ||
145 | }, | ||
138 | }; | 146 | }; |
139 | 147 | ||
140 | static struct plat_sci_port sci_platform_data[] = { | 148 | 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 @@ | |||
1 | /* | 1 | /* |
2 | * SuperH On-Chip RTC Support | 2 | * SuperH On-Chip RTC Support |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Paul Mundt | 4 | * Copyright (C) 2006, 2007 Paul Mundt |
5 | * Copyright (C) 2006 Jamie Lenehan | 5 | * Copyright (C) 2006 Jamie Lenehan |
6 | * | 6 | * |
7 | * Based on the old arch/sh/kernel/cpu/rtc.c by: | 7 | * Based on the old arch/sh/kernel/cpu/rtc.c by: |
@@ -23,16 +23,19 @@ | |||
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <asm/rtc.h> | ||
26 | 27 | ||
27 | #define DRV_NAME "sh-rtc" | 28 | #define DRV_NAME "sh-rtc" |
28 | #define DRV_VERSION "0.1.2" | 29 | #define DRV_VERSION "0.1.3" |
29 | 30 | ||
30 | #ifdef CONFIG_CPU_SH3 | 31 | #ifdef CONFIG_CPU_SH3 |
31 | #define rtc_reg_size sizeof(u16) | 32 | #define rtc_reg_size sizeof(u16) |
32 | #define RTC_BIT_INVERTED 0 /* No bug on SH7708, SH7709A */ | 33 | #define RTC_BIT_INVERTED 0 /* No bug on SH7708, SH7709A */ |
34 | #define RTC_DEF_CAPABILITIES 0UL | ||
33 | #elif defined(CONFIG_CPU_SH4) | 35 | #elif defined(CONFIG_CPU_SH4) |
34 | #define rtc_reg_size sizeof(u32) | 36 | #define rtc_reg_size sizeof(u32) |
35 | #define RTC_BIT_INVERTED 0x40 /* bug on SH7750, SH7750S */ | 37 | #define RTC_BIT_INVERTED 0x40 /* bug on SH7750, SH7750S */ |
38 | #define RTC_DEF_CAPABILITIES RTC_CAP_4_DIGIT_YEAR | ||
36 | #endif | 39 | #endif |
37 | 40 | ||
38 | #define RTC_REG(r) ((r) * rtc_reg_size) | 41 | #define RTC_REG(r) ((r) * rtc_reg_size) |
@@ -80,6 +83,7 @@ struct sh_rtc { | |||
80 | struct rtc_device *rtc_dev; | 83 | struct rtc_device *rtc_dev; |
81 | spinlock_t lock; | 84 | spinlock_t lock; |
82 | int rearm_aie; | 85 | int rearm_aie; |
86 | unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */ | ||
83 | }; | 87 | }; |
84 | 88 | ||
85 | static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) | 89 | 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) | |||
319 | tm->tm_mday = BCD2BIN(readb(rtc->regbase + RDAYCNT)); | 323 | tm->tm_mday = BCD2BIN(readb(rtc->regbase + RDAYCNT)); |
320 | tm->tm_mon = BCD2BIN(readb(rtc->regbase + RMONCNT)) - 1; | 324 | tm->tm_mon = BCD2BIN(readb(rtc->regbase + RMONCNT)) - 1; |
321 | 325 | ||
322 | #if defined(CONFIG_CPU_SH4) | 326 | if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { |
323 | yr = readw(rtc->regbase + RYRCNT); | 327 | yr = readw(rtc->regbase + RYRCNT); |
324 | yr100 = BCD2BIN(yr >> 8); | 328 | yr100 = BCD2BIN(yr >> 8); |
325 | yr &= 0xff; | 329 | yr &= 0xff; |
326 | #else | 330 | } else { |
327 | yr = readb(rtc->regbase + RYRCNT); | 331 | yr = readb(rtc->regbase + RYRCNT); |
328 | yr100 = BCD2BIN((yr == 0x99) ? 0x19 : 0x20); | 332 | yr100 = BCD2BIN((yr == 0x99) ? 0x19 : 0x20); |
329 | #endif | 333 | } |
330 | 334 | ||
331 | tm->tm_year = (yr100 * 100 + BCD2BIN(yr)) - 1900; | 335 | tm->tm_year = (yr100 * 100 + BCD2BIN(yr)) - 1900; |
332 | 336 | ||
@@ -375,14 +379,14 @@ static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
375 | writeb(BIN2BCD(tm->tm_mday), rtc->regbase + RDAYCNT); | 379 | writeb(BIN2BCD(tm->tm_mday), rtc->regbase + RDAYCNT); |
376 | writeb(BIN2BCD(tm->tm_mon + 1), rtc->regbase + RMONCNT); | 380 | writeb(BIN2BCD(tm->tm_mon + 1), rtc->regbase + RMONCNT); |
377 | 381 | ||
378 | #ifdef CONFIG_CPU_SH3 | 382 | if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { |
379 | year = tm->tm_year % 100; | 383 | year = (BIN2BCD((tm->tm_year + 1900) / 100) << 8) | |
380 | writeb(BIN2BCD(year), rtc->regbase + RYRCNT); | 384 | BIN2BCD(tm->tm_year % 100); |
381 | #else | 385 | writew(year, rtc->regbase + RYRCNT); |
382 | year = (BIN2BCD((tm->tm_year + 1900) / 100) << 8) | | 386 | } else { |
383 | BIN2BCD(tm->tm_year % 100); | 387 | year = tm->tm_year % 100; |
384 | writew(year, rtc->regbase + RYRCNT); | 388 | writeb(BIN2BCD(year), rtc->regbase + RYRCNT); |
385 | #endif | 389 | } |
386 | 390 | ||
387 | /* Start RTC */ | 391 | /* Start RTC */ |
388 | tmp = readb(rtc->regbase + RCR2); | 392 | tmp = readb(rtc->regbase + RCR2); |
@@ -589,6 +593,17 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
589 | goto err_badmap; | 593 | goto err_badmap; |
590 | } | 594 | } |
591 | 595 | ||
596 | rtc->capabilities = RTC_DEF_CAPABILITIES; | ||
597 | if (pdev->dev.platform_data) { | ||
598 | struct sh_rtc_platform_info *pinfo = pdev->dev.platform_data; | ||
599 | |||
600 | /* | ||
601 | * Some CPUs have special capabilities in addition to the | ||
602 | * default set. Add those in here. | ||
603 | */ | ||
604 | rtc->capabilities |= pinfo->capabilities; | ||
605 | } | ||
606 | |||
592 | platform_set_drvdata(pdev, rtc); | 607 | platform_set_drvdata(pdev, rtc); |
593 | 608 | ||
594 | return 0; | 609 | 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); | |||
5 | extern void (*rtc_sh_get_time)(struct timespec *); | 5 | extern void (*rtc_sh_get_time)(struct timespec *); |
6 | extern int (*rtc_sh_set_time)(const time_t); | 6 | extern int (*rtc_sh_set_time)(const time_t); |
7 | 7 | ||
8 | #define RTC_CAP_4_DIGIT_YEAR (1 << 0) | ||
9 | |||
10 | struct sh_rtc_platform_info { | ||
11 | unsigned long capabilities; | ||
12 | }; | ||
13 | |||
8 | #endif /* _ASM_RTC_H */ | 14 | #endif /* _ASM_RTC_H */ |