| 565 | } |
| 566 | |
| 567 | static int |
| 568 | atrtc_gettime(device_t dev, struct timespec *ts) |
| 569 | { |
| 570 | struct bcd_clocktime bct; |
| 571 | |
| 572 | /* Look if we have a RTC present and the time is valid */ |
| 573 | if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) { |
| 574 | device_printf(dev, "WARNING: Battery failure indication\n"); |
| 575 | return (EINVAL); |
| 576 | } |
| 577 | |
| 578 | /* |
| 579 | * wait for time update to complete |
| 580 | * If RTCSA_TUP is zero, we have at least 244us before next update. |
| 581 | * This is fast enough on most hardware, but a refinement would be |
| 582 | * to make sure that no more than 240us pass after we start reading, |
| 583 | * and try again if so. |
| 584 | */ |
| 585 | mtx_lock(&atrtc_time_lock); |
| 586 | while (rtcin(RTC_STATUSA) & RTCSA_TUP) |
| 587 | continue; |
| 588 | mtx_lock_spin(&atrtc_lock); |
| 589 | bct.sec = rtcin_locked(RTC_SEC); |
| 590 | bct.min = rtcin_locked(RTC_MIN); |
| 591 | bct.hour = rtcin_locked(RTC_HRS); |
| 592 | bct.day = rtcin_locked(RTC_DAY); |
| 593 | bct.mon = rtcin_locked(RTC_MONTH); |
| 594 | bct.year = rtcin_locked(RTC_YEAR); |
| 595 | #ifdef USE_RTC_CENTURY |
| 596 | bct.year |= rtcin_locked(RTC_CENTURY) << 8; |
| 597 | #endif |
| 598 | mtx_unlock_spin(&atrtc_lock); |
| 599 | mtx_unlock(&atrtc_time_lock); |
| 600 | /* dow is unused in timespec conversion and we have no nsec info. */ |
| 601 | bct.dow = 0; |
| 602 | bct.nsec = 0; |
| 603 | clock_dbgprint_bcd(dev, CLOCK_DBG_READ, &bct); |
| 604 | return (clock_bcd_to_ts(&bct, ts, false)); |
| 605 | } |
| 606 | |
| 607 | static device_method_t atrtc_isa_methods[] = { |
| 608 | /* Device interface */ |
nothing calls this directly
no test coverage detected