Page MenuHomeFreeBSD

D35704.id107705.diff
No OneTemporary

D35704.id107705.diff

Index: sys/dev/acpica/acpi_thermal.c
===================================================================
--- sys/dev/acpica/acpi_thermal.c
+++ sys/dev/acpica/acpi_thermal.c
@@ -1006,51 +1006,68 @@
static int
acpi_tz_cpufreq_restore(struct acpi_tz_softc *sc)
{
- device_t dev;
- int error;
+ device_t *devs;
+ int devcount, error, n;
if (!sc->tz_cooling_updated)
return (0);
- if ((dev = devclass_get_device(devclass_find("cpufreq"), 0)) == NULL)
+
+ if ((error = devclass_get_devices(devclass_find("cpufreq"), &devs, &devcount))) {
+ free(devs, M_TEMP);
return (ENXIO);
+ }
+
ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
"temperature %d.%dC: resuming previous clock speed (%d MHz)\n",
TZ_KELVTOC(sc->tz_temperature), sc->tz_cooling_saved_freq);
- error = CPUFREQ_SET(dev, NULL, CPUFREQ_PRIO_KERN);
+ for (n = 0; n < devcount; n++) {
+ if ((error = CPUFREQ_SET(devs[n], NULL, CPUFREQ_PRIO_KERN))) {
+ /*
+ * If you find yourself here: cf_set_method() in kern_cpu.c
+ * requires CPUFREQ_GET() be run before CPUFREQ_SET(), otherwise on
+ * a restore sc->curr_level.total_set.freq = CPUFREQ_VAL_UNKNOWN,
+ * and then if it hasn't been updated the next save/restore will fail.
+ */
+ device_printf(sc->tz_dev, "cpu%d: failed to restore cpufreq priority\n", n);
+ break;
+ }
+ }
if (error == 0)
sc->tz_cooling_updated = FALSE;
+
+ free(devs, M_TEMP);
return (error);
}
static int
acpi_tz_cpufreq_update(struct acpi_tz_softc *sc, int req)
{
- device_t dev;
+ device_t *devs;
struct cf_level *levels;
- int num_levels, error, freq, desired_freq, perf, i;
+ int num_levels, error, freq, desired_freq, perf, devcount, i, n;
levels = malloc(CPUFREQ_MAX_LEVELS * sizeof(*levels), M_TEMP, M_NOWAIT);
if (levels == NULL)
return (ENOMEM);
/*
- * Find the main device, cpufreq0. We don't yet support independent
- * CPU frequency control on SMP.
+ * Find the main device, cpufreq0. We make plans based upon cpu0, and
+ * change all the cpu frequencies to the same level.
*/
- if ((dev = devclass_get_device(devclass_find("cpufreq"), 0)) == NULL) {
- error = ENXIO;
+ if ((error = devclass_get_devices(devclass_find("cpufreq"), &devs, &devcount))) {
+ free(devs, M_TEMP);
goto out;
}
- /* Get the current frequency. */
- error = CPUFREQ_GET(dev, &levels[0]);
+ /* Get the current frequency for cpu0. */
+ error = CPUFREQ_GET(devs[0], &levels[0]);
if (error)
goto out;
freq = levels[0].total_set.freq;
- /* Get the current available frequency levels. */
+ /* Get the current available frequency levels for cpu0. */
num_levels = CPUFREQ_MAX_LEVELS;
- error = CPUFREQ_LEVELS(dev, levels, &num_levels);
+ error = CPUFREQ_LEVELS(devs[0], levels, &num_levels);
if (error) {
if (error == E2BIG)
printf("cpufreq: need to increase CPUFREQ_MAX_LEVELS\n");
@@ -1111,8 +1128,22 @@
TZ_KELVTOC(sc->tz_temperature),
(freq > levels[i].total_set.freq) ? "de" : "in",
freq, levels[i].total_set.freq);
- error = CPUFREQ_SET(dev, &levels[i], CPUFREQ_PRIO_KERN);
- if (error == 0 && !sc->tz_cooling_updated) {
+
+ /* Change all the cpus to the chosen frequency. */
+ for (n = 0; n < devcount; n++) {
+ /* CPUFREQ_SET() fails occasionally without this. */
+ if ((error = CPUFREQ_GET(devs[n], &levels[0])))
+ goto out;
+
+ if ((error = CPUFREQ_LEVELS(devs[n], levels, &num_levels))) {
+ if (error == E2BIG)
+ printf("cpufreq: need to increase CPUFREQ_MAX_LEVELS\n");
+ goto out;
+ }
+ if ((error = CPUFREQ_SET(devs[n], &levels[i], CPUFREQ_PRIO_KERN)))
+ goto out;
+ }
+ if (!sc->tz_cooling_updated) {
sc->tz_cooling_saved_freq = freq;
sc->tz_cooling_updated = TRUE;
}
@@ -1121,6 +1152,7 @@
out:
if (levels)
free(levels, M_TEMP);
+ free(devs, M_TEMP);
return (error);
}

File Metadata

Mime Type
text/plain
Expires
Thu, May 21, 5:02 PM (11 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33400092
Default Alt Text
D35704.id107705.diff (3 KB)

Event Timeline