--- drivers/net/wireless/intel/iwlwifi/mvm/tt.c | 7 +++ drivers/thermal/thermal_core.c | 51 +++++++++++++--------------- drivers/thermal/thermal_core.h | 3 + 3 files changed, 33 insertions(+), 28 deletions(-) Index: linux-pm/drivers/thermal/thermal_core.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.c +++ linux-pm/drivers/thermal/thermal_core.c @@ -300,8 +300,6 @@ static void monitor_thermal_zone(struct thermal_zone_device_set_polling(tz, tz->passive_delay_jiffies); else if (tz->polling_delay_jiffies) thermal_zone_device_set_polling(tz, tz->polling_delay_jiffies); - else if (tz->temperature == THERMAL_TEMP_INVALID) - thermal_zone_device_set_polling(tz, msecs_to_jiffies(THERMAL_RECHECK_DELAY_MS)); } static struct thermal_governor *thermal_get_tz_governor(struct thermal_zone_device *tz) @@ -382,7 +380,7 @@ static void handle_thermal_trip(struct t td->threshold = trip->temperature; if (tz->last_temperature >= old_threshold && - tz->last_temperature != THERMAL_TEMP_INVALID) { + tz->last_temperature != THERMAL_TEMP_INIT) { /* * Mitigation is under way, so it needs to stop if the zone * temperature falls below the low temperature of the trip. @@ -417,27 +415,6 @@ static void handle_thermal_trip(struct t } } -static void update_temperature(struct thermal_zone_device *tz) -{ - int temp, ret; - - ret = __thermal_zone_get_temp(tz, &temp); - if (ret) { - if (ret != -EAGAIN) - dev_warn(&tz->device, - "failed to read out thermal zone (%d)\n", - ret); - return; - } - - tz->last_temperature = tz->temperature; - tz->temperature = temp; - - trace_thermal_temperature(tz); - - thermal_genl_sampling_temp(tz->id, temp); -} - static void thermal_zone_device_check(struct work_struct *work) { struct thermal_zone_device *tz = container_of(work, struct @@ -452,7 +429,7 @@ static void thermal_zone_device_init(str INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check); - tz->temperature = THERMAL_TEMP_INVALID; + tz->temperature = THERMAL_TEMP_INIT; tz->passive = 0; tz->prev_low_trip = -INT_MAX; tz->prev_high_trip = INT_MAX; @@ -501,6 +478,7 @@ void __thermal_zone_device_update(struct struct thermal_trip_desc *td; LIST_HEAD(way_down_list); LIST_HEAD(way_up_list); + int temp, ret; if (tz->suspended) return; @@ -508,10 +486,29 @@ void __thermal_zone_device_update(struct if (!thermal_zone_device_is_enabled(tz)) return; - update_temperature(tz); + ret = __thermal_zone_get_temp(tz, &temp); + if (ret) { + if (ret != -EAGAIN) + dev_info(&tz->device, "Temperature check failed (%d)\n", ret); - if (tz->temperature == THERMAL_TEMP_INVALID) + thermal_zone_device_set_polling(tz, msecs_to_jiffies(THERMAL_RECHECK_DELAY_MS)); + return; + } else if (temp <= THERMAL_TEMP_INVALID) { + /* + * Special case: No valid temperature value is available, but + * the zone owner does not want the core to do anything about + * it. Continue regular zone polling if needed, so that this + * function can be called again, but skip everything else. + */ goto monitor; + } + + tz->last_temperature = tz->temperature; + tz->temperature = temp; + + trace_thermal_temperature(tz); + + thermal_genl_sampling_temp(tz->id, temp); __thermal_zone_set_trips(tz); Index: linux-pm/drivers/net/wireless/intel/iwlwifi/mvm/tt.c =================================================================== --- linux-pm.orig/drivers/net/wireless/intel/iwlwifi/mvm/tt.c +++ linux-pm/drivers/net/wireless/intel/iwlwifi/mvm/tt.c @@ -622,7 +622,12 @@ static int iwl_mvm_tzone_get_temp(struct if (!iwl_mvm_firmware_running(mvm) || mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) { - ret = -ENODATA; + /* + * Tell the core that there is no valid temperature value to + * return, but it need not worry about this. + */ + *temperature = THERMAL_TEMP_INVALID; + ret = 0; goto out; } Index: linux-pm/drivers/thermal/thermal_core.h =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.h +++ linux-pm/drivers/thermal/thermal_core.h @@ -133,6 +133,9 @@ struct thermal_zone_device { struct thermal_trip_desc trips[] __counted_by(num_trips); }; +/* Initial thermal zone temperature. */ +#define THERMAL_TEMP_INIT INT_MIN + /* * Default delay after a failing thermal zone temperature check before * attempting to check it again.