View | Details | Raw Unified | Return to bug 264775
Collapse All | Expand All

(-)b/sys/dev/acpica/acpi_thermal.c (-16 / +48 lines)
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

Return to bug 264775