Messages in this thread Patch in this message | | | From | "Alice Guo (OSS)" <> | Subject | [PATCH v1 2/2] thermal: qoriq: Add device cooling support | Date | Thu, 5 Jan 2023 16:22:34 +0800 |
| |
From: Anson Huang <Anson.Huang@nxp.com>
Register device cooling for first thermal zone manually, when temperature exceeds passive trip, system wide cooling notification will be triggered.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com> Signed-off-by: Alice Guo <alice.guo@nxp.com> Reviewed-by: Jacky Bai <ping.bai@nxp.com> --- drivers/thermal/qoriq_thermal.c | 83 ++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-)
diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c index d111e218f362..3c21b2d184eb 100644 --- a/drivers/thermal/qoriq_thermal.c +++ b/drivers/thermal/qoriq_thermal.c @@ -3,6 +3,7 @@ // Copyright 2016 Freescale Semiconductor, Inc. #include <linux/clk.h> +#include <linux/device_cooling.h> #include <linux/err.h> #include <linux/io.h> #include <linux/module.h> @@ -27,6 +28,7 @@ #define TMSARA_V2 0xe #define TMU_VER1 0x1 #define TMU_VER2 0x2 +#define TMU_TEMP_PASSIVE_COOL_DELTA 10000 #define REGS_TMR 0x000 /* Mode Register */ #define TMR_DISABLE 0x0 @@ -68,6 +70,10 @@ */ struct qoriq_sensor { int id; + struct thermal_zone_device *tzd; + int temp_passive; + int temp_critical; + struct thermal_cooling_device *cdev; }; struct qoriq_tmu_data { @@ -77,6 +83,12 @@ struct qoriq_tmu_data { struct qoriq_sensor sensor[SITES_MAX]; }; +enum tmu_trip { + TMU_TRIP_PASSIVE, + TMU_TRIP_CRITICAL, + TMU_TRIP_NUM, +}; + static struct qoriq_tmu_data *qoriq_sensor_to_data(struct qoriq_sensor *s) { return container_of(s, struct qoriq_tmu_data, sensor[s->id]); @@ -122,14 +134,53 @@ static int tmu_get_temp(struct thermal_zone_device *tz, int *temp) return 0; } +static int tmu_get_trend(struct thermal_zone_device *tz, int trip, + enum thermal_trend *trend) + +{ + struct qoriq_sensor *qsensor = tz->devdata; + int trip_temp; + + if (!qsensor->tzd) + return 0; + + trip_temp = (trip == TMU_TRIP_PASSIVE) ? qsensor->temp_passive : + qsensor->temp_critical; + + if (qsensor->tzd->temperature >= + (trip_temp - TMU_TEMP_PASSIVE_COOL_DELTA)) + *trend = THERMAL_TREND_RAISING; + else + *trend = THERMAL_TREND_DROPPING; + + return 0; +} + +static int tmu_set_trip_temp(struct thermal_zone_device *tz, int trip, + int temp) +{ + struct qoriq_sensor *qsensor = tz->devdata; + + if (trip == TMU_TRIP_CRITICAL) + qsensor->temp_critical = temp; + + if (trip == TMU_TRIP_PASSIVE) + qsensor->temp_passive = temp; + + return 0; +} + static const struct thermal_zone_device_ops tmu_tz_ops = { .get_temp = tmu_get_temp, + .get_trend = tmu_get_trend, + .set_trip_temp = tmu_set_trip_temp, }; static int qoriq_tmu_register_tmu_zone(struct device *dev, struct qoriq_tmu_data *qdata) { int id; + const struct thermal_trip *trip; if (qdata->ver == TMU_VER1) { regmap_write(qdata->regmap, REGS_TMR, @@ -158,10 +209,40 @@ static int qoriq_tmu_register_tmu_zone(struct device *dev, return ret; } + sensor->tzd = tzd; + if (devm_thermal_add_hwmon_sysfs(tzd)) dev_warn(dev, "Failed to add hwmon sysfs attributes\n"); - + /* first thermal zone takes care of system-wide device cooling */ + if (id == 0) { + sensor->cdev = devfreq_cooling_register(); + if (IS_ERR(sensor->cdev)) { + ret = PTR_ERR(sensor->cdev); + pr_err("failed to register devfreq cooling device: %d\n", + ret); + return ret; + } + + ret = thermal_zone_bind_cooling_device(sensor->tzd, + TMU_TRIP_PASSIVE, + sensor->cdev, + THERMAL_NO_LIMIT, + THERMAL_NO_LIMIT, + THERMAL_WEIGHT_DEFAULT); + if (ret) { + pr_err("binding zone %s with cdev %s failed:%d\n", + sensor->tzd->type, + sensor->cdev->type, + ret); + devfreq_cooling_unregister(sensor->cdev); + return ret; + } + + trip = of_thermal_get_trip_points(sensor->tzd); + sensor->temp_passive = trip[0].temperature; + sensor->temp_critical = trip[1].temperature; + } } return 0; -- 2.17.1
| |