kernel: bump 5.4 to 5.4.45
[openwrt/staging/wigyori.git] / target / linux / layerscape / patches-5.4 / 818-thermal-0002-thermal-qoriq-Add-device-cooling-support.patch
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
5
6 Register device cooling for first thermal zone manually, when
7 temperature exceeds passive trip, system wide cooling notification
8 will be triggered.
9
10 Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
11 ---
12 drivers/thermal/qoriq_thermal.c | 80 ++++++++++++++++++++++++++++++++++++++++-
13 1 file changed, 79 insertions(+), 1 deletion(-)
14
15 --- a/drivers/thermal/qoriq_thermal.c
16 +++ b/drivers/thermal/qoriq_thermal.c
17 @@ -3,6 +3,7 @@
18 // Copyright 2016 Freescale Semiconductor, Inc.
19
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>
25 @@ -14,6 +15,7 @@
26 #include "thermal_core.h"
27
28 #define SITES_MAX 16
29 +#define TMU_TEMP_PASSIVE_COOL_DELTA 10000
30
31 /*
32 * QorIQ TMU Registers
33 @@ -69,6 +71,9 @@ struct qoriq_sensor {
34 struct thermal_zone_device *tzd;
35 struct qoriq_tmu_data *qdata;
36 int id;
37 + int temp_passive;
38 + int temp_critical;
39 + struct thermal_cooling_device *cdev;
40 };
41
42 struct qoriq_tmu_data {
43 @@ -78,6 +83,12 @@ struct qoriq_tmu_data {
44 struct qoriq_sensor *sensor[SITES_MAX];
45 };
46
47 +enum tmu_trip {
48 + TMU_TRIP_PASSIVE,
49 + TMU_TRIP_CRITICAL,
50 + TMU_TRIP_NUM,
51 +};
52 +
53 static void tmu_write(struct qoriq_tmu_data *p, u32 val, void __iomem *addr)
54 {
55 if (p->little_endian)
56 @@ -106,14 +117,51 @@ static int tmu_get_temp(void *p, int *te
57 return 0;
58 }
59
60 +static int tmu_get_trend(void *p, int trip, enum thermal_trend *trend)
61 +{
62 + struct qoriq_sensor *qsensor = p;
63 + int trip_temp;
64 +
65 + if (!qsensor->tzd)
66 + return 0;
67 +
68 + trip_temp = (trip == TMU_TRIP_PASSIVE) ? qsensor->temp_passive :
69 + qsensor->temp_critical;
70 +
71 + if (qsensor->tzd->temperature >=
72 + (trip_temp - TMU_TEMP_PASSIVE_COOL_DELTA))
73 + *trend = THERMAL_TREND_RAISE_FULL;
74 + else
75 + *trend = THERMAL_TREND_DROP_FULL;
76 +
77 + return 0;
78 +}
79 +
80 +static int tmu_set_trip_temp(void *p, int trip,
81 + int temp)
82 +{
83 + struct qoriq_sensor *qsensor = p;
84 +
85 + if (trip == TMU_TRIP_CRITICAL)
86 + qsensor->temp_critical = temp;
87 +
88 + if (trip == TMU_TRIP_PASSIVE)
89 + qsensor->temp_passive = temp;
90 +
91 + return 0;
92 +}
93 +
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,
98 };
99
100 static int qoriq_tmu_register_tmu_zone(struct platform_device *pdev)
101 {
102 struct qoriq_tmu_data *qdata = platform_get_drvdata(pdev);
103 - int id, sites = 0;
104 + const struct thermal_trip *trip;
105 + int id, sites = 0, ret;
106
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);
111 }
112
113 + /* first thermal zone takes care of system-wide device cooling */
114 + if (id == 0) {
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",
119 + ret);
120 + return ret;
121 + }
122 +
123 + ret = thermal_zone_bind_cooling_device(qdata->sensor[id]->tzd,
124 + TMU_TRIP_PASSIVE,
125 + qdata->sensor[id]->cdev,
126 + THERMAL_NO_LIMIT,
127 + THERMAL_NO_LIMIT,
128 + THERMAL_WEIGHT_DEFAULT);
129 + if (ret) {
130 + pr_err("binding zone %s with cdev %s failed:%d\n",
131 + qdata->sensor[id]->tzd->type,
132 + qdata->sensor[id]->cdev->type,
133 + ret);
134 + devfreq_cooling_unregister(qdata->sensor[id]->cdev);
135 + return ret;
136 + }
137 +
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;
141 + }
142 +
143 sites |= 0x1 << (15 - id);
144 }
145