Add static inline rtcin_locked() and rtcout_locked() functions for doing a
related series of operations without doing a lock/unlock for each byte. Use them when reading and writing the entire set of time registers. The original rtcin() and writertc() functions which do lock/unlock on each byte still exist, because they are public and called by outside code.
This commit is contained in:
parent
e170090541
commit
e5ef01427c
@ -76,19 +76,40 @@ static u_char rtc_statusb = RTCSB_24HR;
|
|||||||
* RTC support routines
|
* RTC support routines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
static inline u_char
|
||||||
rtcin(int reg)
|
rtcin_locked(int reg)
|
||||||
{
|
{
|
||||||
u_char val;
|
|
||||||
|
|
||||||
RTC_LOCK;
|
|
||||||
if (rtc_reg != reg) {
|
if (rtc_reg != reg) {
|
||||||
inb(0x84);
|
inb(0x84);
|
||||||
outb(IO_RTC, reg);
|
outb(IO_RTC, reg);
|
||||||
rtc_reg = reg;
|
rtc_reg = reg;
|
||||||
inb(0x84);
|
inb(0x84);
|
||||||
}
|
}
|
||||||
val = inb(IO_RTC + 1);
|
return (inb(IO_RTC + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
rtcout_locked(int reg, u_char val)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (rtc_reg != reg) {
|
||||||
|
inb(0x84);
|
||||||
|
outb(IO_RTC, reg);
|
||||||
|
rtc_reg = reg;
|
||||||
|
inb(0x84);
|
||||||
|
}
|
||||||
|
outb(IO_RTC + 1, val);
|
||||||
|
inb(0x84);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rtcin(int reg)
|
||||||
|
{
|
||||||
|
u_char val;
|
||||||
|
|
||||||
|
RTC_LOCK;
|
||||||
|
val = rtcin_locked(reg);
|
||||||
RTC_UNLOCK;
|
RTC_UNLOCK;
|
||||||
return (val);
|
return (val);
|
||||||
}
|
}
|
||||||
@ -98,14 +119,7 @@ writertc(int reg, u_char val)
|
|||||||
{
|
{
|
||||||
|
|
||||||
RTC_LOCK;
|
RTC_LOCK;
|
||||||
if (rtc_reg != reg) {
|
rtcout_locked(reg, val);
|
||||||
inb(0x84);
|
|
||||||
outb(IO_RTC, reg);
|
|
||||||
rtc_reg = reg;
|
|
||||||
inb(0x84);
|
|
||||||
}
|
|
||||||
outb(IO_RTC + 1, val);
|
|
||||||
inb(0x84);
|
|
||||||
RTC_UNLOCK;
|
RTC_UNLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,25 +177,28 @@ atrtc_set(struct timespec *ts)
|
|||||||
clock_ts_to_bcd(ts, &ct, false);
|
clock_ts_to_bcd(ts, &ct, false);
|
||||||
|
|
||||||
mtx_lock(&atrtc_time_lock);
|
mtx_lock(&atrtc_time_lock);
|
||||||
|
RTC_LOCK;
|
||||||
|
|
||||||
/* Disable RTC updates and interrupts. */
|
/* Disable RTC updates and interrupts. */
|
||||||
writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
|
rtcout_locked(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
|
||||||
|
|
||||||
writertc(RTC_SEC, ct.sec); /* Write back Seconds */
|
/* Write all the time registers. */
|
||||||
writertc(RTC_MIN, ct.min); /* Write back Minutes */
|
rtcout_locked(RTC_SEC, ct.sec);
|
||||||
writertc(RTC_HRS, ct.hour); /* Write back Hours */
|
rtcout_locked(RTC_MIN, ct.min);
|
||||||
writertc(RTC_WDAY, ct.dow + 1); /* Write back Weekday */
|
rtcout_locked(RTC_HRS, ct.hour);
|
||||||
writertc(RTC_DAY, ct.day); /* Write back Day */
|
rtcout_locked(RTC_WDAY, ct.dow + 1);
|
||||||
writertc(RTC_MONTH, ct.mon); /* Write back Month */
|
rtcout_locked(RTC_DAY, ct.day);
|
||||||
writertc(RTC_YEAR, ct.year & 0xff); /* Write back Year */
|
rtcout_locked(RTC_MONTH, ct.mon);
|
||||||
|
rtcout_locked(RTC_YEAR, ct.year & 0xff);
|
||||||
#ifdef USE_RTC_CENTURY
|
#ifdef USE_RTC_CENTURY
|
||||||
writertc(RTC_CENTURY, ct.year >> 8); /* ... and Century */
|
rtcout_locked(RTC_CENTURY, ct.year >> 8);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Re-enable RTC updates and interrupts. */
|
/* Re-enable RTC updates and interrupts. */
|
||||||
writertc(RTC_STATUSB, rtc_statusb);
|
rtcout_locked(RTC_STATUSB, rtc_statusb);
|
||||||
rtcin(RTC_INTR);
|
rtcin_locked(RTC_INTR);
|
||||||
|
|
||||||
|
RTC_UNLOCK;
|
||||||
mtx_unlock(&atrtc_time_lock);
|
mtx_unlock(&atrtc_time_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,15 +375,17 @@ atrtc_gettime(device_t dev, struct timespec *ts)
|
|||||||
while (rtcin(RTC_STATUSA) & RTCSA_TUP)
|
while (rtcin(RTC_STATUSA) & RTCSA_TUP)
|
||||||
continue;
|
continue;
|
||||||
critical_enter();
|
critical_enter();
|
||||||
ct.sec = rtcin(RTC_SEC);
|
RTC_LOCK;
|
||||||
ct.min = rtcin(RTC_MIN);
|
ct.sec = rtcin_locked(RTC_SEC);
|
||||||
ct.hour = rtcin(RTC_HRS);
|
ct.min = rtcin_locked(RTC_MIN);
|
||||||
ct.day = rtcin(RTC_DAY);
|
ct.hour = rtcin_locked(RTC_HRS);
|
||||||
ct.mon = rtcin(RTC_MONTH);
|
ct.day = rtcin_locked(RTC_DAY);
|
||||||
ct.year = rtcin(RTC_YEAR);
|
ct.mon = rtcin_locked(RTC_MONTH);
|
||||||
|
ct.year = rtcin_locked(RTC_YEAR);
|
||||||
#ifdef USE_RTC_CENTURY
|
#ifdef USE_RTC_CENTURY
|
||||||
ct.year |= rtcin(RTC_CENTURY) << 8;
|
ct.year |= rtcin_locked(RTC_CENTURY) << 8;
|
||||||
#endif
|
#endif
|
||||||
|
RTC_UNLOCK;
|
||||||
critical_exit();
|
critical_exit();
|
||||||
mtx_unlock(&atrtc_time_lock);
|
mtx_unlock(&atrtc_time_lock);
|
||||||
/* dow is unused in timespec conversion and we have no nsec info. */
|
/* dow is unused in timespec conversion and we have no nsec info. */
|
||||||
|
Loading…
Reference in New Issue
Block a user