kernel: move mv88e6xxx fix to generic backports
[openwrt/openwrt.git] / target / linux / ipq806x / patches-5.4 / 0063-2-tsens-support-configurable-interrupts.patch
1 From 4e87400732c77765afae2ea89ed43837457aa604 Mon Sep 17 00:00:00 2001
2 From: Rajith Cherian <rajith@codeaurora.org>
3 Date: Wed, 1 Feb 2017 19:00:26 +0530
4 Subject: [PATCH] ipq8064: tsens: Support for configurable interrupts
5
6 Provide support for adding configurable high and
7 configurable low trip temperatures. An interrupts is
8 also triggerred when these trip points are hit. The
9 interrupts can be activated or deactivated from sysfs.
10 This functionality is made available only if
11 CONFIG_THERMAL_WRITABLE_TRIPS is defined.
12
13 Change-Id: Ib73f3f9459de4fffce7bb985a0312a88291f4934
14 Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
15 ---
16 .../devicetree/bindings/thermal/qcom-tsens.txt | 4 ++
17 drivers/thermal/of-thermal.c | 63 ++++++++++++++++++----
18 drivers/thermal/qcom/tsens.c | 43 ++++++++++++---
19 drivers/thermal/qcom/tsens.h | 11 ++++
20 drivers/thermal/thermal_core.c | 44 ++++++++++++++-
21 include/linux/thermal.h | 14 +++++
22 6 files changed, 162 insertions(+), 17 deletions(-)
23
24 --- a/drivers/thermal/of-thermal.c
25 +++ b/drivers/thermal/of-thermal.c
26 @@ -91,7 +91,7 @@ static int of_thermal_get_temp(struct th
27 {
28 struct __thermal_zone *data = tz->devdata;
29
30 - if (!data->ops->get_temp)
31 + if (!data->ops->get_temp || (data->mode == THERMAL_DEVICE_DISABLED))
32 return -EINVAL;
33
34 return data->ops->get_temp(data->sensor_data, temp);
35 @@ -102,7 +102,8 @@ static int of_thermal_set_trips(struct t
36 {
37 struct __thermal_zone *data = tz->devdata;
38
39 - if (!data->ops || !data->ops->set_trips)
40 + if (!data->ops || !data->ops->set_trips
41 + || (data->mode == THERMAL_DEVICE_DISABLED))
42 return -EINVAL;
43
44 return data->ops->set_trips(data->sensor_data, low, high);
45 @@ -188,6 +189,9 @@ static int of_thermal_set_emul_temp(stru
46 {
47 struct __thermal_zone *data = tz->devdata;
48
49 + if (data->mode == THERMAL_DEVICE_DISABLED)
50 + return -EINVAL;
51 +
52 return data->ops->set_emul_temp(data->sensor_data, temp);
53 }
54
55 @@ -196,7 +200,7 @@ static int of_thermal_get_trend(struct t
56 {
57 struct __thermal_zone *data = tz->devdata;
58
59 - if (!data->ops->get_trend)
60 + if (!data->ops->get_trend || (data->mode == THERMAL_DEVICE_DISABLED))
61 return -EINVAL;
62
63 return data->ops->get_trend(data->sensor_data, trip, trend);
64 @@ -297,7 +301,9 @@ static int of_thermal_set_mode(struct th
65 mutex_unlock(&tz->lock);
66
67 data->mode = mode;
68 - thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
69 +
70 + if (mode == THERMAL_DEVICE_ENABLED)
71 + thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
72
73 return 0;
74 }
75 @@ -307,7 +313,8 @@ static int of_thermal_get_trip_type(stru
76 {
77 struct __thermal_zone *data = tz->devdata;
78
79 - if (trip >= data->ntrips || trip < 0)
80 + if (trip >= data->ntrips || trip < 0
81 + || (data->mode == THERMAL_DEVICE_DISABLED))
82 return -EDOM;
83
84 *type = data->trips[trip].type;
85 @@ -315,12 +322,39 @@ static int of_thermal_get_trip_type(stru
86 return 0;
87 }
88
89 +static int of_thermal_activate_trip_type(struct thermal_zone_device *tz,
90 + int trip, enum thermal_trip_activation_mode mode)
91 +{
92 + struct __thermal_zone *data = tz->devdata;
93 +
94 + if (trip >= data->ntrips || trip < 0
95 + || (data->mode == THERMAL_DEVICE_DISABLED))
96 + return -EDOM;
97 +
98 + /*
99 + * The configurable_hi and configurable_lo trip points can be
100 + * activated and deactivated.
101 + */
102 +
103 + if (data->ops->set_trip_activate) {
104 + int ret;
105 +
106 + ret = data->ops->set_trip_activate(data->sensor_data,
107 + trip, mode);
108 + if (ret)
109 + return ret;
110 + }
111 +
112 + return 0;
113 +}
114 +
115 static int of_thermal_get_trip_temp(struct thermal_zone_device *tz, int trip,
116 int *temp)
117 {
118 struct __thermal_zone *data = tz->devdata;
119
120 - if (trip >= data->ntrips || trip < 0)
121 + if (trip >= data->ntrips || trip < 0
122 + || (data->mode == THERMAL_DEVICE_DISABLED))
123 return -EDOM;
124
125 *temp = data->trips[trip].temperature;
126 @@ -333,7 +367,8 @@ static int of_thermal_set_trip_temp(stru
127 {
128 struct __thermal_zone *data = tz->devdata;
129
130 - if (trip >= data->ntrips || trip < 0)
131 + if (trip >= data->ntrips || trip < 0
132 + || (data->mode == THERMAL_DEVICE_DISABLED))
133 return -EDOM;
134
135 if (data->ops->set_trip_temp) {
136 @@ -355,7 +390,8 @@ static int of_thermal_get_trip_hyst(stru
137 {
138 struct __thermal_zone *data = tz->devdata;
139
140 - if (trip >= data->ntrips || trip < 0)
141 + if (trip >= data->ntrips || trip < 0
142 + || (data->mode == THERMAL_DEVICE_DISABLED))
143 return -EDOM;
144
145 *hyst = data->trips[trip].hysteresis;
146 @@ -368,7 +404,8 @@ static int of_thermal_set_trip_hyst(stru
147 {
148 struct __thermal_zone *data = tz->devdata;
149
150 - if (trip >= data->ntrips || trip < 0)
151 + if (trip >= data->ntrips || trip < 0
152 + || (data->mode == THERMAL_DEVICE_DISABLED))
153 return -EDOM;
154
155 /* thermal framework should take care of data->mask & (1 << trip) */
156 @@ -443,6 +480,9 @@ thermal_zone_of_add_sensor(struct device
157 if (ops->set_emul_temp)
158 tzd->ops->set_emul_temp = of_thermal_set_emul_temp;
159
160 + if (ops->set_trip_activate)
161 + tzd->ops->set_trip_activate = of_thermal_activate_trip_type;
162 +
163 mutex_unlock(&tzd->lock);
164
165 return tzd;
166 @@ -762,7 +802,10 @@ static const char * const trip_types[] =
167 [THERMAL_TRIP_ACTIVE] = "active",
168 [THERMAL_TRIP_PASSIVE] = "passive",
169 [THERMAL_TRIP_HOT] = "hot",
170 - [THERMAL_TRIP_CRITICAL] = "critical",
171 + [THERMAL_TRIP_CRITICAL] = "critical_high",
172 + [THERMAL_TRIP_CONFIGURABLE_HI] = "configurable_hi",
173 + [THERMAL_TRIP_CONFIGURABLE_LOW] = "configurable_lo",
174 + [THERMAL_TRIP_CRITICAL_LOW] = "critical_low",
175 };
176
177 /**
178 --- a/drivers/thermal/qcom/tsens.c
179 +++ b/drivers/thermal/qcom/tsens.c
180 @@ -22,7 +22,7 @@ static int tsens_get_temp(void *data, in
181
182 static int tsens_get_trend(void *data, int trip, enum thermal_trend *trend)
183 {
184 - const struct tsens_sensor *s = data;
185 + struct tsens_sensor *s = data;
186 struct tsens_priv *priv = s->priv;
187
188 if (priv->ops->get_trend)
189 @@ -31,9 +31,10 @@ static int tsens_get_trend(void *data, i
190 return -ENOTSUPP;
191 }
192
193 -static int __maybe_unused tsens_suspend(struct device *dev)
194 +static int __maybe_unused tsens_suspend(void *data)
195 {
196 - struct tsens_priv *priv = dev_get_drvdata(dev);
197 + struct tsens_sensor *s = data;
198 + struct tsens_priv *priv = s->priv;
199
200 if (priv->ops && priv->ops->suspend)
201 return priv->ops->suspend(priv);
202 @@ -41,9 +42,10 @@ static int __maybe_unused tsens_suspend
203 return 0;
204 }
205
206 -static int __maybe_unused tsens_resume(struct device *dev)
207 +static int __maybe_unused tsens_resume(void *data)
208 {
209 - struct tsens_priv *priv = dev_get_drvdata(dev);
210 + struct tsens_sensor *s = data;
211 + struct tsens_priv *priv = s->priv;
212
213 if (priv->ops && priv->ops->resume)
214 return priv->ops->resume(priv);
215 @@ -51,6 +53,30 @@ static int __maybe_unused tsens_resume(s
216 return 0;
217 }
218
219 +static int __maybe_unused tsens_set_trip_temp(void *data, int trip, int temp)
220 +{
221 + struct tsens_sensor *s = data;
222 + struct tsens_priv *priv = s->priv;
223 +
224 + if (priv->ops && priv->ops->set_trip_temp)
225 + return priv->ops->set_trip_temp(s, trip, temp);
226 +
227 + return 0;
228 +}
229 +
230 +static int __maybe_unused tsens_activate_trip_type(void *data, int trip,
231 + enum thermal_trip_activation_mode mode)
232 +{
233 + struct tsens_sensor *s = data;
234 + struct tsens_priv *priv = s->priv;
235 +
236 + if (priv->ops && priv->ops->set_trip_activate)
237 + return priv->ops->set_trip_activate(s, trip, mode);
238 +
239 + return 0;
240 +}
241 +
242 +
243 static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
244
245 static const struct of_device_id tsens_table[] = {
246 @@ -80,6 +106,8 @@ MODULE_DEVICE_TABLE(of, tsens_table);
247 static const struct thermal_zone_of_device_ops tsens_of_ops = {
248 .get_temp = tsens_get_temp,
249 .get_trend = tsens_get_trend,
250 + .set_trip_temp = tsens_set_trip_temp,
251 + .set_trip_activate = tsens_activate_trip_type,
252 };
253
254 static int tsens_register(struct tsens_priv *priv)
255 @@ -123,7 +151,7 @@ static int tsens_probe(struct platform_d
256 if (id)
257 data = id->data;
258 else
259 - data = &data_8960;
260 + return -EINVAL;
261
262 num_sensors = data->num_sensors;
263
264 @@ -144,6 +172,9 @@ static int tsens_probe(struct platform_d
265 priv->dev = dev;
266 priv->num_sensors = num_sensors;
267 priv->ops = data->ops;
268 +
269 + priv->tsens_irq = platform_get_irq(pdev, 0);
270 +
271 for (i = 0; i < priv->num_sensors; i++) {
272 if (data->hw_ids)
273 priv->sensor[i].hw_id = data->hw_ids[i];
274 --- a/drivers/thermal/qcom/tsens.h
275 +++ b/drivers/thermal/qcom/tsens.h
276 @@ -40,9 +40,12 @@ enum tsens_ver {
277 struct tsens_sensor {
278 struct tsens_priv *priv;
279 struct thermal_zone_device *tzd;
280 + struct work_struct notify_work;
281 int offset;
282 unsigned int id;
283 unsigned int hw_id;
284 + int calib_data;
285 + int calib_data_backup;
286 int slope;
287 u32 status;
288 };
289 @@ -57,6 +60,9 @@ struct tsens_sensor {
290 * @suspend: Function to suspend the tsens device
291 * @resume: Function to resume the tsens device
292 * @get_trend: Function to get the thermal/temp trend
293 + * @set_trip_temp: Function to set trip temp
294 + * @get_trip_temp: Function to get trip temp
295 + * @set_trip_activate: Function to activate trip points
296 */
297 struct tsens_ops {
298 /* mandatory callbacks */
299 @@ -69,6 +75,9 @@ struct tsens_ops {
300 int (*suspend)(struct tsens_priv *priv);
301 int (*resume)(struct tsens_priv *priv);
302 int (*get_trend)(struct tsens_priv *priv, int i, enum thermal_trend *trend);
303 + int (*set_trip_temp)(void *data, int trip, int temp);
304 + int (*set_trip_activate)(void *data, int trip,
305 + enum thermal_trip_activation_mode mode);
306 };
307
308 #define REG_FIELD_FOR_EACH_SENSOR11(_name, _offset, _startbit, _stopbit) \
309 @@ -300,6 +309,7 @@ struct tsens_context {
310 struct tsens_priv {
311 struct device *dev;
312 u32 num_sensors;
313 + u32 tsens_irq;
314 struct regmap *tm_map;
315 struct regmap *srot_map;
316 u32 tm_offset;
317 @@ -308,6 +318,7 @@ struct tsens_priv {
318 const struct tsens_features *feat;
319 const struct reg_field *fields;
320 const struct tsens_ops *ops;
321 + struct work_struct tsens_work;
322 struct tsens_sensor sensor[0];
323 };
324
325 --- a/drivers/thermal/thermal_sysfs.c
326 +++ b/drivers/thermal/thermal_sysfs.c
327 @@ -113,12 +113,48 @@ trip_point_type_show(struct device *dev,
328 return sprintf(buf, "passive\n");
329 case THERMAL_TRIP_ACTIVE:
330 return sprintf(buf, "active\n");
331 + case THERMAL_TRIP_CONFIGURABLE_HI:
332 + return sprintf(buf, "configurable_hi\n");
333 + case THERMAL_TRIP_CONFIGURABLE_LOW:
334 + return sprintf(buf, "configurable_low\n");
335 + case THERMAL_TRIP_CRITICAL_LOW:
336 + return sprintf(buf, "critical_low\n");
337 default:
338 return sprintf(buf, "unknown\n");
339 }
340 }
341
342 static ssize_t
343 +trip_point_type_activate(struct device *dev, struct device_attribute *attr,
344 + const char *buf, size_t count)
345 +{
346 + struct thermal_zone_device *tz = to_thermal_zone(dev);
347 + int trip, ret;
348 + char *enabled = "enabled";
349 + char *disabled = "disabled";
350 +
351 + if (!tz->ops->set_trip_activate)
352 + return -EPERM;
353 +
354 + if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip))
355 + return -EINVAL;
356 +
357 + if (!strncmp(buf, enabled, strlen(enabled)))
358 + ret = tz->ops->set_trip_activate(tz, trip,
359 + THERMAL_TRIP_ACTIVATION_ENABLED);
360 + else if (!strncmp(buf, disabled, strlen(disabled)))
361 + ret = tz->ops->set_trip_activate(tz, trip,
362 + THERMAL_TRIP_ACTIVATION_DISABLED);
363 + else
364 + ret = -EINVAL;
365 +
366 + if (ret)
367 + return ret;
368 +
369 + return count;
370 +}
371 +
372 +static ssize_t
373 trip_point_temp_store(struct device *dev, struct device_attribute *attr,
374 const char *buf, size_t count)
375 {
376 @@ -559,6 +595,12 @@ static int create_trip_attrs(struct ther
377 tz->trip_type_attrs[indx].attr.show = trip_point_type_show;
378 attrs[indx] = &tz->trip_type_attrs[indx].attr.attr;
379
380 + if (IS_ENABLED(CONFIG_THERMAL_WRITABLE_TRIPS)) {
381 + tz->trip_type_attrs[indx].attr.store
382 + = trip_point_type_activate;
383 + tz->trip_type_attrs[indx].attr.attr.mode |= S_IWUSR;
384 + }
385 +
386 /* create trip temp attribute */
387 snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH,
388 "trip_point_%d_temp", indx);
389 --- a/include/linux/thermal.h
390 +++ b/include/linux/thermal.h
391 @@ -63,11 +63,19 @@ enum thermal_device_mode {
392 THERMAL_DEVICE_ENABLED,
393 };
394
395 +enum thermal_trip_activation_mode {
396 + THERMAL_TRIP_ACTIVATION_DISABLED = 0,
397 + THERMAL_TRIP_ACTIVATION_ENABLED,
398 +};
399 +
400 enum thermal_trip_type {
401 THERMAL_TRIP_ACTIVE = 0,
402 THERMAL_TRIP_PASSIVE,
403 THERMAL_TRIP_HOT,
404 THERMAL_TRIP_CRITICAL,
405 + THERMAL_TRIP_CONFIGURABLE_HI,
406 + THERMAL_TRIP_CONFIGURABLE_LOW,
407 + THERMAL_TRIP_CRITICAL_LOW,
408 };
409
410 enum thermal_trend {
411 @@ -105,6 +113,8 @@ struct thermal_zone_device_ops {
412 enum thermal_trip_type *);
413 int (*get_trip_temp) (struct thermal_zone_device *, int, int *);
414 int (*set_trip_temp) (struct thermal_zone_device *, int, int);
415 + int (*set_trip_activate) (struct thermal_zone_device *, int,
416 + enum thermal_trip_activation_mode);
417 int (*get_trip_hyst) (struct thermal_zone_device *, int, int *);
418 int (*set_trip_hyst) (struct thermal_zone_device *, int, int);
419 int (*get_crit_temp) (struct thermal_zone_device *, int *);
420 @@ -349,6 +359,8 @@ struct thermal_genl_event {
421 * temperature.
422 * @set_trip_temp: a pointer to a function that sets the trip temperature on
423 * hardware.
424 + * @activate_trip_type: a pointer to a function to enable/disable trip
425 + * temperature interrupts
426 */
427 struct thermal_zone_of_device_ops {
428 int (*get_temp)(void *, int *);
429 @@ -356,6 +368,8 @@ struct thermal_zone_of_device_ops {
430 int (*set_trips)(void *, int, int);
431 int (*set_emul_temp)(void *, int);
432 int (*set_trip_temp)(void *, int, int);
433 + int (*set_trip_activate)(void *, int,
434 + enum thermal_trip_activation_mode);
435 };
436
437 /**