summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-07-22 22:13:48 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2024-07-22 22:13:48 +0300
commit539fbb912321ab6361ccc08b72f5f83e8a25c24b (patch)
tree13917ec7cfc33df6bc63dc507cea4c245a483631
parent9deed1d5f82cf30308027f9f604a95ac7ffdbe19 (diff)
parente528be3c87be953b73e7826a2d7e4b837cbad39d (diff)
downloadlinux-539fbb912321ab6361ccc08b72f5f83e8a25c24b.tar.xz
Merge tag 'thermal-6.11-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull thermal control fix from Rafael Wysocki: "Fix a flood of kernel messages coming from the thermal core on systems where iwlwifi is loaded, but the network interfaces controlled by it are down (Rafael Wysocki)" * tag 'thermal-6.11-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: thermal: core: Allow thermal zones to tell the core to ignore them
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tt.c10
-rw-r--r--drivers/thermal/thermal_core.c51
-rw-r--r--drivers/thermal/thermal_core.h3
-rw-r--r--drivers/thermal/thermal_helpers.c2
4 files changed, 37 insertions, 29 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
index ed0796aff722..d92470960b38 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
@@ -621,8 +621,14 @@ static int iwl_mvm_tzone_get_temp(struct thermal_zone_device *device,
guard(mvm)(mvm);
if (!iwl_mvm_firmware_running(mvm) ||
- mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
- return -ENODATA;
+ mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) {
+ /*
+ * Tell the core that there is no valid temperature value to
+ * return, but it need not worry about this.
+ */
+ *temperature = THERMAL_TEMP_INVALID;
+ return 0;
+ }
ret = iwl_mvm_get_temp(mvm, &temp);
if (ret)
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 8795187fbc52..f6e700e48aad 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -300,8 +300,6 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz)
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 thermal_zone_device *tz,
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 thermal_zone_device *tz,
}
}
-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(struct thermal_zone_device *tz)
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;
@@ -504,6 +481,7 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
struct thermal_trip_desc *td;
LIST_HEAD(way_down_list);
LIST_HEAD(way_up_list);
+ int temp, ret;
if (tz->suspended)
return;
@@ -511,10 +489,29 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
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);
tz->notify_event = event;
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index 30c0e78859a7..ba8e6fc807ca 100644
--- a/drivers/thermal/thermal_core.h
+++ b/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.
diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c
index 81e019493557..aedb8369e2aa 100644
--- a/drivers/thermal/thermal_helpers.c
+++ b/drivers/thermal/thermal_helpers.c
@@ -163,6 +163,8 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
}
ret = __thermal_zone_get_temp(tz, temp);
+ if (!ret && *temp <= THERMAL_TEMP_INVALID)
+ ret = -ENODATA;
unlock:
mutex_unlock(&tz->lock);