diff options
Diffstat (limited to 'arch/sparc64/kernel/time.c')
-rw-r--r-- | arch/sparc64/kernel/time.c | 79 |
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 | |||
1438 | static 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 | |||
1467 | static 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 | ||
1439 | struct mini_rtc_ops { | 1511 | struct 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 | |||
1532 | static 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 | ||
1461 | static struct mini_rtc_ops *mini_rtc_ops; | 1538 | static 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; |