Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sparc64: Use generic CMOS driver.

Based largely upon a patch by Krzysztof Helt <krzysztof.h1@poczta.fm>

Signed-off-by: David S. Miller <davem@davemloft.net>

+125 -262
+2 -8
arch/sparc/include/asm/mc146818rtc_64.h
··· 7 7 #include <asm/io.h> 8 8 9 9 #ifndef RTC_PORT 10 - #ifdef CONFIG_PCI 11 - extern unsigned long ds1287_regs; 12 - #else 13 - #define ds1287_regs (0UL) 14 - #endif 15 - #define RTC_PORT(x) (ds1287_regs + (x)) 10 + extern unsigned long cmos_regs; 11 + #define RTC_PORT(x) (cmos_regs + (x)) 16 12 #define RTC_ALWAYS_BCD 0 17 13 #endif 18 14 ··· 24 28 outb_p((addr),RTC_PORT(0)); \ 25 29 outb_p((val),RTC_PORT(1)); \ 26 30 }) 27 - 28 - #define RTC_IRQ 8 29 31 30 32 #endif /* __ASM_SPARC64_MC146818RTC_H */
+1
arch/sparc64/Kconfig
··· 21 21 select ARCH_WANT_OPTIONAL_GPIOLIB 22 22 select RTC_CLASS 23 23 select RTC_DRV_M48T59 24 + select RTC_DRV_CMOS 24 25 25 26 config GENERIC_TIME 26 27 bool
+122 -254
arch/sparc64/kernel/time.c
··· 52 52 #include "entry.h" 53 53 54 54 DEFINE_SPINLOCK(rtc_lock); 55 - #ifdef CONFIG_PCI 56 - unsigned long ds1287_regs = 0UL; 57 55 static void __iomem *bq4802_regs; 58 - #endif 59 56 60 57 static int set_rtc_mmss(unsigned long); 61 58 ··· 410 413 static void __init set_system_time(void) 411 414 { 412 415 unsigned int year, mon, day, hour, min, sec; 413 - #ifdef CONFIG_PCI 414 - unsigned long dregs = ds1287_regs; 415 416 void __iomem *bregs = bq4802_regs; 416 - #else 417 - unsigned long dregs = 0UL; 418 - void __iomem *bregs = 0UL; 419 - #endif 417 + unsigned char val = readb(bregs + 0x0e); 418 + unsigned int century; 420 419 421 - if (!dregs && !bregs) { 420 + if (!bregs) { 422 421 prom_printf("Something wrong, clock regs not mapped yet.\n"); 423 422 prom_halt(); 424 423 } 425 424 426 - if (bregs) { 427 - unsigned char val = readb(bregs + 0x0e); 428 - unsigned int century; 425 + /* BQ4802 RTC chip. */ 429 426 430 - /* BQ4802 RTC chip. */ 427 + writeb(val | 0x08, bregs + 0x0e); 431 428 432 - writeb(val | 0x08, bregs + 0x0e); 429 + sec = readb(bregs + 0x00); 430 + min = readb(bregs + 0x02); 431 + hour = readb(bregs + 0x04); 432 + day = readb(bregs + 0x06); 433 + mon = readb(bregs + 0x09); 434 + year = readb(bregs + 0x0a); 435 + century = readb(bregs + 0x0f); 433 436 434 - sec = readb(bregs + 0x00); 435 - min = readb(bregs + 0x02); 436 - hour = readb(bregs + 0x04); 437 - day = readb(bregs + 0x06); 438 - mon = readb(bregs + 0x09); 439 - year = readb(bregs + 0x0a); 440 - century = readb(bregs + 0x0f); 437 + writeb(val, bregs + 0x0e); 441 438 442 - writeb(val, bregs + 0x0e); 439 + BCD_TO_BIN(sec); 440 + BCD_TO_BIN(min); 441 + BCD_TO_BIN(hour); 442 + BCD_TO_BIN(day); 443 + BCD_TO_BIN(mon); 444 + BCD_TO_BIN(year); 445 + BCD_TO_BIN(century); 443 446 444 - BCD_TO_BIN(sec); 445 - BCD_TO_BIN(min); 446 - BCD_TO_BIN(hour); 447 - BCD_TO_BIN(day); 448 - BCD_TO_BIN(mon); 449 - BCD_TO_BIN(year); 450 - BCD_TO_BIN(century); 451 - 452 - year += (century * 100); 453 - } else { 454 - /* Dallas 12887 RTC chip. */ 455 - 456 - do { 457 - sec = CMOS_READ(RTC_SECONDS); 458 - min = CMOS_READ(RTC_MINUTES); 459 - hour = CMOS_READ(RTC_HOURS); 460 - day = CMOS_READ(RTC_DAY_OF_MONTH); 461 - mon = CMOS_READ(RTC_MONTH); 462 - year = CMOS_READ(RTC_YEAR); 463 - } while (sec != CMOS_READ(RTC_SECONDS)); 464 - 465 - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 466 - BCD_TO_BIN(sec); 467 - BCD_TO_BIN(min); 468 - BCD_TO_BIN(hour); 469 - BCD_TO_BIN(day); 470 - BCD_TO_BIN(mon); 471 - BCD_TO_BIN(year); 472 - } 473 - if ((year += 1900) < 1970) 474 - year += 100; 475 - } 447 + year += (century * 100); 476 448 477 449 xtime.tv_sec = mktime(year, mon, day, hour, min, sec); 478 450 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); ··· 512 546 return -EOPNOTSUPP; 513 547 } 514 548 515 - static int __init rtc_model_matches(const char *model) 516 - { 517 - if (strcmp(model, "m5819") && 518 - strcmp(model, "m5819p") && 519 - strcmp(model, "m5823") && 520 - strcmp(model, "ds1287") && 521 - strcmp(model, "bq4802")) 522 - return 0; 549 + unsigned long cmos_regs; 550 + EXPORT_SYMBOL(cmos_regs); 523 551 524 - return 1; 525 - } 552 + struct resource rtc_cmos_resource; 553 + 554 + static struct platform_device rtc_cmos_device = { 555 + .name = "rtc_cmos", 556 + .id = -1, 557 + .resource = &rtc_cmos_resource, 558 + .num_resources = 1, 559 + }; 526 560 527 561 static int __devinit rtc_probe(struct of_device *op, const struct of_device_id *match) 528 562 { 563 + struct resource *r; 564 + 565 + printk(KERN_INFO "%s: RTC regs at 0x%lx\n", 566 + op->node->full_name, op->resource[0].start); 567 + 568 + /* The CMOS RTC driver only accepts IORESOURCE_IO, so cons 569 + * up a fake resource so that the probe works for all cases. 570 + * When the RTC is behind an ISA bus it will have IORESOURCE_IO 571 + * already, whereas when it's behind EBUS is will be IORESOURCE_MEM. 572 + */ 573 + 574 + r = &rtc_cmos_resource; 575 + r->flags = IORESOURCE_IO; 576 + r->name = op->resource[0].name; 577 + r->start = op->resource[0].start; 578 + r->end = op->resource[0].end; 579 + 580 + cmos_regs = op->resource[0].start; 581 + return platform_device_register(&rtc_cmos_device); 582 + } 583 + 584 + static struct of_device_id rtc_match[] = { 585 + { 586 + .name = "rtc", 587 + .compatible = "m5819", 588 + }, 589 + { 590 + .name = "rtc", 591 + .compatible = "isa-m5819p", 592 + }, 593 + { 594 + .name = "rtc", 595 + .compatible = "isa-m5823p", 596 + }, 597 + { 598 + .name = "rtc", 599 + .compatible = "ds1287", 600 + }, 601 + {}, 602 + }; 603 + 604 + static struct of_platform_driver rtc_driver = { 605 + .match_table = rtc_match, 606 + .probe = rtc_probe, 607 + .driver = { 608 + .name = "rtc", 609 + }, 610 + }; 611 + 612 + static int __devinit bq4802_probe(struct of_device *op, const struct of_device_id *match) 613 + { 529 614 struct device_node *dp = op->node; 530 - const char *model = of_get_property(dp, "model", NULL); 531 - const char *compat = of_get_property(dp, "compatible", NULL); 532 - unsigned long size, flags; 533 - void __iomem *regs; 615 + unsigned long flags; 534 616 535 - if (!model) 536 - model = compat; 537 - 538 - if (!model || !rtc_model_matches(model)) 539 - return -ENODEV; 540 - 541 - size = (op->resource[0].end - op->resource[0].start) + 1; 542 - regs = of_ioremap(&op->resource[0], 0, size, "clock"); 543 - if (!regs) 617 + bq4802_regs = of_ioremap(&op->resource[0], 0, resource_size(&op->resource[0]), "bq4802"); 618 + if (!bq4802_regs) 544 619 return -ENOMEM; 545 620 546 - #ifdef CONFIG_PCI 547 - if (!strcmp(model, "ds1287") || 548 - !strcmp(model, "m5819") || 549 - !strcmp(model, "m5819p") || 550 - !strcmp(model, "m5823")) { 551 - ds1287_regs = (unsigned long) regs; 552 - } else if (!strcmp(model, "bq4802")) { 553 - bq4802_regs = regs; 554 - } 555 - #endif 556 - printk(KERN_INFO "%s: Clock regs at %p\n", dp->full_name, regs); 621 + printk(KERN_INFO "%s: Clock regs at %p\n", dp->full_name, bq4802_regs); 557 622 558 623 local_irq_save(flags); 559 624 ··· 595 598 return 0; 596 599 } 597 600 598 - static struct of_device_id rtc_match[] = { 601 + static struct of_device_id bq4802_match[] = { 599 602 { 600 603 .name = "rtc", 604 + .compatible = "bq4802", 601 605 }, 602 - {}, 603 606 }; 604 607 605 - static struct of_platform_driver rtc_driver = { 606 - .match_table = rtc_match, 607 - .probe = rtc_probe, 608 + static struct of_platform_driver bq4802_driver = { 609 + .match_table = bq4802_match, 610 + .probe = bq4802_probe, 608 611 .driver = { 609 - .name = "rtc", 612 + .name = "bq4802", 610 613 }, 611 614 }; 612 615 ··· 713 716 714 717 (void) of_register_driver(&rtc_driver, &of_platform_bus_type); 715 718 (void) of_register_driver(&mostek_driver, &of_platform_bus_type); 719 + (void) of_register_driver(&bq4802_driver, &of_platform_bus_type); 716 720 717 721 return 0; 718 722 } ··· 987 989 static int set_rtc_mmss(unsigned long nowtime) 988 990 { 989 991 int real_seconds, real_minutes, chip_minutes; 990 - #ifdef CONFIG_PCI 991 - unsigned long dregs = ds1287_regs; 992 992 void __iomem *bregs = bq4802_regs; 993 - #else 994 - unsigned long dregs = 0UL; 995 - void __iomem *bregs = 0UL; 996 - #endif 997 993 unsigned long flags; 994 + unsigned char val; 995 + int retval = 0; 998 996 999 997 /* 1000 998 * Not having a register set can lead to trouble. 1001 999 * Also starfire doesn't have a tod clock. 1002 1000 */ 1003 - if (!dregs && !bregs) 1001 + if (!bregs) 1004 1002 return -1; 1005 1003 1006 - if (bregs) { 1007 - int retval = 0; 1008 - unsigned char val = readb(bregs + 0x0e); 1004 + spin_lock_irqsave(&rtc_lock, flags); 1009 1005 1010 - /* BQ4802 RTC chip. */ 1006 + val = readb(bregs + 0x0e); 1011 1007 1012 - writeb(val | 0x08, bregs + 0x0e); 1008 + /* BQ4802 RTC chip. */ 1013 1009 1014 - chip_minutes = readb(bregs + 0x02); 1015 - BCD_TO_BIN(chip_minutes); 1016 - real_seconds = nowtime % 60; 1017 - real_minutes = nowtime / 60; 1018 - if (((abs(real_minutes - chip_minutes) + 15)/30) & 1) 1019 - real_minutes += 30; 1020 - real_minutes %= 60; 1010 + writeb(val | 0x08, bregs + 0x0e); 1021 1011 1022 - if (abs(real_minutes - chip_minutes) < 30) { 1023 - BIN_TO_BCD(real_seconds); 1024 - BIN_TO_BCD(real_minutes); 1025 - writeb(real_seconds, bregs + 0x00); 1026 - writeb(real_minutes, bregs + 0x02); 1027 - } else { 1028 - printk(KERN_WARNING 1029 - "set_rtc_mmss: can't update from %d to %d\n", 1030 - chip_minutes, real_minutes); 1031 - retval = -1; 1032 - } 1012 + chip_minutes = readb(bregs + 0x02); 1013 + BCD_TO_BIN(chip_minutes); 1014 + real_seconds = nowtime % 60; 1015 + real_minutes = nowtime / 60; 1016 + if (((abs(real_minutes - chip_minutes) + 15)/30) & 1) 1017 + real_minutes += 30; 1018 + real_minutes %= 60; 1033 1019 1034 - writeb(val, bregs + 0x0e); 1035 - 1036 - return retval; 1020 + if (abs(real_minutes - chip_minutes) < 30) { 1021 + BIN_TO_BCD(real_seconds); 1022 + BIN_TO_BCD(real_minutes); 1023 + writeb(real_seconds, bregs + 0x00); 1024 + writeb(real_minutes, bregs + 0x02); 1037 1025 } else { 1038 - int retval = 0; 1039 - unsigned char save_control, save_freq_select; 1040 - 1041 - /* Stolen from arch/i386/kernel/time.c, see there for 1042 - * credits and descriptive comments. 1043 - */ 1044 - spin_lock_irqsave(&rtc_lock, flags); 1045 - save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ 1046 - CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); 1047 - 1048 - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ 1049 - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); 1050 - 1051 - chip_minutes = CMOS_READ(RTC_MINUTES); 1052 - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) 1053 - BCD_TO_BIN(chip_minutes); 1054 - real_seconds = nowtime % 60; 1055 - real_minutes = nowtime / 60; 1056 - if (((abs(real_minutes - chip_minutes) + 15)/30) & 1) 1057 - real_minutes += 30; 1058 - real_minutes %= 60; 1059 - 1060 - if (abs(real_minutes - chip_minutes) < 30) { 1061 - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 1062 - BIN_TO_BCD(real_seconds); 1063 - BIN_TO_BCD(real_minutes); 1064 - } 1065 - CMOS_WRITE(real_seconds,RTC_SECONDS); 1066 - CMOS_WRITE(real_minutes,RTC_MINUTES); 1067 - } else { 1068 - printk(KERN_WARNING 1069 - "set_rtc_mmss: can't update from %d to %d\n", 1070 - chip_minutes, real_minutes); 1071 - retval = -1; 1072 - } 1073 - 1074 - CMOS_WRITE(save_control, RTC_CONTROL); 1075 - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); 1076 - spin_unlock_irqrestore(&rtc_lock, flags); 1077 - 1078 - return retval; 1026 + printk(KERN_WARNING 1027 + "set_rtc_mmss: can't update from %d to %d\n", 1028 + chip_minutes, real_minutes); 1029 + retval = -1; 1079 1030 } 1031 + 1032 + writeb(val, bregs + 0x0e); 1033 + 1034 + spin_unlock_irqrestore(&rtc_lock, flags); 1035 + 1036 + return retval; 1080 1037 } 1081 1038 1082 1039 #define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ ··· 1155 1202 return hypervisor_set_time(seconds); 1156 1203 } 1157 1204 1158 - #ifdef CONFIG_PCI 1159 1205 static void bq4802_get_rtc_time(struct rtc_time *time) 1160 1206 { 1161 1207 unsigned char val = readb(bq4802_regs + 0x0e); ··· 1227 1275 return 0; 1228 1276 } 1229 1277 1230 - static void cmos_get_rtc_time(struct rtc_time *rtc_tm) 1231 - { 1232 - unsigned char ctrl; 1233 - 1234 - rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); 1235 - rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); 1236 - rtc_tm->tm_hour = CMOS_READ(RTC_HOURS); 1237 - rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH); 1238 - rtc_tm->tm_mon = CMOS_READ(RTC_MONTH); 1239 - rtc_tm->tm_year = CMOS_READ(RTC_YEAR); 1240 - rtc_tm->tm_wday = CMOS_READ(RTC_DAY_OF_WEEK); 1241 - 1242 - ctrl = CMOS_READ(RTC_CONTROL); 1243 - if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 1244 - BCD_TO_BIN(rtc_tm->tm_sec); 1245 - BCD_TO_BIN(rtc_tm->tm_min); 1246 - BCD_TO_BIN(rtc_tm->tm_hour); 1247 - BCD_TO_BIN(rtc_tm->tm_mday); 1248 - BCD_TO_BIN(rtc_tm->tm_mon); 1249 - BCD_TO_BIN(rtc_tm->tm_year); 1250 - BCD_TO_BIN(rtc_tm->tm_wday); 1251 - } 1252 - 1253 - if (rtc_tm->tm_year <= 69) 1254 - rtc_tm->tm_year += 100; 1255 - 1256 - rtc_tm->tm_mon--; 1257 - } 1258 - 1259 - static int cmos_set_rtc_time(struct rtc_time *rtc_tm) 1260 - { 1261 - unsigned char mon, day, hrs, min, sec; 1262 - unsigned char save_control, save_freq_select; 1263 - unsigned int yrs; 1264 - 1265 - yrs = rtc_tm->tm_year; 1266 - mon = rtc_tm->tm_mon + 1; 1267 - day = rtc_tm->tm_mday; 1268 - hrs = rtc_tm->tm_hour; 1269 - min = rtc_tm->tm_min; 1270 - sec = rtc_tm->tm_sec; 1271 - 1272 - if (yrs >= 100) 1273 - yrs -= 100; 1274 - 1275 - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 1276 - BIN_TO_BCD(sec); 1277 - BIN_TO_BCD(min); 1278 - BIN_TO_BCD(hrs); 1279 - BIN_TO_BCD(day); 1280 - BIN_TO_BCD(mon); 1281 - BIN_TO_BCD(yrs); 1282 - } 1283 - 1284 - save_control = CMOS_READ(RTC_CONTROL); 1285 - CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); 1286 - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); 1287 - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); 1288 - 1289 - CMOS_WRITE(yrs, RTC_YEAR); 1290 - CMOS_WRITE(mon, RTC_MONTH); 1291 - CMOS_WRITE(day, RTC_DAY_OF_MONTH); 1292 - CMOS_WRITE(hrs, RTC_HOURS); 1293 - CMOS_WRITE(min, RTC_MINUTES); 1294 - CMOS_WRITE(sec, RTC_SECONDS); 1295 - 1296 - CMOS_WRITE(save_control, RTC_CONTROL); 1297 - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); 1298 - 1299 - return 0; 1300 - } 1301 - #endif /* CONFIG_PCI */ 1302 - 1303 1278 struct mini_rtc_ops { 1304 1279 void (*get_rtc_time)(struct rtc_time *); 1305 1280 int (*set_rtc_time)(struct rtc_time *); ··· 1242 1363 .set_rtc_time = hypervisor_set_rtc_time, 1243 1364 }; 1244 1365 1245 - #ifdef CONFIG_PCI 1246 1366 static struct mini_rtc_ops bq4802_rtc_ops = { 1247 1367 .get_rtc_time = bq4802_get_rtc_time, 1248 1368 .set_rtc_time = bq4802_set_rtc_time, 1249 1369 }; 1250 - 1251 - static struct mini_rtc_ops cmos_rtc_ops = { 1252 - .get_rtc_time = cmos_get_rtc_time, 1253 - .set_rtc_time = cmos_set_rtc_time, 1254 - }; 1255 - #endif /* CONFIG_PCI */ 1256 1370 1257 1371 static struct mini_rtc_ops *mini_rtc_ops; 1258 1372 ··· 1373 1501 mini_rtc_ops = &hypervisor_rtc_ops; 1374 1502 else if (this_is_starfire) 1375 1503 mini_rtc_ops = &starfire_rtc_ops; 1376 - #ifdef CONFIG_PCI 1377 1504 else if (bq4802_regs) 1378 1505 mini_rtc_ops = &bq4802_rtc_ops; 1379 - else if (ds1287_regs) 1380 - mini_rtc_ops = &cmos_rtc_ops; 1381 - #endif /* CONFIG_PCI */ 1382 1506 else 1383 1507 return -ENODEV; 1384 1508