aboutsummaryrefslogtreecommitdiff
path: root/sys/x86
diff options
context:
space:
mode:
authorIan Lepore <ian@FreeBSD.org>2018-01-16 03:02:41 +0000
committerIan Lepore <ian@FreeBSD.org>2018-01-16 03:02:41 +0000
commite5ef01427cf92fa9482e9338144886d39c44f3a5 (patch)
tree65a46ef5af5df8c0ee62d771ec9bb0aae948dcd5 /sys/x86
parente1700905414b5b59e8df72ca16114ed0ce2b5565 (diff)
downloadsrc-e5ef01427cf92fa9482e9338144886d39c44f3a5.tar.gz
src-e5ef01427cf92fa9482e9338144886d39c44f3a5.zip
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.
Notes
Notes: svn path=/head/; revision=328039
Diffstat (limited to 'sys/x86')
-rw-r--r--sys/x86/isa/atrtc.c77
1 files changed, 48 insertions, 29 deletions
diff --git a/sys/x86/isa/atrtc.c b/sys/x86/isa/atrtc.c
index 54aa55737edb..34b2fd66ba97 100644
--- a/sys/x86/isa/atrtc.c
+++ b/sys/x86/isa/atrtc.c
@@ -76,28 +76,23 @@ static u_char rtc_statusb = RTCSB_24HR;
* RTC support routines
*/
-int
-rtcin(int reg)
+static inline u_char
+rtcin_locked(int reg)
{
- u_char val;
- RTC_LOCK;
if (rtc_reg != reg) {
inb(0x84);
outb(IO_RTC, reg);
rtc_reg = reg;
inb(0x84);
}
- val = inb(IO_RTC + 1);
- RTC_UNLOCK;
- return (val);
+ return (inb(IO_RTC + 1));
}
-void
-writertc(int reg, u_char val)
+static inline void
+rtcout_locked(int reg, u_char val)
{
- RTC_LOCK;
if (rtc_reg != reg) {
inb(0x84);
outb(IO_RTC, reg);
@@ -106,6 +101,25 @@ writertc(int reg, u_char val)
}
outb(IO_RTC + 1, val);
inb(0x84);
+}
+
+int
+rtcin(int reg)
+{
+ u_char val;
+
+ RTC_LOCK;
+ val = rtcin_locked(reg);
+ RTC_UNLOCK;
+ return (val);
+}
+
+void
+writertc(int reg, u_char val)
+{
+
+ RTC_LOCK;
+ rtcout_locked(reg, val);
RTC_UNLOCK;
}
@@ -163,25 +177,28 @@ atrtc_set(struct timespec *ts)
clock_ts_to_bcd(ts, &ct, false);
mtx_lock(&atrtc_time_lock);
+ RTC_LOCK;
/* Disable RTC updates and interrupts. */
- writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
-
- writertc(RTC_SEC, ct.sec); /* Write back Seconds */
- writertc(RTC_MIN, ct.min); /* Write back Minutes */
- writertc(RTC_HRS, ct.hour); /* Write back Hours */
- writertc(RTC_WDAY, ct.dow + 1); /* Write back Weekday */
- writertc(RTC_DAY, ct.day); /* Write back Day */
- writertc(RTC_MONTH, ct.mon); /* Write back Month */
- writertc(RTC_YEAR, ct.year & 0xff); /* Write back Year */
+ rtcout_locked(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
+
+ /* Write all the time registers. */
+ rtcout_locked(RTC_SEC, ct.sec);
+ rtcout_locked(RTC_MIN, ct.min);
+ rtcout_locked(RTC_HRS, ct.hour);
+ rtcout_locked(RTC_WDAY, ct.dow + 1);
+ rtcout_locked(RTC_DAY, ct.day);
+ rtcout_locked(RTC_MONTH, ct.mon);
+ rtcout_locked(RTC_YEAR, ct.year & 0xff);
#ifdef USE_RTC_CENTURY
- writertc(RTC_CENTURY, ct.year >> 8); /* ... and Century */
+ rtcout_locked(RTC_CENTURY, ct.year >> 8);
#endif
/* Re-enable RTC updates and interrupts. */
- writertc(RTC_STATUSB, rtc_statusb);
- rtcin(RTC_INTR);
+ rtcout_locked(RTC_STATUSB, rtc_statusb);
+ rtcin_locked(RTC_INTR);
+ RTC_UNLOCK;
mtx_unlock(&atrtc_time_lock);
}
@@ -358,15 +375,17 @@ atrtc_gettime(device_t dev, struct timespec *ts)
while (rtcin(RTC_STATUSA) & RTCSA_TUP)
continue;
critical_enter();
- ct.sec = rtcin(RTC_SEC);
- ct.min = rtcin(RTC_MIN);
- ct.hour = rtcin(RTC_HRS);
- ct.day = rtcin(RTC_DAY);
- ct.mon = rtcin(RTC_MONTH);
- ct.year = rtcin(RTC_YEAR);
+ RTC_LOCK;
+ ct.sec = rtcin_locked(RTC_SEC);
+ ct.min = rtcin_locked(RTC_MIN);
+ ct.hour = rtcin_locked(RTC_HRS);
+ ct.day = rtcin_locked(RTC_DAY);
+ ct.mon = rtcin_locked(RTC_MONTH);
+ ct.year = rtcin_locked(RTC_YEAR);
#ifdef USE_RTC_CENTURY
- ct.year |= rtcin(RTC_CENTURY) << 8;
+ ct.year |= rtcin_locked(RTC_CENTURY) << 8;
#endif
+ RTC_UNLOCK;
critical_exit();
mtx_unlock(&atrtc_time_lock);
/* dow is unused in timespec conversion and we have no nsec info. */