aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/time.c')
-rw-r--r--arch/sparc64/kernel/time.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 592ffcd57605..e340eb401fb9 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -1434,6 +1434,78 @@ static int bq4802_set_rtc_time(struct rtc_time *time)
1434 1434
1435 return 0; 1435 return 0;
1436} 1436}
1437
1438static void cmos_get_rtc_time(struct rtc_time *rtc_tm)
1439{
1440 unsigned char ctrl;
1441
1442 rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
1443 rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
1444 rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
1445 rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
1446 rtc_tm->tm_mon = CMOS_READ(RTC_MONTH);
1447 rtc_tm->tm_year = CMOS_READ(RTC_YEAR);
1448 rtc_tm->tm_wday = CMOS_READ(RTC_DAY_OF_WEEK);
1449
1450 ctrl = CMOS_READ(RTC_CONTROL);
1451 if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
1452 BCD_TO_BIN(rtc_tm->tm_sec);
1453 BCD_TO_BIN(rtc_tm->tm_min);
1454 BCD_TO_BIN(rtc_tm->tm_hour);
1455 BCD_TO_BIN(rtc_tm->tm_mday);
1456 BCD_TO_BIN(rtc_tm->tm_mon);
1457 BCD_TO_BIN(rtc_tm->tm_year);
1458 BCD_TO_BIN(rtc_tm->tm_wday);
1459 }
1460
1461 if (rtc_tm->tm_year <= 69)
1462 rtc_tm->tm_year += 100;
1463
1464 rtc_tm->tm_mon--;
1465}
1466
1467static int cmos_set_rtc_time(struct rtc_time *rtc_tm)
1468{
1469 unsigned char mon, day, hrs, min, sec;
1470 unsigned char save_control, save_freq_select;
1471 unsigned int yrs;
1472
1473 yrs = rtc_tm->tm_year;
1474 mon = rtc_tm->tm_mon + 1;
1475 day = rtc_tm->tm_mday;
1476 hrs = rtc_tm->tm_hour;
1477 min = rtc_tm->tm_min;
1478 sec = rtc_tm->tm_sec;
1479
1480 if (yrs >= 100)
1481 yrs -= 100;
1482
1483 if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
1484 BIN_TO_BCD(sec);
1485 BIN_TO_BCD(min);
1486 BIN_TO_BCD(hrs);
1487 BIN_TO_BCD(day);
1488 BIN_TO_BCD(mon);
1489 BIN_TO_BCD(yrs);
1490 }
1491
1492 save_control = CMOS_READ(RTC_CONTROL);
1493 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
1494 save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
1495 CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
1496
1497 CMOS_WRITE(yrs, RTC_YEAR);
1498 CMOS_WRITE(mon, RTC_MONTH);
1499 CMOS_WRITE(day, RTC_DAY_OF_MONTH);
1500 CMOS_WRITE(hrs, RTC_HOURS);
1501 CMOS_WRITE(min, RTC_MINUTES);
1502 CMOS_WRITE(sec, RTC_SECONDS);
1503
1504 CMOS_WRITE(save_control, RTC_CONTROL);
1505 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
1506
1507 return 0;
1508}
1437#endif /* CONFIG_PCI */ 1509#endif /* CONFIG_PCI */
1438 1510
1439struct mini_rtc_ops { 1511struct mini_rtc_ops {
@@ -1456,6 +1528,11 @@ static struct mini_rtc_ops bq4802_rtc_ops = {
1456 .get_rtc_time = bq4802_get_rtc_time, 1528 .get_rtc_time = bq4802_get_rtc_time,
1457 .set_rtc_time = bq4802_set_rtc_time, 1529 .set_rtc_time = bq4802_set_rtc_time,
1458}; 1530};
1531
1532static struct mini_rtc_ops cmos_rtc_ops = {
1533 .get_rtc_time = cmos_get_rtc_time,
1534 .set_rtc_time = cmos_set_rtc_time,
1535};
1459#endif /* CONFIG_PCI */ 1536#endif /* CONFIG_PCI */
1460 1537
1461static struct mini_rtc_ops *mini_rtc_ops; 1538static struct mini_rtc_ops *mini_rtc_ops;
@@ -1583,6 +1660,8 @@ static int __init rtc_mini_init(void)
1583#ifdef CONFIG_PCI 1660#ifdef CONFIG_PCI
1584 else if (bq4802_regs) 1661 else if (bq4802_regs)
1585 mini_rtc_ops = &bq4802_rtc_ops; 1662 mini_rtc_ops = &bq4802_rtc_ops;
1663 else if (ds1287_regs)
1664 mini_rtc_ops = &cmos_rtc_ops;
1586#endif /* CONFIG_PCI */ 1665#endif /* CONFIG_PCI */
1587 else 1666 else
1588 return -ENODEV; 1667 return -ENODEV;