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; |
