diff -u powerd.orig/powerd.8 powerd/powerd.8 --- powerd.orig/powerd.8 2009-07-05 16:04:19.000000000 +0200 +++ powerd/powerd.8 2009-07-05 17:18:12.000000000 +0200 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD: src/usr.sbin/powerd/powerd.8,v 1.13 2008/12/24 09:17:30 trhodes Exp $ .\" -.Dd December 24, 2008 +.Dd July 5, 2009 .Dt POWERD 8 .Os .Sh NAME @@ -33,7 +33,9 @@ .Sh SYNOPSIS .Nm .Op Fl a Ar mode +.Op Fl x Ar maxspeed .Op Fl b Ar mode +.Op Fl y Ar maxspeed .Op Fl i Ar percent .Op Fl n Ar mode .Op Fl p Ar ival @@ -45,22 +47,10 @@ .Nm utility monitors the system state and sets various power control options accordingly. -It offers three modes (maximum, minimum, and adaptive) that can be -individually selected while on AC power or batteries. -The modes maximum, minimum, adaptive and hiadaptive may be abbreviated -max, min, adp, hadp. -.Pp -Maximum mode chooses the highest performance values. -Minimum mode selects the lowest performance values to get the most power -savings. -Adaptive mode attempts to strike a balance by degrading performance when -the system appears idle and increasing it when the system is busy. -It offers a good balance between a small performance loss for greatly -increased power savings. -Hiadaptive mode is alike adaptive mode, but tuned for systems where -performance and interactivity are more important then power consumption. -It rises frequency faster, drops slower and keeps twice lower CPU load. -The default mode is adaptive for battery power and hiadaptive for the rest. +It offers multiple modes (maximum, minimum, and two adaptive modes) that can be +individually selected while on AC power or batteries. See +.Ar MODES +below for details. .Pp The .Nm @@ -99,7 +89,57 @@ Messages about power changes will be printed to stdout and .Nm will operate in the foreground. +.It Fl x Ar mode +Selects the +.Ar maxspeed +in Mhz for adaptive modes to use while on AC power. +.It Fl y Ar mode +Selects the +.Ar maxspeed +in Mhz for adaptive modes to use while on battery power. .El +.Sh MODES +The following +.Ar mode +flags are currently implemented: +.Pp +.Ar max +or +.Ar maximum +mode chooses the highest performance values. +.Pp +.Ar min +or +.Ar minimum +mode selects the lowest performance values to get the most power +savings. +.Pp +.Ar adp +or +.Ar adaptive +mode attempts to strike a balance by degrading performance when +the system appears idle and increasing it when the system is busy. +It offers a good balance between a small performance loss for greatly +increased power savings. +.Pp +.Ar hadp +or +.Ar hiadaptive +mode is alike adaptive mode, but tuned for systems where +performance and interactivity are more important then power consumption. +It rises frequency faster, drops slower and keeps twice lower CPU load. +.Pp +For both adaptive modes, it is possible to set +.Ar maxspeed +to lower power consumption by limiting the dynamic range +.Nm +uses. +.Pp +The default mode is +.Ar adaptive +for battery power and +.Ar hiadaptive +for the rest. .Sh SEE ALSO .Xr acpi 4 , .Xr apm 4 , @@ -121,6 +161,8 @@ then updated it for .Xr cpufreq 4 , added features, and wrote this manual page. +.An Rene Schickbauer +added speed limiting and rewrote parts of this manual page. .Sh BUGS The .Nm diff -u powerd.orig/powerd.c powerd/powerd.c --- powerd.orig/powerd.c 2009-07-05 16:04:19.000000000 +0200 +++ powerd/powerd.c 2009-07-05 17:22:35.000000000 +0200 @@ -118,6 +118,9 @@ #endif static int devd_pipe = -1; +static int maxspeed_ac = 0; +static int maxspeed_battery = 0; + #define DEVD_RETRY_INTERVAL 60 /* seconds */ static struct timeval tried_devd; @@ -418,7 +421,7 @@ { fprintf(stderr, -"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival] [-r %%] [-P pidfile]\n"); +"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival] [-r %%] [-P pidfile] [-x maxspeed] [-y maxspeed]\n"); exit(1); } @@ -431,13 +434,16 @@ struct pidfh *pfh = NULL; const char *pidfile = NULL; int freq, curfreq, initfreq, *freqs, i, j, *mwatts, numfreqs, load; - int ch, mode, mode_ac, mode_battery, mode_none; + int ch, mode, mode_ac, mode_battery, mode_none, maxspeed; uint64_t mjoules_used; size_t len; /* Default mode for all AC states is adaptive. */ mode_ac = mode_none = MODE_HIADAPTIVE; mode_battery = MODE_ADAPTIVE; + maxspeed_ac = 0; + maxspeed_battery = 0; + maxspeed = 0; cpu_running_mark = DEFAULT_ACTIVE_PERCENT; cpu_idle_mark = DEFAULT_IDLE_PERCENT; poll_ival = DEFAULT_POLL_INTERVAL; @@ -448,7 +454,7 @@ if (geteuid() != 0) errx(1, "must be root to run"); - while ((ch = getopt(argc, argv, "a:b:i:n:p:P:r:v")) != -1) + while ((ch = getopt(argc, argv, "a:b:x:y:i:n:p:P:r:v")) != -1) switch (ch) { case 'a': parse_mode(optarg, &mode_ac, ch); @@ -464,6 +470,22 @@ usage(); } break; + case 'x': + maxspeed_ac = atoi(optarg); + if (maxspeed_ac <= 0) { + warnx("%d is not a valid CPU speed", + maxspeed_ac); + usage(); + } + break; + case 'y': + maxspeed_battery = atoi(optarg); + if (maxspeed_battery <= 0) { + warnx("%d is not a valid CPU speed", + maxspeed_battery); + usage(); + } + break; case 'n': parse_mode(optarg, &mode_none, ch); break; @@ -574,12 +596,15 @@ switch (acline_status) { case SRC_AC: mode = mode_ac; + maxspeed = maxspeed_ac; break; case SRC_BATTERY: mode = mode_battery; + maxspeed = maxspeed_battery; break; case SRC_UNKNOWN: mode = mode_none; + maxspeed = 0; break; default: errx(1, "invalid AC line status %d", acline_status); @@ -647,6 +672,7 @@ freq *= 2; else freq = freq * load / cpu_running_mark; + if (freq > freqs[0]) freq = freqs[0]; } else if (load < cpu_idle_mark && @@ -657,6 +683,11 @@ if (freq < freqs[numfreqs - 1]) freq = freqs[numfreqs - 1]; } + if(maxspeed > 0 && freq > maxspeed) { + if(vflag) + printf("Limiting calculated freq (%d Mhz) to %d Mhz\n", freq, maxspeed); + freq = maxspeed; + } } else { /* MODE_HIADAPTIVE */ if (load > cpu_running_mark / 2) { if (load > 95 || load > cpu_running_mark) @@ -673,6 +704,11 @@ if (freq < freqs[numfreqs - 1]) freq = freqs[numfreqs - 1]; } + if(maxspeed > 0 && freq > maxspeed) { + if(vflag) + printf("Limiting calculated freq (%d Mhz) to %d Mhz\n", freq, maxspeed); + freq = maxspeed; + } } if (vflag) { printf("load %3d%%, current freq %4d MHz (%2d), wanted freq %4d MHz\n",