Created
June 11, 2014 23:51
-
-
Save tuxillo/982cecc71af297dddde8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/usr.sbin/powerd/Makefile b/usr.sbin/powerd/Makefile | |
index 2890ca0..6df7072 100644 | |
--- a/usr.sbin/powerd/Makefile | |
+++ b/usr.sbin/powerd/Makefile | |
@@ -3,6 +3,7 @@ | |
PROG= powerd | |
MAN= powerd.8 | |
+SRCS= acpi.c powerd.c powerd.h | |
LDADD+= -lutil | |
DPADD+= ${LIBUTIL} | |
diff --git a/usr.sbin/powerd/acpi.c b/usr.sbin/powerd/acpi.c | |
new file mode 100644 | |
index 0000000..c9dff9f | |
--- /dev/null | |
+++ b/usr.sbin/powerd/acpi.c | |
@@ -0,0 +1,142 @@ | |
+/* | |
+ * Copyright (c) 2014 The DragonFly Project. All rights reserved. | |
+ * | |
+ * This code is derived from software contributed to The DragonFly Project | |
+ * by Matthew Dillon <dillon@backplane.com> | |
+ * by Antonio Huete <tuxillo@quantumachine.net> | |
+ * | |
+ * Redistribution and use in source and binary forms, with or without | |
+ * modification, are permitted provided that the following conditions | |
+ * are met: | |
+ * | |
+ * 1. Redistributions of source code must retain the above copyright | |
+ * notice, this list of conditions and the following disclaimer. | |
+ * 2. Redistributions in binary form must reproduce the above copyright | |
+ * notice, this list of conditions and the following disclaimer in | |
+ * the documentation and/or other materials provided with the | |
+ * distribution. | |
+ * 3. Neither the name of The DragonFly Project nor the names of its | |
+ * contributors may be used to endorse or promote products derived | |
+ * from this software without specific, prior written permission. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, | |
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | |
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
+ * SUCH DAMAGE. | |
+ */ | |
+ | |
+#include <stdio.h> | |
+#include <err.h> | |
+#include <stdlib.h> | |
+#include <string.h> | |
+#include <strings.h> | |
+#include <unistd.h> | |
+#include <sys/sysctl.h> | |
+ | |
+#include "powerd.h" | |
+ | |
+int | |
+powerd_acpi_probe(void) | |
+{ | |
+ char buf[64]; | |
+ int dom; | |
+ | |
+ for (dom = 0; dom < MAXDOM; dom++) { | |
+ snprintf(buf, sizeof(buf), | |
+ "hw.acpi.cpu.px_dom%d.available", dom); | |
+ if (sysctlbyname(buf, NULL, NULL, NULL, 0) != -1) | |
+ return 1; /* Found */ | |
+ } | |
+ return 0; /* Not found */ | |
+} | |
+ | |
+void | |
+powerd_acpi_init(void) | |
+{ | |
+ struct powerd_cpu_domain *cdp; | |
+ char members[1024]; | |
+ size_t msize; | |
+ size_t buflen; | |
+ char buf[128]; | |
+ char *sysid; | |
+ char *ptr; | |
+ char *str; | |
+ int dom; | |
+ int n; | |
+ int v; | |
+ | |
+ SLIST_INIT(&psdevs[ACPIDEV].doms); | |
+ | |
+ /* | |
+ * Iterate MAXDOM domains using ACPI P-State sysctls and create a | |
+ * new structure for every domain found. All domains found will be | |
+ * on a SLIST for convenience. | |
+ * Please note that this assumes P-States do not change after they | |
+ * have been discovered and set to the sysctl. | |
+ */ | |
+ for (dom = 0; dom < MAXDOM; dom++) { | |
+ snprintf(buf, sizeof(buf), | |
+ "hw.acpi.cpu.px_dom%d.available", dom); | |
+ if (sysctlbyname(buf, NULL, NULL, NULL, 0) != -1) { | |
+ cdp = malloc(sizeof(*cdp)); | |
+ if (cdp == NULL) | |
+ err(1, "Out of memory"); | |
+ | |
+ bzero(cdp, sizeof(*cdp)); | |
+ msize = sizeof(members); | |
+ snprintf(buf, sizeof(buf), | |
+ "hw.acpi.cpu.px_dom%d.members", dom); | |
+ if (sysctlbyname(buf, members, &msize, NULL, 0) == 0) { | |
+ members[msize] = 0; | |
+ for (str = strtok(members, " "); str; | |
+ str = strtok(NULL, " ")) { | |
+ n = -1; | |
+ sscanf(str, "cpu%d", &n); | |
+ if (n >= 0) | |
+ cdp->ncpus++; | |
+ } | |
+ } | |
+ | |
+ asprintf(&sysid, "hw.acpi.cpu.px_dom%d.available", dom); | |
+ buflen = sizeof(buf) - 1; | |
+ v = sysctlbyname(sysid, buf, &buflen, NULL, 0); | |
+ free(sysid); | |
+ if (v < 0) | |
+ err(1, "sysctl failed"); | |
+ buf[buflen] = 0; /* NULL termination */ | |
+ | |
+ ptr = buf; | |
+ while (ptr && (v = strtol(ptr, &ptr, 10)) > 0) | |
+ psdevs[ACPIDEV].ncpus++; | |
+ | |
+ SLIST_INSERT_HEAD(&psdevs[ACPIDEV].doms, cdp, entry); | |
+ } | |
+ } | |
+} | |
+ | |
+int | |
+powerd_acpi_setfreq(int dom, void *freq) | |
+{ | |
+ char *buf; | |
+ size_t buflen; | |
+ int error; | |
+ int v; | |
+ | |
+ error = 0; | |
+ v = *(int *)(freq); | |
+ | |
+ buflen = sizeof(v); | |
+ asprintf(&buf, "hw.acpi.cpu.px_dom%d.select", dom); | |
+ if ((error = sysctlbyname(buf, NULL, NULL, &v, buflen)) < 0) | |
+ syslog(LOG_WARN, "dom%d: failed setting state to %d", dom, v); | |
+ | |
+ return error; | |
+} | |
diff --git a/usr.sbin/powerd/clockmod.c b/usr.sbin/powerd/clockmod.c | |
new file mode 100644 | |
index 0000000..1e9faff | |
--- /dev/null | |
+++ b/usr.sbin/powerd/clockmod.c | |
@@ -0,0 +1,74 @@ | |
+/* | |
+ * Copyright (c) 2014 The DragonFly Project. All rights reserved. | |
+ * | |
+ * This code is derived from software contributed to The DragonFly Project | |
+ * by Matthew Dillon <dillon@backplane.com> | |
+ * by Antonio Huete <tuxillo@quantumachine.net> | |
+ * | |
+ * Redistribution and use in source and binary forms, with or without | |
+ * modification, are permitted provided that the following conditions | |
+ * are met: | |
+ * | |
+ * 1. Redistributions of source code must retain the above copyright | |
+ * notice, this list of conditions and the following disclaimer. | |
+ * 2. Redistributions in binary form must reproduce the above copyright | |
+ * notice, this list of conditions and the following disclaimer in | |
+ * the documentation and/or other materials provided with the | |
+ * distribution. | |
+ * 3. Neither the name of The DragonFly Project nor the names of its | |
+ * contributors may be used to endorse or promote products derived | |
+ * from this software without specific, prior written permission. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, | |
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | |
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
+ * SUCH DAMAGE. | |
+ */ | |
+ | |
+#include <stdio.h> | |
+ | |
+const char *clockmod_fmt[3] = { | |
+ "machdep.clockmod_dom%d.available", | |
+ "machdep.clockmod_dom%d.members", | |
+ "machdep.clockmod_dom%d.select" | |
+}; | |
+ | |
+int | |
+powerd_clockmod_probe(void) | |
+{ | |
+ char buf[64]; | |
+ int dom; | |
+ | |
+ for (dom = 0; dom < MAXDOM; dom++) { | |
+ snprintf(buf, sizeof(buf), | |
+ "machdep.clockmod_dom%d.available", dom); | |
+ if (sysctlbyname(buf, NULL, NULL, NULL, 0) != -1) | |
+ return 1; /* Found */ | |
+ } | |
+ return 0; /* Not found */ | |
+} | |
+ | |
+void | |
+powerd_clockmod_init(void) | |
+{ | |
+} | |
+ | |
+int | |
+powerd_clockmod_getcpudom(int dom) | |
+{ | |
+ return 0; | |
+} | |
+ | |
+int | |
+powerd_clockmod_setfreq(int dom, int freq) | |
+{ | |
+ return 0; | |
+} | |
diff --git a/usr.sbin/powerd/powerd.c b/usr.sbin/powerd/powerd.c | |
index 0a48c3f..a96b089 100644 | |
--- a/usr.sbin/powerd/powerd.c | |
+++ b/usr.sbin/powerd/powerd.c | |
@@ -34,24 +34,12 @@ | |
/* | |
* The powerd daemon monitors the cpu load and adjusts cpu frequencies | |
- * via hw.acpi.cpu.px_dom*. | |
+ * via appropriate sysctls. | |
*/ | |
+#include "powerd.h" | |
-#include <sys/types.h> | |
-#include <sys/sysctl.h> | |
-#include <sys/kinfo.h> | |
-#include <sys/file.h> | |
-#include <stdio.h> | |
-#include <stdlib.h> | |
-#include <unistd.h> | |
-#include <string.h> | |
-#include <syslog.h> | |
- | |
-static void usage(void); | |
-static double getcputime(void); | |
-static void acpi_setcpufreq(int nstate); | |
-static void setupdominfo(void); | |
- | |
+int StateDev = 0; | |
+int DelaySecs = 60; | |
int DebugOpt; | |
int CpuLimit; /* # of cpus at max frequency */ | |
int DomLimit; /* # of domains at max frequency */ | |
@@ -115,10 +103,10 @@ main(int ac, char **av) | |
} | |
/* | |
- * Wait hw.acpi.cpu.px_dom* sysctl to be created by kernel | |
+ * Wait P-State sysctl to be created by kernel. | |
* | |
- * Since hw.acpi.cpu.px_dom* creation is queued into ACPI | |
- * taskqueue and ACPI taskqueue is shared across various | |
+ * For example, since hw.acpi.cpu.px_dom* creation is queued | |
+ * into ACPI taskqueue and ACPI taskqueue is shared across various | |
* ACPI modules, any delay in other modules may cause | |
* hw.acpi.cpu.px_dom* to be created at quite a later time | |
* (e.g. cmbat module's task could take quite a lot of time). | |
@@ -131,14 +119,11 @@ main(int ac, char **av) | |
getcputime(); | |
savg = 0.0; | |
- setupdominfo(); | |
- if (DomBeg >= DomEnd) { | |
- sleep(1); | |
+ if (setupdominfo() == -1) { | |
+ sleep(DelaySecs); | |
continue; | |
} | |
- DomLimit = DomEnd; | |
- CpuLimit = NCpus; | |
break; | |
} | |
@@ -154,15 +139,16 @@ main(int ac, char **av) | |
savg = (savg * 7.0 + qavg) / 8.0; | |
nstate = savg / Trigger; | |
- if (nstate > NCpus) | |
- nstate = NCpus; | |
+ if (nstate > psdevs[StateDev].ncpus) | |
+ nstate = psdevs[StateDev].ncpus; | |
if (DebugOpt) { | |
printf("\rqavg=%5.2f savg=%5.2f %2d/%2d ncpus=%d\r", | |
qavg, savg, CpuLimit, DomLimit, nstate); | |
fflush(stdout); | |
} | |
+ | |
if (nstate != CpuLimit) | |
- acpi_setcpufreq(nstate); | |
+ setcpufreq(nstate); | |
sleep(1); | |
} | |
} | |
@@ -179,45 +165,35 @@ setupdominfo(void) | |
char members[1024]; | |
char *str; | |
size_t msize; | |
+ int domfound = 0; | |
+ static tries = 0; | |
int i; | |
int n; | |
- for (i = 0; i < 256; ++i) { | |
- snprintf(buf, sizeof(buf), | |
- "hw.acpi.cpu.px_dom%d.available", i); | |
- if (sysctlbyname(buf, NULL, NULL, NULL, 0) >= 0) | |
- break; | |
- } | |
- DomBeg = i; | |
- | |
- for (i = 255; i >= DomBeg; --i) { | |
- snprintf(buf, sizeof(buf), | |
- "hw.acpi.cpu.px_dom%d.available", i); | |
- if (sysctlbyname(buf, NULL, NULL, NULL, 0) >= 0) { | |
- ++i; | |
- break; | |
- } | |
- } | |
- DomEnd = i; | |
- | |
- for (i = DomBeg; i < DomEnd; ++i) { | |
- snprintf(buf, sizeof(buf), | |
- "hw.acpi.cpu.px_dom%d.members", i); | |
- msize = sizeof(members); | |
- if (sysctlbyname(buf, members, &msize, NULL, 0) == 0) { | |
- members[msize] = 0; | |
- for (str = strtok(members, " "); str; | |
- str = strtok(NULL, " ")) { | |
- n = -1; | |
- sscanf(str, "cpu%d", &n); | |
- if (n >= 0) { | |
- ++NCpus; | |
- ++CpuCount[i]; | |
- CpuToDom[n]= i; | |
- } | |
- } | |
+ /* Find out which method to use */ | |
+ if (psdevs[ACPIDEV].probe()) { | |
+ if (DebugOpt) | |
+ syslog(LOG_INFO, "Using ACPI P-State sysctl."); | |
+ StateDev = ACPIDEV; | |
+ } else if (pstate_dev_avail[CLKMDEV].probe()) { | |
+ if (DebugOpt) | |
+ syslog(LOG_INFO, "Using clockmod(4) sysctl."); | |
+ StateDev = CLKMDEV; | |
+ } else { | |
+ if (++tries > 120 && DebugOpt) { | |
+ tries = 0; | |
+ syslog(LOG_WARNING, "Can't detect CPU P-State handlers."); | |
} | |
+ StateDev = INVLDEV; | |
+ return; | |
} | |
+ | |
+ /* | |
+ * Initialise the method we found. | |
+ * XXX Use priorities please | |
+ */ | |
+ PSDEV_INIT(); | |
+ | |
} | |
/* | |
@@ -253,6 +229,31 @@ getcputime(void) | |
return((double)delta / 1000000.0); | |
} | |
+static | |
+void | |
+freq_hilo(char *buf, int *hi, int *lo) | |
+{ | |
+ char *tmp; | |
+ int v; | |
+ | |
+ if (buf == NULL) | |
+ return; | |
+ | |
+ tmp = strdup(buf); | |
+ if (active_fmt == clockmod_fmt) { | |
+ /* Remove % sign for strtol() */ | |
+ while ((tmp = strchr(tmp, '%')) != NULL) | |
+ *(tmp++) = ' '; | |
+ } | |
+ | |
+ while (tmp && (v = strtol(tmp, &tmp, 10)) > 0) { | |
+ if (*lo == 0 || *lo > v) | |
+ *lo = v; | |
+ if (*hi == 0 || *hi < v) | |
+ *hi = v; | |
+ } | |
+} | |
+ | |
/* | |
* nstate is the requested number of cpus that we wish to run at full | |
* frequency. We calculate how many domains we have to adjust to reach | |
@@ -262,7 +263,7 @@ getcputime(void) | |
*/ | |
static | |
void | |
-acpi_setcpufreq(int nstate) | |
+setcpufreq(int nstate) | |
{ | |
int ncpus = 0; | |
int increasing = (nstate > CpuLimit); | |
@@ -274,7 +275,6 @@ acpi_setcpufreq(int nstate) | |
int desired; | |
int v; | |
char *sysid; | |
- char *ptr; | |
char buf[256]; | |
size_t buflen; | |
cpumask_t global_cpumask; | |
@@ -320,7 +320,7 @@ acpi_setcpufreq(int nstate) | |
/* | |
* Retrieve availability list | |
*/ | |
- asprintf(&sysid, "hw.acpi.cpu.px_dom%d.available", dom); | |
+ asprintf(&sysid, active_fmt[0], dom); | |
buflen = sizeof(buf) - 1; | |
v = sysctlbyname(sysid, buf, &buflen, NULL, 0); | |
free(sysid); | |
@@ -331,21 +331,15 @@ acpi_setcpufreq(int nstate) | |
/* | |
* Parse out the highest and lowest cpu frequencies | |
*/ | |
- ptr = buf; | |
highest = lowest = 0; | |
- while (ptr && (v = strtol(ptr, &ptr, 10)) > 0) { | |
- if (lowest == 0 || lowest > v) | |
- lowest = v; | |
- if (highest == 0 || highest < v) | |
- highest = v; | |
- } | |
+ freq_hilo(buf, &highest, &lowest); | |
/* | |
* Calculate the desired cpu frequency, test, and set. | |
*/ | |
desired = increasing ? highest : lowest; | |
- asprintf(&sysid, "hw.acpi.cpu.px_dom%d.select", dom); | |
+ asprintf(&sysid, active_fmt[2], dom); | |
buflen = sizeof(v); | |
v = 0; | |
sysctlbyname(sysid, &v, &buflen, NULL, 0); | |
diff --git a/usr.sbin/powerd/powerd.h b/usr.sbin/powerd/powerd.h | |
new file mode 100644 | |
index 0000000..b6cdf52 | |
--- /dev/null | |
+++ b/usr.sbin/powerd/powerd.h | |
@@ -0,0 +1,130 @@ | |
+/* | |
+ * Copyright (c) 2010 The DragonFly Project. All rights reserved. | |
+ * | |
+ * This code is derived from software contributed to The DragonFly Project | |
+ * by Matthew Dillon <dillon@backplane.com> | |
+ * | |
+ * Redistribution and use in source and binary forms, with or without | |
+ * modification, are permitted provided that the following conditions | |
+ * are met: | |
+ * | |
+ * 1. Redistributions of source code must retain the above copyright | |
+ * notice, this list of conditions and the following disclaimer. | |
+ * 2. Redistributions in binary form must reproduce the above copyright | |
+ * notice, this list of conditions and the following disclaimer in | |
+ * the documentation and/or other materials provided with the | |
+ * distribution. | |
+ * 3. Neither the name of The DragonFly Project nor the names of its | |
+ * contributors may be used to endorse or promote products derived | |
+ * from this software without specific, prior written permission. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, | |
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | |
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
+ * SUCH DAMAGE. | |
+ */ | |
+ | |
+/* | |
+ * The powerd daemon monitors the cpu load and adjusts cpu frequencies | |
+ * via appropriate sysctls. | |
+ */ | |
+#ifndef _POWERD_H_ | |
+#define _POWERD_H_ | |
+ | |
+#include <sys/types.h> | |
+#include <sys/queue.h> | |
+ | |
+/* | |
+ * As of now there are at least two methods of detecting/changing | |
+ * CPU P-States. | |
+ * One is via ACPI's sysctls hw.acpi.cpu.px_dom* but there is also | |
+ * clockmod(4) which provides different sysctls that need to be taken | |
+ * in account. Although it's unlikely devices diverge from ACPI in the | |
+ * future, below data structures will provide an easy way of plugging-in | |
+ * new ways of identifying, detecting and changing CPU P-States. | |
+ * | |
+ * Every P-State "method" will have to provide ways of: | |
+ * - Probing: Determine whether the method is available. | |
+ * - Initialising: Set up the data structure itself. | |
+ * - Giving information: I.e. domain index of a CPU | |
+ * - Changing frequencies. | |
+ * | |
+ */ | |
+#define MAXDOM 256 | |
+#define NFREQS 32 | |
+#define NDEVS 2 | |
+#define CPUPDOM 16 | |
+ | |
+enum { | |
+ ACPIDEV = 0, | |
+ CLKMDEV = 1, | |
+ INVLDEV = 99 | |
+}; | |
+ | |
+struct powerd_cpu_domain { | |
+ SLIST_ENTRY(powerd_cpu_domain) entry; | |
+ uint16_t idx; | |
+ uint16_t nfreqs; | |
+ uint16_t domfreqs[NFREQS]; | |
+}; | |
+ | |
+struct powerd_pstate_dev { | |
+ SLIST_HEAD(dom_head, powerd_cpu_domain) doms; | |
+ uint8_t prio; | |
+ uint16_t ndomains; | |
+ uint16_t ncpus; | |
+ | |
+ int (*probe)(void); | |
+ void (*init)(void); | |
+ int (*getcpudom)(int); | |
+ int (*setfreq)(int, void *); | |
+}; | |
+ | |
+#define PSDEV_INIT() (psdevs[StateDev].init()) | |
+#define PSDEV_SETFREQ(dom,freq) (psdevs[StateDev].setfreq(dom, freq)) | |
+ | |
+/* ACPI prototypes */ | |
+int powerd_acpi_probe(void); | |
+void powerd_acpi_init(void); | |
+int powerd_acpi_getcpudom(int); | |
+int powerd_acpi_setfreq(int, void *); | |
+ | |
+/* clockmod prototypes */ | |
+int powerd_clockmod_probe(void); | |
+void powerd_clockmod_init(void); | |
+int powerd_clockmod_getcpudom(int); | |
+int powerd_clockmod_setfreq(int, void *); | |
+ | |
+ | |
+struct powerd_pstate_dev psdevs[NDEVS] = { | |
+ /* ACPI-sysctl */ | |
+ { | |
+ SLIST_HEAD_INITIALIZER(doms), | |
+ 0, /* preferred method */ | |
+ 0, | |
+ powerd_acpi_probe, | |
+ powerd_acpi_init, | |
+ powerd_acpi_getcpudom, | |
+ powerd_acpi_setfreq | |
+ }, | |
+ /* clockmod-sysctl */ | |
+ { | |
+ SLIST_HEAD_INITIALIZER(doms), | |
+ 0, /* preferred method */ | |
+ 1, | |
+ powerd_clockmod_probe, | |
+ powerd_clockmod_init, | |
+ powerd_clockmod_getcpudom, | |
+ powerd_clockmod_setfreq | |
+ } | |
+}; | |
+ | |
+#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment