aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2011-07-14 21:00:26 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2011-07-14 21:00:26 +0000
commit08e1b4f4a9967b8872b69534e103dcc2af234105 (patch)
tree9a2f51e9df71efecc4be43c619d3287cabc1edf5 /sys
parent5dbee633d22f727e8a10c16c24934646ed889bed (diff)
downloadsrc-08e1b4f4a9967b8872b69534e103dcc2af234105.tar.gz
src-08e1b4f4a9967b8872b69534e103dcc2af234105.zip
If TSC stops ticking in C3, disable deep sleep when the user forcefully
select TSC as timecounter hardware. Tested by: Fabian Keil (freebsd-listen at fabiankeil dot de)
Notes
Notes: svn path=/head/; revision=224042
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_tc.c6
-rw-r--r--sys/sys/timetc.h2
-rw-r--r--sys/x86/x86/tsc.c1
3 files changed, 9 insertions, 0 deletions
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index 39d6f230b5b2..0c520711ef73 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -492,6 +492,12 @@ tc_windup(void)
/* Now is a good time to change timecounters. */
if (th->th_counter != timecounter) {
+#ifndef __arm__
+ if ((timecounter->tc_flags & TC_FLAGS_C3STOP) != 0)
+ cpu_disable_deep_sleep++;
+ if ((th->th_counter->tc_flags & TC_FLAGS_C3STOP) != 0)
+ cpu_disable_deep_sleep--;
+#endif
th->th_counter = timecounter;
th->th_offset_count = ncount;
tc_min_ticktock_freq = max(1, timecounter->tc_frequency /
diff --git a/sys/sys/timetc.h b/sys/sys/timetc.h
index dc1dea408c6e..6881b95ed154 100644
--- a/sys/sys/timetc.h
+++ b/sys/sys/timetc.h
@@ -57,6 +57,8 @@ struct timecounter {
* another timecounter higher means better. Negative
* means "only use at explicit request".
*/
+ u_int tc_flags;
+#define TC_FLAGS_C3STOP 1 /* Timer dies in C3. */
void *tc_priv;
/* Pointer to the timecounter's private parts. */
diff --git a/sys/x86/x86/tsc.c b/sys/x86/x86/tsc.c
index 5f17f62d923e..0b383bf7ef21 100644
--- a/sys/x86/x86/tsc.c
+++ b/sys/x86/x86/tsc.c
@@ -452,6 +452,7 @@ init_TSC_tc(void)
if (cpu_can_deep_sleep && cpu_vendor_id == CPU_VENDOR_INTEL &&
(amd_pminfo & AMDPM_TSC_INVARIANT) == 0) {
tsc_timecounter.tc_quality = -1000;
+ tsc_timecounter.tc_flags |= TC_FLAGS_C3STOP;
if (bootverbose)
printf("TSC timecounter disabled: C3 enabled.\n");
goto init;