ipq806x: refresh 4.19 patches
[oweals/openwrt.git] / target / linux / ipq806x / patches-4.19 / 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 @@ -77,7 +77,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 @@ -88,7 +88,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 @@ -174,6 +175,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 @@ -182,7 +186,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 @@ -271,7 +275,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 @@ -281,7 +287,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 @@ -289,12 +296,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 @@ -307,7 +341,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 @@ -329,7 +364,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 @@ -342,7 +378,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 @@ -417,6 +454,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 @@ -711,7 +751,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 @@ -31,7 +31,7 @@ static int tsens_get_temp(void *data, in
181  
182  static int tsens_get_trend(void *p, int trip, enum thermal_trend *trend)
183  {
184 -       const struct tsens_sensor *s = p;
185 +       struct tsens_sensor *s = p;
186         struct tsens_device *tmdev = s->tmdev;
187  
188         if (tmdev->ops->get_trend)
189 @@ -40,9 +40,10 @@ static int tsens_get_trend(void *p, int
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_device *tmdev = dev_get_drvdata(dev);
197 +       struct tsens_sensor *s = data;
198 +       struct tsens_device *tmdev = s->tmdev;
199  
200         if (tmdev->ops && tmdev->ops->suspend)
201                 return tmdev->ops->suspend(tmdev);
202 @@ -50,9 +51,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_device *tmdev = dev_get_drvdata(dev);
210 +       struct tsens_sensor *s = data;
211 +       struct tsens_device *tmdev = s->tmdev;
212  
213         if (tmdev->ops && tmdev->ops->resume)
214                 return tmdev->ops->resume(tmdev);
215 @@ -60,6 +62,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_device *tmdev = s->tmdev;
223 +
224 +       if (tmdev->ops && tmdev->ops->set_trip_temp)
225 +               return tmdev->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_device *tmdev = s->tmdev;
235 +
236 +       if (tmdev->ops && tmdev->ops->set_trip_activate)
237 +               return tmdev->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 @@ -86,6 +112,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_device *tmdev)
255 @@ -134,7 +162,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 @@ -155,6 +183,9 @@ static int tsens_probe(struct platform_d
265         tmdev->dev = dev;
266         tmdev->num_sensors = num_sensors;
267         tmdev->ops = data->ops;
268 +
269 +       tmdev->tsens_irq = platform_get_irq(pdev, 0);
270 +
271         for (i = 0;  i < tmdev->num_sensors; i++) {
272                 if (data->hw_ids)
273                         tmdev->sensor[i].hw_id = data->hw_ids[i];
274 --- a/drivers/thermal/qcom/tsens.h
275 +++ b/drivers/thermal/qcom/tsens.h
276 @@ -24,9 +24,12 @@ struct tsens_device;
277  struct tsens_sensor {
278         struct tsens_device             *tmdev;
279         struct thermal_zone_device      *tzd;
280 +       struct work_struct              notify_work;
281         int                             offset;
282         int                             id;
283         int                             hw_id;
284 +       int                             calib_data;
285 +       int                             calib_data_backup;
286         int                             slope;
287         u32                             status;
288  };
289 @@ -41,6 +44,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 @@ -53,6 +59,9 @@ struct tsens_ops {
300         int (*suspend)(struct tsens_device *);
301         int (*resume)(struct tsens_device *);
302         int (*get_trend)(struct tsens_device *, int, enum thermal_trend *);
303 +       int (*set_trip_temp)(void *, int, int);
304 +       int (*set_trip_activate)(void *, int,
305 +                                       enum thermal_trip_activation_mode);
306  };
307  
308  /**
309 @@ -76,10 +85,12 @@ struct tsens_context {
310  struct tsens_device {
311         struct device                   *dev;
312         u32                             num_sensors;
313 +       u32                             tsens_irq;
314         struct regmap                   *map;
315         u32                             tm_offset;
316         struct tsens_context            ctx;
317         const struct tsens_ops          *ops;
318 +       struct work_struct              tsens_work;
319         struct tsens_sensor             sensor[0];
320  };
321  
322 --- a/drivers/thermal/thermal_sysfs.c
323 +++ b/drivers/thermal/thermal_sysfs.c
324 @@ -113,12 +113,48 @@ trip_point_type_show(struct device *dev,
325                 return sprintf(buf, "passive\n");
326         case THERMAL_TRIP_ACTIVE:
327                 return sprintf(buf, "active\n");
328 +       case THERMAL_TRIP_CONFIGURABLE_HI:
329 +               return sprintf(buf, "configurable_hi\n");
330 +       case THERMAL_TRIP_CONFIGURABLE_LOW:
331 +               return sprintf(buf, "configurable_low\n");
332 +       case THERMAL_TRIP_CRITICAL_LOW:
333 +               return sprintf(buf, "critical_low\n");
334         default:
335                 return sprintf(buf, "unknown\n");
336         }
337  }
338  
339  static ssize_t
340 +trip_point_type_activate(struct device *dev, struct device_attribute *attr,
341 +                                               const char *buf, size_t count)
342 +{
343 +       struct thermal_zone_device *tz = to_thermal_zone(dev);
344 +       int trip, ret;
345 +       char *enabled = "enabled";
346 +       char *disabled = "disabled";
347 +
348 +       if (!tz->ops->set_trip_activate)
349 +               return -EPERM;
350 +
351 +       if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip))
352 +               return -EINVAL;
353 +
354 +       if (!strncmp(buf, enabled, strlen(enabled)))
355 +               ret = tz->ops->set_trip_activate(tz, trip,
356 +                               THERMAL_TRIP_ACTIVATION_ENABLED);
357 +       else if (!strncmp(buf, disabled, strlen(disabled)))
358 +               ret = tz->ops->set_trip_activate(tz, trip,
359 +                               THERMAL_TRIP_ACTIVATION_DISABLED);
360 +       else
361 +               ret = -EINVAL;
362 +
363 +       if (ret)
364 +               return ret;
365 +
366 +       return count;
367 +}
368 +
369 +static ssize_t
370  trip_point_temp_store(struct device *dev, struct device_attribute *attr,
371                       const char *buf, size_t count)
372  {
373 @@ -559,6 +595,12 @@ static int create_trip_attrs(struct ther
374                 tz->trip_type_attrs[indx].attr.show = trip_point_type_show;
375                 attrs[indx] = &tz->trip_type_attrs[indx].attr.attr;
376  
377 +               if (IS_ENABLED(CONFIG_THERMAL_WRITABLE_TRIPS)) {
378 +                       tz->trip_type_attrs[indx].attr.store
379 +                                               = trip_point_type_activate;
380 +                       tz->trip_type_attrs[indx].attr.attr.mode |= S_IWUSR;
381 +               }
382 +
383                 /* create trip temp attribute */
384                 snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH,
385                          "trip_point_%d_temp", indx);
386 --- a/include/linux/thermal.h
387 +++ b/include/linux/thermal.h
388 @@ -63,11 +63,19 @@ enum thermal_device_mode {
389         THERMAL_DEVICE_ENABLED,
390  };
391  
392 +enum thermal_trip_activation_mode {
393 +       THERMAL_TRIP_ACTIVATION_DISABLED = 0,
394 +       THERMAL_TRIP_ACTIVATION_ENABLED,
395 +};
396 +
397  enum thermal_trip_type {
398         THERMAL_TRIP_ACTIVE = 0,
399         THERMAL_TRIP_PASSIVE,
400         THERMAL_TRIP_HOT,
401         THERMAL_TRIP_CRITICAL,
402 +       THERMAL_TRIP_CONFIGURABLE_HI,
403 +       THERMAL_TRIP_CONFIGURABLE_LOW,
404 +       THERMAL_TRIP_CRITICAL_LOW,
405  };
406  
407  enum thermal_trend {
408 @@ -105,6 +113,8 @@ struct thermal_zone_device_ops {
409                 enum thermal_trip_type *);
410         int (*get_trip_temp) (struct thermal_zone_device *, int, int *);
411         int (*set_trip_temp) (struct thermal_zone_device *, int, int);
412 +       int (*set_trip_activate) (struct thermal_zone_device *, int,
413 +                                       enum thermal_trip_activation_mode);
414         int (*get_trip_hyst) (struct thermal_zone_device *, int, int *);
415         int (*set_trip_hyst) (struct thermal_zone_device *, int, int);
416         int (*get_crit_temp) (struct thermal_zone_device *, int *);
417 @@ -349,6 +359,8 @@ struct thermal_genl_event {
418   *                temperature.
419   * @set_trip_temp: a pointer to a function that sets the trip temperature on
420   *                hardware.
421 + * @activate_trip_type: a pointer to a function to enable/disable trip
422 + *             temperature interrupts
423   */
424  struct thermal_zone_of_device_ops {
425         int (*get_temp)(void *, int *);
426 @@ -356,6 +368,8 @@ struct thermal_zone_of_device_ops {
427         int (*set_trips)(void *, int, int);
428         int (*set_emul_temp)(void *, int);
429         int (*set_trip_temp)(void *, int, int);
430 +       int (*set_trip_activate)(void *, int,
431 +                               enum thermal_trip_activation_mode);
432  };
433  
434  /**