aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-29 00:54:34 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-29 17:16:50 -0400
commit29b503f11cd648b3628be3a546f97da95a6670ce (patch)
tree534ac37509091dd14b03d5cd84e89a757eafae27
parentcca4c231028405950a15f5a27d7326d18d909784 (diff)
sparc64: Use generic BQ4802 RTC driver.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc64/Kconfig1
-rw-r--r--arch/sparc64/kernel/time.c201
2 files changed, 12 insertions, 190 deletions
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index e0d783bbae09..a4ec899faa42 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -22,6 +22,7 @@ config SPARC64
22 select RTC_CLASS 22 select RTC_CLASS
23 select RTC_DRV_M48T59 23 select RTC_DRV_M48T59
24 select RTC_DRV_CMOS 24 select RTC_DRV_CMOS
25 select RTC_DRV_BQ4802
25 26
26config GENERIC_TIME 27config GENERIC_TIME
27 bool 28 bool
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index abdeead4e5b9..5e199a0e4378 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -52,9 +52,6 @@
52#include "entry.h" 52#include "entry.h"
53 53
54DEFINE_SPINLOCK(rtc_lock); 54DEFINE_SPINLOCK(rtc_lock);
55static void __iomem *bq4802_regs;
56
57static int set_rtc_mmss(unsigned long);
58 55
59#define TICK_PRIV_BIT (1UL << 63) 56#define TICK_PRIV_BIT (1UL << 63)
60#define TICKCMP_IRQ_BIT (1UL << 63) 57#define TICKCMP_IRQ_BIT (1UL << 63)
@@ -403,50 +400,7 @@ int update_persistent_clock(struct timespec now)
403 if (rtc) 400 if (rtc)
404 return rtc_set_mmss(rtc, now.tv_sec); 401 return rtc_set_mmss(rtc, now.tv_sec);
405 402
406 return set_rtc_mmss(now.tv_sec); 403 return -1;
407}
408
409/* Probe for the real time clock chip. */
410static void __init set_system_time(void)
411{
412 unsigned int year, mon, day, hour, min, sec;
413 void __iomem *bregs = bq4802_regs;
414 unsigned char val = readb(bregs + 0x0e);
415 unsigned int century;
416
417 if (!bregs) {
418 prom_printf("Something wrong, clock regs not mapped yet.\n");
419 prom_halt();
420 }
421
422 /* BQ4802 RTC chip. */
423
424 writeb(val | 0x08, bregs + 0x0e);
425
426 sec = readb(bregs + 0x00);
427 min = readb(bregs + 0x02);
428 hour = readb(bregs + 0x04);
429 day = readb(bregs + 0x06);
430 mon = readb(bregs + 0x09);
431 year = readb(bregs + 0x0a);
432 century = readb(bregs + 0x0f);
433
434 writeb(val, bregs + 0x0e);
435
436 BCD_TO_BIN(sec);
437 BCD_TO_BIN(min);
438 BCD_TO_BIN(hour);
439 BCD_TO_BIN(day);
440 BCD_TO_BIN(mon);
441 BCD_TO_BIN(year);
442 BCD_TO_BIN(century);
443
444 year += (century * 100);
445
446 xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
447 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
448 set_normalized_timespec(&wall_to_monotonic,
449 -xtime.tv_sec, -xtime.tv_nsec);
450} 404}
451 405
452/* davem suggests we keep this within the 4M locked kernel image */ 406/* davem suggests we keep this within the 4M locked kernel image */
@@ -575,24 +529,20 @@ static struct of_platform_driver rtc_driver = {
575 }, 529 },
576}; 530};
577 531
532static struct platform_device rtc_bq4802_device = {
533 .name = "rtc-bq4802",
534 .id = -1,
535 .num_resources = 1,
536};
537
578static int __devinit bq4802_probe(struct of_device *op, const struct of_device_id *match) 538static int __devinit bq4802_probe(struct of_device *op, const struct of_device_id *match)
579{ 539{
580 struct device_node *dp = op->node;
581 unsigned long flags;
582
583 bq4802_regs = of_ioremap(&op->resource[0], 0, resource_size(&op->resource[0]), "bq4802");
584 if (!bq4802_regs)
585 return -ENOMEM;
586
587 printk(KERN_INFO "%s: Clock regs at %p\n", dp->full_name, bq4802_regs);
588 540
589 local_irq_save(flags); 541 printk(KERN_INFO "%s: BQ4802 regs at 0x%lx\n",
590 542 op->node->full_name, op->resource[0].start);
591 set_system_time();
592
593 local_irq_restore(flags);
594 543
595 return 0; 544 rtc_bq4802_device.resource = &op->resource[0];
545 return platform_device_register(&rtc_bq4802_device);
596} 546}
597 547
598static struct of_device_id bq4802_match[] = { 548static struct of_device_id bq4802_match[] = {
@@ -984,56 +934,6 @@ unsigned long long sched_clock(void)
984 >> SPARC64_NSEC_PER_CYC_SHIFT; 934 >> SPARC64_NSEC_PER_CYC_SHIFT;
985} 935}
986 936
987static int set_rtc_mmss(unsigned long nowtime)
988{
989 int real_seconds, real_minutes, chip_minutes;
990 void __iomem *bregs = bq4802_regs;
991 unsigned long flags;
992 unsigned char val;
993 int retval = 0;
994
995 /*
996 * Not having a register set can lead to trouble.
997 * Also starfire doesn't have a tod clock.
998 */
999 if (!bregs)
1000 return -1;
1001
1002 spin_lock_irqsave(&rtc_lock, flags);
1003
1004 val = readb(bregs + 0x0e);
1005
1006 /* BQ4802 RTC chip. */
1007
1008 writeb(val | 0x08, bregs + 0x0e);
1009
1010 chip_minutes = readb(bregs + 0x02);
1011 BCD_TO_BIN(chip_minutes);
1012 real_seconds = nowtime % 60;
1013 real_minutes = nowtime / 60;
1014 if (((abs(real_minutes - chip_minutes) + 15)/30) & 1)
1015 real_minutes += 30;
1016 real_minutes %= 60;
1017
1018 if (abs(real_minutes - chip_minutes) < 30) {
1019 BIN_TO_BCD(real_seconds);
1020 BIN_TO_BCD(real_minutes);
1021 writeb(real_seconds, bregs + 0x00);
1022 writeb(real_minutes, bregs + 0x02);
1023 } else {
1024 printk(KERN_WARNING
1025 "set_rtc_mmss: can't update from %d to %d\n",
1026 chip_minutes, real_minutes);
1027 retval = -1;
1028 }
1029
1030 writeb(val, bregs + 0x0e);
1031
1032 spin_unlock_irqrestore(&rtc_lock, flags);
1033
1034 return retval;
1035}
1036
1037#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ 937#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */
1038static unsigned char mini_rtc_status; /* bitmapped status byte. */ 938static unsigned char mini_rtc_status; /* bitmapped status byte. */
1039 939
@@ -1155,78 +1055,6 @@ static int hypervisor_set_rtc_time(struct rtc_time *time)
1155 return hypervisor_set_time(seconds); 1055 return hypervisor_set_time(seconds);
1156} 1056}
1157 1057
1158static void bq4802_get_rtc_time(struct rtc_time *time)
1159{
1160 unsigned char val = readb(bq4802_regs + 0x0e);
1161 unsigned int century;
1162
1163 writeb(val | 0x08, bq4802_regs + 0x0e);
1164
1165 time->tm_sec = readb(bq4802_regs + 0x00);
1166 time->tm_min = readb(bq4802_regs + 0x02);
1167 time->tm_hour = readb(bq4802_regs + 0x04);
1168 time->tm_mday = readb(bq4802_regs + 0x06);
1169 time->tm_mon = readb(bq4802_regs + 0x09);
1170 time->tm_year = readb(bq4802_regs + 0x0a);
1171 time->tm_wday = readb(bq4802_regs + 0x08);
1172 century = readb(bq4802_regs + 0x0f);
1173
1174 writeb(val, bq4802_regs + 0x0e);
1175
1176 BCD_TO_BIN(time->tm_sec);
1177 BCD_TO_BIN(time->tm_min);
1178 BCD_TO_BIN(time->tm_hour);
1179 BCD_TO_BIN(time->tm_mday);
1180 BCD_TO_BIN(time->tm_mon);
1181 BCD_TO_BIN(time->tm_year);
1182 BCD_TO_BIN(time->tm_wday);
1183 BCD_TO_BIN(century);
1184
1185 time->tm_year += (century * 100);
1186 time->tm_year -= 1900;
1187
1188 time->tm_mon--;
1189}
1190
1191static int bq4802_set_rtc_time(struct rtc_time *time)
1192{
1193 unsigned char val = readb(bq4802_regs + 0x0e);
1194 unsigned char sec, min, hrs, day, mon, yrs, century;
1195 unsigned int year;
1196
1197 year = time->tm_year + 1900;
1198 century = year / 100;
1199 yrs = year % 100;
1200
1201 mon = time->tm_mon + 1; /* tm_mon starts at zero */
1202 day = time->tm_mday;
1203 hrs = time->tm_hour;
1204 min = time->tm_min;
1205 sec = time->tm_sec;
1206
1207 BIN_TO_BCD(sec);
1208 BIN_TO_BCD(min);
1209 BIN_TO_BCD(hrs);
1210 BIN_TO_BCD(day);
1211 BIN_TO_BCD(mon);
1212 BIN_TO_BCD(yrs);
1213 BIN_TO_BCD(century);
1214
1215 writeb(val | 0x08, bq4802_regs + 0x0e);
1216
1217 writeb(sec, bq4802_regs + 0x00);
1218 writeb(min, bq4802_regs + 0x02);
1219 writeb(hrs, bq4802_regs + 0x04);
1220 writeb(day, bq4802_regs + 0x06);
1221 writeb(mon, bq4802_regs + 0x09);
1222 writeb(yrs, bq4802_regs + 0x0a);
1223 writeb(century, bq4802_regs + 0x0f);
1224
1225 writeb(val, bq4802_regs + 0x0e);
1226
1227 return 0;
1228}
1229
1230struct mini_rtc_ops { 1058struct mini_rtc_ops {
1231 void (*get_rtc_time)(struct rtc_time *); 1059 void (*get_rtc_time)(struct rtc_time *);
1232 int (*set_rtc_time)(struct rtc_time *); 1060 int (*set_rtc_time)(struct rtc_time *);
@@ -1242,11 +1070,6 @@ static struct mini_rtc_ops hypervisor_rtc_ops = {
1242 .set_rtc_time = hypervisor_set_rtc_time, 1070 .set_rtc_time = hypervisor_set_rtc_time,
1243}; 1071};
1244 1072
1245static struct mini_rtc_ops bq4802_rtc_ops = {
1246 .get_rtc_time = bq4802_get_rtc_time,
1247 .set_rtc_time = bq4802_set_rtc_time,
1248};
1249
1250static struct mini_rtc_ops *mini_rtc_ops; 1073static struct mini_rtc_ops *mini_rtc_ops;
1251 1074
1252static inline void mini_get_rtc_time(struct rtc_time *time) 1075static inline void mini_get_rtc_time(struct rtc_time *time)
@@ -1373,8 +1196,6 @@ static int __init rtc_mini_init(void)
1373 mini_rtc_ops = &hypervisor_rtc_ops; 1196 mini_rtc_ops = &hypervisor_rtc_ops;
1374 else if (this_is_starfire) 1197 else if (this_is_starfire)
1375 mini_rtc_ops = &starfire_rtc_ops; 1198 mini_rtc_ops = &starfire_rtc_ops;
1376 else if (bq4802_regs)
1377 mini_rtc_ops = &bq4802_rtc_ops;
1378 else 1199 else
1379 return -ENODEV; 1200 return -ENODEV;
1380 1201