Merge back Intel thermal control changes for 6.3.
This commit is contained in:
commit
a5c926acd0
@ -84,6 +84,9 @@ DPTF ACPI Drivers interface
|
||||
https:/github.com/intel/thermal_daemon for decoding
|
||||
thermal table.
|
||||
|
||||
``production_mode`` (RO)
|
||||
When different from zero, manufacturer locked thermal configuration
|
||||
from further changes.
|
||||
|
||||
ACPI Thermal Relationship table interface
|
||||
------------------------------------------
|
||||
|
@ -1079,8 +1079,6 @@ struct mbox_list {
|
||||
#if IS_ENABLED(CONFIG_THERMAL)
|
||||
struct ch_thermal {
|
||||
struct thermal_zone_device *tzdev;
|
||||
int trip_temp;
|
||||
int trip_type;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -29,36 +29,12 @@ static int cxgb4_thermal_get_temp(struct thermal_zone_device *tzdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxgb4_thermal_get_trip_type(struct thermal_zone_device *tzdev,
|
||||
int trip, enum thermal_trip_type *type)
|
||||
{
|
||||
struct adapter *adap = tzdev->devdata;
|
||||
|
||||
if (!adap->ch_thermal.trip_temp)
|
||||
return -EINVAL;
|
||||
|
||||
*type = adap->ch_thermal.trip_type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxgb4_thermal_get_trip_temp(struct thermal_zone_device *tzdev,
|
||||
int trip, int *temp)
|
||||
{
|
||||
struct adapter *adap = tzdev->devdata;
|
||||
|
||||
if (!adap->ch_thermal.trip_temp)
|
||||
return -EINVAL;
|
||||
|
||||
*temp = adap->ch_thermal.trip_temp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct thermal_zone_device_ops cxgb4_thermal_ops = {
|
||||
.get_temp = cxgb4_thermal_get_temp,
|
||||
.get_trip_type = cxgb4_thermal_get_trip_type,
|
||||
.get_trip_temp = cxgb4_thermal_get_trip_temp,
|
||||
};
|
||||
|
||||
static struct thermal_trip trip = { .type = THERMAL_TRIP_CRITICAL } ;
|
||||
|
||||
int cxgb4_thermal_init(struct adapter *adap)
|
||||
{
|
||||
struct ch_thermal *ch_thermal = &adap->ch_thermal;
|
||||
@ -79,15 +55,14 @@ int cxgb4_thermal_init(struct adapter *adap)
|
||||
if (ret < 0) {
|
||||
num_trip = 0; /* could not get trip temperature */
|
||||
} else {
|
||||
ch_thermal->trip_temp = val * 1000;
|
||||
ch_thermal->trip_type = THERMAL_TRIP_CRITICAL;
|
||||
trip.temperature = val * 1000;
|
||||
}
|
||||
|
||||
snprintf(ch_tz_name, sizeof(ch_tz_name), "cxgb4_%s", adap->name);
|
||||
ch_thermal->tzdev = thermal_zone_device_register(ch_tz_name, num_trip,
|
||||
0, adap,
|
||||
&cxgb4_thermal_ops,
|
||||
NULL, 0, 0);
|
||||
ch_thermal->tzdev = thermal_zone_device_register_with_trips(ch_tz_name, &trip, num_trip,
|
||||
0, adap,
|
||||
&cxgb4_thermal_ops,
|
||||
NULL, 0, 0);
|
||||
if (IS_ERR(ch_thermal->tzdev)) {
|
||||
ret = PTR_ERR(ch_thermal->tzdev);
|
||||
dev_err(adap->pdev_dev, "Failed to register thermal zone\n");
|
||||
|
@ -36,33 +36,39 @@ enum mlxsw_thermal_trips {
|
||||
MLXSW_THERMAL_TEMP_TRIP_HOT,
|
||||
};
|
||||
|
||||
struct mlxsw_thermal_trip {
|
||||
int type;
|
||||
int temp;
|
||||
int hyst;
|
||||
struct mlxsw_cooling_states {
|
||||
int min_state;
|
||||
int max_state;
|
||||
};
|
||||
|
||||
static const struct mlxsw_thermal_trip default_thermal_trips[] = {
|
||||
static const struct thermal_trip default_thermal_trips[] = {
|
||||
{ /* In range - 0-40% PWM */
|
||||
.type = THERMAL_TRIP_ACTIVE,
|
||||
.temp = MLXSW_THERMAL_ASIC_TEMP_NORM,
|
||||
.hyst = MLXSW_THERMAL_HYSTERESIS_TEMP,
|
||||
.min_state = 0,
|
||||
.max_state = (4 * MLXSW_THERMAL_MAX_STATE) / 10,
|
||||
.temperature = MLXSW_THERMAL_ASIC_TEMP_NORM,
|
||||
.hysteresis = MLXSW_THERMAL_HYSTERESIS_TEMP,
|
||||
},
|
||||
{
|
||||
/* In range - 40-100% PWM */
|
||||
.type = THERMAL_TRIP_ACTIVE,
|
||||
.temp = MLXSW_THERMAL_ASIC_TEMP_HIGH,
|
||||
.hyst = MLXSW_THERMAL_HYSTERESIS_TEMP,
|
||||
.min_state = (4 * MLXSW_THERMAL_MAX_STATE) / 10,
|
||||
.max_state = MLXSW_THERMAL_MAX_STATE,
|
||||
.temperature = MLXSW_THERMAL_ASIC_TEMP_HIGH,
|
||||
.hysteresis = MLXSW_THERMAL_HYSTERESIS_TEMP,
|
||||
},
|
||||
{ /* Warning */
|
||||
.type = THERMAL_TRIP_HOT,
|
||||
.temp = MLXSW_THERMAL_ASIC_TEMP_HOT,
|
||||
.temperature = MLXSW_THERMAL_ASIC_TEMP_HOT,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mlxsw_cooling_states default_cooling_states[] = {
|
||||
{
|
||||
.min_state = 0,
|
||||
.max_state = (4 * MLXSW_THERMAL_MAX_STATE) / 10,
|
||||
},
|
||||
{
|
||||
.min_state = (4 * MLXSW_THERMAL_MAX_STATE) / 10,
|
||||
.max_state = MLXSW_THERMAL_MAX_STATE,
|
||||
},
|
||||
{
|
||||
.min_state = MLXSW_THERMAL_MAX_STATE,
|
||||
.max_state = MLXSW_THERMAL_MAX_STATE,
|
||||
},
|
||||
@ -78,7 +84,8 @@ struct mlxsw_thermal;
|
||||
struct mlxsw_thermal_module {
|
||||
struct mlxsw_thermal *parent;
|
||||
struct thermal_zone_device *tzdev;
|
||||
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
|
||||
struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
|
||||
struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS];
|
||||
int module; /* Module or gearbox number */
|
||||
u8 slot_index;
|
||||
};
|
||||
@ -99,7 +106,8 @@ struct mlxsw_thermal {
|
||||
int polling_delay;
|
||||
struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
|
||||
u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1];
|
||||
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
|
||||
struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
|
||||
struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS];
|
||||
struct mlxsw_thermal_area line_cards[];
|
||||
};
|
||||
|
||||
@ -136,9 +144,9 @@ static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal,
|
||||
static void
|
||||
mlxsw_thermal_module_trips_reset(struct mlxsw_thermal_module *tz)
|
||||
{
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = 0;
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temp = 0;
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temp = 0;
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temperature = 0;
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temperature = 0;
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temperature = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -180,12 +188,12 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core,
|
||||
* by subtracting double hysteresis value.
|
||||
*/
|
||||
if (crit_temp >= MLXSW_THERMAL_MODULE_TEMP_SHIFT)
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = crit_temp -
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temperature = crit_temp -
|
||||
MLXSW_THERMAL_MODULE_TEMP_SHIFT;
|
||||
else
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = crit_temp;
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temp = crit_temp;
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temp = emerg_temp;
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temperature = crit_temp;
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temperature = crit_temp;
|
||||
tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temperature = emerg_temp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -202,11 +210,11 @@ static int mlxsw_thermal_bind(struct thermal_zone_device *tzdev,
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
|
||||
const struct mlxsw_thermal_trip *trip = &thermal->trips[i];
|
||||
const struct mlxsw_cooling_states *state = &thermal->cooling_states[i];
|
||||
|
||||
err = thermal_zone_bind_cooling_device(tzdev, i, cdev,
|
||||
trip->max_state,
|
||||
trip->min_state,
|
||||
state->max_state,
|
||||
state->min_state,
|
||||
THERMAL_WEIGHT_DEFAULT);
|
||||
if (err < 0) {
|
||||
dev_err(dev, "Failed to bind cooling device to trip %d\n", i);
|
||||
@ -260,61 +268,6 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlxsw_thermal_get_trip_type(struct thermal_zone_device *tzdev,
|
||||
int trip,
|
||||
enum thermal_trip_type *p_type)
|
||||
{
|
||||
struct mlxsw_thermal *thermal = tzdev->devdata;
|
||||
|
||||
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
|
||||
return -EINVAL;
|
||||
|
||||
*p_type = thermal->trips[trip].type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlxsw_thermal_get_trip_temp(struct thermal_zone_device *tzdev,
|
||||
int trip, int *p_temp)
|
||||
{
|
||||
struct mlxsw_thermal *thermal = tzdev->devdata;
|
||||
|
||||
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
|
||||
return -EINVAL;
|
||||
|
||||
*p_temp = thermal->trips[trip].temp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlxsw_thermal_set_trip_temp(struct thermal_zone_device *tzdev,
|
||||
int trip, int temp)
|
||||
{
|
||||
struct mlxsw_thermal *thermal = tzdev->devdata;
|
||||
|
||||
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
|
||||
return -EINVAL;
|
||||
|
||||
thermal->trips[trip].temp = temp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlxsw_thermal_get_trip_hyst(struct thermal_zone_device *tzdev,
|
||||
int trip, int *p_hyst)
|
||||
{
|
||||
struct mlxsw_thermal *thermal = tzdev->devdata;
|
||||
|
||||
*p_hyst = thermal->trips[trip].hyst;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlxsw_thermal_set_trip_hyst(struct thermal_zone_device *tzdev,
|
||||
int trip, int hyst)
|
||||
{
|
||||
struct mlxsw_thermal *thermal = tzdev->devdata;
|
||||
|
||||
thermal->trips[trip].hyst = hyst;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct thermal_zone_params mlxsw_thermal_params = {
|
||||
.no_hwmon = true,
|
||||
};
|
||||
@ -323,11 +276,6 @@ static struct thermal_zone_device_ops mlxsw_thermal_ops = {
|
||||
.bind = mlxsw_thermal_bind,
|
||||
.unbind = mlxsw_thermal_unbind,
|
||||
.get_temp = mlxsw_thermal_get_temp,
|
||||
.get_trip_type = mlxsw_thermal_get_trip_type,
|
||||
.get_trip_temp = mlxsw_thermal_get_trip_temp,
|
||||
.set_trip_temp = mlxsw_thermal_set_trip_temp,
|
||||
.get_trip_hyst = mlxsw_thermal_get_trip_hyst,
|
||||
.set_trip_hyst = mlxsw_thermal_set_trip_hyst,
|
||||
};
|
||||
|
||||
static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev,
|
||||
@ -342,11 +290,11 @@ static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev,
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < MLXSW_THERMAL_NUM_TRIPS; i++) {
|
||||
const struct mlxsw_thermal_trip *trip = &tz->trips[i];
|
||||
const struct mlxsw_cooling_states *state = &tz->cooling_states[i];
|
||||
|
||||
err = thermal_zone_bind_cooling_device(tzdev, i, cdev,
|
||||
trip->max_state,
|
||||
trip->min_state,
|
||||
state->max_state,
|
||||
state->min_state,
|
||||
THERMAL_WEIGHT_DEFAULT);
|
||||
if (err < 0)
|
||||
goto err_thermal_zone_bind_cooling_device;
|
||||
@ -434,74 +382,10 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_thermal_module_trip_type_get(struct thermal_zone_device *tzdev, int trip,
|
||||
enum thermal_trip_type *p_type)
|
||||
{
|
||||
struct mlxsw_thermal_module *tz = tzdev->devdata;
|
||||
|
||||
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
|
||||
return -EINVAL;
|
||||
|
||||
*p_type = tz->trips[trip].type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_thermal_module_trip_temp_get(struct thermal_zone_device *tzdev,
|
||||
int trip, int *p_temp)
|
||||
{
|
||||
struct mlxsw_thermal_module *tz = tzdev->devdata;
|
||||
|
||||
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
|
||||
return -EINVAL;
|
||||
|
||||
*p_temp = tz->trips[trip].temp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_thermal_module_trip_temp_set(struct thermal_zone_device *tzdev,
|
||||
int trip, int temp)
|
||||
{
|
||||
struct mlxsw_thermal_module *tz = tzdev->devdata;
|
||||
|
||||
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
|
||||
return -EINVAL;
|
||||
|
||||
tz->trips[trip].temp = temp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_thermal_module_trip_hyst_get(struct thermal_zone_device *tzdev, int trip,
|
||||
int *p_hyst)
|
||||
{
|
||||
struct mlxsw_thermal_module *tz = tzdev->devdata;
|
||||
|
||||
*p_hyst = tz->trips[trip].hyst;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_thermal_module_trip_hyst_set(struct thermal_zone_device *tzdev, int trip,
|
||||
int hyst)
|
||||
{
|
||||
struct mlxsw_thermal_module *tz = tzdev->devdata;
|
||||
|
||||
tz->trips[trip].hyst = hyst;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
|
||||
.bind = mlxsw_thermal_module_bind,
|
||||
.unbind = mlxsw_thermal_module_unbind,
|
||||
.get_temp = mlxsw_thermal_module_temp_get,
|
||||
.get_trip_type = mlxsw_thermal_module_trip_type_get,
|
||||
.get_trip_temp = mlxsw_thermal_module_trip_temp_get,
|
||||
.set_trip_temp = mlxsw_thermal_module_trip_temp_set,
|
||||
.get_trip_hyst = mlxsw_thermal_module_trip_hyst_get,
|
||||
.set_trip_hyst = mlxsw_thermal_module_trip_hyst_set,
|
||||
};
|
||||
|
||||
static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
|
||||
@ -531,11 +415,6 @@ static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = {
|
||||
.bind = mlxsw_thermal_module_bind,
|
||||
.unbind = mlxsw_thermal_module_unbind,
|
||||
.get_temp = mlxsw_thermal_gearbox_temp_get,
|
||||
.get_trip_type = mlxsw_thermal_module_trip_type_get,
|
||||
.get_trip_temp = mlxsw_thermal_module_trip_temp_get,
|
||||
.set_trip_temp = mlxsw_thermal_module_trip_temp_set,
|
||||
.get_trip_hyst = mlxsw_thermal_module_trip_hyst_get,
|
||||
.set_trip_hyst = mlxsw_thermal_module_trip_hyst_set,
|
||||
};
|
||||
|
||||
static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev,
|
||||
@ -617,7 +496,8 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz)
|
||||
else
|
||||
snprintf(tz_name, sizeof(tz_name), "mlxsw-module%d",
|
||||
module_tz->module + 1);
|
||||
module_tz->tzdev = thermal_zone_device_register(tz_name,
|
||||
module_tz->tzdev = thermal_zone_device_register_with_trips(tz_name,
|
||||
module_tz->trips,
|
||||
MLXSW_THERMAL_NUM_TRIPS,
|
||||
MLXSW_THERMAL_TRIP_MASK,
|
||||
module_tz,
|
||||
@ -661,6 +541,8 @@ mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
|
||||
module_tz->parent = thermal;
|
||||
memcpy(module_tz->trips, default_thermal_trips,
|
||||
sizeof(thermal->trips));
|
||||
memcpy(module_tz->cooling_states, default_cooling_states,
|
||||
sizeof(thermal->cooling_states));
|
||||
/* Initialize all trip point. */
|
||||
mlxsw_thermal_module_trips_reset(module_tz);
|
||||
/* Read module temperature and thresholds. */
|
||||
@ -756,7 +638,8 @@ mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
|
||||
else
|
||||
snprintf(tz_name, sizeof(tz_name), "mlxsw-gearbox%d",
|
||||
gearbox_tz->module + 1);
|
||||
gearbox_tz->tzdev = thermal_zone_device_register(tz_name,
|
||||
gearbox_tz->tzdev = thermal_zone_device_register_with_trips(tz_name,
|
||||
gearbox_tz->trips,
|
||||
MLXSW_THERMAL_NUM_TRIPS,
|
||||
MLXSW_THERMAL_TRIP_MASK,
|
||||
gearbox_tz,
|
||||
@ -813,6 +696,8 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
|
||||
gearbox_tz = &area->tz_gearbox_arr[i];
|
||||
memcpy(gearbox_tz->trips, default_thermal_trips,
|
||||
sizeof(thermal->trips));
|
||||
memcpy(gearbox_tz->cooling_states, default_cooling_states,
|
||||
sizeof(thermal->cooling_states));
|
||||
gearbox_tz->module = i;
|
||||
gearbox_tz->parent = thermal;
|
||||
gearbox_tz->slot_index = area->slot_index;
|
||||
@ -928,6 +813,7 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
thermal->core = core;
|
||||
thermal->bus_info = bus_info;
|
||||
memcpy(thermal->trips, default_thermal_trips, sizeof(thermal->trips));
|
||||
memcpy(thermal->cooling_states, default_cooling_states, sizeof(thermal->cooling_states));
|
||||
thermal->line_cards[0].slot_index = 0;
|
||||
|
||||
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfcr), mfcr_pl);
|
||||
@ -981,7 +867,8 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
MLXSW_THERMAL_SLOW_POLL_INT :
|
||||
MLXSW_THERMAL_POLL_INT;
|
||||
|
||||
thermal->tzdev = thermal_zone_device_register("mlxsw",
|
||||
thermal->tzdev = thermal_zone_device_register_with_trips("mlxsw",
|
||||
thermal->trips,
|
||||
MLXSW_THERMAL_NUM_TRIPS,
|
||||
MLXSW_THERMAL_TRIP_MASK,
|
||||
thermal,
|
||||
|
@ -501,7 +501,7 @@ struct iwl_mvm_tt_mgmt {
|
||||
* @tzone: thermal zone device data
|
||||
*/
|
||||
struct iwl_mvm_thermal_device {
|
||||
s16 temp_trips[IWL_MAX_DTS_TRIPS];
|
||||
struct thermal_trip trips[IWL_MAX_DTS_TRIPS];
|
||||
u8 fw_trips_index[IWL_MAX_DTS_TRIPS];
|
||||
struct thermal_zone_device *tzone;
|
||||
};
|
||||
|
@ -573,11 +573,11 @@ int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm)
|
||||
* and uncompressed, the FW should get it compressed and sorted
|
||||
*/
|
||||
|
||||
/* compress temp_trips to cmd array, remove uninitialized values*/
|
||||
/* compress trips to cmd array, remove uninitialized values*/
|
||||
for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
|
||||
if (mvm->tz_device.temp_trips[i] != S16_MIN) {
|
||||
if (mvm->tz_device.trips[i].temperature != INT_MIN) {
|
||||
cmd.thresholds[idx++] =
|
||||
cpu_to_le16(mvm->tz_device.temp_trips[i]);
|
||||
cpu_to_le16((s16)(mvm->tz_device.trips[i].temperature / 1000));
|
||||
}
|
||||
}
|
||||
cmd.num_temps = cpu_to_le32(idx);
|
||||
@ -593,8 +593,8 @@ int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm)
|
||||
*/
|
||||
for (i = 0; i < idx; i++) {
|
||||
for (j = 0; j < IWL_MAX_DTS_TRIPS; j++) {
|
||||
if (le16_to_cpu(cmd.thresholds[i]) ==
|
||||
mvm->tz_device.temp_trips[j])
|
||||
if ((int)(le16_to_cpu(cmd.thresholds[i]) * 1000) ==
|
||||
mvm->tz_device.trips[j].temperature)
|
||||
mvm->tz_device.fw_trips_index[i] = j;
|
||||
}
|
||||
}
|
||||
@ -638,37 +638,12 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_mvm_tzone_get_trip_temp(struct thermal_zone_device *device,
|
||||
int trip, int *temp)
|
||||
{
|
||||
struct iwl_mvm *mvm = (struct iwl_mvm *)device->devdata;
|
||||
|
||||
if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS)
|
||||
return -EINVAL;
|
||||
|
||||
*temp = mvm->tz_device.temp_trips[trip] * 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_mvm_tzone_get_trip_type(struct thermal_zone_device *device,
|
||||
int trip, enum thermal_trip_type *type)
|
||||
{
|
||||
if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS)
|
||||
return -EINVAL;
|
||||
|
||||
*type = THERMAL_TRIP_PASSIVE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device,
|
||||
int trip, int temp)
|
||||
{
|
||||
struct iwl_mvm *mvm = (struct iwl_mvm *)device->devdata;
|
||||
struct iwl_mvm_thermal_device *tzone;
|
||||
int i, ret;
|
||||
s16 temperature;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
@ -678,40 +653,17 @@ static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((temp / 1000) > S16_MAX) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
temperature = (s16)(temp / 1000);
|
||||
tzone = &mvm->tz_device;
|
||||
|
||||
if (!tzone) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* no updates*/
|
||||
if (tzone->temp_trips[trip] == temperature) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* already existing temperature */
|
||||
for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
|
||||
if (tzone->temp_trips[i] == temperature) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
tzone->temp_trips[trip] = temperature;
|
||||
|
||||
ret = iwl_mvm_send_temp_report_ths_cmd(mvm);
|
||||
out:
|
||||
mutex_unlock(&mvm->mutex);
|
||||
@ -720,8 +672,6 @@ out:
|
||||
|
||||
static struct thermal_zone_device_ops tzone_ops = {
|
||||
.get_temp = iwl_mvm_tzone_get_temp,
|
||||
.get_trip_temp = iwl_mvm_tzone_get_trip_temp,
|
||||
.get_trip_type = iwl_mvm_tzone_get_trip_type,
|
||||
.set_trip_temp = iwl_mvm_tzone_set_trip_temp,
|
||||
};
|
||||
|
||||
@ -743,7 +693,8 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
|
||||
BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
|
||||
|
||||
sprintf(name, "iwlwifi_%u", atomic_inc_return(&counter) & 0xFF);
|
||||
mvm->tz_device.tzone = thermal_zone_device_register(name,
|
||||
mvm->tz_device.tzone = thermal_zone_device_register_with_trips(name,
|
||||
mvm->tz_device.trips,
|
||||
IWL_MAX_DTS_TRIPS,
|
||||
IWL_WRITABLE_TRIPS_MSK,
|
||||
mvm, &tzone_ops,
|
||||
@ -766,8 +717,10 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
|
||||
/* 0 is a valid temperature,
|
||||
* so initialize the array with S16_MIN which invalid temperature
|
||||
*/
|
||||
for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++)
|
||||
mvm->tz_device.temp_trips[i] = S16_MIN;
|
||||
for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++) {
|
||||
mvm->tz_device.trips[i].temperature = INT_MIN;
|
||||
mvm->tz_device.trips[i].type = THERMAL_TRIP_PASSIVE;
|
||||
}
|
||||
}
|
||||
|
||||
static int iwl_mvm_tcool_get_max_state(struct thermal_cooling_device *cdev,
|
||||
|
@ -46,6 +46,8 @@
|
||||
* measured by the on-die thermal monitor are within 0 <= Tj <= 90. So,
|
||||
* assume 89°C is critical temperature.
|
||||
*/
|
||||
#define ACERHDF_DEFAULT_TEMP_FANON 60000
|
||||
#define ACERHDF_DEFAULT_TEMP_FANOFF 53000
|
||||
#define ACERHDF_TEMP_CRIT 89000
|
||||
#define ACERHDF_FAN_OFF 0
|
||||
#define ACERHDF_FAN_AUTO 1
|
||||
@ -70,8 +72,8 @@ static int kernelmode;
|
||||
#endif
|
||||
|
||||
static unsigned int interval = 10;
|
||||
static unsigned int fanon = 60000;
|
||||
static unsigned int fanoff = 53000;
|
||||
static unsigned int fanon = ACERHDF_DEFAULT_TEMP_FANON;
|
||||
static unsigned int fanoff = ACERHDF_DEFAULT_TEMP_FANOFF;
|
||||
static unsigned int verbose;
|
||||
static unsigned int list_supported;
|
||||
static unsigned int fanstate = ACERHDF_FAN_AUTO;
|
||||
@ -137,6 +139,15 @@ struct ctrl_settings {
|
||||
int mcmd_enable;
|
||||
};
|
||||
|
||||
static struct thermal_trip trips[] = {
|
||||
[0] = { .temperature = ACERHDF_DEFAULT_TEMP_FANON,
|
||||
.hysteresis = ACERHDF_DEFAULT_TEMP_FANON - ACERHDF_DEFAULT_TEMP_FANOFF,
|
||||
.type = THERMAL_TRIP_ACTIVE },
|
||||
|
||||
[1] = { .temperature = ACERHDF_TEMP_CRIT,
|
||||
.type = THERMAL_TRIP_CRITICAL }
|
||||
};
|
||||
|
||||
static struct ctrl_settings ctrl_cfg __read_mostly;
|
||||
|
||||
/* Register addresses and values for different BIOS versions */
|
||||
@ -326,6 +337,15 @@ static void acerhdf_check_param(struct thermal_zone_device *thermal)
|
||||
fanon = ACERHDF_MAX_FANON;
|
||||
}
|
||||
|
||||
if (fanon < fanoff) {
|
||||
pr_err("fanoff temperature (%d) is above fanon temperature (%d), clamping to %d\n",
|
||||
fanoff, fanon, fanon);
|
||||
fanoff = fanon;
|
||||
};
|
||||
|
||||
trips[0].temperature = fanon;
|
||||
trips[0].hysteresis = fanon - fanoff;
|
||||
|
||||
if (kernelmode && prev_interval != interval) {
|
||||
if (interval > ACERHDF_MAX_INTERVAL) {
|
||||
pr_err("interval too high, set to %d\n",
|
||||
@ -424,43 +444,6 @@ static int acerhdf_change_mode(struct thermal_zone_device *thermal,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acerhdf_get_trip_type(struct thermal_zone_device *thermal, int trip,
|
||||
enum thermal_trip_type *type)
|
||||
{
|
||||
if (trip == 0)
|
||||
*type = THERMAL_TRIP_ACTIVE;
|
||||
else if (trip == 1)
|
||||
*type = THERMAL_TRIP_CRITICAL;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acerhdf_get_trip_hyst(struct thermal_zone_device *thermal, int trip,
|
||||
int *temp)
|
||||
{
|
||||
if (trip != 0)
|
||||
return -EINVAL;
|
||||
|
||||
*temp = fanon - fanoff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acerhdf_get_trip_temp(struct thermal_zone_device *thermal, int trip,
|
||||
int *temp)
|
||||
{
|
||||
if (trip == 0)
|
||||
*temp = fanon;
|
||||
else if (trip == 1)
|
||||
*temp = ACERHDF_TEMP_CRIT;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acerhdf_get_crit_temp(struct thermal_zone_device *thermal,
|
||||
int *temperature)
|
||||
{
|
||||
@ -474,13 +457,9 @@ static struct thermal_zone_device_ops acerhdf_dev_ops = {
|
||||
.unbind = acerhdf_unbind,
|
||||
.get_temp = acerhdf_get_ec_temp,
|
||||
.change_mode = acerhdf_change_mode,
|
||||
.get_trip_type = acerhdf_get_trip_type,
|
||||
.get_trip_hyst = acerhdf_get_trip_hyst,
|
||||
.get_trip_temp = acerhdf_get_trip_temp,
|
||||
.get_crit_temp = acerhdf_get_crit_temp,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* cooling device callback functions
|
||||
* get maximal fan cooling state
|
||||
@ -710,10 +689,10 @@ static int __init acerhdf_register_thermal(void)
|
||||
if (IS_ERR(cl_dev))
|
||||
return -EINVAL;
|
||||
|
||||
thz_dev = thermal_zone_device_register("acerhdf", 2, 0, NULL,
|
||||
&acerhdf_dev_ops,
|
||||
&acerhdf_zone_params, 0,
|
||||
(kernelmode) ? interval*1000 : 0);
|
||||
thz_dev = thermal_zone_device_register_with_trips("acerhdf", trips, ARRAY_SIZE(trips),
|
||||
0, NULL, &acerhdf_dev_ops,
|
||||
&acerhdf_zone_params, 0,
|
||||
(kernelmode) ? interval*1000 : 0);
|
||||
if (IS_ERR(thz_dev))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -76,6 +76,10 @@ config THERMAL_OF
|
||||
Say 'Y' here if you need to build thermal infrastructure
|
||||
based on device tree.
|
||||
|
||||
config THERMAL_ACPI
|
||||
depends on ACPI
|
||||
bool
|
||||
|
||||
config THERMAL_WRITABLE_TRIPS
|
||||
bool "Enable writable trip points"
|
||||
help
|
||||
|
@ -13,6 +13,7 @@ thermal_sys-$(CONFIG_THERMAL_NETLINK) += thermal_netlink.o
|
||||
# interface to/from other layers providing sensors
|
||||
thermal_sys-$(CONFIG_THERMAL_HWMON) += thermal_hwmon.o
|
||||
thermal_sys-$(CONFIG_THERMAL_OF) += thermal_of.o
|
||||
thermal_sys-$(CONFIG_THERMAL_ACPI) += thermal_acpi.o
|
||||
|
||||
# governors
|
||||
thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += gov_fair_share.o
|
||||
|
@ -761,8 +761,7 @@ static void armada_set_sane_name(struct platform_device *pdev,
|
||||
}
|
||||
|
||||
/* Save the name locally */
|
||||
strncpy(priv->zone_name, name, THERMAL_NAME_LENGTH - 1);
|
||||
priv->zone_name[THERMAL_NAME_LENGTH - 1] = '\0';
|
||||
strscpy(priv->zone_name, name, THERMAL_NAME_LENGTH);
|
||||
|
||||
/* Then check there are no '-' or hwmon core will complain */
|
||||
do {
|
||||
@ -785,33 +784,34 @@ static int armada_configure_overheat_int(struct armada_thermal_priv *priv,
|
||||
int sensor_id)
|
||||
{
|
||||
/* Retrieve the critical trip point to enable the overheat interrupt */
|
||||
const struct thermal_trip *trips = of_thermal_get_trip_points(tz);
|
||||
struct thermal_trip trip;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (!trips)
|
||||
return -EINVAL;
|
||||
for (i = 0; i < thermal_zone_get_num_trips(tz); i++) {
|
||||
|
||||
for (i = 0; i < of_thermal_get_ntrips(tz); i++)
|
||||
if (trips[i].type == THERMAL_TRIP_CRITICAL)
|
||||
break;
|
||||
ret = thermal_zone_get_trip(tz, i, &trip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (i == of_thermal_get_ntrips(tz))
|
||||
return -EINVAL;
|
||||
if (trip.type != THERMAL_TRIP_CRITICAL)
|
||||
continue;
|
||||
|
||||
ret = armada_select_channel(priv, sensor_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = armada_select_channel(priv, sensor_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
armada_set_overheat_thresholds(priv,
|
||||
trips[i].temperature,
|
||||
trips[i].hysteresis);
|
||||
priv->overheat_sensor = tz;
|
||||
priv->interrupt_source = sensor_id;
|
||||
armada_set_overheat_thresholds(priv, trip.temperature,
|
||||
trip.hysteresis);
|
||||
priv->overheat_sensor = tz;
|
||||
priv->interrupt_source = sensor_id;
|
||||
|
||||
armada_enable_overheat_interrupt(priv);
|
||||
armada_enable_overheat_interrupt(priv);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int armada_thermal_probe(struct platform_device *pdev)
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/thermal.h>
|
||||
|
||||
#include "../thermal_core.h"
|
||||
#include "../thermal_hwmon.h"
|
||||
|
||||
#define BCM2835_TS_TSENSCTL 0x00
|
||||
@ -224,7 +225,8 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
|
||||
*/
|
||||
val = readl(data->regs + BCM2835_TS_TSENSCTL);
|
||||
if (!(val & BCM2835_TS_TSENSCTL_RSTB)) {
|
||||
int trip_temp, offset, slope;
|
||||
struct thermal_trip trip;
|
||||
int offset, slope;
|
||||
|
||||
slope = thermal_zone_get_slope(tz);
|
||||
offset = thermal_zone_get_offset(tz);
|
||||
@ -232,7 +234,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
|
||||
* For now we deal only with critical, otherwise
|
||||
* would need to iterate
|
||||
*/
|
||||
err = tz->ops->get_trip_temp(tz, 0, &trip_temp);
|
||||
err = thermal_zone_get_trip(tz, 0, &trip);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"Not able to read trip_temp: %d\n",
|
||||
@ -249,7 +251,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
|
||||
val |= (0xFE << BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT);
|
||||
|
||||
/* trip_adc value from info */
|
||||
val |= bcm2835_thermal_temp2adc(trip_temp,
|
||||
val |= bcm2835_thermal_temp2adc(trip.temperature,
|
||||
offset,
|
||||
slope)
|
||||
<< BCM2835_TS_TSENSCTL_THOLD_SHIFT;
|
||||
|
@ -120,44 +120,6 @@ static irqreturn_t da9062_thermal_irq_handler(int irq, void *data)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int da9062_thermal_get_trip_type(struct thermal_zone_device *z,
|
||||
int trip,
|
||||
enum thermal_trip_type *type)
|
||||
{
|
||||
struct da9062_thermal *thermal = z->devdata;
|
||||
|
||||
switch (trip) {
|
||||
case 0:
|
||||
*type = THERMAL_TRIP_HOT;
|
||||
break;
|
||||
default:
|
||||
dev_err(thermal->dev,
|
||||
"Driver does not support more than 1 trip-wire\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int da9062_thermal_get_trip_temp(struct thermal_zone_device *z,
|
||||
int trip,
|
||||
int *temp)
|
||||
{
|
||||
struct da9062_thermal *thermal = z->devdata;
|
||||
|
||||
switch (trip) {
|
||||
case 0:
|
||||
*temp = DA9062_MILLI_CELSIUS(125);
|
||||
break;
|
||||
default:
|
||||
dev_err(thermal->dev,
|
||||
"Driver does not support more than 1 trip-wire\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int da9062_thermal_get_temp(struct thermal_zone_device *z,
|
||||
int *temp)
|
||||
{
|
||||
@ -172,8 +134,10 @@ static int da9062_thermal_get_temp(struct thermal_zone_device *z,
|
||||
|
||||
static struct thermal_zone_device_ops da9062_thermal_ops = {
|
||||
.get_temp = da9062_thermal_get_temp,
|
||||
.get_trip_type = da9062_thermal_get_trip_type,
|
||||
.get_trip_temp = da9062_thermal_get_trip_temp,
|
||||
};
|
||||
|
||||
static struct thermal_trip trips[] = {
|
||||
{ .temperature = DA9062_MILLI_CELSIUS(125), .type = THERMAL_TRIP_HOT },
|
||||
};
|
||||
|
||||
static const struct da9062_thermal_config da9062_config = {
|
||||
@ -228,10 +192,10 @@ static int da9062_thermal_probe(struct platform_device *pdev)
|
||||
INIT_DELAYED_WORK(&thermal->work, da9062_thermal_poll_on);
|
||||
mutex_init(&thermal->lock);
|
||||
|
||||
thermal->zone = thermal_zone_device_register(thermal->config->name,
|
||||
1, 0, thermal,
|
||||
&da9062_thermal_ops, NULL, pp_tmp,
|
||||
0);
|
||||
thermal->zone = thermal_zone_device_register_with_trips(thermal->config->name,
|
||||
trips, ARRAY_SIZE(trips), 0, thermal,
|
||||
&da9062_thermal_ops, NULL, pp_tmp,
|
||||
0);
|
||||
if (IS_ERR(thermal->zone)) {
|
||||
dev_err(&pdev->dev, "Cannot register thermal zone device\n");
|
||||
ret = PTR_ERR(thermal->zone);
|
||||
|
@ -13,26 +13,28 @@
|
||||
|
||||
#include "thermal_core.h"
|
||||
|
||||
static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
||||
static int thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id)
|
||||
{
|
||||
int trip_temp, trip_hyst;
|
||||
struct thermal_trip trip;
|
||||
struct thermal_instance *instance;
|
||||
int ret;
|
||||
|
||||
tz->ops->get_trip_temp(tz, trip, &trip_temp);
|
||||
ret = __thermal_zone_get_trip(tz, trip_id, &trip);
|
||||
if (ret) {
|
||||
pr_warn_once("Failed to retrieve trip point %d\n", trip_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!tz->ops->get_trip_hyst) {
|
||||
pr_warn_once("Undefined get_trip_hyst for thermal zone %s - "
|
||||
"running with default hysteresis zero\n", tz->type);
|
||||
trip_hyst = 0;
|
||||
} else
|
||||
tz->ops->get_trip_hyst(tz, trip, &trip_hyst);
|
||||
if (!trip.hysteresis)
|
||||
dev_info_once(&tz->device,
|
||||
"Zero hysteresis value for thermal zone %s\n", tz->type);
|
||||
|
||||
dev_dbg(&tz->device, "Trip%d[temp=%d]:temp=%d:hyst=%d\n",
|
||||
trip, trip_temp, tz->temperature,
|
||||
trip_hyst);
|
||||
trip_id, trip.temperature, tz->temperature,
|
||||
trip.hysteresis);
|
||||
|
||||
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
|
||||
if (instance->trip != trip)
|
||||
if (instance->trip != trip_id)
|
||||
continue;
|
||||
|
||||
/* in case fan is in initial state, switch the fan off */
|
||||
@ -50,10 +52,10 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
||||
* enable fan when temperature exceeds trip_temp and disable
|
||||
* the fan in case it falls below trip_temp minus hysteresis
|
||||
*/
|
||||
if (instance->target == 0 && tz->temperature >= trip_temp)
|
||||
if (instance->target == 0 && tz->temperature >= trip.temperature)
|
||||
instance->target = 1;
|
||||
else if (instance->target == 1 &&
|
||||
tz->temperature <= trip_temp - trip_hyst)
|
||||
tz->temperature <= trip.temperature - trip.hysteresis)
|
||||
instance->target = 0;
|
||||
|
||||
dev_dbg(&instance->cdev->device, "target=%d\n",
|
||||
@ -63,6 +65,8 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
||||
instance->cdev->updated = false; /* cdev needs update */
|
||||
mutex_unlock(&instance->cdev->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,10 +99,13 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
||||
static int bang_bang_control(struct thermal_zone_device *tz, int trip)
|
||||
{
|
||||
struct thermal_instance *instance;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&tz->lock);
|
||||
|
||||
thermal_zone_trip_update(tz, trip);
|
||||
ret = thermal_zone_trip_update(tz, trip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
list_for_each_entry(instance, &tz->thermal_instances, tz_node)
|
||||
thermal_cdev_update(instance->cdev);
|
||||
|
@ -21,16 +21,12 @@
|
||||
*/
|
||||
static int get_trip_level(struct thermal_zone_device *tz)
|
||||
{
|
||||
int count = 0;
|
||||
int trip_temp;
|
||||
enum thermal_trip_type trip_type;
|
||||
|
||||
if (tz->num_trips == 0 || !tz->ops->get_trip_temp)
|
||||
return 0;
|
||||
struct thermal_trip trip;
|
||||
int count;
|
||||
|
||||
for (count = 0; count < tz->num_trips; count++) {
|
||||
tz->ops->get_trip_temp(tz, count, &trip_temp);
|
||||
if (tz->temperature < trip_temp)
|
||||
__thermal_zone_get_trip(tz, count, &trip);
|
||||
if (tz->temperature < trip.temperature)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -38,10 +34,8 @@ static int get_trip_level(struct thermal_zone_device *tz)
|
||||
* count > 0 only if temperature is greater than first trip
|
||||
* point, in which case, trip_point = count - 1
|
||||
*/
|
||||
if (count > 0) {
|
||||
tz->ops->get_trip_type(tz, count - 1, &trip_type);
|
||||
trace_thermal_zone_trip(tz, count - 1, trip_type);
|
||||
}
|
||||
if (count > 0)
|
||||
trace_thermal_zone_trip(tz, count - 1, trip.type);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -124,16 +124,15 @@ static void estimate_pid_constants(struct thermal_zone_device *tz,
|
||||
u32 sustainable_power, int trip_switch_on,
|
||||
int control_temp)
|
||||
{
|
||||
struct thermal_trip trip;
|
||||
u32 temperature_threshold = control_temp;
|
||||
int ret;
|
||||
int switch_on_temp;
|
||||
u32 temperature_threshold;
|
||||
s32 k_i;
|
||||
|
||||
ret = tz->ops->get_trip_temp(tz, trip_switch_on, &switch_on_temp);
|
||||
if (ret)
|
||||
switch_on_temp = 0;
|
||||
ret = __thermal_zone_get_trip(tz, trip_switch_on, &trip);
|
||||
if (!ret)
|
||||
temperature_threshold -= trip.temperature;
|
||||
|
||||
temperature_threshold = control_temp - switch_on_temp;
|
||||
/*
|
||||
* estimate_pid_constants() tries to find appropriate default
|
||||
* values for thermal zones that don't provide them. If a
|
||||
@ -519,10 +518,10 @@ static void get_governor_trips(struct thermal_zone_device *tz,
|
||||
last_passive = INVALID_TRIP;
|
||||
|
||||
for (i = 0; i < tz->num_trips; i++) {
|
||||
enum thermal_trip_type type;
|
||||
struct thermal_trip trip;
|
||||
int ret;
|
||||
|
||||
ret = tz->ops->get_trip_type(tz, i, &type);
|
||||
ret = __thermal_zone_get_trip(tz, i, &trip);
|
||||
if (ret) {
|
||||
dev_warn(&tz->device,
|
||||
"Failed to get trip point %d type: %d\n", i,
|
||||
@ -530,14 +529,14 @@ static void get_governor_trips(struct thermal_zone_device *tz,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type == THERMAL_TRIP_PASSIVE) {
|
||||
if (trip.type == THERMAL_TRIP_PASSIVE) {
|
||||
if (!found_first_passive) {
|
||||
params->trip_switch_on = i;
|
||||
found_first_passive = true;
|
||||
} else {
|
||||
last_passive = i;
|
||||
}
|
||||
} else if (type == THERMAL_TRIP_ACTIVE) {
|
||||
} else if (trip.type == THERMAL_TRIP_ACTIVE) {
|
||||
last_active = i;
|
||||
} else {
|
||||
break;
|
||||
@ -632,7 +631,7 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
|
||||
{
|
||||
int ret;
|
||||
struct power_allocator_params *params;
|
||||
int control_temp;
|
||||
struct thermal_trip trip;
|
||||
|
||||
ret = check_power_actors(tz);
|
||||
if (ret)
|
||||
@ -658,13 +657,12 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
|
||||
get_governor_trips(tz, params);
|
||||
|
||||
if (tz->num_trips > 0) {
|
||||
ret = tz->ops->get_trip_temp(tz,
|
||||
params->trip_max_desired_temperature,
|
||||
&control_temp);
|
||||
ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature,
|
||||
&trip);
|
||||
if (!ret)
|
||||
estimate_pid_constants(tz, tz->tzp->sustainable_power,
|
||||
params->trip_switch_on,
|
||||
control_temp);
|
||||
trip.temperature);
|
||||
}
|
||||
|
||||
reset_pid_controller(params);
|
||||
@ -694,11 +692,11 @@ static void power_allocator_unbind(struct thermal_zone_device *tz)
|
||||
tz->governor_data = NULL;
|
||||
}
|
||||
|
||||
static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
|
||||
static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id)
|
||||
{
|
||||
int ret;
|
||||
int switch_on_temp, control_temp;
|
||||
struct power_allocator_params *params = tz->governor_data;
|
||||
struct thermal_trip trip;
|
||||
int ret;
|
||||
bool update;
|
||||
|
||||
lockdep_assert_held(&tz->lock);
|
||||
@ -707,13 +705,12 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
|
||||
* We get called for every trip point but we only need to do
|
||||
* our calculations once
|
||||
*/
|
||||
if (trip != params->trip_max_desired_temperature)
|
||||
if (trip_id != params->trip_max_desired_temperature)
|
||||
return 0;
|
||||
|
||||
ret = tz->ops->get_trip_temp(tz, params->trip_switch_on,
|
||||
&switch_on_temp);
|
||||
if (!ret && (tz->temperature < switch_on_temp)) {
|
||||
update = (tz->last_temperature >= switch_on_temp);
|
||||
ret = __thermal_zone_get_trip(tz, params->trip_switch_on, &trip);
|
||||
if (!ret && (tz->temperature < trip.temperature)) {
|
||||
update = (tz->last_temperature >= trip.temperature);
|
||||
tz->passive = 0;
|
||||
reset_pid_controller(params);
|
||||
allow_maximum_power(tz, update);
|
||||
@ -722,16 +719,14 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
|
||||
|
||||
tz->passive = 1;
|
||||
|
||||
ret = tz->ops->get_trip_temp(tz, params->trip_max_desired_temperature,
|
||||
&control_temp);
|
||||
ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature, &trip);
|
||||
if (ret) {
|
||||
dev_warn(&tz->device,
|
||||
"Failed to get the maximum desired temperature: %d\n",
|
||||
dev_warn(&tz->device, "Failed to get the maximum desired temperature: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return allocate_power(tz, control_temp);
|
||||
return allocate_power(tz, trip.temperature);
|
||||
}
|
||||
|
||||
static struct thermal_governor thermal_gov_power_allocator = {
|
||||
|
@ -95,30 +95,28 @@ static void update_passive_instance(struct thermal_zone_device *tz,
|
||||
tz->passive += value;
|
||||
}
|
||||
|
||||
static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
||||
static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id)
|
||||
{
|
||||
int trip_temp;
|
||||
enum thermal_trip_type trip_type;
|
||||
enum thermal_trend trend;
|
||||
struct thermal_instance *instance;
|
||||
struct thermal_trip trip;
|
||||
bool throttle = false;
|
||||
int old_target;
|
||||
|
||||
tz->ops->get_trip_temp(tz, trip, &trip_temp);
|
||||
tz->ops->get_trip_type(tz, trip, &trip_type);
|
||||
__thermal_zone_get_trip(tz, trip_id, &trip);
|
||||
|
||||
trend = get_tz_trend(tz, trip);
|
||||
trend = get_tz_trend(tz, trip_id);
|
||||
|
||||
if (tz->temperature >= trip_temp) {
|
||||
if (tz->temperature >= trip.temperature) {
|
||||
throttle = true;
|
||||
trace_thermal_zone_trip(tz, trip, trip_type);
|
||||
trace_thermal_zone_trip(tz, trip_id, trip.type);
|
||||
}
|
||||
|
||||
dev_dbg(&tz->device, "Trip%d[type=%d,temp=%d]:trend=%d,throttle=%d\n",
|
||||
trip, trip_type, trip_temp, trend, throttle);
|
||||
trip_id, trip.type, trip.temperature, trend, throttle);
|
||||
|
||||
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
|
||||
if (instance->trip != trip)
|
||||
if (instance->trip != trip_id)
|
||||
continue;
|
||||
|
||||
old_target = instance->target;
|
||||
@ -132,11 +130,11 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
||||
/* Activate a passive thermal instance */
|
||||
if (old_target == THERMAL_NO_TARGET &&
|
||||
instance->target != THERMAL_NO_TARGET)
|
||||
update_passive_instance(tz, trip_type, 1);
|
||||
update_passive_instance(tz, trip.type, 1);
|
||||
/* Deactivate a passive thermal instance */
|
||||
else if (old_target != THERMAL_NO_TARGET &&
|
||||
instance->target == THERMAL_NO_TARGET)
|
||||
update_passive_instance(tz, trip_type, -1);
|
||||
update_passive_instance(tz, trip.type, -1);
|
||||
|
||||
instance->initialized = true;
|
||||
mutex_lock(&instance->cdev->lock);
|
||||
|
@ -482,7 +482,7 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
|
||||
struct hisi_thermal_sensor *sensor)
|
||||
{
|
||||
int ret, i;
|
||||
const struct thermal_trip *trip;
|
||||
struct thermal_trip trip;
|
||||
|
||||
sensor->tzd = devm_thermal_of_zone_register(&pdev->dev,
|
||||
sensor->id, sensor,
|
||||
@ -495,11 +495,12 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
trip = of_thermal_get_trip_points(sensor->tzd);
|
||||
for (i = 0; i < thermal_zone_get_num_trips(sensor->tzd); i++) {
|
||||
|
||||
for (i = 0; i < of_thermal_get_ntrips(sensor->tzd); i++) {
|
||||
if (trip[i].type == THERMAL_TRIP_PASSIVE) {
|
||||
sensor->thres_temp = trip[i].temperature;
|
||||
thermal_zone_get_trip(sensor->tzd, i, &trip);
|
||||
|
||||
if (trip.type == THERMAL_TRIP_PASSIVE) {
|
||||
sensor->thres_temp = trip.temperature;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,6 @@
|
||||
enum imx_thermal_trip {
|
||||
IMX_TRIP_PASSIVE,
|
||||
IMX_TRIP_CRITICAL,
|
||||
IMX_TRIP_NUM,
|
||||
};
|
||||
|
||||
#define IMX_POLLING_DELAY 2000 /* millisecond */
|
||||
@ -115,6 +114,11 @@ struct thermal_soc_data {
|
||||
u32 low_alarm_shift;
|
||||
};
|
||||
|
||||
static struct thermal_trip trips[] = {
|
||||
[IMX_TRIP_PASSIVE] = { .type = THERMAL_TRIP_PASSIVE },
|
||||
[IMX_TRIP_CRITICAL] = { .type = THERMAL_TRIP_CRITICAL },
|
||||
};
|
||||
|
||||
static struct thermal_soc_data thermal_imx6q_data = {
|
||||
.version = TEMPMON_IMX6Q,
|
||||
|
||||
@ -201,8 +205,6 @@ struct imx_thermal_data {
|
||||
struct thermal_cooling_device *cdev;
|
||||
struct regmap *tempmon;
|
||||
u32 c1, c2; /* See formula in imx_init_calib() */
|
||||
int temp_passive;
|
||||
int temp_critical;
|
||||
int temp_max;
|
||||
int alarm_temp;
|
||||
int last_temp;
|
||||
@ -279,12 +281,12 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
|
||||
|
||||
/* Update alarm value to next higher trip point for TEMPMON_IMX6Q */
|
||||
if (data->socdata->version == TEMPMON_IMX6Q) {
|
||||
if (data->alarm_temp == data->temp_passive &&
|
||||
*temp >= data->temp_passive)
|
||||
imx_set_alarm_temp(data, data->temp_critical);
|
||||
if (data->alarm_temp == data->temp_critical &&
|
||||
*temp < data->temp_passive) {
|
||||
imx_set_alarm_temp(data, data->temp_passive);
|
||||
if (data->alarm_temp == trips[IMX_TRIP_PASSIVE].temperature &&
|
||||
*temp >= trips[IMX_TRIP_PASSIVE].temperature)
|
||||
imx_set_alarm_temp(data, trips[IMX_TRIP_CRITICAL].temperature);
|
||||
if (data->alarm_temp == trips[IMX_TRIP_CRITICAL].temperature &&
|
||||
*temp < trips[IMX_TRIP_PASSIVE].temperature) {
|
||||
imx_set_alarm_temp(data, trips[IMX_TRIP_PASSIVE].temperature);
|
||||
dev_dbg(&tz->device, "thermal alarm off: T < %d\n",
|
||||
data->alarm_temp / 1000);
|
||||
}
|
||||
@ -330,29 +332,10 @@ static int imx_change_mode(struct thermal_zone_device *tz,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_get_trip_type(struct thermal_zone_device *tz, int trip,
|
||||
enum thermal_trip_type *type)
|
||||
{
|
||||
*type = (trip == IMX_TRIP_PASSIVE) ? THERMAL_TRIP_PASSIVE :
|
||||
THERMAL_TRIP_CRITICAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_get_crit_temp(struct thermal_zone_device *tz, int *temp)
|
||||
{
|
||||
struct imx_thermal_data *data = tz->devdata;
|
||||
*temp = trips[IMX_TRIP_CRITICAL].temperature;
|
||||
|
||||
*temp = data->temp_critical;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_get_trip_temp(struct thermal_zone_device *tz, int trip,
|
||||
int *temp)
|
||||
{
|
||||
struct imx_thermal_data *data = tz->devdata;
|
||||
|
||||
*temp = (trip == IMX_TRIP_PASSIVE) ? data->temp_passive :
|
||||
data->temp_critical;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -371,10 +354,10 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
|
||||
return -EPERM;
|
||||
|
||||
/* do not allow passive to be set higher than critical */
|
||||
if (temp < 0 || temp > data->temp_critical)
|
||||
if (temp < 0 || temp > trips[IMX_TRIP_CRITICAL].temperature)
|
||||
return -EINVAL;
|
||||
|
||||
data->temp_passive = temp;
|
||||
trips[IMX_TRIP_PASSIVE].temperature = temp;
|
||||
|
||||
imx_set_alarm_temp(data, temp);
|
||||
|
||||
@ -423,8 +406,6 @@ static struct thermal_zone_device_ops imx_tz_ops = {
|
||||
.unbind = imx_unbind,
|
||||
.get_temp = imx_get_temp,
|
||||
.change_mode = imx_change_mode,
|
||||
.get_trip_type = imx_get_trip_type,
|
||||
.get_trip_temp = imx_get_trip_temp,
|
||||
.get_crit_temp = imx_get_crit_temp,
|
||||
.set_trip_temp = imx_set_trip_temp,
|
||||
};
|
||||
@ -507,8 +488,8 @@ static void imx_init_temp_grade(struct platform_device *pdev, u32 ocotp_mem0)
|
||||
* Set the critical trip point at 5 °C under max
|
||||
* Set the passive trip point at 10 °C under max (changeable via sysfs)
|
||||
*/
|
||||
data->temp_critical = data->temp_max - (1000 * 5);
|
||||
data->temp_passive = data->temp_max - (1000 * 10);
|
||||
trips[IMX_TRIP_PASSIVE].temperature = data->temp_max - (1000 * 10);
|
||||
trips[IMX_TRIP_CRITICAL].temperature = data->temp_max - (1000 * 5);
|
||||
}
|
||||
|
||||
static int imx_init_from_tempmon_data(struct platform_device *pdev)
|
||||
@ -743,12 +724,13 @@ static int imx_thermal_probe(struct platform_device *pdev)
|
||||
goto legacy_cleanup;
|
||||
}
|
||||
|
||||
data->tz = thermal_zone_device_register("imx_thermal_zone",
|
||||
IMX_TRIP_NUM,
|
||||
BIT(IMX_TRIP_PASSIVE), data,
|
||||
&imx_tz_ops, NULL,
|
||||
IMX_PASSIVE_DELAY,
|
||||
IMX_POLLING_DELAY);
|
||||
data->tz = thermal_zone_device_register_with_trips("imx_thermal_zone",
|
||||
trips,
|
||||
ARRAY_SIZE(trips),
|
||||
BIT(IMX_TRIP_PASSIVE), data,
|
||||
&imx_tz_ops, NULL,
|
||||
IMX_PASSIVE_DELAY,
|
||||
IMX_POLLING_DELAY);
|
||||
if (IS_ERR(data->tz)) {
|
||||
ret = PTR_ERR(data->tz);
|
||||
dev_err(&pdev->dev,
|
||||
@ -758,8 +740,8 @@ static int imx_thermal_probe(struct platform_device *pdev)
|
||||
|
||||
dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC"
|
||||
" critical:%dC passive:%dC\n", data->temp_grade,
|
||||
data->temp_max / 1000, data->temp_critical / 1000,
|
||||
data->temp_passive / 1000);
|
||||
data->temp_max / 1000, trips[IMX_TRIP_CRITICAL].temperature / 1000,
|
||||
trips[IMX_TRIP_PASSIVE].temperature / 1000);
|
||||
|
||||
/* Enable measurements at ~ 10 Hz */
|
||||
regmap_write(map, data->socdata->measure_freq_ctrl + REG_CLR,
|
||||
@ -767,10 +749,10 @@ static int imx_thermal_probe(struct platform_device *pdev)
|
||||
measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
|
||||
regmap_write(map, data->socdata->measure_freq_ctrl + REG_SET,
|
||||
measure_freq << data->socdata->measure_freq_shift);
|
||||
imx_set_alarm_temp(data, data->temp_passive);
|
||||
imx_set_alarm_temp(data, trips[IMX_TRIP_PASSIVE].temperature);
|
||||
|
||||
if (data->socdata->version == TEMPMON_IMX6SX)
|
||||
imx_set_panic_temp(data, data->temp_critical);
|
||||
imx_set_panic_temp(data, trips[IMX_TRIP_CRITICAL].temperature);
|
||||
|
||||
regmap_write(map, data->socdata->sensor_ctrl + REG_CLR,
|
||||
data->socdata->power_down_mask);
|
||||
|
@ -12,11 +12,16 @@ config X86_THERMAL_VECTOR
|
||||
def_bool y
|
||||
depends on X86 && CPU_SUP_INTEL && X86_LOCAL_APIC
|
||||
|
||||
config INTEL_TCC
|
||||
bool
|
||||
depends on X86
|
||||
|
||||
config X86_PKG_TEMP_THERMAL
|
||||
tristate "X86 package temperature thermal driver"
|
||||
depends on X86_THERMAL_VECTOR
|
||||
select THERMAL_GOV_USER_SPACE
|
||||
select THERMAL_WRITABLE_TRIPS
|
||||
select INTEL_TCC
|
||||
default m
|
||||
help
|
||||
Enable this to register CPU digital sensor for package temperature as
|
||||
@ -28,6 +33,7 @@ config INTEL_SOC_DTS_IOSF_CORE
|
||||
tristate
|
||||
depends on X86 && PCI
|
||||
select IOSF_MBI
|
||||
select INTEL_TCC
|
||||
help
|
||||
This is becoming a common feature for Intel SoCs to expose the additional
|
||||
digital temperature sensors (DTSs) using side band interface (IOSF). This
|
||||
@ -75,6 +81,7 @@ config INTEL_BXT_PMIC_THERMAL
|
||||
config INTEL_PCH_THERMAL
|
||||
tristate "Intel PCH Thermal Reporting Driver"
|
||||
depends on X86 && PCI
|
||||
select THERMAL_ACPI if ACPI
|
||||
help
|
||||
Enable this to support thermal reporting on certain intel PCHs.
|
||||
Thermal reporting device will provide temperature reading,
|
||||
@ -83,6 +90,7 @@ config INTEL_PCH_THERMAL
|
||||
config INTEL_TCC_COOLING
|
||||
tristate "Intel TCC offset cooling Driver"
|
||||
depends on X86
|
||||
select INTEL_TCC
|
||||
help
|
||||
Enable this to support system cooling by adjusting the effective TCC
|
||||
activation temperature via the TCC Offset register, which is widely
|
||||
|
@ -2,6 +2,7 @@
|
||||
#
|
||||
# Makefile for various Intel thermal drivers.
|
||||
|
||||
obj-$(CONFIG_INTEL_TCC) += intel_tcc.o
|
||||
obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
|
||||
obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o
|
||||
obj-$(CONFIG_INTEL_SOC_DTS_IOSF_CORE) += intel_soc_dts_iosf.o
|
||||
|
@ -10,6 +10,7 @@ config INT340X_THERMAL
|
||||
select ACPI_THERMAL_REL
|
||||
select ACPI_FAN
|
||||
select INTEL_SOC_DTS_IOSF_CORE
|
||||
select INTEL_TCC
|
||||
select PROC_THERMAL_MMIO_RAPL if POWERCAP
|
||||
help
|
||||
Newer laptops and tablets that use ACPI may have thermal sensors and
|
||||
|
@ -60,6 +60,7 @@ struct int3400_thermal_priv {
|
||||
int odvp_count;
|
||||
int *odvp;
|
||||
u32 os_uuid_mask;
|
||||
int production_mode;
|
||||
struct odvp_attr *odvp_attrs;
|
||||
};
|
||||
|
||||
@ -130,10 +131,7 @@ static ssize_t available_uuids_show(struct device *dev,
|
||||
|
||||
for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; i++) {
|
||||
if (priv->uuid_bitmap & (1 << i))
|
||||
length += scnprintf(&buf[length],
|
||||
PAGE_SIZE - length,
|
||||
"%s\n",
|
||||
int3400_thermal_uuids[i]);
|
||||
length += sysfs_emit_at(buf, length, int3400_thermal_uuids[i]);
|
||||
}
|
||||
|
||||
return length;
|
||||
@ -151,10 +149,7 @@ static ssize_t current_uuid_show(struct device *dev,
|
||||
|
||||
for (i = 0; i <= INT3400_THERMAL_CRITICAL; i++) {
|
||||
if (priv->os_uuid_mask & BIT(i))
|
||||
length += scnprintf(&buf[length],
|
||||
PAGE_SIZE - length,
|
||||
"%s\n",
|
||||
int3400_thermal_uuids[i]);
|
||||
length += sysfs_emit_at(buf, length, int3400_thermal_uuids[i]);
|
||||
}
|
||||
|
||||
if (length)
|
||||
@ -315,6 +310,44 @@ end:
|
||||
return result;
|
||||
}
|
||||
|
||||
static ssize_t production_mode_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct int3400_thermal_priv *priv = dev_get_drvdata(dev);
|
||||
|
||||
return sysfs_emit(buf, "%d\n", priv->production_mode);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(production_mode);
|
||||
|
||||
static int production_mode_init(struct int3400_thermal_priv *priv)
|
||||
{
|
||||
unsigned long long mode;
|
||||
acpi_status status;
|
||||
int ret;
|
||||
|
||||
priv->production_mode = -1;
|
||||
|
||||
status = acpi_evaluate_integer(priv->adev->handle, "DCFG", NULL, &mode);
|
||||
/* If the method is not present, this is not an error */
|
||||
if (ACPI_FAILURE(status))
|
||||
return 0;
|
||||
|
||||
ret = sysfs_create_file(&priv->pdev->dev.kobj, &dev_attr_production_mode.attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->production_mode = mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void production_mode_exit(struct int3400_thermal_priv *priv)
|
||||
{
|
||||
if (priv->production_mode >= 0)
|
||||
sysfs_remove_file(&priv->pdev->dev.kobj, &dev_attr_production_mode.attr);
|
||||
}
|
||||
|
||||
static ssize_t odvp_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
@ -610,8 +643,15 @@ static int int3400_thermal_probe(struct platform_device *pdev)
|
||||
if (result)
|
||||
goto free_sysfs;
|
||||
|
||||
result = production_mode_init(priv);
|
||||
if (result)
|
||||
goto free_notify;
|
||||
|
||||
return 0;
|
||||
|
||||
free_notify:
|
||||
acpi_remove_notify_handler(priv->adev->handle, ACPI_DEVICE_NOTIFY,
|
||||
int3400_notify);
|
||||
free_sysfs:
|
||||
cleanup_odvp(priv);
|
||||
if (!ZERO_OR_NULL_PTR(priv->data_vault)) {
|
||||
@ -638,6 +678,8 @@ static int int3400_thermal_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct int3400_thermal_priv *priv = platform_get_drvdata(pdev);
|
||||
|
||||
production_mode_exit(priv);
|
||||
|
||||
acpi_remove_notify_handler(
|
||||
priv->adev->handle, ACPI_DEVICE_NOTIFY,
|
||||
int3400_notify);
|
||||
|
@ -18,9 +18,6 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone,
|
||||
unsigned long long tmp;
|
||||
acpi_status status;
|
||||
|
||||
if (d->override_ops && d->override_ops->get_temp)
|
||||
return d->override_ops->get_temp(zone, temp);
|
||||
|
||||
status = acpi_evaluate_integer(d->adev->handle, "_TMP", NULL, &tmp);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
@ -46,9 +43,6 @@ static int int340x_thermal_get_trip_temp(struct thermal_zone_device *zone,
|
||||
struct int34x_thermal_zone *d = zone->devdata;
|
||||
int i, ret = 0;
|
||||
|
||||
if (d->override_ops && d->override_ops->get_trip_temp)
|
||||
return d->override_ops->get_trip_temp(zone, trip, temp);
|
||||
|
||||
mutex_lock(&d->trip_mutex);
|
||||
|
||||
if (trip < d->aux_trip_nr)
|
||||
@ -83,9 +77,6 @@ static int int340x_thermal_get_trip_type(struct thermal_zone_device *zone,
|
||||
struct int34x_thermal_zone *d = zone->devdata;
|
||||
int i, ret = 0;
|
||||
|
||||
if (d->override_ops && d->override_ops->get_trip_type)
|
||||
return d->override_ops->get_trip_type(zone, trip, type);
|
||||
|
||||
mutex_lock(&d->trip_mutex);
|
||||
|
||||
if (trip < d->aux_trip_nr)
|
||||
@ -120,9 +111,6 @@ static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone,
|
||||
acpi_status status;
|
||||
char name[10];
|
||||
|
||||
if (d->override_ops && d->override_ops->set_trip_temp)
|
||||
return d->override_ops->set_trip_temp(zone, trip, temp);
|
||||
|
||||
snprintf(name, sizeof(name), "PAT%d", trip);
|
||||
status = acpi_execute_simple_method(d->adev->handle, name,
|
||||
millicelsius_to_deci_kelvin(temp));
|
||||
@ -142,9 +130,6 @@ static int int340x_thermal_get_trip_hyst(struct thermal_zone_device *zone,
|
||||
acpi_status status;
|
||||
unsigned long long hyst;
|
||||
|
||||
if (d->override_ops && d->override_ops->get_trip_hyst)
|
||||
return d->override_ops->get_trip_hyst(zone, trip, temp);
|
||||
|
||||
status = acpi_evaluate_integer(d->adev->handle, "GTSH", NULL, &hyst);
|
||||
if (ACPI_FAILURE(status))
|
||||
*temp = 0;
|
||||
@ -229,7 +214,7 @@ static struct thermal_zone_params int340x_thermal_params = {
|
||||
};
|
||||
|
||||
struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
|
||||
struct thermal_zone_device_ops *override_ops)
|
||||
int (*get_temp) (struct thermal_zone_device *, int *))
|
||||
{
|
||||
struct int34x_thermal_zone *int34x_thermal_zone;
|
||||
acpi_status status;
|
||||
@ -245,7 +230,16 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
|
||||
mutex_init(&int34x_thermal_zone->trip_mutex);
|
||||
|
||||
int34x_thermal_zone->adev = adev;
|
||||
int34x_thermal_zone->override_ops = override_ops;
|
||||
|
||||
int34x_thermal_zone->ops = kmemdup(&int340x_thermal_zone_ops,
|
||||
sizeof(int340x_thermal_zone_ops), GFP_KERNEL);
|
||||
if (!int34x_thermal_zone->ops) {
|
||||
ret = -ENOMEM;
|
||||
goto err_ops_alloc;
|
||||
}
|
||||
|
||||
if (get_temp)
|
||||
int34x_thermal_zone->ops->get_temp = get_temp;
|
||||
|
||||
status = acpi_evaluate_integer(adev->handle, "PATC", NULL, &trip_cnt);
|
||||
if (ACPI_FAILURE(status))
|
||||
@ -276,7 +270,7 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
|
||||
acpi_device_bid(adev),
|
||||
trip_cnt,
|
||||
trip_mask, int34x_thermal_zone,
|
||||
&int340x_thermal_zone_ops,
|
||||
int34x_thermal_zone->ops,
|
||||
&int340x_thermal_params,
|
||||
0, 0);
|
||||
if (IS_ERR(int34x_thermal_zone->zone)) {
|
||||
@ -295,6 +289,8 @@ err_thermal_zone:
|
||||
acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table);
|
||||
kfree(int34x_thermal_zone->aux_trips);
|
||||
err_trip_alloc:
|
||||
kfree(int34x_thermal_zone->ops);
|
||||
err_ops_alloc:
|
||||
mutex_destroy(&int34x_thermal_zone->trip_mutex);
|
||||
kfree(int34x_thermal_zone);
|
||||
return ERR_PTR(ret);
|
||||
@ -307,6 +303,7 @@ void int340x_thermal_zone_remove(struct int34x_thermal_zone
|
||||
thermal_zone_device_unregister(int34x_thermal_zone->zone);
|
||||
acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table);
|
||||
kfree(int34x_thermal_zone->aux_trips);
|
||||
kfree(int34x_thermal_zone->ops);
|
||||
mutex_destroy(&int34x_thermal_zone->trip_mutex);
|
||||
kfree(int34x_thermal_zone);
|
||||
}
|
||||
|
@ -29,14 +29,14 @@ struct int34x_thermal_zone {
|
||||
int hot_temp;
|
||||
int hot_trip_id;
|
||||
struct thermal_zone_device *zone;
|
||||
struct thermal_zone_device_ops *override_ops;
|
||||
struct thermal_zone_device_ops *ops;
|
||||
void *priv_data;
|
||||
struct acpi_lpat_conversion_table *lpat_table;
|
||||
struct mutex trip_mutex;
|
||||
};
|
||||
|
||||
struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *,
|
||||
struct thermal_zone_device_ops *override_ops);
|
||||
int (*get_temp) (struct thermal_zone_device *, int *));
|
||||
void int340x_thermal_zone_remove(struct int34x_thermal_zone *);
|
||||
int int340x_thermal_read_trips(struct int34x_thermal_zone *int34x_zone);
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
* Copyright (c) 2014, Intel Corporation.
|
||||
*/
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/intel_tcc.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
@ -68,54 +69,17 @@ static const struct attribute_group power_limit_attribute_group = {
|
||||
.name = "power_limits"
|
||||
};
|
||||
|
||||
static int tcc_get_offset(void)
|
||||
{
|
||||
u64 val;
|
||||
int err;
|
||||
|
||||
err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return (val >> 24) & 0x3f;
|
||||
}
|
||||
|
||||
static ssize_t tcc_offset_degree_celsius_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int tcc;
|
||||
int offset;
|
||||
|
||||
tcc = tcc_get_offset();
|
||||
if (tcc < 0)
|
||||
return tcc;
|
||||
offset = intel_tcc_get_offset(-1);
|
||||
if (offset < 0)
|
||||
return offset;
|
||||
|
||||
return sprintf(buf, "%d\n", tcc);
|
||||
}
|
||||
|
||||
static int tcc_offset_update(unsigned int tcc)
|
||||
{
|
||||
u64 val;
|
||||
int err;
|
||||
|
||||
if (tcc > 63)
|
||||
return -EINVAL;
|
||||
|
||||
err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (val & BIT(31))
|
||||
return -EPERM;
|
||||
|
||||
val &= ~GENMASK_ULL(29, 24);
|
||||
val |= (tcc & 0x3f) << 24;
|
||||
|
||||
err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
return sprintf(buf, "%d\n", offset);
|
||||
}
|
||||
|
||||
static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
|
||||
@ -136,7 +100,7 @@ static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
|
||||
if (kstrtouint(buf, 0, &tcc))
|
||||
return -EINVAL;
|
||||
|
||||
err = tcc_offset_update(tcc);
|
||||
err = intel_tcc_set_offset(-1, tcc);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -145,72 +109,27 @@ static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
|
||||
|
||||
static DEVICE_ATTR_RW(tcc_offset_degree_celsius);
|
||||
|
||||
static int stored_tjmax; /* since it is fixed, we can have local storage */
|
||||
|
||||
static int get_tjmax(void)
|
||||
{
|
||||
u32 eax, edx;
|
||||
u32 val;
|
||||
int err;
|
||||
|
||||
err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
val = (eax >> 16) & 0xff;
|
||||
if (val)
|
||||
return val;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int read_temp_msr(int *temp)
|
||||
static int proc_thermal_get_zone_temp(struct thermal_zone_device *zone,
|
||||
int *temp)
|
||||
{
|
||||
int cpu;
|
||||
u32 eax, edx;
|
||||
int err;
|
||||
unsigned long curr_temp_off = 0;
|
||||
int curr_temp;
|
||||
|
||||
*temp = 0;
|
||||
|
||||
for_each_online_cpu(cpu) {
|
||||
err = rdmsr_safe_on_cpu(cpu, MSR_IA32_THERM_STATUS, &eax,
|
||||
&edx);
|
||||
if (err)
|
||||
goto err_ret;
|
||||
else {
|
||||
if (eax & 0x80000000) {
|
||||
curr_temp_off = (eax >> 16) & 0x7f;
|
||||
if (!*temp || curr_temp_off < *temp)
|
||||
*temp = curr_temp_off;
|
||||
} else {
|
||||
err = -EINVAL;
|
||||
goto err_ret;
|
||||
}
|
||||
}
|
||||
curr_temp = intel_tcc_get_temp(cpu, false);
|
||||
if (curr_temp < 0)
|
||||
return curr_temp;
|
||||
if (!*temp || curr_temp > *temp)
|
||||
*temp = curr_temp;
|
||||
}
|
||||
|
||||
*temp *= 1000;
|
||||
|
||||
return 0;
|
||||
err_ret:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int proc_thermal_get_zone_temp(struct thermal_zone_device *zone,
|
||||
int *temp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = read_temp_msr(temp);
|
||||
if (!ret)
|
||||
*temp = (stored_tjmax - *temp) * 1000;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct thermal_zone_device_ops proc_thermal_local_ops = {
|
||||
.get_temp = proc_thermal_get_zone_temp,
|
||||
};
|
||||
|
||||
static int proc_thermal_read_ppcc(struct proc_thermal_device *proc_priv)
|
||||
{
|
||||
int i;
|
||||
@ -285,7 +204,7 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv)
|
||||
struct acpi_device *adev;
|
||||
acpi_status status;
|
||||
unsigned long long tmp;
|
||||
struct thermal_zone_device_ops *ops = NULL;
|
||||
int (*get_temp) (struct thermal_zone_device *, int *) = NULL;
|
||||
int ret;
|
||||
|
||||
adev = ACPI_COMPANION(dev);
|
||||
@ -302,12 +221,11 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv)
|
||||
status = acpi_evaluate_integer(adev->handle, "_TMP", NULL, &tmp);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
/* there is no _TMP method, add local method */
|
||||
stored_tjmax = get_tjmax();
|
||||
if (stored_tjmax > 0)
|
||||
ops = &proc_thermal_local_ops;
|
||||
if (intel_tcc_get_tjmax(-1) > 0)
|
||||
get_temp = proc_thermal_get_zone_temp;
|
||||
}
|
||||
|
||||
proc_priv->int340x_zone = int340x_thermal_zone_add(adev, ops);
|
||||
proc_priv->int340x_zone = int340x_thermal_zone_add(adev, get_temp);
|
||||
if (IS_ERR(proc_priv->int340x_zone)) {
|
||||
return PTR_ERR(proc_priv->int340x_zone);
|
||||
} else
|
||||
@ -356,7 +274,7 @@ static int tcc_offset_save = -1;
|
||||
|
||||
int proc_thermal_suspend(struct device *dev)
|
||||
{
|
||||
tcc_offset_save = tcc_get_offset();
|
||||
tcc_offset_save = intel_tcc_get_offset(-1);
|
||||
if (tcc_offset_save < 0)
|
||||
dev_warn(dev, "failed to save offset (%d)\n", tcc_offset_save);
|
||||
|
||||
@ -373,7 +291,7 @@ int proc_thermal_resume(struct device *dev)
|
||||
|
||||
/* Do not update if saving failed */
|
||||
if (tcc_offset_save >= 0)
|
||||
tcc_offset_update(tcc_offset_save);
|
||||
intel_tcc_set_offset(-1, tcc_offset_save);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -460,6 +378,7 @@ void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device *
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(proc_thermal_mmio_remove);
|
||||
|
||||
MODULE_IMPORT_NS(INTEL_TCC);
|
||||
MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
|
||||
MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -144,34 +144,6 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sys_get_trip_temp(struct thermal_zone_device *tzd,
|
||||
int trip, int *temp)
|
||||
{
|
||||
struct proc_thermal_pci *pci_info = tzd->devdata;
|
||||
u32 _temp;
|
||||
|
||||
proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_THRES_0, &_temp);
|
||||
if (!_temp) {
|
||||
*temp = THERMAL_TEMP_INVALID;
|
||||
} else {
|
||||
int tjmax;
|
||||
|
||||
proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_TJMAX, &tjmax);
|
||||
_temp = tjmax - _temp;
|
||||
*temp = (unsigned long)_temp * 1000;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sys_get_trip_type(struct thermal_zone_device *tzd, int trip,
|
||||
enum thermal_trip_type *type)
|
||||
{
|
||||
*type = THERMAL_TRIP_PASSIVE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
|
||||
{
|
||||
struct proc_thermal_pci *pci_info = tzd->devdata;
|
||||
@ -200,10 +172,26 @@ static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_trip_temp(struct proc_thermal_pci *pci_info)
|
||||
{
|
||||
int temp, tjmax;
|
||||
|
||||
proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_THRES_0, &temp);
|
||||
if (!temp)
|
||||
return THERMAL_TEMP_INVALID;
|
||||
|
||||
proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_TJMAX, &tjmax);
|
||||
temp = (tjmax - temp) * 1000;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
static struct thermal_trip psv_trip = {
|
||||
.type = THERMAL_TRIP_PASSIVE,
|
||||
};
|
||||
|
||||
static struct thermal_zone_device_ops tzone_ops = {
|
||||
.get_temp = sys_get_curr_temp,
|
||||
.get_trip_temp = sys_get_trip_temp,
|
||||
.get_trip_type = sys_get_trip_type,
|
||||
.set_trip_temp = sys_set_trip_temp,
|
||||
};
|
||||
|
||||
@ -251,7 +239,10 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
|
||||
if (ret)
|
||||
goto err_ret_thermal;
|
||||
|
||||
pci_info->tzone = thermal_zone_device_register("TCPU_PCI", 1, 1, pci_info,
|
||||
psv_trip.temperature = get_trip_temp(pci_info);
|
||||
|
||||
pci_info->tzone = thermal_zone_device_register_with_trips("TCPU_PCI", &psv_trip,
|
||||
1, 1, pci_info,
|
||||
&tzone_ops,
|
||||
&tzone_params, 0, 0);
|
||||
if (IS_ERR(pci_info->tzone)) {
|
||||
|
@ -232,9 +232,9 @@ static DEFINE_MUTEX(intel_menlow_attr_lock);
|
||||
|
||||
/*
|
||||
* sensor_get_auxtrip - get the current auxtrip value from sensor
|
||||
* @name: Thermalzone name
|
||||
* @auxtype : AUX0/AUX1
|
||||
* @buf: syfs buffer
|
||||
* @handle: Object handle
|
||||
* @index : GET_AUX1/GET_AUX0
|
||||
* @value : The address will be fill by the value
|
||||
*/
|
||||
static int sensor_get_auxtrip(acpi_handle handle, int index,
|
||||
unsigned long long *value)
|
||||
@ -254,9 +254,9 @@ static int sensor_get_auxtrip(acpi_handle handle, int index,
|
||||
|
||||
/*
|
||||
* sensor_set_auxtrip - set the new auxtrip value to sensor
|
||||
* @name: Thermalzone name
|
||||
* @auxtype : AUX0/AUX1
|
||||
* @buf: syfs buffer
|
||||
* @handle: Object handle
|
||||
* @index : GET_AUX1/GET_AUX0
|
||||
* @value : The value will be set
|
||||
*/
|
||||
static int sensor_set_auxtrip(acpi_handle handle, int index, int value)
|
||||
{
|
||||
|
@ -29,6 +29,7 @@
|
||||
#define PCH_THERMAL_DID_CNL_LP 0x02F9 /* CNL-LP PCH */
|
||||
#define PCH_THERMAL_DID_CML_H 0X06F9 /* CML-H PCH */
|
||||
#define PCH_THERMAL_DID_LWB 0xA1B1 /* Lewisburg PCH */
|
||||
#define PCH_THERMAL_DID_WBG 0x8D24 /* Wellsburg PCH */
|
||||
|
||||
/* Wildcat Point-LP PCH Thermal registers */
|
||||
#define WPT_TEMP 0x0000 /* Temperature */
|
||||
@ -65,6 +66,8 @@
|
||||
#define WPT_TEMP_OFFSET (PCH_TEMP_OFFSET * MILLIDEGREE_PER_DEGREE)
|
||||
#define GET_PCH_TEMP(x) (((x) / 2) + PCH_TEMP_OFFSET)
|
||||
|
||||
#define PCH_MAX_TRIPS 3 /* critical, hot, passive */
|
||||
|
||||
/* Amount of time for each cooling delay, 100ms by default for now */
|
||||
static unsigned int delay_timeout = 100;
|
||||
module_param(delay_timeout, int, 0644);
|
||||
@ -82,12 +85,7 @@ struct pch_thermal_device {
|
||||
const struct pch_dev_ops *ops;
|
||||
struct pci_dev *pdev;
|
||||
struct thermal_zone_device *tzd;
|
||||
int crt_trip_id;
|
||||
unsigned long crt_temp;
|
||||
int hot_trip_id;
|
||||
unsigned long hot_temp;
|
||||
int psv_trip_id;
|
||||
unsigned long psv_temp;
|
||||
struct thermal_trip trips[PCH_MAX_TRIPS];
|
||||
bool bios_enabled;
|
||||
};
|
||||
|
||||
@ -102,33 +100,22 @@ static void pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd,
|
||||
int *nr_trips)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
|
||||
ptd->psv_trip_id = -1;
|
||||
int ret;
|
||||
|
||||
adev = ACPI_COMPANION(&ptd->pdev->dev);
|
||||
if (adev) {
|
||||
unsigned long long r;
|
||||
acpi_status status;
|
||||
if (!adev)
|
||||
return;
|
||||
|
||||
status = acpi_evaluate_integer(adev->handle, "_PSV", NULL,
|
||||
&r);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
unsigned long trip_temp;
|
||||
ret = thermal_acpi_trip_passive(adev, &ptd->trips[*nr_trips]);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
trip_temp = deci_kelvin_to_millicelsius(r);
|
||||
if (trip_temp) {
|
||||
ptd->psv_temp = trip_temp;
|
||||
ptd->psv_trip_id = *nr_trips;
|
||||
++(*nr_trips);
|
||||
}
|
||||
}
|
||||
}
|
||||
++(*nr_trips);
|
||||
}
|
||||
#else
|
||||
static void pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd,
|
||||
int *nr_trips)
|
||||
{
|
||||
ptd->psv_trip_id = -1;
|
||||
|
||||
}
|
||||
#endif
|
||||
@ -163,21 +150,19 @@ static int pch_wpt_init(struct pch_thermal_device *ptd, int *nr_trips)
|
||||
}
|
||||
|
||||
read_trips:
|
||||
ptd->crt_trip_id = -1;
|
||||
trip_temp = readw(ptd->hw_base + WPT_CTT);
|
||||
trip_temp &= 0x1FF;
|
||||
if (trip_temp) {
|
||||
ptd->crt_temp = GET_WPT_TEMP(trip_temp);
|
||||
ptd->crt_trip_id = 0;
|
||||
ptd->trips[*nr_trips].temperature = GET_WPT_TEMP(trip_temp);
|
||||
ptd->trips[*nr_trips].type = THERMAL_TRIP_CRITICAL;
|
||||
++(*nr_trips);
|
||||
}
|
||||
|
||||
ptd->hot_trip_id = -1;
|
||||
trip_temp = readw(ptd->hw_base + WPT_PHL);
|
||||
trip_temp &= 0x1FF;
|
||||
if (trip_temp) {
|
||||
ptd->hot_temp = GET_WPT_TEMP(trip_temp);
|
||||
ptd->hot_trip_id = *nr_trips;
|
||||
ptd->trips[*nr_trips].temperature = GET_WPT_TEMP(trip_temp);
|
||||
ptd->trips[*nr_trips].type = THERMAL_TRIP_HOT;
|
||||
++(*nr_trips);
|
||||
}
|
||||
|
||||
@ -298,39 +283,6 @@ static int pch_thermal_get_temp(struct thermal_zone_device *tzd, int *temp)
|
||||
return ptd->ops->get_temp(ptd, temp);
|
||||
}
|
||||
|
||||
static int pch_get_trip_type(struct thermal_zone_device *tzd, int trip,
|
||||
enum thermal_trip_type *type)
|
||||
{
|
||||
struct pch_thermal_device *ptd = tzd->devdata;
|
||||
|
||||
if (ptd->crt_trip_id == trip)
|
||||
*type = THERMAL_TRIP_CRITICAL;
|
||||
else if (ptd->hot_trip_id == trip)
|
||||
*type = THERMAL_TRIP_HOT;
|
||||
else if (ptd->psv_trip_id == trip)
|
||||
*type = THERMAL_TRIP_PASSIVE;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pch_get_trip_temp(struct thermal_zone_device *tzd, int trip, int *temp)
|
||||
{
|
||||
struct pch_thermal_device *ptd = tzd->devdata;
|
||||
|
||||
if (ptd->crt_trip_id == trip)
|
||||
*temp = ptd->crt_temp;
|
||||
else if (ptd->hot_trip_id == trip)
|
||||
*temp = ptd->hot_temp;
|
||||
else if (ptd->psv_trip_id == trip)
|
||||
*temp = ptd->psv_temp;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pch_critical(struct thermal_zone_device *tzd)
|
||||
{
|
||||
dev_dbg(&tzd->device, "%s: critical temperature reached\n", tzd->type);
|
||||
@ -338,8 +290,6 @@ static void pch_critical(struct thermal_zone_device *tzd)
|
||||
|
||||
static struct thermal_zone_device_ops tzd_ops = {
|
||||
.get_temp = pch_thermal_get_temp,
|
||||
.get_trip_type = pch_get_trip_type,
|
||||
.get_trip_temp = pch_get_trip_temp,
|
||||
.critical = pch_critical,
|
||||
};
|
||||
|
||||
@ -350,6 +300,7 @@ enum board_ids {
|
||||
board_cnl,
|
||||
board_cml,
|
||||
board_lwb,
|
||||
board_wbg,
|
||||
};
|
||||
|
||||
static const struct board_info {
|
||||
@ -380,6 +331,10 @@ static const struct board_info {
|
||||
.name = "pch_lewisburg",
|
||||
.ops = &pch_dev_ops_wpt,
|
||||
},
|
||||
[board_wbg] = {
|
||||
.name = "pch_wellsburg",
|
||||
.ops = &pch_dev_ops_wpt,
|
||||
},
|
||||
};
|
||||
|
||||
static int intel_pch_thermal_probe(struct pci_dev *pdev,
|
||||
@ -423,8 +378,9 @@ static int intel_pch_thermal_probe(struct pci_dev *pdev,
|
||||
if (err)
|
||||
goto error_cleanup;
|
||||
|
||||
ptd->tzd = thermal_zone_device_register(bi->name, nr_trips, 0, ptd,
|
||||
&tzd_ops, NULL, 0, 0);
|
||||
ptd->tzd = thermal_zone_device_register_with_trips(bi->name, ptd->trips,
|
||||
nr_trips, 0, ptd,
|
||||
&tzd_ops, NULL, 0, 0);
|
||||
if (IS_ERR(ptd->tzd)) {
|
||||
dev_err(&pdev->dev, "Failed to register thermal zone %s\n",
|
||||
bi->name);
|
||||
@ -495,6 +451,8 @@ static const struct pci_device_id intel_pch_thermal_id[] = {
|
||||
.driver_data = board_cml, },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_LWB),
|
||||
.driver_data = board_lwb, },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_WBG),
|
||||
.driver_data = board_wbg, },
|
||||
{ 0, },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, intel_pch_thermal_id);
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/intel_tcc.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -45,32 +46,6 @@
|
||||
/* DTS0 and DTS 1 */
|
||||
#define SOC_MAX_DTS_SENSORS 2
|
||||
|
||||
static int get_tj_max(u32 *tj_max)
|
||||
{
|
||||
u32 eax, edx;
|
||||
u32 val;
|
||||
int err;
|
||||
|
||||
err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
|
||||
if (err)
|
||||
goto err_ret;
|
||||
else {
|
||||
val = (eax >> 16) & 0xff;
|
||||
if (val)
|
||||
*tj_max = val * 1000;
|
||||
else {
|
||||
err = -EINVAL;
|
||||
goto err_ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_ret:
|
||||
*tj_max = 0;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int sys_get_trip_temp(struct thermal_zone_device *tzd, int trip,
|
||||
int *temp)
|
||||
{
|
||||
@ -405,7 +380,7 @@ struct intel_soc_dts_sensors *intel_soc_dts_iosf_init(
|
||||
{
|
||||
struct intel_soc_dts_sensors *sensors;
|
||||
bool notification;
|
||||
u32 tj_max;
|
||||
int tj_max;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
@ -415,8 +390,9 @@ struct intel_soc_dts_sensors *intel_soc_dts_iosf_init(
|
||||
if (!trip_count || read_only_trip_count > trip_count)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (get_tj_max(&tj_max))
|
||||
return ERR_PTR(-EINVAL);
|
||||
tj_max = intel_tcc_get_tjmax(-1);
|
||||
if (tj_max < 0)
|
||||
return ERR_PTR(tj_max);
|
||||
|
||||
sensors = kzalloc(sizeof(*sensors), GFP_KERNEL);
|
||||
if (!sensors)
|
||||
@ -475,4 +451,5 @@ void intel_soc_dts_iosf_exit(struct intel_soc_dts_sensors *sensors)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_exit);
|
||||
|
||||
MODULE_IMPORT_NS(INTEL_TCC);
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
139
drivers/thermal/intel/intel_tcc.c
Normal file
139
drivers/thermal/intel/intel_tcc.c
Normal file
@ -0,0 +1,139 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* intel_tcc.c - Library for Intel TCC (thermal control circuitry) MSR access
|
||||
* Copyright (c) 2022, Intel Corporation.
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/intel_tcc.h>
|
||||
#include <asm/msr.h>
|
||||
|
||||
/**
|
||||
* intel_tcc_get_tjmax() - returns the default TCC activation Temperature
|
||||
* @cpu: cpu that the MSR should be run on, nagative value means any cpu.
|
||||
*
|
||||
* Get the TjMax value, which is the default thermal throttling or TCC
|
||||
* activation temperature in degrees C.
|
||||
*
|
||||
* Return: Tjmax value in degrees C on success, negative error code otherwise.
|
||||
*/
|
||||
int intel_tcc_get_tjmax(int cpu)
|
||||
{
|
||||
u32 low, high;
|
||||
int val, err;
|
||||
|
||||
if (cpu < 0)
|
||||
err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &low, &high);
|
||||
else
|
||||
err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &low, &high);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
val = (low >> 16) & 0xff;
|
||||
|
||||
return val ? val : -ENODATA;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(intel_tcc_get_tjmax, INTEL_TCC);
|
||||
|
||||
/**
|
||||
* intel_tcc_get_offset() - returns the TCC Offset value to Tjmax
|
||||
* @cpu: cpu that the MSR should be run on, nagative value means any cpu.
|
||||
*
|
||||
* Get the TCC offset value to Tjmax. The effective thermal throttling or TCC
|
||||
* activation temperature equals "Tjmax" - "TCC Offset", in degrees C.
|
||||
*
|
||||
* Return: Tcc offset value in degrees C on success, negative error code otherwise.
|
||||
*/
|
||||
int intel_tcc_get_offset(int cpu)
|
||||
{
|
||||
u32 low, high;
|
||||
int err;
|
||||
|
||||
if (cpu < 0)
|
||||
err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &low, &high);
|
||||
else
|
||||
err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &low, &high);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return (low >> 24) & 0x3f;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(intel_tcc_get_offset, INTEL_TCC);
|
||||
|
||||
/**
|
||||
* intel_tcc_set_offset() - set the TCC offset value to Tjmax
|
||||
* @cpu: cpu that the MSR should be run on, nagative value means any cpu.
|
||||
* @offset: TCC offset value in degree C
|
||||
*
|
||||
* Set the TCC Offset value to Tjmax. The effective thermal throttling or TCC
|
||||
* activation temperature equals "Tjmax" - "TCC Offset", in degree C.
|
||||
*
|
||||
* Return: On success returns 0, negative error code otherwise.
|
||||
*/
|
||||
|
||||
int intel_tcc_set_offset(int cpu, int offset)
|
||||
{
|
||||
u32 low, high;
|
||||
int err;
|
||||
|
||||
if (offset < 0 || offset > 0x3f)
|
||||
return -EINVAL;
|
||||
|
||||
if (cpu < 0)
|
||||
err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &low, &high);
|
||||
else
|
||||
err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &low, &high);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* MSR Locked */
|
||||
if (low & BIT(31))
|
||||
return -EPERM;
|
||||
|
||||
low &= ~(0x3f << 24);
|
||||
low |= offset << 24;
|
||||
|
||||
if (cpu < 0)
|
||||
return wrmsr_safe(MSR_IA32_TEMPERATURE_TARGET, low, high);
|
||||
else
|
||||
return wrmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, low, high);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(intel_tcc_set_offset, INTEL_TCC);
|
||||
|
||||
/**
|
||||
* intel_tcc_get_temp() - returns the current temperature
|
||||
* @cpu: cpu that the MSR should be run on, nagative value means any cpu.
|
||||
* @pkg: true: Package Thermal Sensor. false: Core Thermal Sensor.
|
||||
*
|
||||
* Get the current temperature returned by the CPU core/package level
|
||||
* thermal sensor, in degrees C.
|
||||
*
|
||||
* Return: Temperature in degrees C on success, negative error code otherwise.
|
||||
*/
|
||||
int intel_tcc_get_temp(int cpu, bool pkg)
|
||||
{
|
||||
u32 low, high;
|
||||
u32 msr = pkg ? MSR_IA32_PACKAGE_THERM_STATUS : MSR_IA32_THERM_STATUS;
|
||||
int tjmax, temp, err;
|
||||
|
||||
tjmax = intel_tcc_get_tjmax(cpu);
|
||||
if (tjmax < 0)
|
||||
return tjmax;
|
||||
|
||||
if (cpu < 0)
|
||||
err = rdmsr_safe(msr, &low, &high);
|
||||
else
|
||||
err = rdmsr_safe_on_cpu(cpu, msr, &low, &high);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Temperature is beyond the valid thermal sensor range */
|
||||
if (!(low & BIT(31)))
|
||||
return -ENODATA;
|
||||
|
||||
temp = tjmax - ((low >> 16) & 0x7f);
|
||||
|
||||
/* Do not allow negative CPU temperature */
|
||||
return temp >= 0 ? temp : -ENODATA;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(intel_tcc_get_temp, INTEL_TCC);
|
@ -7,12 +7,11 @@
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/intel_tcc.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
|
||||
#define TCC_SHIFT 24
|
||||
#define TCC_MASK (0x3fULL<<24)
|
||||
#define TCC_PROGRAMMABLE BIT(30)
|
||||
#define TCC_LOCKED BIT(31)
|
||||
|
||||
@ -21,47 +20,26 @@ static struct thermal_cooling_device *tcc_cdev;
|
||||
static int tcc_get_max_state(struct thermal_cooling_device *cdev, unsigned long
|
||||
*state)
|
||||
{
|
||||
*state = TCC_MASK >> TCC_SHIFT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tcc_offset_update(int tcc)
|
||||
{
|
||||
u64 val;
|
||||
int err;
|
||||
|
||||
err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
val &= ~TCC_MASK;
|
||||
val |= tcc << TCC_SHIFT;
|
||||
|
||||
err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
*state = 0x3f;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tcc_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
|
||||
*state)
|
||||
{
|
||||
u64 val;
|
||||
int err;
|
||||
int offset = intel_tcc_get_offset(-1);
|
||||
|
||||
err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
|
||||
if (err)
|
||||
return err;
|
||||
if (offset < 0)
|
||||
return offset;
|
||||
|
||||
*state = (val & TCC_MASK) >> TCC_SHIFT;
|
||||
*state = offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tcc_set_cur_state(struct thermal_cooling_device *cdev, unsigned long
|
||||
state)
|
||||
{
|
||||
return tcc_offset_update(state);
|
||||
return intel_tcc_set_offset(-1, (int)state);
|
||||
}
|
||||
|
||||
static const struct thermal_cooling_device_ops tcc_cooling_ops = {
|
||||
@ -140,6 +118,7 @@ static void __exit tcc_cooling_exit(void)
|
||||
|
||||
module_exit(tcc_cooling_exit)
|
||||
|
||||
MODULE_IMPORT_NS(INTEL_TCC);
|
||||
MODULE_DESCRIPTION("TCC offset cooling device Driver");
|
||||
MODULE_AUTHOR("Zhang Rui <rui.zhang@intel.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/intel_tcc.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/device.h>
|
||||
@ -48,11 +49,11 @@ MODULE_PARM_DESC(notify_delay_ms,
|
||||
struct zone_device {
|
||||
int cpu;
|
||||
bool work_scheduled;
|
||||
u32 tj_max;
|
||||
u32 msr_pkg_therm_low;
|
||||
u32 msr_pkg_therm_high;
|
||||
struct delayed_work work;
|
||||
struct thermal_zone_device *tzone;
|
||||
struct thermal_trip *trips;
|
||||
struct cpumask cpumask;
|
||||
};
|
||||
|
||||
@ -104,71 +105,17 @@ static struct zone_device *pkg_temp_thermal_get_dev(unsigned int cpu)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* tj-max is interesting because threshold is set relative to this
|
||||
* temperature.
|
||||
*/
|
||||
static int get_tj_max(int cpu, u32 *tj_max)
|
||||
{
|
||||
u32 eax, edx, val;
|
||||
int err;
|
||||
|
||||
err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
val = (eax >> 16) & 0xff;
|
||||
*tj_max = val * 1000;
|
||||
|
||||
return val ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
|
||||
{
|
||||
struct zone_device *zonedev = tzd->devdata;
|
||||
u32 eax, edx;
|
||||
int val;
|
||||
|
||||
rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_STATUS,
|
||||
&eax, &edx);
|
||||
if (eax & 0x80000000) {
|
||||
*temp = zonedev->tj_max - ((eax >> 16) & 0x7f) * 1000;
|
||||
pr_debug("sys_get_curr_temp %d\n", *temp);
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int sys_get_trip_temp(struct thermal_zone_device *tzd,
|
||||
int trip, int *temp)
|
||||
{
|
||||
struct zone_device *zonedev = tzd->devdata;
|
||||
unsigned long thres_reg_value;
|
||||
u32 mask, shift, eax, edx;
|
||||
int ret;
|
||||
|
||||
if (trip >= MAX_NUMBER_OF_TRIPS)
|
||||
return -EINVAL;
|
||||
|
||||
if (trip) {
|
||||
mask = THERM_MASK_THRESHOLD1;
|
||||
shift = THERM_SHIFT_THRESHOLD1;
|
||||
} else {
|
||||
mask = THERM_MASK_THRESHOLD0;
|
||||
shift = THERM_SHIFT_THRESHOLD0;
|
||||
}
|
||||
|
||||
ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||
&eax, &edx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
thres_reg_value = (eax & mask) >> shift;
|
||||
if (thres_reg_value)
|
||||
*temp = zonedev->tj_max - thres_reg_value * 1000;
|
||||
else
|
||||
*temp = THERMAL_TEMP_INVALID;
|
||||
pr_debug("sys_get_trip_temp %d\n", *temp);
|
||||
val = intel_tcc_get_temp(zonedev->cpu, true);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
*temp = val * 1000;
|
||||
pr_debug("sys_get_curr_temp %d\n", *temp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -177,9 +124,14 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
|
||||
{
|
||||
struct zone_device *zonedev = tzd->devdata;
|
||||
u32 l, h, mask, shift, intr;
|
||||
int ret;
|
||||
int tj_max, ret;
|
||||
|
||||
if (trip >= MAX_NUMBER_OF_TRIPS || temp >= zonedev->tj_max)
|
||||
tj_max = intel_tcc_get_tjmax(zonedev->cpu);
|
||||
if (tj_max < 0)
|
||||
return tj_max;
|
||||
tj_max *= 1000;
|
||||
|
||||
if (trip >= MAX_NUMBER_OF_TRIPS || temp >= tj_max)
|
||||
return -EINVAL;
|
||||
|
||||
ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||
@ -204,7 +156,7 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
|
||||
if (!temp) {
|
||||
l &= ~intr;
|
||||
} else {
|
||||
l |= (zonedev->tj_max - temp)/1000 << shift;
|
||||
l |= (tj_max - temp)/1000 << shift;
|
||||
l |= intr;
|
||||
}
|
||||
|
||||
@ -212,18 +164,9 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
|
||||
l, h);
|
||||
}
|
||||
|
||||
static int sys_get_trip_type(struct thermal_zone_device *thermal, int trip,
|
||||
enum thermal_trip_type *type)
|
||||
{
|
||||
*type = THERMAL_TRIP_PASSIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Thermal zone callback registry */
|
||||
static struct thermal_zone_device_ops tzone_ops = {
|
||||
.get_temp = sys_get_curr_temp,
|
||||
.get_trip_temp = sys_get_trip_temp,
|
||||
.get_trip_type = sys_get_trip_type,
|
||||
.set_trip_temp = sys_set_trip_temp,
|
||||
};
|
||||
|
||||
@ -323,12 +266,55 @@ static int pkg_thermal_notify(u64 msr_val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct thermal_trip *pkg_temp_thermal_trips_init(int cpu, int tj_max, int num_trips)
|
||||
{
|
||||
struct thermal_trip *trips;
|
||||
unsigned long thres_reg_value;
|
||||
u32 mask, shift, eax, edx;
|
||||
int ret, i;
|
||||
|
||||
trips = kzalloc(sizeof(*trips) * num_trips, GFP_KERNEL);
|
||||
if (!trips)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
for (i = 0; i < num_trips; i++) {
|
||||
|
||||
if (i) {
|
||||
mask = THERM_MASK_THRESHOLD1;
|
||||
shift = THERM_SHIFT_THRESHOLD1;
|
||||
} else {
|
||||
mask = THERM_MASK_THRESHOLD0;
|
||||
shift = THERM_SHIFT_THRESHOLD0;
|
||||
}
|
||||
|
||||
ret = rdmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||
&eax, &edx);
|
||||
if (ret < 0) {
|
||||
kfree(trips);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
thres_reg_value = (eax & mask) >> shift;
|
||||
|
||||
trips[i].temperature = thres_reg_value ?
|
||||
tj_max - thres_reg_value * 1000 : THERMAL_TEMP_INVALID;
|
||||
|
||||
trips[i].type = THERMAL_TRIP_PASSIVE;
|
||||
|
||||
pr_debug("%s: cpu=%d, trip=%d, temp=%d\n",
|
||||
__func__, cpu, i, trips[i].temperature);
|
||||
}
|
||||
|
||||
return trips;
|
||||
}
|
||||
|
||||
static int pkg_temp_thermal_device_add(unsigned int cpu)
|
||||
{
|
||||
int id = topology_logical_die_id(cpu);
|
||||
u32 tj_max, eax, ebx, ecx, edx;
|
||||
u32 eax, ebx, ecx, edx;
|
||||
struct zone_device *zonedev;
|
||||
int thres_count, err;
|
||||
int tj_max;
|
||||
|
||||
if (id >= max_id)
|
||||
return -ENOMEM;
|
||||
@ -340,32 +326,34 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
|
||||
|
||||
thres_count = clamp_val(thres_count, 0, MAX_NUMBER_OF_TRIPS);
|
||||
|
||||
err = get_tj_max(cpu, &tj_max);
|
||||
if (err)
|
||||
return err;
|
||||
tj_max = intel_tcc_get_tjmax(cpu);
|
||||
if (tj_max < 0)
|
||||
return tj_max;
|
||||
|
||||
zonedev = kzalloc(sizeof(*zonedev), GFP_KERNEL);
|
||||
if (!zonedev)
|
||||
return -ENOMEM;
|
||||
|
||||
zonedev->trips = pkg_temp_thermal_trips_init(cpu, tj_max, thres_count);
|
||||
if (IS_ERR(zonedev->trips)) {
|
||||
err = PTR_ERR(zonedev->trips);
|
||||
goto out_kfree_zonedev;
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&zonedev->work, pkg_temp_thermal_threshold_work_fn);
|
||||
zonedev->cpu = cpu;
|
||||
zonedev->tj_max = tj_max;
|
||||
zonedev->tzone = thermal_zone_device_register("x86_pkg_temp",
|
||||
thres_count,
|
||||
zonedev->tzone = thermal_zone_device_register_with_trips("x86_pkg_temp",
|
||||
zonedev->trips, thres_count,
|
||||
(thres_count == MAX_NUMBER_OF_TRIPS) ? 0x03 : 0x01,
|
||||
zonedev, &tzone_ops, &pkg_temp_tz_params, 0, 0);
|
||||
if (IS_ERR(zonedev->tzone)) {
|
||||
err = PTR_ERR(zonedev->tzone);
|
||||
kfree(zonedev);
|
||||
return err;
|
||||
goto out_kfree_trips;
|
||||
}
|
||||
err = thermal_zone_device_enable(zonedev->tzone);
|
||||
if (err) {
|
||||
thermal_zone_device_unregister(zonedev->tzone);
|
||||
kfree(zonedev);
|
||||
return err;
|
||||
}
|
||||
if (err)
|
||||
goto out_unregister_tz;
|
||||
|
||||
/* Store MSR value for package thermal interrupt, to restore at exit */
|
||||
rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, zonedev->msr_pkg_therm_low,
|
||||
zonedev->msr_pkg_therm_high);
|
||||
@ -374,7 +362,16 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
|
||||
raw_spin_lock_irq(&pkg_temp_lock);
|
||||
zones[id] = zonedev;
|
||||
raw_spin_unlock_irq(&pkg_temp_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
out_unregister_tz:
|
||||
thermal_zone_device_unregister(zonedev->tzone);
|
||||
out_kfree_trips:
|
||||
kfree(zonedev->trips);
|
||||
out_kfree_zonedev:
|
||||
kfree(zonedev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int pkg_thermal_cpu_offline(unsigned int cpu)
|
||||
@ -458,8 +455,10 @@ static int pkg_thermal_cpu_offline(unsigned int cpu)
|
||||
raw_spin_unlock_irq(&pkg_temp_lock);
|
||||
|
||||
/* Final cleanup if this is the last cpu */
|
||||
if (lastcpu)
|
||||
if (lastcpu) {
|
||||
kfree(zonedev->trips);
|
||||
kfree(zonedev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -531,6 +530,7 @@ static void __exit pkg_temp_thermal_exit(void)
|
||||
}
|
||||
module_exit(pkg_temp_thermal_exit)
|
||||
|
||||
MODULE_IMPORT_NS(INTEL_TCC);
|
||||
MODULE_DESCRIPTION("X86 PKG TEMP Thermal Driver");
|
||||
MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -264,17 +264,17 @@ skip:
|
||||
return qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg);
|
||||
}
|
||||
|
||||
static int qpnp_tm_set_trip_temp(struct thermal_zone_device *tz, int trip, int temp)
|
||||
static int qpnp_tm_set_trip_temp(struct thermal_zone_device *tz, int trip_id, int temp)
|
||||
{
|
||||
struct qpnp_tm_chip *chip = tz->devdata;
|
||||
const struct thermal_trip *trip_points;
|
||||
struct thermal_trip trip;
|
||||
int ret;
|
||||
|
||||
trip_points = of_thermal_get_trip_points(chip->tz_dev);
|
||||
if (!trip_points)
|
||||
return -EINVAL;
|
||||
ret = __thermal_zone_get_trip(chip->tz_dev, trip_id, &trip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (trip_points[trip].type != THERMAL_TRIP_CRITICAL)
|
||||
if (trip.type != THERMAL_TRIP_CRITICAL)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
@ -300,22 +300,17 @@ static irqreturn_t qpnp_tm_isr(int irq, void *data)
|
||||
|
||||
static int qpnp_tm_get_critical_trip_temp(struct qpnp_tm_chip *chip)
|
||||
{
|
||||
int ntrips;
|
||||
const struct thermal_trip *trips;
|
||||
int i;
|
||||
struct thermal_trip trip;
|
||||
int i, ret;
|
||||
|
||||
ntrips = of_thermal_get_ntrips(chip->tz_dev);
|
||||
if (ntrips <= 0)
|
||||
return THERMAL_TEMP_INVALID;
|
||||
for (i = 0; i < thermal_zone_get_num_trips(chip->tz_dev); i++) {
|
||||
|
||||
trips = of_thermal_get_trip_points(chip->tz_dev);
|
||||
if (!trips)
|
||||
return THERMAL_TEMP_INVALID;
|
||||
ret = thermal_zone_get_trip(chip->tz_dev, i, &trip);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < ntrips; i++) {
|
||||
if (of_thermal_is_trip_valid(chip->tz_dev, i) &&
|
||||
trips[i].type == THERMAL_TRIP_CRITICAL)
|
||||
return trips[i].temperature;
|
||||
if (trip.type == THERMAL_TRIP_CRITICAL)
|
||||
return trip.temperature;
|
||||
}
|
||||
|
||||
return THERMAL_TEMP_INVALID;
|
||||
@ -353,7 +348,12 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip)
|
||||
if (stage)
|
||||
chip->temp = qpnp_tm_decode_temp(chip, stage);
|
||||
|
||||
mutex_unlock(&chip->lock);
|
||||
|
||||
crit_temp = qpnp_tm_get_critical_trip_temp(chip);
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
|
||||
ret = qpnp_tm_update_critical_trip_temp(chip, crit_temp);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
@ -529,7 +529,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto error_unregister;
|
||||
|
||||
ret = of_thermal_get_ntrips(tsc->zone);
|
||||
ret = thermal_zone_get_num_trips(tsc->zone);
|
||||
if (ret < 0)
|
||||
goto error_unregister;
|
||||
|
||||
|
@ -278,52 +278,12 @@ static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp)
|
||||
return rcar_thermal_get_current_temp(priv, temp);
|
||||
}
|
||||
|
||||
static int rcar_thermal_get_trip_type(struct thermal_zone_device *zone,
|
||||
int trip, enum thermal_trip_type *type)
|
||||
{
|
||||
struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
|
||||
struct device *dev = rcar_priv_to_dev(priv);
|
||||
|
||||
/* see rcar_thermal_get_temp() */
|
||||
switch (trip) {
|
||||
case 0: /* +90 <= temp */
|
||||
*type = THERMAL_TRIP_CRITICAL;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "rcar driver trip error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rcar_thermal_get_trip_temp(struct thermal_zone_device *zone,
|
||||
int trip, int *temp)
|
||||
{
|
||||
struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
|
||||
struct device *dev = rcar_priv_to_dev(priv);
|
||||
|
||||
/* see rcar_thermal_get_temp() */
|
||||
switch (trip) {
|
||||
case 0: /* +90 <= temp */
|
||||
*temp = MCELSIUS(90);
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "rcar driver trip error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct thermal_zone_device_ops rcar_thermal_zone_of_ops = {
|
||||
static struct thermal_zone_device_ops rcar_thermal_zone_ops = {
|
||||
.get_temp = rcar_thermal_get_temp,
|
||||
};
|
||||
|
||||
static struct thermal_zone_device_ops rcar_thermal_zone_ops = {
|
||||
.get_temp = rcar_thermal_get_temp,
|
||||
.get_trip_type = rcar_thermal_get_trip_type,
|
||||
.get_trip_temp = rcar_thermal_get_trip_temp,
|
||||
static struct thermal_trip trips[] = {
|
||||
{ .type = THERMAL_TRIP_CRITICAL, .temperature = 90000 }
|
||||
};
|
||||
|
||||
/*
|
||||
@ -529,11 +489,10 @@ static int rcar_thermal_probe(struct platform_device *pdev)
|
||||
if (chip->use_of_thermal) {
|
||||
priv->zone = devm_thermal_of_zone_register(
|
||||
dev, i, priv,
|
||||
&rcar_thermal_zone_of_ops);
|
||||
&rcar_thermal_zone_ops);
|
||||
} else {
|
||||
priv->zone = thermal_zone_device_register(
|
||||
"rcar_thermal",
|
||||
1, 0, priv,
|
||||
priv->zone = thermal_zone_device_register_with_trips(
|
||||
"rcar_thermal", trips, ARRAY_SIZE(trips), 0, priv,
|
||||
&rcar_thermal_zone_ops, NULL, 0,
|
||||
idle);
|
||||
|
||||
|
@ -260,31 +260,23 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
|
||||
{
|
||||
struct exynos_tmu_data *data = platform_get_drvdata(pdev);
|
||||
struct thermal_zone_device *tzd = data->tzd;
|
||||
const struct thermal_trip * const trips =
|
||||
of_thermal_get_trip_points(tzd);
|
||||
int num_trips = thermal_zone_get_num_trips(tzd);
|
||||
unsigned int status;
|
||||
int ret = 0, temp, hyst;
|
||||
int ret = 0, temp;
|
||||
|
||||
if (!trips) {
|
||||
dev_err(&pdev->dev,
|
||||
"Cannot get trip points from device tree!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (data->soc != SOC_ARCH_EXYNOS5433) /* FIXME */
|
||||
ret = tzd->ops->get_crit_temp(tzd, &temp);
|
||||
if (ret) {
|
||||
ret = thermal_zone_get_crit_temp(tzd, &temp);
|
||||
if (ret && data->soc != SOC_ARCH_EXYNOS5433) { /* FIXME */
|
||||
dev_err(&pdev->dev,
|
||||
"No CRITICAL trip point defined in device tree!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (of_thermal_get_ntrips(tzd) > data->ntrip) {
|
||||
if (num_trips > data->ntrip) {
|
||||
dev_info(&pdev->dev,
|
||||
"More trip points than supported by this TMU.\n");
|
||||
dev_info(&pdev->dev,
|
||||
"%d trip points should be configured in polling mode.\n",
|
||||
(of_thermal_get_ntrips(tzd) - data->ntrip));
|
||||
num_trips - data->ntrip);
|
||||
}
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
@ -297,25 +289,22 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
|
||||
ret = -EBUSY;
|
||||
} else {
|
||||
int i, ntrips =
|
||||
min_t(int, of_thermal_get_ntrips(tzd), data->ntrip);
|
||||
min_t(int, num_trips, data->ntrip);
|
||||
|
||||
data->tmu_initialize(pdev);
|
||||
|
||||
/* Write temperature code for rising and falling threshold */
|
||||
for (i = 0; i < ntrips; i++) {
|
||||
/* Write temperature code for rising threshold */
|
||||
ret = tzd->ops->get_trip_temp(tzd, i, &temp);
|
||||
if (ret)
|
||||
goto err;
|
||||
temp /= MCELSIUS;
|
||||
data->tmu_set_trip_temp(data, i, temp);
|
||||
|
||||
/* Write temperature code for falling threshold */
|
||||
ret = tzd->ops->get_trip_hyst(tzd, i, &hyst);
|
||||
struct thermal_trip trip;
|
||||
|
||||
ret = thermal_zone_get_trip(tzd, i, &trip);
|
||||
if (ret)
|
||||
goto err;
|
||||
hyst /= MCELSIUS;
|
||||
data->tmu_set_trip_hyst(data, i, temp, hyst);
|
||||
|
||||
data->tmu_set_trip_temp(data, i, trip.temperature / MCELSIUS);
|
||||
data->tmu_set_trip_hyst(data, i, trip.temperature / MCELSIUS,
|
||||
trip.hysteresis / MCELSIUS);
|
||||
}
|
||||
|
||||
data->tmu_clear_irqs(data);
|
||||
@ -360,21 +349,23 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
|
||||
}
|
||||
|
||||
static void exynos4210_tmu_set_trip_temp(struct exynos_tmu_data *data,
|
||||
int trip, u8 temp)
|
||||
int trip_id, u8 temp)
|
||||
{
|
||||
const struct thermal_trip * const trips =
|
||||
of_thermal_get_trip_points(data->tzd);
|
||||
struct thermal_trip trip;
|
||||
u8 ref, th_code;
|
||||
|
||||
ref = trips[0].temperature / MCELSIUS;
|
||||
if (thermal_zone_get_trip(data->tzd, 0, &trip))
|
||||
return;
|
||||
|
||||
if (trip == 0) {
|
||||
ref = trip.temperature / MCELSIUS;
|
||||
|
||||
if (trip_id == 0) {
|
||||
th_code = temp_to_code(data, ref);
|
||||
writeb(th_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
|
||||
}
|
||||
|
||||
temp -= ref;
|
||||
writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + trip * 4);
|
||||
writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + trip_id * 4);
|
||||
}
|
||||
|
||||
/* failing thresholds are not supported on Exynos4210 */
|
||||
@ -562,13 +553,14 @@ static void exynos4210_tmu_control(struct platform_device *pdev, bool on)
|
||||
{
|
||||
struct exynos_tmu_data *data = platform_get_drvdata(pdev);
|
||||
struct thermal_zone_device *tz = data->tzd;
|
||||
struct thermal_trip trip;
|
||||
unsigned int con, interrupt_en = 0, i;
|
||||
|
||||
con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
|
||||
|
||||
if (on) {
|
||||
for (i = 0; i < data->ntrip; i++) {
|
||||
if (!of_thermal_is_trip_valid(tz, i))
|
||||
if (thermal_zone_get_trip(tz, i, &trip))
|
||||
continue;
|
||||
|
||||
interrupt_en |=
|
||||
@ -592,13 +584,14 @@ static void exynos5433_tmu_control(struct platform_device *pdev, bool on)
|
||||
{
|
||||
struct exynos_tmu_data *data = platform_get_drvdata(pdev);
|
||||
struct thermal_zone_device *tz = data->tzd;
|
||||
struct thermal_trip trip;
|
||||
unsigned int con, interrupt_en = 0, pd_det_en, i;
|
||||
|
||||
con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
|
||||
|
||||
if (on) {
|
||||
for (i = 0; i < data->ntrip; i++) {
|
||||
if (!of_thermal_is_trip_valid(tz, i))
|
||||
if (thermal_zone_get_trip(tz, i, &trip))
|
||||
continue;
|
||||
|
||||
interrupt_en |=
|
||||
@ -623,13 +616,14 @@ static void exynos7_tmu_control(struct platform_device *pdev, bool on)
|
||||
{
|
||||
struct exynos_tmu_data *data = platform_get_drvdata(pdev);
|
||||
struct thermal_zone_device *tz = data->tzd;
|
||||
struct thermal_trip trip;
|
||||
unsigned int con, interrupt_en = 0, i;
|
||||
|
||||
con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
|
||||
|
||||
if (on) {
|
||||
for (i = 0; i < data->ntrip; i++) {
|
||||
if (!of_thermal_is_trip_valid(tz, i))
|
||||
if (thermal_zone_get_trip(tz, i, &trip))
|
||||
continue;
|
||||
|
||||
interrupt_en |=
|
||||
|
@ -134,48 +134,12 @@ static int st_thermal_get_temp(struct thermal_zone_device *th, int *temperature)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st_thermal_get_trip_type(struct thermal_zone_device *th,
|
||||
int trip, enum thermal_trip_type *type)
|
||||
{
|
||||
struct st_thermal_sensor *sensor = th->devdata;
|
||||
struct device *dev = sensor->dev;
|
||||
|
||||
switch (trip) {
|
||||
case 0:
|
||||
*type = THERMAL_TRIP_CRITICAL;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "invalid trip point\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st_thermal_get_trip_temp(struct thermal_zone_device *th,
|
||||
int trip, int *temp)
|
||||
{
|
||||
struct st_thermal_sensor *sensor = th->devdata;
|
||||
struct device *dev = sensor->dev;
|
||||
|
||||
switch (trip) {
|
||||
case 0:
|
||||
*temp = mcelsius(sensor->cdata->crit_temp);
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "Invalid trip point\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct thermal_zone_device_ops st_tz_ops = {
|
||||
.get_temp = st_thermal_get_temp,
|
||||
.get_trip_type = st_thermal_get_trip_type,
|
||||
.get_trip_temp = st_thermal_get_trip_temp,
|
||||
};
|
||||
|
||||
static struct thermal_trip trip;
|
||||
|
||||
int st_thermal_register(struct platform_device *pdev,
|
||||
const struct of_device_id *st_thermal_of_match)
|
||||
{
|
||||
@ -238,9 +202,12 @@ int st_thermal_register(struct platform_device *pdev,
|
||||
|
||||
polling_delay = sensor->ops->register_enable_irq ? 0 : 1000;
|
||||
|
||||
trip.temperature = sensor->cdata->crit_temp;
|
||||
trip.type = THERMAL_TRIP_CRITICAL;
|
||||
|
||||
sensor->thermal_dev =
|
||||
thermal_zone_device_register(dev_name(dev), 1, 0, sensor,
|
||||
&st_tz_ops, NULL, 0, polling_delay);
|
||||
thermal_zone_device_register_with_trips(dev_name(dev), &trip, 1, 0, sensor,
|
||||
&st_tz_ops, NULL, 0, polling_delay);
|
||||
if (IS_ERR(sensor->thermal_dev)) {
|
||||
dev_err(dev, "failed to register thermal zone device\n");
|
||||
ret = PTR_ERR(sensor->thermal_dev);
|
||||
|
@ -582,23 +582,23 @@ static int tsensor_group_thermtrip_get(struct tegra_soctherm *ts, int id)
|
||||
return temp;
|
||||
}
|
||||
|
||||
static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip, int temp)
|
||||
static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip_id, int temp)
|
||||
{
|
||||
struct tegra_thermctl_zone *zone = tz->devdata;
|
||||
struct tegra_soctherm *ts = zone->ts;
|
||||
struct thermal_trip trip;
|
||||
const struct tegra_tsensor_group *sg = zone->sg;
|
||||
struct device *dev = zone->dev;
|
||||
enum thermal_trip_type type;
|
||||
int ret;
|
||||
|
||||
if (!tz)
|
||||
return -EINVAL;
|
||||
|
||||
ret = tz->ops->get_trip_type(tz, trip, &type);
|
||||
ret = __thermal_zone_get_trip(tz, trip_id, &trip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (type == THERMAL_TRIP_CRITICAL) {
|
||||
if (trip.type == THERMAL_TRIP_CRITICAL) {
|
||||
/*
|
||||
* If thermtrips property is set in DT,
|
||||
* doesn't need to program critical type trip to HW,
|
||||
@ -609,7 +609,7 @@ static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip
|
||||
else
|
||||
return 0;
|
||||
|
||||
} else if (type == THERMAL_TRIP_HOT) {
|
||||
} else if (trip.type == THERMAL_TRIP_HOT) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < THROTTLE_SIZE; i++) {
|
||||
@ -620,7 +620,7 @@ static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip
|
||||
continue;
|
||||
|
||||
cdev = ts->throt_cfgs[i].cdev;
|
||||
if (get_thermal_instance(tz, cdev, trip))
|
||||
if (get_thermal_instance(tz, cdev, trip_id))
|
||||
stc = find_throttle_cfg_by_name(ts, cdev->type);
|
||||
else
|
||||
continue;
|
||||
@ -687,25 +687,20 @@ static const struct thermal_zone_device_ops tegra_of_thermal_ops = {
|
||||
.set_trips = tegra_thermctl_set_trips,
|
||||
};
|
||||
|
||||
static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp)
|
||||
static int get_hot_temp(struct thermal_zone_device *tz, int *trip_id, int *temp)
|
||||
{
|
||||
int ntrips, i, ret;
|
||||
enum thermal_trip_type type;
|
||||
int i, ret;
|
||||
struct thermal_trip trip;
|
||||
|
||||
ntrips = of_thermal_get_ntrips(tz);
|
||||
if (ntrips <= 0)
|
||||
return -EINVAL;
|
||||
for (i = 0; i < thermal_zone_get_num_trips(tz); i++) {
|
||||
|
||||
for (i = 0; i < ntrips; i++) {
|
||||
ret = tz->ops->get_trip_type(tz, i, &type);
|
||||
ret = thermal_zone_get_trip(tz, i, &trip);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
if (type == THERMAL_TRIP_HOT) {
|
||||
ret = tz->ops->get_trip_temp(tz, i, temp);
|
||||
if (!ret)
|
||||
*trip = i;
|
||||
|
||||
return ret;
|
||||
if (trip.type == THERMAL_TRIP_HOT) {
|
||||
*trip_id = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -747,7 +742,7 @@ static int tegra_soctherm_set_hwtrips(struct device *dev,
|
||||
/* Get thermtrips. If missing, try to get critical trips. */
|
||||
temperature = tsensor_group_thermtrip_get(ts, sg->id);
|
||||
if (min_low_temp == temperature)
|
||||
if (tz->ops->get_crit_temp(tz, &temperature))
|
||||
if (thermal_zone_get_crit_temp(tz, &temperature))
|
||||
temperature = max_high_temp;
|
||||
|
||||
ret = thermtrip_program(dev, sg, temperature);
|
||||
|
@ -316,18 +316,17 @@ static void tegra_tsensor_get_hw_channel_trips(struct thermal_zone_device *tzd,
|
||||
*hot_trip = 85000;
|
||||
*crit_trip = 90000;
|
||||
|
||||
for (i = 0; i < tzd->num_trips; i++) {
|
||||
enum thermal_trip_type type;
|
||||
int trip_temp;
|
||||
for (i = 0; i < thermal_zone_get_num_trips(tzd); i++) {
|
||||
|
||||
tzd->ops->get_trip_temp(tzd, i, &trip_temp);
|
||||
tzd->ops->get_trip_type(tzd, i, &type);
|
||||
struct thermal_trip trip;
|
||||
|
||||
if (type == THERMAL_TRIP_HOT)
|
||||
*hot_trip = trip_temp;
|
||||
thermal_zone_get_trip(tzd, i, &trip);
|
||||
|
||||
if (type == THERMAL_TRIP_CRITICAL)
|
||||
*crit_trip = trip_temp;
|
||||
if (trip.type == THERMAL_TRIP_HOT)
|
||||
*hot_trip = trip.temperature;
|
||||
|
||||
if (trip.type == THERMAL_TRIP_CRITICAL)
|
||||
*crit_trip = trip.temperature;
|
||||
}
|
||||
|
||||
/* clamp hardware trips to the calibration limits */
|
||||
|
150
drivers/thermal/thermal_acpi.c
Normal file
150
drivers/thermal/thermal_acpi.c
Normal file
@ -0,0 +1,150 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2023 Linaro Limited
|
||||
* Copyright 2023 Intel Corporation
|
||||
*
|
||||
* Library routines for populating a generic thermal trip point structure
|
||||
* with data obtained by evaluating a specific object in the ACPI Namespace.
|
||||
*/
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include "thermal_core.h"
|
||||
|
||||
/*
|
||||
* Minimum temperature for full military grade is 218°K (-55°C) and
|
||||
* max temperature is 448°K (175°C). We can consider those values as
|
||||
* the boundaries for the [trips] temperature returned by the
|
||||
* firmware. Any values out of these boundaries may be considered
|
||||
* bogus and we can assume the firmware has no data to provide.
|
||||
*/
|
||||
#define TEMP_MIN_DECIK 2180
|
||||
#define TEMP_MAX_DECIK 4480
|
||||
|
||||
static int thermal_acpi_trip_init(struct acpi_device *adev,
|
||||
enum thermal_trip_type type, int id,
|
||||
struct thermal_trip *trip)
|
||||
{
|
||||
unsigned long long temp;
|
||||
acpi_status status;
|
||||
char obj_name[5];
|
||||
|
||||
switch (type) {
|
||||
case THERMAL_TRIP_ACTIVE:
|
||||
if (id < 0 || id > 9)
|
||||
return -EINVAL;
|
||||
|
||||
obj_name[1] = 'A';
|
||||
obj_name[2] = 'C';
|
||||
obj_name[3] = '0' + id;
|
||||
break;
|
||||
case THERMAL_TRIP_PASSIVE:
|
||||
obj_name[1] = 'P';
|
||||
obj_name[2] = 'S';
|
||||
obj_name[3] = 'V';
|
||||
break;
|
||||
case THERMAL_TRIP_HOT:
|
||||
obj_name[1] = 'H';
|
||||
obj_name[2] = 'O';
|
||||
obj_name[3] = 'T';
|
||||
break;
|
||||
case THERMAL_TRIP_CRITICAL:
|
||||
obj_name[1] = 'C';
|
||||
obj_name[2] = 'R';
|
||||
obj_name[3] = 'T';
|
||||
break;
|
||||
}
|
||||
|
||||
obj_name[0] = '_';
|
||||
obj_name[4] = '\0';
|
||||
|
||||
status = acpi_evaluate_integer(adev->handle, obj_name, NULL, &temp);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_handle_debug(adev->handle, "%s evaluation failed\n", obj_name);
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
if (temp < TEMP_MIN_DECIK || temp >= TEMP_MAX_DECIK) {
|
||||
acpi_handle_debug(adev->handle, "%s result %llu out of range\n",
|
||||
obj_name, temp);
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
trip->temperature = deci_kelvin_to_millicelsius(temp);
|
||||
trip->hysteresis = 0;
|
||||
trip->type = type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* thermal_acpi_trip_active - Get the specified active trip point
|
||||
* @adev: Thermal zone ACPI device object to get the description from.
|
||||
* @id: Active cooling level (0 - 9).
|
||||
* @trip: Trip point structure to be populated on success.
|
||||
*
|
||||
* Evaluate the _ACx object for the thermal zone represented by @adev to obtain
|
||||
* the temperature of the active cooling trip point corresponding to the active
|
||||
* cooling level given by @id and initialize @trip as an active trip point using
|
||||
* that temperature value.
|
||||
*
|
||||
* Return 0 on success or a negative error value on failure.
|
||||
*/
|
||||
int thermal_acpi_trip_active(struct acpi_device *adev, int id,
|
||||
struct thermal_trip *trip)
|
||||
{
|
||||
return thermal_acpi_trip_init(adev, THERMAL_TRIP_ACTIVE, id, trip);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_acpi_trip_active);
|
||||
|
||||
/**
|
||||
* thermal_acpi_trip_passive - Get the passive trip point
|
||||
* @adev: Thermal zone ACPI device object to get the description from.
|
||||
* @trip: Trip point structure to be populated on success.
|
||||
*
|
||||
* Evaluate the _PSV object for the thermal zone represented by @adev to obtain
|
||||
* the temperature of the passive cooling trip point and initialize @trip as a
|
||||
* passive trip point using that temperature value.
|
||||
*
|
||||
* Return 0 on success or -ENODATA on failure.
|
||||
*/
|
||||
int thermal_acpi_trip_passive(struct acpi_device *adev, struct thermal_trip *trip)
|
||||
{
|
||||
return thermal_acpi_trip_init(adev, THERMAL_TRIP_PASSIVE, INT_MAX, trip);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_acpi_trip_passive);
|
||||
|
||||
/**
|
||||
* thermal_acpi_trip_hot - Get the near critical trip point
|
||||
* @adev: the ACPI device to get the description from.
|
||||
* @trip: a &struct thermal_trip to be filled if the function succeed.
|
||||
*
|
||||
* Evaluate the _HOT object for the thermal zone represented by @adev to obtain
|
||||
* the temperature of the trip point at which the system is expected to be put
|
||||
* into the S4 sleep state and initialize @trip as a hot trip point using that
|
||||
* temperature value.
|
||||
*
|
||||
* Return 0 on success or -ENODATA on failure.
|
||||
*/
|
||||
int thermal_acpi_trip_hot(struct acpi_device *adev, struct thermal_trip *trip)
|
||||
{
|
||||
return thermal_acpi_trip_init(adev, THERMAL_TRIP_HOT, INT_MAX, trip);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_acpi_trip_hot);
|
||||
|
||||
/**
|
||||
* thermal_acpi_trip_critical - Get the critical trip point
|
||||
* @adev: the ACPI device to get the description from.
|
||||
* @trip: a &struct thermal_trip to be filled if the function succeed.
|
||||
*
|
||||
* Evaluate the _CRT object for the thermal zone represented by @adev to obtain
|
||||
* the temperature of the critical cooling trip point and initialize @trip as a
|
||||
* critical trip point using that temperature value.
|
||||
*
|
||||
* Return 0 on success or -ENODATA on failure.
|
||||
*/
|
||||
int thermal_acpi_trip_critical(struct acpi_device *adev, struct thermal_trip *trip)
|
||||
{
|
||||
return thermal_acpi_trip_init(adev, THERMAL_TRIP_CRITICAL, INT_MAX, trip);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_acpi_trip_critical);
|
@ -344,35 +344,31 @@ static void handle_critical_trips(struct thermal_zone_device *tz,
|
||||
tz->ops->critical(tz);
|
||||
}
|
||||
|
||||
static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
|
||||
static void handle_thermal_trip(struct thermal_zone_device *tz, int trip_id)
|
||||
{
|
||||
enum thermal_trip_type type;
|
||||
int trip_temp, hyst = 0;
|
||||
struct thermal_trip trip;
|
||||
|
||||
/* Ignore disabled trip points */
|
||||
if (test_bit(trip, &tz->trips_disabled))
|
||||
if (test_bit(trip_id, &tz->trips_disabled))
|
||||
return;
|
||||
|
||||
tz->ops->get_trip_temp(tz, trip, &trip_temp);
|
||||
tz->ops->get_trip_type(tz, trip, &type);
|
||||
if (tz->ops->get_trip_hyst)
|
||||
tz->ops->get_trip_hyst(tz, trip, &hyst);
|
||||
__thermal_zone_get_trip(tz, trip_id, &trip);
|
||||
|
||||
if (tz->last_temperature != THERMAL_TEMP_INVALID) {
|
||||
if (tz->last_temperature < trip_temp &&
|
||||
tz->temperature >= trip_temp)
|
||||
thermal_notify_tz_trip_up(tz->id, trip,
|
||||
if (tz->last_temperature < trip.temperature &&
|
||||
tz->temperature >= trip.temperature)
|
||||
thermal_notify_tz_trip_up(tz->id, trip_id,
|
||||
tz->temperature);
|
||||
if (tz->last_temperature >= trip_temp &&
|
||||
tz->temperature < (trip_temp - hyst))
|
||||
thermal_notify_tz_trip_down(tz->id, trip,
|
||||
if (tz->last_temperature >= trip.temperature &&
|
||||
tz->temperature < (trip.temperature - trip.hysteresis))
|
||||
thermal_notify_tz_trip_down(tz->id, trip_id,
|
||||
tz->temperature);
|
||||
}
|
||||
|
||||
if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
|
||||
handle_critical_trips(tz, trip, trip_temp, type);
|
||||
if (trip.type == THERMAL_TRIP_CRITICAL || trip.type == THERMAL_TRIP_HOT)
|
||||
handle_critical_trips(tz, trip_id, trip.temperature, trip.type);
|
||||
else
|
||||
handle_non_critical_trips(tz, trip);
|
||||
handle_non_critical_trips(tz, trip_id);
|
||||
}
|
||||
|
||||
static void update_temperature(struct thermal_zone_device *tz)
|
||||
@ -1166,6 +1162,119 @@ static void thermal_set_delay_jiffies(unsigned long *delay_jiffies, int delay_ms
|
||||
*delay_jiffies = round_jiffies(*delay_jiffies);
|
||||
}
|
||||
|
||||
int thermal_zone_get_num_trips(struct thermal_zone_device *tz)
|
||||
{
|
||||
return tz->num_trips;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_get_num_trips);
|
||||
|
||||
int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp)
|
||||
{
|
||||
int i, ret = -EINVAL;
|
||||
|
||||
if (tz->ops->get_crit_temp)
|
||||
return tz->ops->get_crit_temp(tz, temp);
|
||||
|
||||
if (!tz->trips)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
for (i = 0; i < tz->num_trips; i++) {
|
||||
if (tz->trips[i].type == THERMAL_TRIP_CRITICAL) {
|
||||
*temp = tz->trips[i].temperature;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&tz->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_get_crit_temp);
|
||||
|
||||
int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
|
||||
struct thermal_trip *trip)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!tz || trip_id < 0 || trip_id >= tz->num_trips || !trip)
|
||||
return -EINVAL;
|
||||
|
||||
if (tz->trips) {
|
||||
*trip = tz->trips[trip_id];
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tz->ops->get_trip_hyst) {
|
||||
ret = tz->ops->get_trip_hyst(tz, trip_id, &trip->hysteresis);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
trip->hysteresis = 0;
|
||||
}
|
||||
|
||||
ret = tz->ops->get_trip_temp(tz, trip_id, &trip->temperature);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return tz->ops->get_trip_type(tz, trip_id, &trip->type);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__thermal_zone_get_trip);
|
||||
|
||||
int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
|
||||
struct thermal_trip *trip)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
ret = __thermal_zone_get_trip(tz, trip_id, trip);
|
||||
mutex_unlock(&tz->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_get_trip);
|
||||
|
||||
int thermal_zone_set_trip(struct thermal_zone_device *tz, int trip_id,
|
||||
const struct thermal_trip *trip)
|
||||
{
|
||||
struct thermal_trip t;
|
||||
int ret;
|
||||
|
||||
if (!tz->ops->set_trip_temp && !tz->ops->set_trip_hyst && !tz->trips)
|
||||
return -EINVAL;
|
||||
|
||||
ret = __thermal_zone_get_trip(tz, trip_id, &t);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (t.type != trip->type)
|
||||
return -EINVAL;
|
||||
|
||||
if (t.temperature != trip->temperature && tz->ops->set_trip_temp) {
|
||||
ret = tz->ops->set_trip_temp(tz, trip_id, trip->temperature);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (t.hysteresis != trip->hysteresis && tz->ops->set_trip_hyst) {
|
||||
ret = tz->ops->set_trip_hyst(tz, trip_id, trip->hysteresis);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (tz->trips && (t.temperature != trip->temperature || t.hysteresis != trip->hysteresis))
|
||||
tz->trips[trip_id] = *trip;
|
||||
|
||||
thermal_notify_tz_trip_change(tz->id, trip_id, trip->type,
|
||||
trip->temperature, trip->hysteresis);
|
||||
|
||||
__thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* thermal_zone_device_register_with_trips() - register a new thermal zone device
|
||||
* @type: the thermal zone device type
|
||||
@ -1198,8 +1307,6 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
|
||||
int polling_delay)
|
||||
{
|
||||
struct thermal_zone_device *tz;
|
||||
enum thermal_trip_type trip_type;
|
||||
int trip_temp;
|
||||
int id;
|
||||
int result;
|
||||
int count;
|
||||
@ -1239,7 +1346,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (num_trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp))
|
||||
if (num_trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp) && !trips)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
tz = kzalloc(sizeof(*tz), GFP_KERNEL);
|
||||
@ -1290,9 +1397,10 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
|
||||
goto release_device;
|
||||
|
||||
for (count = 0; count < num_trips; count++) {
|
||||
if (tz->ops->get_trip_type(tz, count, &trip_type) ||
|
||||
tz->ops->get_trip_temp(tz, count, &trip_temp) ||
|
||||
!trip_temp)
|
||||
struct thermal_trip trip;
|
||||
|
||||
result = thermal_zone_get_trip(tz, count, &trip);
|
||||
if (result)
|
||||
set_bit(count, &tz->trips_disabled);
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,8 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
|
||||
|
||||
/* Helpers */
|
||||
void __thermal_zone_set_trips(struct thermal_zone_device *tz);
|
||||
int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
|
||||
struct thermal_trip *trip);
|
||||
int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
|
||||
|
||||
/* sysfs I/F */
|
||||
@ -137,28 +139,6 @@ thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
|
||||
#endif /* CONFIG_THERMAL_STATISTICS */
|
||||
|
||||
/* device tree support */
|
||||
#ifdef CONFIG_THERMAL_OF
|
||||
int of_thermal_get_ntrips(struct thermal_zone_device *);
|
||||
bool of_thermal_is_trip_valid(struct thermal_zone_device *, int);
|
||||
const struct thermal_trip *
|
||||
of_thermal_get_trip_points(struct thermal_zone_device *);
|
||||
#else
|
||||
static inline int of_thermal_get_ntrips(struct thermal_zone_device *tz)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz,
|
||||
int trip)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline const struct thermal_trip *
|
||||
of_thermal_get_trip_points(struct thermal_zone_device *tz)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int thermal_zone_device_is_enabled(struct thermal_zone_device *tz);
|
||||
|
||||
#endif /* __THERMAL_CORE_H__ */
|
||||
|
@ -83,7 +83,7 @@ int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
|
||||
int ret = -EINVAL;
|
||||
int count;
|
||||
int crit_temp = INT_MAX;
|
||||
enum thermal_trip_type type;
|
||||
struct thermal_trip trip;
|
||||
|
||||
lockdep_assert_held(&tz->lock);
|
||||
|
||||
@ -91,10 +91,9 @@ int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
|
||||
|
||||
if (IS_ENABLED(CONFIG_THERMAL_EMULATION) && tz->emul_temperature) {
|
||||
for (count = 0; count < tz->num_trips; count++) {
|
||||
ret = tz->ops->get_trip_type(tz, count, &type);
|
||||
if (!ret && type == THERMAL_TRIP_CRITICAL) {
|
||||
ret = tz->ops->get_trip_temp(tz, count,
|
||||
&crit_temp);
|
||||
ret = __thermal_zone_get_trip(tz, count, &trip);
|
||||
if (!ret && trip.type == THERMAL_TRIP_CRITICAL) {
|
||||
crit_temp = trip.temperature;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -164,29 +163,30 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
|
||||
*/
|
||||
void __thermal_zone_set_trips(struct thermal_zone_device *tz)
|
||||
{
|
||||
int low = -INT_MAX;
|
||||
int high = INT_MAX;
|
||||
int trip_temp, hysteresis;
|
||||
struct thermal_trip trip;
|
||||
int low = -INT_MAX, high = INT_MAX;
|
||||
int i, ret;
|
||||
|
||||
lockdep_assert_held(&tz->lock);
|
||||
|
||||
if (!tz->ops->set_trips || !tz->ops->get_trip_hyst)
|
||||
if (!tz->ops->set_trips)
|
||||
return;
|
||||
|
||||
for (i = 0; i < tz->num_trips; i++) {
|
||||
int trip_low;
|
||||
|
||||
tz->ops->get_trip_temp(tz, i, &trip_temp);
|
||||
tz->ops->get_trip_hyst(tz, i, &hysteresis);
|
||||
ret = __thermal_zone_get_trip(tz, i , &trip);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
trip_low = trip_temp - hysteresis;
|
||||
trip_low = trip.temperature - trip.hysteresis;
|
||||
|
||||
if (trip_low < tz->temperature && trip_low > low)
|
||||
low = trip_low;
|
||||
|
||||
if (trip_temp > tz->temperature && trip_temp < high)
|
||||
high = trip_temp;
|
||||
if (trip.temperature > tz->temperature &&
|
||||
trip.temperature < high)
|
||||
high = trip.temperature;
|
||||
}
|
||||
|
||||
/* No need to change trip points */
|
||||
|
@ -452,7 +452,8 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
|
||||
struct sk_buff *msg = p->msg;
|
||||
struct thermal_zone_device *tz;
|
||||
struct nlattr *start_trip;
|
||||
int i, id;
|
||||
struct thermal_trip trip;
|
||||
int ret, i, id;
|
||||
|
||||
if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID])
|
||||
return -EINVAL;
|
||||
@ -471,18 +472,14 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
|
||||
|
||||
for (i = 0; i < tz->num_trips; i++) {
|
||||
|
||||
enum thermal_trip_type type;
|
||||
int temp, hyst = 0;
|
||||
|
||||
tz->ops->get_trip_type(tz, i, &type);
|
||||
tz->ops->get_trip_temp(tz, i, &temp);
|
||||
if (tz->ops->get_trip_hyst)
|
||||
tz->ops->get_trip_hyst(tz, i, &hyst);
|
||||
ret = __thermal_zone_get_trip(tz, i, &trip);
|
||||
if (ret)
|
||||
goto out_cancel_nest;
|
||||
|
||||
if (nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_ID, i) ||
|
||||
nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TYPE, type) ||
|
||||
nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TEMP, temp) ||
|
||||
nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_HYST, hyst))
|
||||
nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TYPE, trip.type) ||
|
||||
nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TEMP, trip.temperature) ||
|
||||
nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_HYST, trip.hysteresis))
|
||||
goto out_cancel_nest;
|
||||
}
|
||||
|
||||
|
@ -19,117 +19,6 @@
|
||||
|
||||
#include "thermal_core.h"
|
||||
|
||||
/**
|
||||
* of_thermal_get_ntrips - function to export number of available trip
|
||||
* points.
|
||||
* @tz: pointer to a thermal zone
|
||||
*
|
||||
* This function is a globally visible wrapper to get number of trip points
|
||||
* stored in the local struct __thermal_zone
|
||||
*
|
||||
* Return: number of available trip points, -ENODEV when data not available
|
||||
*/
|
||||
int of_thermal_get_ntrips(struct thermal_zone_device *tz)
|
||||
{
|
||||
return tz->num_trips;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_thermal_get_ntrips);
|
||||
|
||||
/**
|
||||
* of_thermal_is_trip_valid - function to check if trip point is valid
|
||||
*
|
||||
* @tz: pointer to a thermal zone
|
||||
* @trip: trip point to evaluate
|
||||
*
|
||||
* This function is responsible for checking if passed trip point is valid
|
||||
*
|
||||
* Return: true if trip point is valid, false otherwise
|
||||
*/
|
||||
bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, int trip)
|
||||
{
|
||||
if (trip >= tz->num_trips || trip < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid);
|
||||
|
||||
/**
|
||||
* of_thermal_get_trip_points - function to get access to a globally exported
|
||||
* trip points
|
||||
*
|
||||
* @tz: pointer to a thermal zone
|
||||
*
|
||||
* This function provides a pointer to trip points table
|
||||
*
|
||||
* Return: pointer to trip points table, NULL otherwise
|
||||
*/
|
||||
const struct thermal_trip *
|
||||
of_thermal_get_trip_points(struct thermal_zone_device *tz)
|
||||
{
|
||||
return tz->trips;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_thermal_get_trip_points);
|
||||
|
||||
static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip,
|
||||
enum thermal_trip_type *type)
|
||||
{
|
||||
if (trip >= tz->num_trips || trip < 0)
|
||||
return -EDOM;
|
||||
|
||||
*type = tz->trips[trip].type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_thermal_get_trip_temp(struct thermal_zone_device *tz, int trip,
|
||||
int *temp)
|
||||
{
|
||||
if (trip >= tz->num_trips || trip < 0)
|
||||
return -EDOM;
|
||||
|
||||
*temp = tz->trips[trip].temperature;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_thermal_get_trip_hyst(struct thermal_zone_device *tz, int trip,
|
||||
int *hyst)
|
||||
{
|
||||
if (trip >= tz->num_trips || trip < 0)
|
||||
return -EDOM;
|
||||
|
||||
*hyst = tz->trips[trip].hysteresis;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip,
|
||||
int hyst)
|
||||
{
|
||||
if (trip >= tz->num_trips || trip < 0)
|
||||
return -EDOM;
|
||||
|
||||
/* thermal framework should take care of data->mask & (1 << trip) */
|
||||
tz->trips[trip].hysteresis = hyst;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_thermal_get_crit_temp(struct thermal_zone_device *tz,
|
||||
int *temp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tz->num_trips; i++)
|
||||
if (tz->trips[i].type == THERMAL_TRIP_CRITICAL) {
|
||||
*temp = tz->trips[i].temperature;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*** functions parsing device tree nodes ***/
|
||||
|
||||
static int of_find_trip_id(struct device_node *np, struct device_node *trip)
|
||||
@ -628,11 +517,6 @@ struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor,
|
||||
goto out_kfree_trips;
|
||||
}
|
||||
|
||||
of_ops->get_trip_type = of_ops->get_trip_type ? : of_thermal_get_trip_type;
|
||||
of_ops->get_trip_temp = of_ops->get_trip_temp ? : of_thermal_get_trip_temp;
|
||||
of_ops->get_trip_hyst = of_ops->get_trip_hyst ? : of_thermal_get_trip_hyst;
|
||||
of_ops->set_trip_hyst = of_ops->set_trip_hyst ? : of_thermal_set_trip_hyst;
|
||||
of_ops->get_crit_temp = of_ops->get_crit_temp ? : of_thermal_get_crit_temp;
|
||||
of_ops->bind = thermal_of_bind;
|
||||
of_ops->unbind = thermal_of_unbind;
|
||||
|
||||
|
@ -83,27 +83,25 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||
enum thermal_trip_type type;
|
||||
int trip, result;
|
||||
struct thermal_trip trip;
|
||||
int trip_id, result;
|
||||
|
||||
if (!tz->ops->get_trip_type)
|
||||
return -EPERM;
|
||||
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_type", &trip) != 1)
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_type", &trip_id) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
if (device_is_registered(dev))
|
||||
result = tz->ops->get_trip_type(tz, trip, &type);
|
||||
result = __thermal_zone_get_trip(tz, trip_id, &trip);
|
||||
else
|
||||
result = -ENODEV;
|
||||
|
||||
mutex_unlock(&tz->lock);
|
||||
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
switch (type) {
|
||||
switch (trip.type) {
|
||||
case THERMAL_TRIP_CRITICAL:
|
||||
return sprintf(buf, "critical\n");
|
||||
case THERMAL_TRIP_HOT:
|
||||
@ -122,17 +120,10 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||
int trip, ret;
|
||||
int temperature, hyst = 0;
|
||||
enum thermal_trip_type type;
|
||||
struct thermal_trip trip;
|
||||
int trip_id, ret;
|
||||
|
||||
if (!tz->ops->set_trip_temp && !tz->trips)
|
||||
return -EPERM;
|
||||
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (kstrtoint(buf, 10, &temperature))
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
@ -142,36 +133,19 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (tz->ops->set_trip_temp) {
|
||||
ret = tz->ops->set_trip_temp(tz, trip, temperature);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (tz->trips)
|
||||
tz->trips[trip].temperature = temperature;
|
||||
|
||||
if (tz->ops->get_trip_hyst) {
|
||||
ret = tz->ops->get_trip_hyst(tz, trip, &hyst);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ret = tz->ops->get_trip_type(tz, trip, &type);
|
||||
ret = __thermal_zone_get_trip(tz, trip_id, &trip);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
thermal_notify_tz_trip_change(tz->id, trip, type, temperature, hyst);
|
||||
|
||||
__thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
|
||||
ret = kstrtoint(buf, 10, &trip.temperature);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
ret = thermal_zone_set_trip(tz, trip_id, &trip);
|
||||
unlock:
|
||||
mutex_unlock(&tz->lock);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
|
||||
return ret ? ret : count;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
@ -179,19 +153,16 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||
int trip, ret;
|
||||
int temperature;
|
||||
struct thermal_trip trip;
|
||||
int trip_id, ret;
|
||||
|
||||
if (!tz->ops->get_trip_temp)
|
||||
return -EPERM;
|
||||
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip) != 1)
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
if (device_is_registered(dev))
|
||||
ret = tz->ops->get_trip_temp(tz, trip, &temperature);
|
||||
ret = __thermal_zone_get_trip(tz, trip_id, &trip);
|
||||
else
|
||||
ret = -ENODEV;
|
||||
|
||||
@ -200,7 +171,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return sprintf(buf, "%d\n", temperature);
|
||||
return sprintf(buf, "%d\n", trip.temperature);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
@ -208,16 +179,13 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||
int trip, ret;
|
||||
int temperature;
|
||||
struct thermal_trip trip;
|
||||
int trip_id, ret;
|
||||
|
||||
if (!tz->ops->set_trip_hyst)
|
||||
return -EPERM;
|
||||
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip) != 1)
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (kstrtoint(buf, 10, &temperature))
|
||||
if (kstrtoint(buf, 10, &trip.hysteresis))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
@ -227,16 +195,11 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are not doing any check on the 'temperature' value
|
||||
* here. The driver implementing 'set_trip_hyst' has to
|
||||
* take care of this.
|
||||
*/
|
||||
ret = tz->ops->set_trip_hyst(tz, trip, temperature);
|
||||
|
||||
if (!ret)
|
||||
__thermal_zone_set_trips(tz);
|
||||
|
||||
ret = __thermal_zone_get_trip(tz, trip_id, &trip);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
ret = thermal_zone_set_trip(tz, trip_id, &trip);
|
||||
unlock:
|
||||
mutex_unlock(&tz->lock);
|
||||
|
||||
@ -248,25 +211,22 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||
int trip, ret;
|
||||
int temperature;
|
||||
struct thermal_trip trip;
|
||||
int trip_id, ret;
|
||||
|
||||
if (!tz->ops->get_trip_hyst)
|
||||
return -EPERM;
|
||||
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip) != 1)
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
if (device_is_registered(dev))
|
||||
ret = tz->ops->get_trip_hyst(tz, trip, &temperature);
|
||||
ret = __thermal_zone_get_trip(tz, trip_id, &trip);
|
||||
else
|
||||
ret = -ENODEV;
|
||||
|
||||
mutex_unlock(&tz->lock);
|
||||
|
||||
return ret ? ret : sprintf(buf, "%d\n", temperature);
|
||||
return ret ? ret : sprintf(buf, "%d\n", trip.hysteresis);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
@ -491,23 +451,20 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (tz->ops->get_trip_hyst) {
|
||||
tz->trip_hyst_attrs = kcalloc(tz->num_trips,
|
||||
sizeof(*tz->trip_hyst_attrs),
|
||||
GFP_KERNEL);
|
||||
if (!tz->trip_hyst_attrs) {
|
||||
kfree(tz->trip_type_attrs);
|
||||
kfree(tz->trip_temp_attrs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
tz->trip_hyst_attrs = kcalloc(tz->num_trips,
|
||||
sizeof(*tz->trip_hyst_attrs),
|
||||
GFP_KERNEL);
|
||||
if (!tz->trip_hyst_attrs) {
|
||||
kfree(tz->trip_type_attrs);
|
||||
kfree(tz->trip_temp_attrs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
attrs = kcalloc(tz->num_trips * 3 + 1, sizeof(*attrs), GFP_KERNEL);
|
||||
if (!attrs) {
|
||||
kfree(tz->trip_type_attrs);
|
||||
kfree(tz->trip_temp_attrs);
|
||||
if (tz->ops->get_trip_hyst)
|
||||
kfree(tz->trip_hyst_attrs);
|
||||
kfree(tz->trip_hyst_attrs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -540,9 +497,6 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
|
||||
}
|
||||
attrs[indx + tz->num_trips] = &tz->trip_temp_attrs[indx].attr.attr;
|
||||
|
||||
/* create Optional trip hyst attribute */
|
||||
if (!tz->ops->get_trip_hyst)
|
||||
continue;
|
||||
snprintf(tz->trip_hyst_attrs[indx].name, THERMAL_NAME_LENGTH,
|
||||
"trip_point_%d_hyst", indx);
|
||||
|
||||
@ -579,8 +533,7 @@ static void destroy_trip_attrs(struct thermal_zone_device *tz)
|
||||
|
||||
kfree(tz->trip_type_attrs);
|
||||
kfree(tz->trip_temp_attrs);
|
||||
if (tz->ops->get_trip_hyst)
|
||||
kfree(tz->trip_hyst_attrs);
|
||||
kfree(tz->trip_hyst_attrs);
|
||||
kfree(tz->trips_attribute_group.attrs);
|
||||
}
|
||||
|
||||
|
@ -38,21 +38,6 @@
|
||||
/* Update rates */
|
||||
#define FAST_TEMP_MONITORING_RATE 250
|
||||
|
||||
/* helper macros */
|
||||
/**
|
||||
* ti_thermal_get_trip_value - returns trip temperature based on index
|
||||
* @i: trip index
|
||||
*/
|
||||
#define ti_thermal_get_trip_value(i) \
|
||||
(OMAP_TRIP_HOT + ((i) * OMAP_TRIP_STEP))
|
||||
|
||||
/**
|
||||
* ti_thermal_is_valid_trip - check for trip index
|
||||
* @i: trip index
|
||||
*/
|
||||
#define ti_thermal_is_valid_trip(trip) \
|
||||
((trip) >= 0 && (trip) < OMAP_TRIP_NUMBER)
|
||||
|
||||
#ifdef CONFIG_TI_THERMAL
|
||||
int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, char *domain);
|
||||
int ti_thermal_remove_sensor(struct ti_bandgap *bgp, int id);
|
||||
|
@ -248,8 +248,7 @@ static int uniphier_tm_probe(struct platform_device *pdev)
|
||||
struct regmap *regmap;
|
||||
struct device_node *parent;
|
||||
struct uniphier_tm_dev *tdev;
|
||||
const struct thermal_trip *trips;
|
||||
int i, ret, irq, ntrips, crit_temp = INT_MAX;
|
||||
int i, ret, irq, crit_temp = INT_MAX;
|
||||
|
||||
tdev = devm_kzalloc(dev, sizeof(*tdev), GFP_KERNEL);
|
||||
if (!tdev)
|
||||
@ -296,20 +295,18 @@ static int uniphier_tm_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(tdev->tz_dev);
|
||||
}
|
||||
|
||||
/* get trip points */
|
||||
trips = of_thermal_get_trip_points(tdev->tz_dev);
|
||||
ntrips = of_thermal_get_ntrips(tdev->tz_dev);
|
||||
if (ntrips > ALERT_CH_NUM) {
|
||||
dev_err(dev, "thermal zone has too many trips\n");
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
/* set alert temperatures */
|
||||
for (i = 0; i < ntrips; i++) {
|
||||
if (trips[i].type == THERMAL_TRIP_CRITICAL &&
|
||||
trips[i].temperature < crit_temp)
|
||||
crit_temp = trips[i].temperature;
|
||||
uniphier_tm_set_alert(tdev, i, trips[i].temperature);
|
||||
for (i = 0; i < thermal_zone_get_num_trips(tdev->tz_dev); i++) {
|
||||
struct thermal_trip trip;
|
||||
|
||||
ret = thermal_zone_get_trip(tdev->tz_dev, i, &trip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (trip.type == THERMAL_TRIP_CRITICAL &&
|
||||
trip.temperature < crit_temp)
|
||||
crit_temp = trip.temperature;
|
||||
uniphier_tm_set_alert(tdev, i, trip.temperature);
|
||||
tdev->alert_en[i] = true;
|
||||
}
|
||||
if (crit_temp > CRITICAL_TEMP_LIMIT) {
|
||||
|
18
include/linux/intel_tcc.h
Normal file
18
include/linux/intel_tcc.h
Normal file
@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* header for Intel TCC (thermal control circuitry) library
|
||||
*
|
||||
* Copyright (C) 2022 Intel Corporation.
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_TCC_H__
|
||||
#define __INTEL_TCC_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
int intel_tcc_get_tjmax(int cpu);
|
||||
int intel_tcc_get_offset(int cpu);
|
||||
int intel_tcc_set_offset(int cpu, int offset);
|
||||
int intel_tcc_get_temp(int cpu, bool pkg);
|
||||
|
||||
#endif /* __INTEL_TCC_H__ */
|
@ -334,6 +334,26 @@ static inline void devm_thermal_of_zone_unregister(struct device *dev,
|
||||
}
|
||||
#endif
|
||||
|
||||
int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
|
||||
struct thermal_trip *trip);
|
||||
int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
|
||||
struct thermal_trip *trip);
|
||||
|
||||
int thermal_zone_set_trip(struct thermal_zone_device *tz, int trip_id,
|
||||
const struct thermal_trip *trip);
|
||||
|
||||
int thermal_zone_get_num_trips(struct thermal_zone_device *tz);
|
||||
|
||||
int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp);
|
||||
|
||||
#ifdef CONFIG_THERMAL_ACPI
|
||||
int thermal_acpi_trip_active(struct acpi_device *adev, int id,
|
||||
struct thermal_trip *trip);
|
||||
int thermal_acpi_trip_passive(struct acpi_device *adev, struct thermal_trip *trip);
|
||||
int thermal_acpi_trip_hot(struct acpi_device *adev, struct thermal_trip *trip);
|
||||
int thermal_acpi_trip_critical(struct acpi_device *adev, struct thermal_trip *trip);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_THERMAL
|
||||
struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
|
||||
void *, struct thermal_zone_device_ops *,
|
||||
|
Loading…
x
Reference in New Issue
Block a user