diff --git a/usr.sbin/powerd/powerd.8 b/usr.sbin/powerd/powerd.8 index 853282ca6bba..7ab295a555d4 100644 --- a/usr.sbin/powerd/powerd.8 +++ b/usr.sbin/powerd/powerd.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 4, 2013 +.Dd January 6, 2019 .Dt POWERD 8 .Os .Sh NAME @@ -41,6 +41,7 @@ .Op Fl p Ar ival .Op Fl P Ar pidfile .Op Fl r Ar percent +.Op Fl s Ar source .Op Fl v .Sh DESCRIPTION The @@ -117,6 +118,14 @@ The default is Specifies the CPU load percent level where adaptive mode should consider the CPU running and increase performance. The default is 75% or higher. +.It Fl s Ar source +Enforces method for AC line state refresh; by default, it is chosen +automatically. +The set of valid methods is +.Cm sysctl , devd +and +.Cm apm +(i386 only). .It Fl v Verbose mode. Messages about power changes will be printed to stdout and diff --git a/usr.sbin/powerd/powerd.c b/usr.sbin/powerd/powerd.c index 45e0fc75d418..974e3195476b 100644 --- a/usr.sbin/powerd/powerd.c +++ b/usr.sbin/powerd/powerd.c @@ -113,14 +113,16 @@ static int vflag; static volatile sig_atomic_t exit_requested; static power_src_t acline_status; -static enum { +typedef enum { ac_none, ac_sysctl, ac_acpi_devd, #ifdef USE_APM ac_apm, #endif -} acline_mode; +} acline_mode_t; +static acline_mode_t acline_mode; +static acline_mode_t acline_mode_user = ac_none; #ifdef USE_APM static int apm_fd = -1; #endif @@ -286,21 +288,28 @@ get_freq_id(int freq, int *freqs, int numfreqs) static void acline_init(void) { + int skip_source_check; + acline_mib_len = 4; acline_status = SRC_UNKNOWN; + skip_source_check = (acline_mode_user == ac_none || + acline_mode_user == ac_acpi_devd); - if (sysctlnametomib(ACPIAC, acline_mib, &acline_mib_len) == 0) { + if ((skip_source_check || acline_mode_user == ac_sysctl) && + sysctlnametomib(ACPIAC, acline_mib, &acline_mib_len) == 0) { acline_mode = ac_sysctl; if (vflag) warnx("using sysctl for AC line status"); #ifdef __powerpc__ - } else if (sysctlnametomib(PMUAC, acline_mib, &acline_mib_len) == 0) { + } else if ((skip_source_check || acline_mode_user == ac_sysctl) && + sysctlnametomib(PMUAC, acline_mib, &acline_mib_len) == 0) { acline_mode = ac_sysctl; if (vflag) warnx("using sysctl for AC line status"); #endif #ifdef USE_APM - } else if ((apm_fd = open(APMDEV, O_RDONLY)) >= 0) { + } else if ((skip_source_check || acline_mode_user == ac_apm) && + (apm_fd = open(APMDEV, O_RDONLY)) >= 0) { if (vflag) warnx("using APM for AC line status"); acline_mode = ac_apm; @@ -360,7 +369,17 @@ acline_read(void) } #endif /* try to (re)connect to devd */ - if (acline_mode == ac_sysctl) { +#ifdef USE_APM + if ((acline_mode == ac_sysctl && + (acline_mode_user == ac_none || + acline_mode_user == ac_acpi_devd)) || + (acline_mode == ac_apm && + acline_mode_user == ac_acpi_devd)) { +#else + if (acline_mode == ac_sysctl && + (acline_mode_user == ac_none || + acline_mode_user == ac_acpi_devd)) { +#endif struct timeval now; gettimeofday(&now, NULL); @@ -425,6 +444,21 @@ parse_mode(char *arg, int *mode, int ch) errx(1, "bad option: -%c %s", (char)ch, optarg); } +static void +parse_acline_mode(char *arg, int ch) +{ + if (strcmp(arg, "sysctl") == 0) + acline_mode_user = ac_sysctl; + else if (strcmp(arg, "devd") == 0) + acline_mode_user = ac_acpi_devd; +#ifdef USE_APM + else if (strcmp(arg, "apm") == 0) + acline_mode_user = ac_apm; +#endif + else + errx(1, "bad option: -%c %s", (char)ch, optarg); +} + static void handle_sigs(int __unused sig) { @@ -437,7 +471,7 @@ usage(void) { fprintf(stderr, -"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-m freq] [-M freq] [-n mode] [-p ival] [-r %%] [-P pidfile]\n"); +"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-m freq] [-M freq] [-n mode] [-p ival] [-r %%] [-s source] [-P pidfile]\n"); exit(1); } @@ -468,7 +502,7 @@ main(int argc, char * argv[]) if (geteuid() != 0) errx(1, "must be root to run"); - while ((ch = getopt(argc, argv, "a:b:i:m:M:n:p:P:r:v")) != -1) + while ((ch = getopt(argc, argv, "a:b:i:m:M:n:p:P:r:s:v")) != -1) switch (ch) { case 'a': parse_mode(optarg, &mode_ac, ch); @@ -476,6 +510,9 @@ main(int argc, char * argv[]) case 'b': parse_mode(optarg, &mode_battery, ch); break; + case 's': + parse_acline_mode(optarg, ch); + break; case 'i': cpu_idle_mark = atoi(optarg); if (cpu_idle_mark < 0 || cpu_idle_mark > 100) {