Lines 1006-1056
acpi_tz_thread(void *arg)
Link Here
|
1006 |
static int |
1006 |
static int |
1007 |
acpi_tz_cpufreq_restore(struct acpi_tz_softc *sc) |
1007 |
acpi_tz_cpufreq_restore(struct acpi_tz_softc *sc) |
1008 |
{ |
1008 |
{ |
1009 |
device_t dev; |
1009 |
device_t *devs; |
1010 |
int error; |
1010 |
int devcount, error, n; |
1011 |
|
1011 |
|
1012 |
if (!sc->tz_cooling_updated) |
1012 |
if (!sc->tz_cooling_updated) |
1013 |
return (0); |
1013 |
return (0); |
1014 |
if ((dev = devclass_get_device(devclass_find("cpufreq"), 0)) == NULL) |
1014 |
|
|
|
1015 |
if ((error = devclass_get_devices(devclass_find("cpufreq"), &devs, &devcount))) { |
1016 |
free(devs, M_TEMP); |
1015 |
return (ENXIO); |
1017 |
return (ENXIO); |
|
|
1018 |
} |
1019 |
|
1016 |
ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), |
1020 |
ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), |
1017 |
"temperature %d.%dC: resuming previous clock speed (%d MHz)\n", |
1021 |
"temperature %d.%dC: resuming previous clock speed (%d MHz)\n", |
1018 |
TZ_KELVTOC(sc->tz_temperature), sc->tz_cooling_saved_freq); |
1022 |
TZ_KELVTOC(sc->tz_temperature), sc->tz_cooling_saved_freq); |
1019 |
error = CPUFREQ_SET(dev, NULL, CPUFREQ_PRIO_KERN); |
1023 |
for (n = 0; n < devcount; n++) { |
|
|
1024 |
if ((error = CPUFREQ_SET(devs[n], NULL, CPUFREQ_PRIO_KERN))) { |
1025 |
/* |
1026 |
* If you find yourself here: cf_set_method() in kern_cpu.c |
1027 |
* requires CPUFREQ_GET() be run before CPUFREQ_SET(), otherwise on |
1028 |
* a restore sc->curr_level.total_set.freq = CPUFREQ_VAL_UNKNOWN, |
1029 |
* and then if it hasn't been updated the next save/restore will fail. |
1030 |
*/ |
1031 |
device_printf(sc->tz_dev, "cpu%d: failed to restore cpufreq priority\n", n); |
1032 |
break; |
1033 |
} |
1034 |
} |
1020 |
if (error == 0) |
1035 |
if (error == 0) |
1021 |
sc->tz_cooling_updated = FALSE; |
1036 |
sc->tz_cooling_updated = FALSE; |
|
|
1037 |
|
1038 |
free(devs, M_TEMP); |
1022 |
return (error); |
1039 |
return (error); |
1023 |
} |
1040 |
} |
1024 |
|
1041 |
|
1025 |
static int |
1042 |
static int |
1026 |
acpi_tz_cpufreq_update(struct acpi_tz_softc *sc, int req) |
1043 |
acpi_tz_cpufreq_update(struct acpi_tz_softc *sc, int req) |
1027 |
{ |
1044 |
{ |
1028 |
device_t dev; |
1045 |
device_t *devs; |
1029 |
struct cf_level *levels; |
1046 |
struct cf_level *levels; |
1030 |
int num_levels, error, freq, desired_freq, perf, i; |
1047 |
int num_levels, error, freq, desired_freq, perf, devcount, i, n; |
1031 |
|
1048 |
|
1032 |
levels = malloc(CPUFREQ_MAX_LEVELS * sizeof(*levels), M_TEMP, M_NOWAIT); |
1049 |
levels = malloc(CPUFREQ_MAX_LEVELS * sizeof(*levels), M_TEMP, M_NOWAIT); |
1033 |
if (levels == NULL) |
1050 |
if (levels == NULL) |
1034 |
return (ENOMEM); |
1051 |
return (ENOMEM); |
1035 |
|
1052 |
|
1036 |
/* |
1053 |
/* |
1037 |
* Find the main device, cpufreq0. We don't yet support independent |
1054 |
* Find the main device, cpufreq0. We make plans based upon cpu0, and |
1038 |
* CPU frequency control on SMP. |
1055 |
* change all the cpu frequencies to the same level. |
1039 |
*/ |
1056 |
*/ |
1040 |
if ((dev = devclass_get_device(devclass_find("cpufreq"), 0)) == NULL) { |
1057 |
if ((error = devclass_get_devices(devclass_find("cpufreq"), &devs, &devcount))) { |
1041 |
error = ENXIO; |
1058 |
free(devs, M_TEMP); |
1042 |
goto out; |
1059 |
goto out; |
1043 |
} |
1060 |
} |
1044 |
|
1061 |
|
1045 |
/* Get the current frequency. */ |
1062 |
/* Get the current frequency for cpu0. */ |
1046 |
error = CPUFREQ_GET(dev, &levels[0]); |
1063 |
error = CPUFREQ_GET(devs[0], &levels[0]); |
1047 |
if (error) |
1064 |
if (error) |
1048 |
goto out; |
1065 |
goto out; |
1049 |
freq = levels[0].total_set.freq; |
1066 |
freq = levels[0].total_set.freq; |
1050 |
|
1067 |
|
1051 |
/* Get the current available frequency levels. */ |
1068 |
/* Get the current available frequency levels for cpu0. */ |
1052 |
num_levels = CPUFREQ_MAX_LEVELS; |
1069 |
num_levels = CPUFREQ_MAX_LEVELS; |
1053 |
error = CPUFREQ_LEVELS(dev, levels, &num_levels); |
1070 |
error = CPUFREQ_LEVELS(devs[0], levels, &num_levels); |
1054 |
if (error) { |
1071 |
if (error) { |
1055 |
if (error == E2BIG) |
1072 |
if (error == E2BIG) |
1056 |
printf("cpufreq: need to increase CPUFREQ_MAX_LEVELS\n"); |
1073 |
printf("cpufreq: need to increase CPUFREQ_MAX_LEVELS\n"); |
Lines 1111-1118
acpi_tz_cpufreq_update(struct acpi_tz_softc *sc, int req)
Link Here
|
1111 |
TZ_KELVTOC(sc->tz_temperature), |
1128 |
TZ_KELVTOC(sc->tz_temperature), |
1112 |
(freq > levels[i].total_set.freq) ? "de" : "in", |
1129 |
(freq > levels[i].total_set.freq) ? "de" : "in", |
1113 |
freq, levels[i].total_set.freq); |
1130 |
freq, levels[i].total_set.freq); |
1114 |
error = CPUFREQ_SET(dev, &levels[i], CPUFREQ_PRIO_KERN); |
1131 |
|
1115 |
if (error == 0 && !sc->tz_cooling_updated) { |
1132 |
/* Change all the cpus to the chosen frequency. */ |
|
|
1133 |
for (n = 0; n < devcount; n++) { |
1134 |
/* CPUFREQ_SET() fails occasionally without this. */ |
1135 |
if ((error = CPUFREQ_GET(devs[n], &levels[0]))) |
1136 |
goto out; |
1137 |
|
1138 |
if ((error = CPUFREQ_LEVELS(devs[n], levels, &num_levels))) { |
1139 |
if (error == E2BIG) |
1140 |
printf("cpufreq: need to increase CPUFREQ_MAX_LEVELS\n"); |
1141 |
goto out; |
1142 |
} |
1143 |
if ((error = CPUFREQ_SET(devs[n], &levels[i], CPUFREQ_PRIO_KERN))) |
1144 |
goto out; |
1145 |
} |
1146 |
if (!sc->tz_cooling_updated) { |
1116 |
sc->tz_cooling_saved_freq = freq; |
1147 |
sc->tz_cooling_saved_freq = freq; |
1117 |
sc->tz_cooling_updated = TRUE; |
1148 |
sc->tz_cooling_updated = TRUE; |
1118 |
} |
1149 |
} |
Lines 1121-1126
acpi_tz_cpufreq_update(struct acpi_tz_softc *sc, int req)
Link Here
|
1121 |
out: |
1152 |
out: |
1122 |
if (levels) |
1153 |
if (levels) |
1123 |
free(levels, M_TEMP); |
1154 |
free(levels, M_TEMP); |
|
|
1155 |
free(devs, M_TEMP); |
1124 |
return (error); |
1156 |
return (error); |
1125 |
} |
1157 |
} |
1126 |
|
1158 |
|