aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2005-10-30 18:03:36 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-30 20:37:30 -0500
commit7811fb8f400a3dbfa027d86bb583a31c66fddfc3 (patch)
tree2df816ff6559a0e2f9d7537e1accdfe932e027d4
parent5f819949ee4e5a06c2e0054cbb42f3f0d170d779 (diff)
[PATCH] hpet-RTC: cache the comparator register
Reads from an HPET register require a round trip to the south bridge and are almost as slow as PCI reads. By caching the last value we've written to the comparator register, we can eliminate all HPET reads from the fast path in the emulated RTC interrupt handler. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Acked-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/i386/kernel/time_hpet.c5
-rw-r--r--arch/x86_64/kernel/time.c5
2 files changed, 8 insertions, 2 deletions
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
index cb1f313858e3..9caeaa315cd7 100644
--- a/arch/i386/kernel/time_hpet.c
+++ b/arch/i386/kernel/time_hpet.c
@@ -275,6 +275,7 @@ static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
275static unsigned long PIE_count; 275static unsigned long PIE_count;
276 276
277static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */ 277static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
278static unsigned int hpet_t1_cmp; /* cached comparator register */
278 279
279/* 280/*
280 * Timer 1 for RTC, we do not use periodic interrupt feature, 281 * Timer 1 for RTC, we do not use periodic interrupt feature,
@@ -306,6 +307,7 @@ int hpet_rtc_timer_init(void)
306 cnt = hpet_readl(HPET_COUNTER); 307 cnt = hpet_readl(HPET_COUNTER);
307 cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq); 308 cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
308 hpet_writel(cnt, HPET_T1_CMP); 309 hpet_writel(cnt, HPET_T1_CMP);
310 hpet_t1_cmp = cnt;
309 local_irq_restore(flags); 311 local_irq_restore(flags);
310 312
311 cfg = hpet_readl(HPET_T1_CFG); 313 cfg = hpet_readl(HPET_T1_CFG);
@@ -333,9 +335,10 @@ static void hpet_rtc_timer_reinit(void)
333 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; 335 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
334 336
335 /* It is more accurate to use the comparator value than current count.*/ 337 /* It is more accurate to use the comparator value than current count.*/
336 cnt = hpet_readl(HPET_T1_CMP); 338 cnt = hpet_t1_cmp;
337 cnt += hpet_tick*HZ/hpet_rtc_int_freq; 339 cnt += hpet_tick*HZ/hpet_rtc_int_freq;
338 hpet_writel(cnt, HPET_T1_CMP); 340 hpet_writel(cnt, HPET_T1_CMP);
341 hpet_t1_cmp = cnt;
339} 342}
340 343
341/* 344/*
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 35a896ef4c35..fdaddc4e5284 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -1089,6 +1089,7 @@ static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
1089static unsigned long PIE_count; 1089static unsigned long PIE_count;
1090 1090
1091static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */ 1091static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
1092static unsigned int hpet_t1_cmp; /* cached comparator register */
1092 1093
1093int is_hpet_enabled(void) 1094int is_hpet_enabled(void)
1094{ 1095{
@@ -1125,6 +1126,7 @@ int hpet_rtc_timer_init(void)
1125 cnt = hpet_readl(HPET_COUNTER); 1126 cnt = hpet_readl(HPET_COUNTER);
1126 cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq); 1127 cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
1127 hpet_writel(cnt, HPET_T1_CMP); 1128 hpet_writel(cnt, HPET_T1_CMP);
1129 hpet_t1_cmp = cnt;
1128 local_irq_restore(flags); 1130 local_irq_restore(flags);
1129 1131
1130 cfg = hpet_readl(HPET_T1_CFG); 1132 cfg = hpet_readl(HPET_T1_CFG);
@@ -1152,9 +1154,10 @@ static void hpet_rtc_timer_reinit(void)
1152 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; 1154 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
1153 1155
1154 /* It is more accurate to use the comparator value than current count.*/ 1156 /* It is more accurate to use the comparator value than current count.*/
1155 cnt = hpet_readl(HPET_T1_CMP); 1157 cnt = hpet_t1_cmp;
1156 cnt += hpet_tick*HZ/hpet_rtc_int_freq; 1158 cnt += hpet_tick*HZ/hpet_rtc_int_freq;
1157 hpet_writel(cnt, HPET_T1_CMP); 1159 hpet_writel(cnt, HPET_T1_CMP);
1160 hpet_t1_cmp = cnt;
1158} 1161}
1159 1162
1160/* 1163/*