summaryrefslogtreecommitdiff
path: root/drivers/thermal
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2023-01-25 15:52:25 +0100
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2023-01-27 15:11:12 +0100
commitb1bf9dbffc3049ca22ab36cb807b671655a936d0 (patch)
treeb8a8b84c93d9ad8a60d974a37c3592b4efe3ecf2 /drivers/thermal
parent97efecfdbf6fe4915e7f71603b634d5ad3f210b1 (diff)
downloadlwn-b1bf9dbffc3049ca22ab36cb807b671655a936d0.tar.gz
lwn-b1bf9dbffc3049ca22ab36cb807b671655a936d0.zip
thermal: intel: int340x: Rework updating trip points
It is generally invalid to change the trip point indices after they have been exposed via sysfs. Moreover, the thermal objects in the ACPI namespace cannot go away and appear on the fly. In practice, the only thing that can happen when the INT3403_PERF_TRIP_POINT_CHANGED notification is sent by the platform firmware is a change of the return values of those thermal objects. For this reason, add a special function for updating the trip point temperatures after re-evaluating the respective ACPI thermal objects and change int3403_notify() to invoke it instead of int340x_thermal_read_trips() that would change the trip point indices on errors. Also remove the locking from the latter, because it is only called before registering the thermal zone and it cannot race with the zone's callbacks. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/intel/int340x_thermal/int3403_thermal.c2
-rw-r--r--drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c51
-rw-r--r--drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h2
3 files changed, 47 insertions, 8 deletions
diff --git a/drivers/thermal/intel/int340x_thermal/int3403_thermal.c b/drivers/thermal/intel/int340x_thermal/int3403_thermal.c
index 71d084c4c456..e418d270bc76 100644
--- a/drivers/thermal/intel/int340x_thermal/int3403_thermal.c
+++ b/drivers/thermal/intel/int340x_thermal/int3403_thermal.c
@@ -69,7 +69,7 @@ static void int3403_notify(acpi_handle handle,
THERMAL_TRIP_VIOLATED);
break;
case INT3403_PERF_TRIP_POINT_CHANGED:
- int340x_thermal_read_trips(obj->int340x_zone);
+ int340x_thermal_update_trips(obj->int340x_zone);
int340x_thermal_zone_device_update(obj->int340x_zone,
THERMAL_TRIP_CHANGED);
break;
diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c
index 40c1e8a8bc1b..78768d0b0d9d 100644
--- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c
+++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c
@@ -168,13 +168,11 @@ static int int340x_thermal_get_trip_config(acpi_handle handle, char *name,
return 0;
}
-int int340x_thermal_read_trips(struct int34x_thermal_zone *int34x_zone)
+static int int340x_thermal_read_trips(struct int34x_thermal_zone *int34x_zone)
{
int trip_cnt = int34x_zone->aux_trip_nr;
int i;
- mutex_lock(&int34x_zone->trip_mutex);
-
int34x_zone->crt_trip_id = -1;
if (!int340x_thermal_get_trip_config(int34x_zone->adev->handle, "_CRT",
&int34x_zone->crt_temp))
@@ -202,11 +200,8 @@ int int340x_thermal_read_trips(struct int34x_thermal_zone *int34x_zone)
int34x_zone->act_trips[i].valid = true;
}
- mutex_unlock(&int34x_zone->trip_mutex);
-
return trip_cnt;
}
-EXPORT_SYMBOL_GPL(int340x_thermal_read_trips);
static struct thermal_zone_params int340x_thermal_params = {
.governor_name = "user_space",
@@ -309,6 +304,50 @@ void int340x_thermal_zone_remove(struct int34x_thermal_zone
}
EXPORT_SYMBOL_GPL(int340x_thermal_zone_remove);
+void int340x_thermal_update_trips(struct int34x_thermal_zone *int34x_zone)
+{
+ acpi_handle zone_handle = int34x_zone->adev->handle;
+ int i, err;
+
+ mutex_lock(&int34x_zone->trip_mutex);
+
+ if (int34x_zone->crt_trip_id > 0) {
+ err = int340x_thermal_get_trip_config(zone_handle, "_CRT",
+ &int34x_zone->crt_temp);
+ if (err)
+ int34x_zone->crt_temp = THERMAL_TEMP_INVALID;
+ }
+
+ if (int34x_zone->hot_trip_id > 0) {
+ err = int340x_thermal_get_trip_config(zone_handle, "_HOT",
+ &int34x_zone->hot_temp);
+ if (err)
+ int34x_zone->hot_temp = THERMAL_TEMP_INVALID;
+ }
+
+ if (int34x_zone->psv_trip_id > 0) {
+ err = int340x_thermal_get_trip_config(zone_handle, "_PSV",
+ &int34x_zone->psv_temp);
+ if (err)
+ int34x_zone->psv_temp = THERMAL_TEMP_INVALID;
+ }
+
+ for (i = 0; i < INT340X_THERMAL_MAX_ACT_TRIP_COUNT; i++) {
+ char name[5] = { '_', 'A', 'C', '0' + i, '\0' };
+
+ if (!int34x_zone->act_trips[i].valid)
+ break;
+
+ err = int340x_thermal_get_trip_config(zone_handle, name,
+ &int34x_zone->act_trips[i].temp);
+ if (err)
+ int34x_zone->act_trips[i].temp = THERMAL_TEMP_INVALID;
+ }
+
+ mutex_unlock(&int34x_zone->trip_mutex);
+}
+EXPORT_SYMBOL_GPL(int340x_thermal_update_trips);
+
MODULE_AUTHOR("Aaron Lu <aaron.lu@intel.com>");
MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
MODULE_DESCRIPTION("Intel INT340x common thermal zone handler");
diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h
index 6610a9cc441b..0a7b0f009aa0 100644
--- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h
+++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h
@@ -38,7 +38,7 @@ struct int34x_thermal_zone {
struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *,
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);
+void int340x_thermal_update_trips(struct int34x_thermal_zone *int34x_zone);
static inline void int340x_thermal_zone_set_priv_data(
struct int34x_thermal_zone *tzone, void *priv_data)