fbdev: imsttfb: Fix use after free bug in imsttfb_probe
[linux-block.git] / drivers / thermal / rcar_gen3_thermal.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  R-Car Gen3 THS thermal sensor driver
4  *  Based on rcar_thermal.c and work from Hien Dang and Khiem Nguyen.
5  *
6  * Copyright (C) 2016 Renesas Electronics Corporation.
7  * Copyright (C) 2016 Sang Engineering
8  */
9 #include <linux/delay.h>
10 #include <linux/err.h>
11 #include <linux/interrupt.h>
12 #include <linux/io.h>
13 #include <linux/module.h>
14 #include <linux/of_device.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/thermal.h>
18
19 #include "thermal_hwmon.h"
20
21 /* Register offsets */
22 #define REG_GEN3_IRQSTR         0x04
23 #define REG_GEN3_IRQMSK         0x08
24 #define REG_GEN3_IRQCTL         0x0C
25 #define REG_GEN3_IRQEN          0x10
26 #define REG_GEN3_IRQTEMP1       0x14
27 #define REG_GEN3_IRQTEMP2       0x18
28 #define REG_GEN3_IRQTEMP3       0x1C
29 #define REG_GEN3_THCTR          0x20
30 #define REG_GEN3_TEMP           0x28
31 #define REG_GEN3_THCODE1        0x50
32 #define REG_GEN3_THCODE2        0x54
33 #define REG_GEN3_THCODE3        0x58
34 #define REG_GEN3_PTAT1          0x5c
35 #define REG_GEN3_PTAT2          0x60
36 #define REG_GEN3_PTAT3          0x64
37 #define REG_GEN3_THSCP          0x68
38
39 /* IRQ{STR,MSK,EN} bits */
40 #define IRQ_TEMP1               BIT(0)
41 #define IRQ_TEMP2               BIT(1)
42 #define IRQ_TEMP3               BIT(2)
43 #define IRQ_TEMPD1              BIT(3)
44 #define IRQ_TEMPD2              BIT(4)
45 #define IRQ_TEMPD3              BIT(5)
46
47 /* THCTR bits */
48 #define THCTR_PONM      BIT(6)
49 #define THCTR_THSST     BIT(0)
50
51 /* THSCP bits */
52 #define THSCP_COR_PARA_VLD      (BIT(15) | BIT(14))
53
54 #define CTEMP_MASK      0xFFF
55
56 #define MCELSIUS(temp)  ((temp) * 1000)
57 #define GEN3_FUSE_MASK  0xFFF
58
59 #define TSC_MAX_NUM     5
60
61 /* Structure for thermal temperature calculation */
62 struct equation_coefs {
63         int a1;
64         int b1;
65         int a2;
66         int b2;
67 };
68
69 struct rcar_gen3_thermal_tsc {
70         void __iomem *base;
71         struct thermal_zone_device *zone;
72         struct equation_coefs coef;
73         int tj_t;
74         int thcode[3];
75 };
76
77 struct rcar_gen3_thermal_priv {
78         struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM];
79         struct thermal_zone_device_ops ops;
80         unsigned int num_tscs;
81         int ptat[3];
82 };
83
84 static inline u32 rcar_gen3_thermal_read(struct rcar_gen3_thermal_tsc *tsc,
85                                          u32 reg)
86 {
87         return ioread32(tsc->base + reg);
88 }
89
90 static inline void rcar_gen3_thermal_write(struct rcar_gen3_thermal_tsc *tsc,
91                                            u32 reg, u32 data)
92 {
93         iowrite32(data, tsc->base + reg);
94 }
95
96 /*
97  * Linear approximation for temperature
98  *
99  * [reg] = [temp] * a + b => [temp] = ([reg] - b) / a
100  *
101  * The constants a and b are calculated using two triplets of int values PTAT
102  * and THCODE. PTAT and THCODE can either be read from hardware or use hard
103  * coded values from driver. The formula to calculate a and b are taken from
104  * BSP and sparsely documented and understood.
105  *
106  * Examining the linear formula and the formula used to calculate constants a
107  * and b while knowing that the span for PTAT and THCODE values are between
108  * 0x000 and 0xfff the largest integer possible is 0xfff * 0xfff == 0xffe001.
109  * Integer also needs to be signed so that leaves 7 bits for binary
110  * fixed point scaling.
111  */
112
113 #define FIXPT_SHIFT 7
114 #define FIXPT_INT(_x) ((_x) << FIXPT_SHIFT)
115 #define INT_FIXPT(_x) ((_x) >> FIXPT_SHIFT)
116 #define FIXPT_DIV(_a, _b) DIV_ROUND_CLOSEST(((_a) << FIXPT_SHIFT), (_b))
117 #define FIXPT_TO_MCELSIUS(_x) ((_x) * 1000 >> FIXPT_SHIFT)
118
119 #define RCAR3_THERMAL_GRAN 500 /* mili Celsius */
120
121 /* no idea where these constants come from */
122 #define TJ_3 -41
123
124 static void rcar_gen3_thermal_calc_coefs(struct rcar_gen3_thermal_priv *priv,
125                                          struct rcar_gen3_thermal_tsc *tsc,
126                                          int ths_tj_1)
127 {
128         /* TODO: Find documentation and document constant calculation formula */
129
130         /*
131          * Division is not scaled in BSP and if scaled it might overflow
132          * the dividend (4095 * 4095 << 14 > INT_MAX) so keep it unscaled
133          */
134         tsc->tj_t = (FIXPT_INT((priv->ptat[1] - priv->ptat[2]) * (ths_tj_1 - TJ_3))
135                      / (priv->ptat[0] - priv->ptat[2])) + FIXPT_INT(TJ_3);
136
137         tsc->coef.a1 = FIXPT_DIV(FIXPT_INT(tsc->thcode[1] - tsc->thcode[2]),
138                                  tsc->tj_t - FIXPT_INT(TJ_3));
139         tsc->coef.b1 = FIXPT_INT(tsc->thcode[2]) - tsc->coef.a1 * TJ_3;
140
141         tsc->coef.a2 = FIXPT_DIV(FIXPT_INT(tsc->thcode[1] - tsc->thcode[0]),
142                                  tsc->tj_t - FIXPT_INT(ths_tj_1));
143         tsc->coef.b2 = FIXPT_INT(tsc->thcode[0]) - tsc->coef.a2 * ths_tj_1;
144 }
145
146 static int rcar_gen3_thermal_round(int temp)
147 {
148         int result, round_offs;
149
150         round_offs = temp >= 0 ? RCAR3_THERMAL_GRAN / 2 :
151                 -RCAR3_THERMAL_GRAN / 2;
152         result = (temp + round_offs) / RCAR3_THERMAL_GRAN;
153         return result * RCAR3_THERMAL_GRAN;
154 }
155
156 static int rcar_gen3_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
157 {
158         struct rcar_gen3_thermal_tsc *tsc = thermal_zone_device_priv(tz);
159         int mcelsius, val;
160         int reg;
161
162         /* Read register and convert to mili Celsius */
163         reg = rcar_gen3_thermal_read(tsc, REG_GEN3_TEMP) & CTEMP_MASK;
164
165         if (reg <= tsc->thcode[1])
166                 val = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b1,
167                                 tsc->coef.a1);
168         else
169                 val = FIXPT_DIV(FIXPT_INT(reg) - tsc->coef.b2,
170                                 tsc->coef.a2);
171         mcelsius = FIXPT_TO_MCELSIUS(val);
172
173         /* Guaranteed operating range is -40C to 125C. */
174
175         /* Round value to device granularity setting */
176         *temp = rcar_gen3_thermal_round(mcelsius);
177
178         return 0;
179 }
180
181 static int rcar_gen3_thermal_mcelsius_to_temp(struct rcar_gen3_thermal_tsc *tsc,
182                                               int mcelsius)
183 {
184         int celsius, val;
185
186         celsius = DIV_ROUND_CLOSEST(mcelsius, 1000);
187         if (celsius <= INT_FIXPT(tsc->tj_t))
188                 val = celsius * tsc->coef.a1 + tsc->coef.b1;
189         else
190                 val = celsius * tsc->coef.a2 + tsc->coef.b2;
191
192         return INT_FIXPT(val);
193 }
194
195 static int rcar_gen3_thermal_set_trips(struct thermal_zone_device *tz, int low, int high)
196 {
197         struct rcar_gen3_thermal_tsc *tsc = thermal_zone_device_priv(tz);
198         u32 irqmsk = 0;
199
200         if (low != -INT_MAX) {
201                 irqmsk |= IRQ_TEMPD1;
202                 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP1,
203                                         rcar_gen3_thermal_mcelsius_to_temp(tsc, low));
204         }
205
206         if (high != INT_MAX) {
207                 irqmsk |= IRQ_TEMP2;
208                 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP2,
209                                         rcar_gen3_thermal_mcelsius_to_temp(tsc, high));
210         }
211
212         rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, irqmsk);
213
214         return 0;
215 }
216
217 static const struct thermal_zone_device_ops rcar_gen3_tz_of_ops = {
218         .get_temp       = rcar_gen3_thermal_get_temp,
219         .set_trips      = rcar_gen3_thermal_set_trips,
220 };
221
222 static irqreturn_t rcar_gen3_thermal_irq(int irq, void *data)
223 {
224         struct rcar_gen3_thermal_priv *priv = data;
225         unsigned int i;
226         u32 status;
227
228         for (i = 0; i < priv->num_tscs; i++) {
229                 status = rcar_gen3_thermal_read(priv->tscs[i], REG_GEN3_IRQSTR);
230                 rcar_gen3_thermal_write(priv->tscs[i], REG_GEN3_IRQSTR, 0);
231                 if (status && priv->tscs[i]->zone)
232                         thermal_zone_device_update(priv->tscs[i]->zone,
233                                                    THERMAL_EVENT_UNSPECIFIED);
234         }
235
236         return IRQ_HANDLED;
237 }
238
239 static bool rcar_gen3_thermal_read_fuses(struct rcar_gen3_thermal_priv *priv)
240 {
241         unsigned int i;
242         u32 thscp;
243
244         /* If fuses are not set, fallback to pseudo values. */
245         thscp = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_THSCP);
246         if ((thscp & THSCP_COR_PARA_VLD) != THSCP_COR_PARA_VLD) {
247                 /* Default THCODE values in case FUSEs are not set. */
248                 static const int thcodes[TSC_MAX_NUM][3] = {
249                         { 3397, 2800, 2221 },
250                         { 3393, 2795, 2216 },
251                         { 3389, 2805, 2237 },
252                         { 3415, 2694, 2195 },
253                         { 3356, 2724, 2244 },
254                 };
255
256                 priv->ptat[0] = 2631;
257                 priv->ptat[1] = 1509;
258                 priv->ptat[2] = 435;
259
260                 for (i = 0; i < priv->num_tscs; i++) {
261                         struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
262
263                         tsc->thcode[0] = thcodes[i][0];
264                         tsc->thcode[1] = thcodes[i][1];
265                         tsc->thcode[2] = thcodes[i][2];
266                 }
267
268                 return false;
269         }
270
271         /*
272          * Set the pseudo calibration points with fused values.
273          * PTAT is shared between all TSCs but only fused for the first
274          * TSC while THCODEs are fused for each TSC.
275          */
276         priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT1) &
277                 GEN3_FUSE_MASK;
278         priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT2) &
279                 GEN3_FUSE_MASK;
280         priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT3) &
281                 GEN3_FUSE_MASK;
282
283         for (i = 0; i < priv->num_tscs; i++) {
284                 struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
285
286                 tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE1) &
287                         GEN3_FUSE_MASK;
288                 tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE2) &
289                         GEN3_FUSE_MASK;
290                 tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE3) &
291                         GEN3_FUSE_MASK;
292         }
293
294         return true;
295 }
296
297 static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_priv *priv,
298                                    struct rcar_gen3_thermal_tsc *tsc)
299 {
300         u32 reg_val;
301
302         reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR);
303         reg_val &= ~THCTR_PONM;
304         rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val);
305
306         usleep_range(1000, 2000);
307
308         rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0);
309         rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, 0);
310         if (priv->ops.set_trips)
311                 rcar_gen3_thermal_write(tsc, REG_GEN3_IRQEN,
312                                         IRQ_TEMPD1 | IRQ_TEMP2);
313
314         reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR);
315         reg_val |= THCTR_THSST;
316         rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val);
317
318         usleep_range(1000, 2000);
319 }
320
321 static const int rcar_gen3_ths_tj_1 = 126;
322 static const int rcar_gen3_ths_tj_1_m3_w = 116;
323 static const struct of_device_id rcar_gen3_thermal_dt_ids[] = {
324         {
325                 .compatible = "renesas,r8a774a1-thermal",
326                 .data = &rcar_gen3_ths_tj_1_m3_w,
327         },
328         {
329                 .compatible = "renesas,r8a774b1-thermal",
330                 .data = &rcar_gen3_ths_tj_1,
331         },
332         {
333                 .compatible = "renesas,r8a774e1-thermal",
334                 .data = &rcar_gen3_ths_tj_1,
335         },
336         {
337                 .compatible = "renesas,r8a7795-thermal",
338                 .data = &rcar_gen3_ths_tj_1,
339         },
340         {
341                 .compatible = "renesas,r8a7796-thermal",
342                 .data = &rcar_gen3_ths_tj_1_m3_w,
343         },
344         {
345                 .compatible = "renesas,r8a77961-thermal",
346                 .data = &rcar_gen3_ths_tj_1_m3_w,
347         },
348         {
349                 .compatible = "renesas,r8a77965-thermal",
350                 .data = &rcar_gen3_ths_tj_1,
351         },
352         {
353                 .compatible = "renesas,r8a77980-thermal",
354                 .data = &rcar_gen3_ths_tj_1,
355         },
356         {
357                 .compatible = "renesas,r8a779a0-thermal",
358                 .data = &rcar_gen3_ths_tj_1,
359         },
360         {
361                 .compatible = "renesas,r8a779f0-thermal",
362                 .data = &rcar_gen3_ths_tj_1,
363         },
364         {
365                 .compatible = "renesas,r8a779g0-thermal",
366                 .data = &rcar_gen3_ths_tj_1,
367         },
368         {},
369 };
370 MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids);
371
372 static int rcar_gen3_thermal_remove(struct platform_device *pdev)
373 {
374         struct device *dev = &pdev->dev;
375
376         pm_runtime_put(dev);
377         pm_runtime_disable(dev);
378
379         return 0;
380 }
381
382 static void rcar_gen3_hwmon_action(void *data)
383 {
384         struct thermal_zone_device *zone = data;
385
386         thermal_remove_hwmon_sysfs(zone);
387 }
388
389 static int rcar_gen3_thermal_request_irqs(struct rcar_gen3_thermal_priv *priv,
390                                           struct platform_device *pdev)
391 {
392         struct device *dev = &pdev->dev;
393         unsigned int i;
394         char *irqname;
395         int ret, irq;
396
397         for (i = 0; i < 2; i++) {
398                 irq = platform_get_irq_optional(pdev, i);
399                 if (irq < 0)
400                         return irq;
401
402                 irqname = devm_kasprintf(dev, GFP_KERNEL, "%s:ch%d",
403                                          dev_name(dev), i);
404                 if (!irqname)
405                         return -ENOMEM;
406
407                 ret = devm_request_threaded_irq(dev, irq, NULL,
408                                                 rcar_gen3_thermal_irq,
409                                                 IRQF_ONESHOT, irqname, priv);
410                 if (ret)
411                         return ret;
412         }
413
414         return 0;
415 }
416
417 static int rcar_gen3_thermal_probe(struct platform_device *pdev)
418 {
419         struct rcar_gen3_thermal_priv *priv;
420         struct device *dev = &pdev->dev;
421         const int *ths_tj_1 = of_device_get_match_data(dev);
422         struct resource *res;
423         struct thermal_zone_device *zone;
424         unsigned int i;
425         int ret;
426
427         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
428         if (!priv)
429                 return -ENOMEM;
430
431         priv->ops = rcar_gen3_tz_of_ops;
432
433         platform_set_drvdata(pdev, priv);
434
435         if (rcar_gen3_thermal_request_irqs(priv, pdev))
436                 priv->ops.set_trips = NULL;
437
438         pm_runtime_enable(dev);
439         pm_runtime_get_sync(dev);
440
441         for (i = 0; i < TSC_MAX_NUM; i++) {
442                 struct rcar_gen3_thermal_tsc *tsc;
443
444                 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
445                 if (!res)
446                         break;
447
448                 tsc = devm_kzalloc(dev, sizeof(*tsc), GFP_KERNEL);
449                 if (!tsc) {
450                         ret = -ENOMEM;
451                         goto error_unregister;
452                 }
453
454                 tsc->base = devm_ioremap_resource(dev, res);
455                 if (IS_ERR(tsc->base)) {
456                         ret = PTR_ERR(tsc->base);
457                         goto error_unregister;
458                 }
459
460                 priv->tscs[i] = tsc;
461         }
462
463         priv->num_tscs = i;
464
465         if (!rcar_gen3_thermal_read_fuses(priv))
466                 dev_info(dev, "No calibration values fused, fallback to driver values\n");
467
468         for (i = 0; i < priv->num_tscs; i++) {
469                 struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
470
471                 rcar_gen3_thermal_init(priv, tsc);
472                 rcar_gen3_thermal_calc_coefs(priv, tsc, *ths_tj_1);
473
474                 zone = devm_thermal_of_zone_register(dev, i, tsc, &priv->ops);
475                 if (IS_ERR(zone)) {
476                         dev_err(dev, "Sensor %u: Can't register thermal zone\n", i);
477                         ret = PTR_ERR(zone);
478                         goto error_unregister;
479                 }
480                 tsc->zone = zone;
481
482                 ret = thermal_add_hwmon_sysfs(tsc->zone);
483                 if (ret)
484                         goto error_unregister;
485
486                 ret = devm_add_action_or_reset(dev, rcar_gen3_hwmon_action, zone);
487                 if (ret)
488                         goto error_unregister;
489
490                 ret = thermal_zone_get_num_trips(tsc->zone);
491                 if (ret < 0)
492                         goto error_unregister;
493
494                 dev_info(dev, "Sensor %u: Loaded %d trip points\n", i, ret);
495         }
496
497         if (!priv->num_tscs) {
498                 ret = -ENODEV;
499                 goto error_unregister;
500         }
501
502         return 0;
503
504 error_unregister:
505         rcar_gen3_thermal_remove(pdev);
506
507         return ret;
508 }
509
510 static int __maybe_unused rcar_gen3_thermal_resume(struct device *dev)
511 {
512         struct rcar_gen3_thermal_priv *priv = dev_get_drvdata(dev);
513         unsigned int i;
514
515         for (i = 0; i < priv->num_tscs; i++) {
516                 struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
517
518                 rcar_gen3_thermal_init(priv, tsc);
519         }
520
521         return 0;
522 }
523
524 static SIMPLE_DEV_PM_OPS(rcar_gen3_thermal_pm_ops, NULL,
525                          rcar_gen3_thermal_resume);
526
527 static struct platform_driver rcar_gen3_thermal_driver = {
528         .driver = {
529                 .name   = "rcar_gen3_thermal",
530                 .pm = &rcar_gen3_thermal_pm_ops,
531                 .of_match_table = rcar_gen3_thermal_dt_ids,
532         },
533         .probe          = rcar_gen3_thermal_probe,
534         .remove         = rcar_gen3_thermal_remove,
535 };
536 module_platform_driver(rcar_gen3_thermal_driver);
537
538 MODULE_LICENSE("GPL v2");
539 MODULE_DESCRIPTION("R-Car Gen3 THS thermal sensor driver");
540 MODULE_AUTHOR("Wolfram Sang <wsa+renesas@sang-engineering.com>");