Index: usr.sbin/powerd/powerd.8 diff -u usr.sbin/powerd/powerd.8.orig usr.sbin/powerd/powerd.8 --- usr.sbin/powerd/powerd.8.orig Sat Jun 18 19:36:21 2005 +++ usr.sbin/powerd/powerd.8 Sun Jun 19 00:05:47 2005 @@ -38,6 +38,7 @@ .Op Fl n Ar mode .Op Fl p Ar ival .Op Fl r Ar percent +.Op Fl t .Op Fl v .Sh DESCRIPTION The @@ -87,6 +88,10 @@ adaptive mode should consider the CPU running and increase performance. The default is 65% or lower. +.It Fl t +When the temperature is too high, the +.Nm +switches the frequency to the lowest value for cooling down. .It Fl v Verbose mode. Messages about power changes will be printed to stdout and Index: usr.sbin/powerd/powerd.c diff -u -p usr.sbin/powerd/powerd.c.orig usr.sbin/powerd/powerd.c --- usr.sbin/powerd/powerd.c.orig Mon Apr 11 05:42:55 2005 +++ usr.sbin/powerd/powerd.c Sun Jun 19 00:14:09 2005 @@ -83,6 +83,7 @@ static int cp_time_mib[2]; static int freq_mib[4]; static int levels_mib[4]; static int acline_mib[3]; +static int thermal_mib[5]; /* Configuration */ static int cpu_running_mark; @@ -91,6 +92,7 @@ static int poll_ival; static int apm_fd; static int exit_requested; +static int thermal_control; static int read_usage_times(long *idle, long *total) @@ -253,7 +255,8 @@ main(int argc, char * argv[]) { long idle, total; int curfreq, *freqs, i, *mwatts, numfreqs; - int ch, mode_ac, mode_battery, mode_none, acline, mode, vflag; + int ch, mode_ac, mode_battery, mode_none, acline, mode, tflag, vflag; + int thermal_flags; uint64_t mjoules_used; size_t len; @@ -263,10 +266,11 @@ main(int argc, char * argv[]) cpu_idle_mark = DEFAULT_IDLE_PERCENT; poll_ival = DEFAULT_POLL_INTERVAL; mjoules_used = 0; + tflag = 0; vflag = 0; apm_fd = -1; - while ((ch = getopt(argc, argv, "a:b:i:n:p:r:v")) != EOF) + while ((ch = getopt(argc, argv, "a:b:i:n:p:r:tv")) != EOF) switch (ch) { case 'a': parse_mode(optarg, &mode_ac, ch); @@ -300,6 +304,9 @@ main(int argc, char * argv[]) usage(); } break; + case 't': + tflag = 1; + break; case 'v': vflag = 1; break; @@ -320,6 +327,12 @@ main(int argc, char * argv[]) len = 4; if (sysctlnametomib("dev.cpu.0.freq_levels", levels_mib, &len)) err(1, "lookup freq_levels"); + if (tflag) { + len = 5; + if (sysctlnametomib("hw.acpi.thermal.tz0.thermal_flags", + thermal_mib, &len) == 0) + thermal_control = 1; + } /* Check if we can read the idle time and supported freqs. */ if (read_usage_times(NULL, NULL)) @@ -381,6 +394,25 @@ main(int argc, char * argv[]) if (i < numfreqs && mwatts[i] != -1) mjoules_used += (mwatts[i] * (poll_ival / 1000)) / 1000; + } + + /* Switch to the lowest frequency when too hot. */ + if (thermal_control) { + len = sizeof(thermal_flags); + if (sysctl(thermal_mib, 5, &thermal_flags, &len, + NULL, 0) == 0 && thermal_flags) { + if (curfreq == freqs[numfreqs - 1]) + continue; + if (vflag) { + printf("high temperature; " + "changing frequency to %d MHz\n", + freqs[numfreqs - 1]); + } + if (set_freq(freqs[numfreqs - 1])) + err(1, "error setting CPU freq %d", + freqs[numfreqs - 1]); + continue; + } } /* Always switch to the lowest frequency in min mode. */