1 From 0a5d1b571ba5bca9c6737572ea4c8b1ad896c3fc Mon Sep 17 00:00:00 2001
2 From: Anson Huang <Anson.Huang@nxp.com>
3 Date: Wed, 7 Aug 2019 13:24:26 +0800
4 Subject: [PATCH] thermal: qoriq: Add device cooling support
6 Register device cooling for first thermal zone manually, when
7 temperature exceeds passive trip, system wide cooling notification
10 Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
12 drivers/thermal/qoriq_thermal.c | 80 ++++++++++++++++++++++++++++++++++++++++-
13 1 file changed, 79 insertions(+), 1 deletion(-)
15 --- a/drivers/thermal/qoriq_thermal.c
16 +++ b/drivers/thermal/qoriq_thermal.c
18 // Copyright 2016 Freescale Semiconductor, Inc.
20 #include <linux/clk.h>
21 +#include <linux/device_cooling.h>
22 #include <linux/module.h>
23 #include <linux/platform_device.h>
24 #include <linux/err.h>
26 #include "thermal_core.h"
29 +#define TMU_TEMP_PASSIVE_COOL_DELTA 10000
33 @@ -69,6 +71,9 @@ struct qoriq_sensor {
34 struct thermal_zone_device *tzd;
35 struct qoriq_tmu_data *qdata;
39 + struct thermal_cooling_device *cdev;
42 struct qoriq_tmu_data {
43 @@ -78,6 +83,12 @@ struct qoriq_tmu_data {
44 struct qoriq_sensor *sensor[SITES_MAX];
53 static void tmu_write(struct qoriq_tmu_data *p, u32 val, void __iomem *addr)
56 @@ -106,14 +117,51 @@ static int tmu_get_temp(void *p, int *te
60 +static int tmu_get_trend(void *p, int trip, enum thermal_trend *trend)
62 + struct qoriq_sensor *qsensor = p;
68 + trip_temp = (trip == TMU_TRIP_PASSIVE) ? qsensor->temp_passive :
69 + qsensor->temp_critical;
71 + if (qsensor->tzd->temperature >=
72 + (trip_temp - TMU_TEMP_PASSIVE_COOL_DELTA))
73 + *trend = THERMAL_TREND_RAISE_FULL;
75 + *trend = THERMAL_TREND_DROP_FULL;
80 +static int tmu_set_trip_temp(void *p, int trip,
83 + struct qoriq_sensor *qsensor = p;
85 + if (trip == TMU_TRIP_CRITICAL)
86 + qsensor->temp_critical = temp;
88 + if (trip == TMU_TRIP_PASSIVE)
89 + qsensor->temp_passive = temp;
94 static const struct thermal_zone_of_device_ops tmu_tz_ops = {
95 .get_temp = tmu_get_temp,
96 + .get_trend = tmu_get_trend,
97 + .set_trip_temp = tmu_set_trip_temp,
100 static int qoriq_tmu_register_tmu_zone(struct platform_device *pdev)
102 struct qoriq_tmu_data *qdata = platform_get_drvdata(pdev);
104 + const struct thermal_trip *trip;
105 + int id, sites = 0, ret;
107 for (id = 0; id < SITES_MAX; id++) {
108 qdata->sensor[id] = devm_kzalloc(&pdev->dev,
109 @@ -132,6 +180,36 @@ static int qoriq_tmu_register_tmu_zone(s
110 return PTR_ERR(qdata->sensor[id]->tzd);
113 + /* first thermal zone takes care of system-wide device cooling */
115 + qdata->sensor[id]->cdev = devfreq_cooling_register();
116 + if (IS_ERR(qdata->sensor[id]->cdev)) {
117 + ret = PTR_ERR(qdata->sensor[id]->cdev);
118 + pr_err("failed to register devfreq cooling device: %d\n",
123 + ret = thermal_zone_bind_cooling_device(qdata->sensor[id]->tzd,
125 + qdata->sensor[id]->cdev,
128 + THERMAL_WEIGHT_DEFAULT);
130 + pr_err("binding zone %s with cdev %s failed:%d\n",
131 + qdata->sensor[id]->tzd->type,
132 + qdata->sensor[id]->cdev->type,
134 + devfreq_cooling_unregister(qdata->sensor[id]->cdev);
138 + trip = of_thermal_get_trip_points(qdata->sensor[id]->tzd);
139 + qdata->sensor[id]->temp_passive = trip[0].temperature;
140 + qdata->sensor[id]->temp_critical = trip[1].temperature;
143 sites |= 0x1 << (15 - id);