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