hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/thermal/qcom/tsens.c
....@@ -1,61 +1,894 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 and
6
- * only version 2 as published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
12
- *
4
+ * Copyright (c) 2019, 2020, Linaro Ltd.
135 */
146
7
+#include <linux/debugfs.h>
158 #include <linux/err.h>
9
+#include <linux/io.h>
1610 #include <linux/module.h>
11
+#include <linux/nvmem-consumer.h>
1712 #include <linux/of.h>
13
+#include <linux/of_address.h>
14
+#include <linux/of_platform.h>
1815 #include <linux/platform_device.h>
1916 #include <linux/pm.h>
17
+#include <linux/regmap.h>
2018 #include <linux/slab.h>
2119 #include <linux/thermal.h>
2220 #include "tsens.h"
2321
24
-static int tsens_get_temp(void *data, int *temp)
25
-{
26
- const struct tsens_sensor *s = data;
27
- struct tsens_device *tmdev = s->tmdev;
22
+/**
23
+ * struct tsens_irq_data - IRQ status and temperature violations
24
+ * @up_viol: upper threshold violated
25
+ * @up_thresh: upper threshold temperature value
26
+ * @up_irq_mask: mask register for upper threshold irqs
27
+ * @up_irq_clear: clear register for uppper threshold irqs
28
+ * @low_viol: lower threshold violated
29
+ * @low_thresh: lower threshold temperature value
30
+ * @low_irq_mask: mask register for lower threshold irqs
31
+ * @low_irq_clear: clear register for lower threshold irqs
32
+ * @crit_viol: critical threshold violated
33
+ * @crit_thresh: critical threshold temperature value
34
+ * @crit_irq_mask: mask register for critical threshold irqs
35
+ * @crit_irq_clear: clear register for critical threshold irqs
36
+ *
37
+ * Structure containing data about temperature threshold settings and
38
+ * irq status if they were violated.
39
+ */
40
+struct tsens_irq_data {
41
+ u32 up_viol;
42
+ int up_thresh;
43
+ u32 up_irq_mask;
44
+ u32 up_irq_clear;
45
+ u32 low_viol;
46
+ int low_thresh;
47
+ u32 low_irq_mask;
48
+ u32 low_irq_clear;
49
+ u32 crit_viol;
50
+ u32 crit_thresh;
51
+ u32 crit_irq_mask;
52
+ u32 crit_irq_clear;
53
+};
2854
29
- return tmdev->ops->get_temp(tmdev, s->id, temp);
55
+char *qfprom_read(struct device *dev, const char *cname)
56
+{
57
+ struct nvmem_cell *cell;
58
+ ssize_t data;
59
+ char *ret;
60
+
61
+ cell = nvmem_cell_get(dev, cname);
62
+ if (IS_ERR(cell))
63
+ return ERR_CAST(cell);
64
+
65
+ ret = nvmem_cell_read(cell, &data);
66
+ nvmem_cell_put(cell);
67
+
68
+ return ret;
3069 }
3170
32
-static int tsens_get_trend(void *p, int trip, enum thermal_trend *trend)
71
+/*
72
+ * Use this function on devices where slope and offset calculations
73
+ * depend on calibration data read from qfprom. On others the slope
74
+ * and offset values are derived from tz->tzp->slope and tz->tzp->offset
75
+ * resp.
76
+ */
77
+void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
78
+ u32 *p2, u32 mode)
3379 {
34
- const struct tsens_sensor *s = p;
35
- struct tsens_device *tmdev = s->tmdev;
80
+ int i;
81
+ int num, den;
3682
37
- if (tmdev->ops->get_trend)
38
- return tmdev->ops->get_trend(tmdev, s->id, trend);
83
+ for (i = 0; i < priv->num_sensors; i++) {
84
+ dev_dbg(priv->dev,
85
+ "%s: sensor%d - data_point1:%#x data_point2:%#x\n",
86
+ __func__, i, p1[i], p2[i]);
87
+
88
+ priv->sensor[i].slope = SLOPE_DEFAULT;
89
+ if (mode == TWO_PT_CALIB) {
90
+ /*
91
+ * slope (m) = adc_code2 - adc_code1 (y2 - y1)/
92
+ * temp_120_degc - temp_30_degc (x2 - x1)
93
+ */
94
+ num = p2[i] - p1[i];
95
+ num *= SLOPE_FACTOR;
96
+ den = CAL_DEGC_PT2 - CAL_DEGC_PT1;
97
+ priv->sensor[i].slope = num / den;
98
+ }
99
+
100
+ priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
101
+ (CAL_DEGC_PT1 *
102
+ priv->sensor[i].slope);
103
+ dev_dbg(priv->dev, "%s: offset:%d\n", __func__,
104
+ priv->sensor[i].offset);
105
+ }
106
+}
107
+
108
+static inline u32 degc_to_code(int degc, const struct tsens_sensor *s)
109
+{
110
+ u64 code = div_u64(((u64)degc * s->slope + s->offset), SLOPE_FACTOR);
111
+
112
+ pr_debug("%s: raw_code: 0x%llx, degc:%d\n", __func__, code, degc);
113
+ return clamp_val(code, THRESHOLD_MIN_ADC_CODE, THRESHOLD_MAX_ADC_CODE);
114
+}
115
+
116
+static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
117
+{
118
+ int degc, num, den;
119
+
120
+ num = (adc_code * SLOPE_FACTOR) - s->offset;
121
+ den = s->slope;
122
+
123
+ if (num > 0)
124
+ degc = num + (den / 2);
125
+ else if (num < 0)
126
+ degc = num - (den / 2);
127
+ else
128
+ degc = num;
129
+
130
+ degc /= den;
131
+
132
+ return degc;
133
+}
134
+
135
+/**
136
+ * tsens_hw_to_mC - Return sign-extended temperature in mCelsius.
137
+ * @s: Pointer to sensor struct
138
+ * @field: Index into regmap_field array pointing to temperature data
139
+ *
140
+ * This function handles temperature returned in ADC code or deciCelsius
141
+ * depending on IP version.
142
+ *
143
+ * Return: Temperature in milliCelsius on success, a negative errno will
144
+ * be returned in error cases
145
+ */
146
+static int tsens_hw_to_mC(const struct tsens_sensor *s, int field)
147
+{
148
+ struct tsens_priv *priv = s->priv;
149
+ u32 resolution;
150
+ u32 temp = 0;
151
+ int ret;
152
+
153
+ resolution = priv->fields[LAST_TEMP_0].msb -
154
+ priv->fields[LAST_TEMP_0].lsb;
155
+
156
+ ret = regmap_field_read(priv->rf[field], &temp);
157
+ if (ret)
158
+ return ret;
159
+
160
+ /* Convert temperature from ADC code to milliCelsius */
161
+ if (priv->feat->adc)
162
+ return code_to_degc(temp, s) * 1000;
163
+
164
+ /* deciCelsius -> milliCelsius along with sign extension */
165
+ return sign_extend32(temp, resolution) * 100;
166
+}
167
+
168
+/**
169
+ * tsens_mC_to_hw - Convert temperature to hardware register value
170
+ * @s: Pointer to sensor struct
171
+ * @temp: temperature in milliCelsius to be programmed to hardware
172
+ *
173
+ * This function outputs the value to be written to hardware in ADC code
174
+ * or deciCelsius depending on IP version.
175
+ *
176
+ * Return: ADC code or temperature in deciCelsius.
177
+ */
178
+static int tsens_mC_to_hw(const struct tsens_sensor *s, int temp)
179
+{
180
+ struct tsens_priv *priv = s->priv;
181
+
182
+ /* milliC to adc code */
183
+ if (priv->feat->adc)
184
+ return degc_to_code(temp / 1000, s);
185
+
186
+ /* milliC to deciC */
187
+ return temp / 100;
188
+}
189
+
190
+static inline enum tsens_ver tsens_version(struct tsens_priv *priv)
191
+{
192
+ return priv->feat->ver_major;
193
+}
194
+
195
+static void tsens_set_interrupt_v1(struct tsens_priv *priv, u32 hw_id,
196
+ enum tsens_irq_type irq_type, bool enable)
197
+{
198
+ u32 index = 0;
199
+
200
+ switch (irq_type) {
201
+ case UPPER:
202
+ index = UP_INT_CLEAR_0 + hw_id;
203
+ break;
204
+ case LOWER:
205
+ index = LOW_INT_CLEAR_0 + hw_id;
206
+ break;
207
+ case CRITICAL:
208
+ /* No critical interrupts before v2 */
209
+ return;
210
+ }
211
+ regmap_field_write(priv->rf[index], enable ? 0 : 1);
212
+}
213
+
214
+static void tsens_set_interrupt_v2(struct tsens_priv *priv, u32 hw_id,
215
+ enum tsens_irq_type irq_type, bool enable)
216
+{
217
+ u32 index_mask = 0, index_clear = 0;
218
+
219
+ /*
220
+ * To enable the interrupt flag for a sensor:
221
+ * - clear the mask bit
222
+ * To disable the interrupt flag for a sensor:
223
+ * - Mask further interrupts for this sensor
224
+ * - Write 1 followed by 0 to clear the interrupt
225
+ */
226
+ switch (irq_type) {
227
+ case UPPER:
228
+ index_mask = UP_INT_MASK_0 + hw_id;
229
+ index_clear = UP_INT_CLEAR_0 + hw_id;
230
+ break;
231
+ case LOWER:
232
+ index_mask = LOW_INT_MASK_0 + hw_id;
233
+ index_clear = LOW_INT_CLEAR_0 + hw_id;
234
+ break;
235
+ case CRITICAL:
236
+ index_mask = CRIT_INT_MASK_0 + hw_id;
237
+ index_clear = CRIT_INT_CLEAR_0 + hw_id;
238
+ break;
239
+ }
240
+
241
+ if (enable) {
242
+ regmap_field_write(priv->rf[index_mask], 0);
243
+ } else {
244
+ regmap_field_write(priv->rf[index_mask], 1);
245
+ regmap_field_write(priv->rf[index_clear], 1);
246
+ regmap_field_write(priv->rf[index_clear], 0);
247
+ }
248
+}
249
+
250
+/**
251
+ * tsens_set_interrupt - Set state of an interrupt
252
+ * @priv: Pointer to tsens controller private data
253
+ * @hw_id: Hardware ID aka. sensor number
254
+ * @irq_type: irq_type from enum tsens_irq_type
255
+ * @enable: false = disable, true = enable
256
+ *
257
+ * Call IP-specific function to set state of an interrupt
258
+ *
259
+ * Return: void
260
+ */
261
+static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id,
262
+ enum tsens_irq_type irq_type, bool enable)
263
+{
264
+ dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__,
265
+ irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW",
266
+ enable ? "en" : "dis");
267
+ if (tsens_version(priv) > VER_1_X)
268
+ tsens_set_interrupt_v2(priv, hw_id, irq_type, enable);
269
+ else
270
+ tsens_set_interrupt_v1(priv, hw_id, irq_type, enable);
271
+}
272
+
273
+/**
274
+ * tsens_threshold_violated - Check if a sensor temperature violated a preset threshold
275
+ * @priv: Pointer to tsens controller private data
276
+ * @hw_id: Hardware ID aka. sensor number
277
+ * @d: Pointer to irq state data
278
+ *
279
+ * Return: 0 if threshold was not violated, 1 if it was violated and negative
280
+ * errno in case of errors
281
+ */
282
+static int tsens_threshold_violated(struct tsens_priv *priv, u32 hw_id,
283
+ struct tsens_irq_data *d)
284
+{
285
+ int ret;
286
+
287
+ ret = regmap_field_read(priv->rf[UPPER_STATUS_0 + hw_id], &d->up_viol);
288
+ if (ret)
289
+ return ret;
290
+ ret = regmap_field_read(priv->rf[LOWER_STATUS_0 + hw_id], &d->low_viol);
291
+ if (ret)
292
+ return ret;
293
+
294
+ if (priv->feat->crit_int) {
295
+ ret = regmap_field_read(priv->rf[CRITICAL_STATUS_0 + hw_id],
296
+ &d->crit_viol);
297
+ if (ret)
298
+ return ret;
299
+ }
300
+
301
+ if (d->up_viol || d->low_viol || d->crit_viol)
302
+ return 1;
303
+
304
+ return 0;
305
+}
306
+
307
+static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,
308
+ const struct tsens_sensor *s,
309
+ struct tsens_irq_data *d)
310
+{
311
+ int ret;
312
+
313
+ ret = regmap_field_read(priv->rf[UP_INT_CLEAR_0 + hw_id], &d->up_irq_clear);
314
+ if (ret)
315
+ return ret;
316
+ ret = regmap_field_read(priv->rf[LOW_INT_CLEAR_0 + hw_id], &d->low_irq_clear);
317
+ if (ret)
318
+ return ret;
319
+ if (tsens_version(priv) > VER_1_X) {
320
+ ret = regmap_field_read(priv->rf[UP_INT_MASK_0 + hw_id], &d->up_irq_mask);
321
+ if (ret)
322
+ return ret;
323
+ ret = regmap_field_read(priv->rf[LOW_INT_MASK_0 + hw_id], &d->low_irq_mask);
324
+ if (ret)
325
+ return ret;
326
+ ret = regmap_field_read(priv->rf[CRIT_INT_CLEAR_0 + hw_id],
327
+ &d->crit_irq_clear);
328
+ if (ret)
329
+ return ret;
330
+ ret = regmap_field_read(priv->rf[CRIT_INT_MASK_0 + hw_id],
331
+ &d->crit_irq_mask);
332
+ if (ret)
333
+ return ret;
334
+
335
+ d->crit_thresh = tsens_hw_to_mC(s, CRIT_THRESH_0 + hw_id);
336
+ } else {
337
+ /* No mask register on older TSENS */
338
+ d->up_irq_mask = 0;
339
+ d->low_irq_mask = 0;
340
+ d->crit_irq_clear = 0;
341
+ d->crit_irq_mask = 0;
342
+ d->crit_thresh = 0;
343
+ }
344
+
345
+ d->up_thresh = tsens_hw_to_mC(s, UP_THRESH_0 + hw_id);
346
+ d->low_thresh = tsens_hw_to_mC(s, LOW_THRESH_0 + hw_id);
347
+
348
+ dev_dbg(priv->dev, "[%u] %s%s: status(%u|%u|%u) | clr(%u|%u|%u) | mask(%u|%u|%u)\n",
349
+ hw_id, __func__,
350
+ (d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",
351
+ d->low_viol, d->up_viol, d->crit_viol,
352
+ d->low_irq_clear, d->up_irq_clear, d->crit_irq_clear,
353
+ d->low_irq_mask, d->up_irq_mask, d->crit_irq_mask);
354
+ dev_dbg(priv->dev, "[%u] %s%s: thresh: (%d:%d:%d)\n", hw_id, __func__,
355
+ (d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",
356
+ d->low_thresh, d->up_thresh, d->crit_thresh);
357
+
358
+ return 0;
359
+}
360
+
361
+static inline u32 masked_irq(u32 hw_id, u32 mask, enum tsens_ver ver)
362
+{
363
+ if (ver > VER_1_X)
364
+ return mask & (1 << hw_id);
365
+
366
+ /* v1, v0.1 don't have a irq mask register */
367
+ return 0;
368
+}
369
+
370
+/**
371
+ * tsens_critical_irq_thread() - Threaded handler for critical interrupts
372
+ * @irq: irq number
373
+ * @data: tsens controller private data
374
+ *
375
+ * Check FSM watchdog bark status and clear if needed.
376
+ * Check all sensors to find ones that violated their critical threshold limits.
377
+ * Clear and then re-enable the interrupt.
378
+ *
379
+ * The level-triggered interrupt might deassert if the temperature returned to
380
+ * within the threshold limits by the time the handler got scheduled. We
381
+ * consider the irq to have been handled in that case.
382
+ *
383
+ * Return: IRQ_HANDLED
384
+ */
385
+static irqreturn_t tsens_critical_irq_thread(int irq, void *data)
386
+{
387
+ struct tsens_priv *priv = data;
388
+ struct tsens_irq_data d;
389
+ int temp, ret, i;
390
+ u32 wdog_status, wdog_count;
391
+
392
+ if (priv->feat->has_watchdog) {
393
+ ret = regmap_field_read(priv->rf[WDOG_BARK_STATUS],
394
+ &wdog_status);
395
+ if (ret)
396
+ return ret;
397
+
398
+ if (wdog_status) {
399
+ /* Clear WDOG interrupt */
400
+ regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 1);
401
+ regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 0);
402
+ ret = regmap_field_read(priv->rf[WDOG_BARK_COUNT],
403
+ &wdog_count);
404
+ if (ret)
405
+ return ret;
406
+ if (wdog_count)
407
+ dev_dbg(priv->dev, "%s: watchdog count: %d\n",
408
+ __func__, wdog_count);
409
+
410
+ /* Fall through to handle critical interrupts if any */
411
+ }
412
+ }
413
+
414
+ for (i = 0; i < priv->num_sensors; i++) {
415
+ const struct tsens_sensor *s = &priv->sensor[i];
416
+ u32 hw_id = s->hw_id;
417
+
418
+ if (!s->tzd)
419
+ continue;
420
+ if (!tsens_threshold_violated(priv, hw_id, &d))
421
+ continue;
422
+ ret = get_temp_tsens_valid(s, &temp);
423
+ if (ret) {
424
+ dev_err(priv->dev, "[%u] %s: error reading sensor\n",
425
+ hw_id, __func__);
426
+ continue;
427
+ }
428
+
429
+ tsens_read_irq_state(priv, hw_id, s, &d);
430
+ if (d.crit_viol &&
431
+ !masked_irq(hw_id, d.crit_irq_mask, tsens_version(priv))) {
432
+ /* Mask critical interrupts, unused on Linux */
433
+ tsens_set_interrupt(priv, hw_id, CRITICAL, false);
434
+ }
435
+ }
436
+
437
+ return IRQ_HANDLED;
438
+}
439
+
440
+/**
441
+ * tsens_irq_thread - Threaded interrupt handler for uplow interrupts
442
+ * @irq: irq number
443
+ * @data: tsens controller private data
444
+ *
445
+ * Check all sensors to find ones that violated their threshold limits. If the
446
+ * temperature is still outside the limits, call thermal_zone_device_update() to
447
+ * update the thresholds, else re-enable the interrupts.
448
+ *
449
+ * The level-triggered interrupt might deassert if the temperature returned to
450
+ * within the threshold limits by the time the handler got scheduled. We
451
+ * consider the irq to have been handled in that case.
452
+ *
453
+ * Return: IRQ_HANDLED
454
+ */
455
+static irqreturn_t tsens_irq_thread(int irq, void *data)
456
+{
457
+ struct tsens_priv *priv = data;
458
+ struct tsens_irq_data d;
459
+ bool enable = true, disable = false;
460
+ unsigned long flags;
461
+ int temp, ret, i;
462
+
463
+ for (i = 0; i < priv->num_sensors; i++) {
464
+ bool trigger = false;
465
+ const struct tsens_sensor *s = &priv->sensor[i];
466
+ u32 hw_id = s->hw_id;
467
+
468
+ if (!s->tzd)
469
+ continue;
470
+ if (!tsens_threshold_violated(priv, hw_id, &d))
471
+ continue;
472
+ ret = get_temp_tsens_valid(s, &temp);
473
+ if (ret) {
474
+ dev_err(priv->dev, "[%u] %s: error reading sensor\n",
475
+ hw_id, __func__);
476
+ continue;
477
+ }
478
+
479
+ spin_lock_irqsave(&priv->ul_lock, flags);
480
+
481
+ tsens_read_irq_state(priv, hw_id, s, &d);
482
+
483
+ if (d.up_viol &&
484
+ !masked_irq(hw_id, d.up_irq_mask, tsens_version(priv))) {
485
+ tsens_set_interrupt(priv, hw_id, UPPER, disable);
486
+ if (d.up_thresh > temp) {
487
+ dev_dbg(priv->dev, "[%u] %s: re-arm upper\n",
488
+ hw_id, __func__);
489
+ tsens_set_interrupt(priv, hw_id, UPPER, enable);
490
+ } else {
491
+ trigger = true;
492
+ /* Keep irq masked */
493
+ }
494
+ } else if (d.low_viol &&
495
+ !masked_irq(hw_id, d.low_irq_mask, tsens_version(priv))) {
496
+ tsens_set_interrupt(priv, hw_id, LOWER, disable);
497
+ if (d.low_thresh < temp) {
498
+ dev_dbg(priv->dev, "[%u] %s: re-arm low\n",
499
+ hw_id, __func__);
500
+ tsens_set_interrupt(priv, hw_id, LOWER, enable);
501
+ } else {
502
+ trigger = true;
503
+ /* Keep irq masked */
504
+ }
505
+ }
506
+
507
+ spin_unlock_irqrestore(&priv->ul_lock, flags);
508
+
509
+ if (trigger) {
510
+ dev_dbg(priv->dev, "[%u] %s: TZ update trigger (%d mC)\n",
511
+ hw_id, __func__, temp);
512
+ thermal_zone_device_update(s->tzd,
513
+ THERMAL_EVENT_UNSPECIFIED);
514
+ } else {
515
+ dev_dbg(priv->dev, "[%u] %s: no violation: %d\n",
516
+ hw_id, __func__, temp);
517
+ }
518
+ }
519
+
520
+ return IRQ_HANDLED;
521
+}
522
+
523
+static int tsens_set_trips(void *_sensor, int low, int high)
524
+{
525
+ struct tsens_sensor *s = _sensor;
526
+ struct tsens_priv *priv = s->priv;
527
+ struct device *dev = priv->dev;
528
+ struct tsens_irq_data d;
529
+ unsigned long flags;
530
+ int high_val, low_val, cl_high, cl_low;
531
+ u32 hw_id = s->hw_id;
532
+
533
+ dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",
534
+ hw_id, __func__, low, high);
535
+
536
+ cl_high = clamp_val(high, -40000, 120000);
537
+ cl_low = clamp_val(low, -40000, 120000);
538
+
539
+ high_val = tsens_mC_to_hw(s, cl_high);
540
+ low_val = tsens_mC_to_hw(s, cl_low);
541
+
542
+ spin_lock_irqsave(&priv->ul_lock, flags);
543
+
544
+ tsens_read_irq_state(priv, hw_id, s, &d);
545
+
546
+ /* Write the new thresholds and clear the status */
547
+ regmap_field_write(priv->rf[LOW_THRESH_0 + hw_id], low_val);
548
+ regmap_field_write(priv->rf[UP_THRESH_0 + hw_id], high_val);
549
+ tsens_set_interrupt(priv, hw_id, LOWER, true);
550
+ tsens_set_interrupt(priv, hw_id, UPPER, true);
551
+
552
+ spin_unlock_irqrestore(&priv->ul_lock, flags);
553
+
554
+ dev_dbg(dev, "[%u] %s: (%d:%d)->(%d:%d)\n",
555
+ hw_id, __func__, d.low_thresh, d.up_thresh, cl_low, cl_high);
556
+
557
+ return 0;
558
+}
559
+
560
+static int tsens_enable_irq(struct tsens_priv *priv)
561
+{
562
+ int ret;
563
+ int val = tsens_version(priv) > VER_1_X ? 7 : 1;
564
+
565
+ ret = regmap_field_write(priv->rf[INT_EN], val);
566
+ if (ret < 0)
567
+ dev_err(priv->dev, "%s: failed to enable interrupts\n",
568
+ __func__);
569
+
570
+ return ret;
571
+}
572
+
573
+static void tsens_disable_irq(struct tsens_priv *priv)
574
+{
575
+ regmap_field_write(priv->rf[INT_EN], 0);
576
+}
577
+
578
+int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)
579
+{
580
+ struct tsens_priv *priv = s->priv;
581
+ int hw_id = s->hw_id;
582
+ u32 temp_idx = LAST_TEMP_0 + hw_id;
583
+ u32 valid_idx = VALID_0 + hw_id;
584
+ u32 valid;
585
+ int ret;
586
+
587
+ ret = regmap_field_read(priv->rf[valid_idx], &valid);
588
+ if (ret)
589
+ return ret;
590
+ while (!valid) {
591
+ /* Valid bit is 0 for 6 AHB clock cycles.
592
+ * At 19.2MHz, 1 AHB clock is ~60ns.
593
+ * We should enter this loop very, very rarely.
594
+ */
595
+ ndelay(400);
596
+ ret = regmap_field_read(priv->rf[valid_idx], &valid);
597
+ if (ret)
598
+ return ret;
599
+ }
600
+
601
+ /* Valid bit is set, OK to read the temperature */
602
+ *temp = tsens_hw_to_mC(s, temp_idx);
603
+
604
+ return 0;
605
+}
606
+
607
+int get_temp_common(const struct tsens_sensor *s, int *temp)
608
+{
609
+ struct tsens_priv *priv = s->priv;
610
+ int hw_id = s->hw_id;
611
+ int last_temp = 0, ret;
612
+
613
+ ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp);
614
+ if (ret)
615
+ return ret;
616
+
617
+ *temp = code_to_degc(last_temp, s) * 1000;
618
+
619
+ return 0;
620
+}
621
+
622
+#ifdef CONFIG_DEBUG_FS
623
+static int dbg_sensors_show(struct seq_file *s, void *data)
624
+{
625
+ struct platform_device *pdev = s->private;
626
+ struct tsens_priv *priv = platform_get_drvdata(pdev);
627
+ int i;
628
+
629
+ seq_printf(s, "max: %2d\nnum: %2d\n\n",
630
+ priv->feat->max_sensors, priv->num_sensors);
631
+
632
+ seq_puts(s, " id slope offset\n--------------------------\n");
633
+ for (i = 0; i < priv->num_sensors; i++) {
634
+ seq_printf(s, "%8d %8d %8d\n", priv->sensor[i].hw_id,
635
+ priv->sensor[i].slope, priv->sensor[i].offset);
636
+ }
637
+
638
+ return 0;
639
+}
640
+
641
+static int dbg_version_show(struct seq_file *s, void *data)
642
+{
643
+ struct platform_device *pdev = s->private;
644
+ struct tsens_priv *priv = platform_get_drvdata(pdev);
645
+ u32 maj_ver, min_ver, step_ver;
646
+ int ret;
647
+
648
+ if (tsens_version(priv) > VER_0_1) {
649
+ ret = regmap_field_read(priv->rf[VER_MAJOR], &maj_ver);
650
+ if (ret)
651
+ return ret;
652
+ ret = regmap_field_read(priv->rf[VER_MINOR], &min_ver);
653
+ if (ret)
654
+ return ret;
655
+ ret = regmap_field_read(priv->rf[VER_STEP], &step_ver);
656
+ if (ret)
657
+ return ret;
658
+ seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver);
659
+ } else {
660
+ seq_puts(s, "0.1.0\n");
661
+ }
662
+
663
+ return 0;
664
+}
665
+
666
+DEFINE_SHOW_ATTRIBUTE(dbg_version);
667
+DEFINE_SHOW_ATTRIBUTE(dbg_sensors);
668
+
669
+static void tsens_debug_init(struct platform_device *pdev)
670
+{
671
+ struct tsens_priv *priv = platform_get_drvdata(pdev);
672
+ struct dentry *root, *file;
673
+
674
+ root = debugfs_lookup("tsens", NULL);
675
+ if (!root)
676
+ priv->debug_root = debugfs_create_dir("tsens", NULL);
677
+ else
678
+ priv->debug_root = root;
679
+
680
+ file = debugfs_lookup("version", priv->debug_root);
681
+ if (!file)
682
+ debugfs_create_file("version", 0444, priv->debug_root,
683
+ pdev, &dbg_version_fops);
684
+
685
+ /* A directory for each instance of the TSENS IP */
686
+ priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root);
687
+ debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops);
688
+}
689
+#else
690
+static inline void tsens_debug_init(struct platform_device *pdev) {}
691
+#endif
692
+
693
+static const struct regmap_config tsens_config = {
694
+ .name = "tm",
695
+ .reg_bits = 32,
696
+ .val_bits = 32,
697
+ .reg_stride = 4,
698
+};
699
+
700
+static const struct regmap_config tsens_srot_config = {
701
+ .name = "srot",
702
+ .reg_bits = 32,
703
+ .val_bits = 32,
704
+ .reg_stride = 4,
705
+};
706
+
707
+int __init init_common(struct tsens_priv *priv)
708
+{
709
+ void __iomem *tm_base, *srot_base;
710
+ struct device *dev = priv->dev;
711
+ u32 ver_minor;
712
+ struct resource *res;
713
+ u32 enabled;
714
+ int ret, i, j;
715
+ struct platform_device *op = of_find_device_by_node(priv->dev->of_node);
716
+
717
+ if (!op)
718
+ return -EINVAL;
719
+
720
+ if (op->num_resources > 1) {
721
+ /* DT with separate SROT and TM address space */
722
+ priv->tm_offset = 0;
723
+ res = platform_get_resource(op, IORESOURCE_MEM, 1);
724
+ srot_base = devm_ioremap_resource(dev, res);
725
+ if (IS_ERR(srot_base)) {
726
+ ret = PTR_ERR(srot_base);
727
+ goto err_put_device;
728
+ }
729
+
730
+ priv->srot_map = devm_regmap_init_mmio(dev, srot_base,
731
+ &tsens_srot_config);
732
+ if (IS_ERR(priv->srot_map)) {
733
+ ret = PTR_ERR(priv->srot_map);
734
+ goto err_put_device;
735
+ }
736
+ } else {
737
+ /* old DTs where SROT and TM were in a contiguous 2K block */
738
+ priv->tm_offset = 0x1000;
739
+ }
740
+
741
+ res = platform_get_resource(op, IORESOURCE_MEM, 0);
742
+ tm_base = devm_ioremap_resource(dev, res);
743
+ if (IS_ERR(tm_base)) {
744
+ ret = PTR_ERR(tm_base);
745
+ goto err_put_device;
746
+ }
747
+
748
+ priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);
749
+ if (IS_ERR(priv->tm_map)) {
750
+ ret = PTR_ERR(priv->tm_map);
751
+ goto err_put_device;
752
+ }
753
+
754
+ if (tsens_version(priv) > VER_0_1) {
755
+ for (i = VER_MAJOR; i <= VER_STEP; i++) {
756
+ priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,
757
+ priv->fields[i]);
758
+ if (IS_ERR(priv->rf[i])) {
759
+ ret = PTR_ERR(priv->rf[i]);
760
+ goto err_put_device;
761
+ }
762
+ }
763
+ ret = regmap_field_read(priv->rf[VER_MINOR], &ver_minor);
764
+ if (ret)
765
+ goto err_put_device;
766
+ }
767
+
768
+ priv->rf[TSENS_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
769
+ priv->fields[TSENS_EN]);
770
+ if (IS_ERR(priv->rf[TSENS_EN])) {
771
+ ret = PTR_ERR(priv->rf[TSENS_EN]);
772
+ goto err_put_device;
773
+ }
774
+ ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
775
+ if (ret)
776
+ goto err_put_device;
777
+ if (!enabled) {
778
+ dev_err(dev, "%s: device not enabled\n", __func__);
779
+ ret = -ENODEV;
780
+ goto err_put_device;
781
+ }
782
+
783
+ priv->rf[SENSOR_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
784
+ priv->fields[SENSOR_EN]);
785
+ if (IS_ERR(priv->rf[SENSOR_EN])) {
786
+ ret = PTR_ERR(priv->rf[SENSOR_EN]);
787
+ goto err_put_device;
788
+ }
789
+ priv->rf[INT_EN] = devm_regmap_field_alloc(dev, priv->tm_map,
790
+ priv->fields[INT_EN]);
791
+ if (IS_ERR(priv->rf[INT_EN])) {
792
+ ret = PTR_ERR(priv->rf[INT_EN]);
793
+ goto err_put_device;
794
+ }
795
+
796
+ /* This loop might need changes if enum regfield_ids is reordered */
797
+ for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) {
798
+ for (i = 0; i < priv->feat->max_sensors; i++) {
799
+ int idx = j + i;
800
+
801
+ priv->rf[idx] = devm_regmap_field_alloc(dev,
802
+ priv->tm_map,
803
+ priv->fields[idx]);
804
+ if (IS_ERR(priv->rf[idx])) {
805
+ ret = PTR_ERR(priv->rf[idx]);
806
+ goto err_put_device;
807
+ }
808
+ }
809
+ }
810
+
811
+ if (priv->feat->crit_int) {
812
+ /* Loop might need changes if enum regfield_ids is reordered */
813
+ for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) {
814
+ for (i = 0; i < priv->feat->max_sensors; i++) {
815
+ int idx = j + i;
816
+
817
+ priv->rf[idx] =
818
+ devm_regmap_field_alloc(dev,
819
+ priv->tm_map,
820
+ priv->fields[idx]);
821
+ if (IS_ERR(priv->rf[idx])) {
822
+ ret = PTR_ERR(priv->rf[idx]);
823
+ goto err_put_device;
824
+ }
825
+ }
826
+ }
827
+ }
828
+
829
+ if (tsens_version(priv) > VER_1_X && ver_minor > 2) {
830
+ /* Watchdog is present only on v2.3+ */
831
+ priv->feat->has_watchdog = 1;
832
+ for (i = WDOG_BARK_STATUS; i <= CC_MON_MASK; i++) {
833
+ priv->rf[i] = devm_regmap_field_alloc(dev, priv->tm_map,
834
+ priv->fields[i]);
835
+ if (IS_ERR(priv->rf[i])) {
836
+ ret = PTR_ERR(priv->rf[i]);
837
+ goto err_put_device;
838
+ }
839
+ }
840
+ /*
841
+ * Watchdog is already enabled, unmask the bark.
842
+ * Disable cycle completion monitoring
843
+ */
844
+ regmap_field_write(priv->rf[WDOG_BARK_MASK], 0);
845
+ regmap_field_write(priv->rf[CC_MON_MASK], 1);
846
+ }
847
+
848
+ spin_lock_init(&priv->ul_lock);
849
+ tsens_enable_irq(priv);
850
+ tsens_debug_init(op);
851
+
852
+err_put_device:
853
+ put_device(&op->dev);
854
+ return ret;
855
+}
856
+
857
+static int tsens_get_temp(void *data, int *temp)
858
+{
859
+ struct tsens_sensor *s = data;
860
+ struct tsens_priv *priv = s->priv;
861
+
862
+ return priv->ops->get_temp(s, temp);
863
+}
864
+
865
+static int tsens_get_trend(void *data, int trip, enum thermal_trend *trend)
866
+{
867
+ struct tsens_sensor *s = data;
868
+ struct tsens_priv *priv = s->priv;
869
+
870
+ if (priv->ops->get_trend)
871
+ return priv->ops->get_trend(s, trend);
39872
40873 return -ENOTSUPP;
41874 }
42875
43876 static int __maybe_unused tsens_suspend(struct device *dev)
44877 {
45
- struct tsens_device *tmdev = dev_get_drvdata(dev);
878
+ struct tsens_priv *priv = dev_get_drvdata(dev);
46879
47
- if (tmdev->ops && tmdev->ops->suspend)
48
- return tmdev->ops->suspend(tmdev);
880
+ if (priv->ops && priv->ops->suspend)
881
+ return priv->ops->suspend(priv);
49882
50883 return 0;
51884 }
52885
53886 static int __maybe_unused tsens_resume(struct device *dev)
54887 {
55
- struct tsens_device *tmdev = dev_get_drvdata(dev);
888
+ struct tsens_priv *priv = dev_get_drvdata(dev);
56889
57
- if (tmdev->ops && tmdev->ops->resume)
58
- return tmdev->ops->resume(tmdev);
890
+ if (priv->ops && priv->ops->resume)
891
+ return priv->ops->resume(priv);
59892
60893 return 0;
61894 }
....@@ -67,11 +900,26 @@
67900 .compatible = "qcom,msm8916-tsens",
68901 .data = &data_8916,
69902 }, {
903
+ .compatible = "qcom,msm8939-tsens",
904
+ .data = &data_8939,
905
+ }, {
906
+ .compatible = "qcom,msm8956-tsens",
907
+ .data = &data_8956,
908
+ }, {
909
+ .compatible = "qcom,msm8960-tsens",
910
+ .data = &data_8960,
911
+ }, {
70912 .compatible = "qcom,msm8974-tsens",
71913 .data = &data_8974,
72914 }, {
915
+ .compatible = "qcom,msm8976-tsens",
916
+ .data = &data_8976,
917
+ }, {
73918 .compatible = "qcom,msm8996-tsens",
74919 .data = &data_8996,
920
+ }, {
921
+ .compatible = "qcom,tsens-v1",
922
+ .data = &data_tsens_v1,
75923 }, {
76924 .compatible = "qcom,tsens-v2",
77925 .data = &data_tsens_v2,
....@@ -83,31 +931,67 @@
83931 static const struct thermal_zone_of_device_ops tsens_of_ops = {
84932 .get_temp = tsens_get_temp,
85933 .get_trend = tsens_get_trend,
934
+ .set_trips = tsens_set_trips,
86935 };
87936
88
-static int tsens_register(struct tsens_device *tmdev)
937
+static int tsens_register_irq(struct tsens_priv *priv, char *irqname,
938
+ irq_handler_t thread_fn)
89939 {
90
- int i;
940
+ struct platform_device *pdev;
941
+ int ret, irq;
942
+
943
+ pdev = of_find_device_by_node(priv->dev->of_node);
944
+ if (!pdev)
945
+ return -ENODEV;
946
+
947
+ irq = platform_get_irq_byname(pdev, irqname);
948
+ if (irq < 0) {
949
+ ret = irq;
950
+ /* For old DTs with no IRQ defined */
951
+ if (irq == -ENXIO)
952
+ ret = 0;
953
+ } else {
954
+ ret = devm_request_threaded_irq(&pdev->dev, irq,
955
+ NULL, thread_fn,
956
+ IRQF_ONESHOT,
957
+ dev_name(&pdev->dev), priv);
958
+ if (ret)
959
+ dev_err(&pdev->dev, "%s: failed to get irq\n",
960
+ __func__);
961
+ else
962
+ enable_irq_wake(irq);
963
+ }
964
+
965
+ put_device(&pdev->dev);
966
+ return ret;
967
+}
968
+
969
+static int tsens_register(struct tsens_priv *priv)
970
+{
971
+ int i, ret;
91972 struct thermal_zone_device *tzd;
92
- u32 *hw_id, n = tmdev->num_sensors;
93973
94
- hw_id = devm_kcalloc(tmdev->dev, n, sizeof(u32), GFP_KERNEL);
95
- if (!hw_id)
96
- return -ENOMEM;
97
-
98
- for (i = 0; i < tmdev->num_sensors; i++) {
99
- tmdev->sensor[i].tmdev = tmdev;
100
- tmdev->sensor[i].id = i;
101
- tzd = devm_thermal_zone_of_sensor_register(tmdev->dev, i,
102
- &tmdev->sensor[i],
974
+ for (i = 0; i < priv->num_sensors; i++) {
975
+ priv->sensor[i].priv = priv;
976
+ tzd = devm_thermal_zone_of_sensor_register(priv->dev, priv->sensor[i].hw_id,
977
+ &priv->sensor[i],
103978 &tsens_of_ops);
104979 if (IS_ERR(tzd))
105980 continue;
106
- tmdev->sensor[i].tzd = tzd;
107
- if (tmdev->ops->enable)
108
- tmdev->ops->enable(tmdev, i);
981
+ priv->sensor[i].tzd = tzd;
982
+ if (priv->ops->enable)
983
+ priv->ops->enable(priv, i);
109984 }
110
- return 0;
985
+
986
+ ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);
987
+ if (ret < 0)
988
+ return ret;
989
+
990
+ if (priv->feat->crit_int)
991
+ ret = tsens_register_irq(priv, "critical",
992
+ tsens_critical_irq_thread);
993
+
994
+ return ret;
111995 }
112996
113997 static int tsens_probe(struct platform_device *pdev)
....@@ -115,8 +999,8 @@
115999 int ret, i;
1161000 struct device *dev;
1171001 struct device_node *np;
118
- struct tsens_device *tmdev;
119
- const struct tsens_data *data;
1002
+ struct tsens_priv *priv;
1003
+ const struct tsens_plat_data *data;
1201004 const struct of_device_id *id;
1211005 u32 num_sensors;
1221006
....@@ -139,57 +1023,59 @@
1391023 of_property_read_u32(np, "#qcom,sensors", &num_sensors);
1401024
1411025 if (num_sensors <= 0) {
142
- dev_err(dev, "invalid number of sensors\n");
1026
+ dev_err(dev, "%s: invalid number of sensors\n", __func__);
1431027 return -EINVAL;
1441028 }
1451029
146
- tmdev = devm_kzalloc(dev,
147
- struct_size(tmdev, sensor, num_sensors),
1030
+ priv = devm_kzalloc(dev,
1031
+ struct_size(priv, sensor, num_sensors),
1481032 GFP_KERNEL);
149
- if (!tmdev)
1033
+ if (!priv)
1501034 return -ENOMEM;
1511035
152
- tmdev->dev = dev;
153
- tmdev->num_sensors = num_sensors;
154
- tmdev->ops = data->ops;
155
- for (i = 0; i < tmdev->num_sensors; i++) {
1036
+ priv->dev = dev;
1037
+ priv->num_sensors = num_sensors;
1038
+ priv->ops = data->ops;
1039
+ for (i = 0; i < priv->num_sensors; i++) {
1561040 if (data->hw_ids)
157
- tmdev->sensor[i].hw_id = data->hw_ids[i];
1041
+ priv->sensor[i].hw_id = data->hw_ids[i];
1581042 else
159
- tmdev->sensor[i].hw_id = i;
1043
+ priv->sensor[i].hw_id = i;
1601044 }
1045
+ priv->feat = data->feat;
1046
+ priv->fields = data->fields;
1611047
162
- if (!tmdev->ops || !tmdev->ops->init || !tmdev->ops->get_temp)
1048
+ platform_set_drvdata(pdev, priv);
1049
+
1050
+ if (!priv->ops || !priv->ops->init || !priv->ops->get_temp)
1631051 return -EINVAL;
1641052
165
- ret = tmdev->ops->init(tmdev);
1053
+ ret = priv->ops->init(priv);
1661054 if (ret < 0) {
167
- dev_err(dev, "tsens init failed\n");
1055
+ dev_err(dev, "%s: init failed\n", __func__);
1681056 return ret;
1691057 }
1701058
171
- if (tmdev->ops->calibrate) {
172
- ret = tmdev->ops->calibrate(tmdev);
1059
+ if (priv->ops->calibrate) {
1060
+ ret = priv->ops->calibrate(priv);
1731061 if (ret < 0) {
1741062 if (ret != -EPROBE_DEFER)
175
- dev_err(dev, "tsens calibration failed\n");
1063
+ dev_err(dev, "%s: calibration failed\n", __func__);
1761064 return ret;
1771065 }
1781066 }
1791067
180
- ret = tsens_register(tmdev);
181
-
182
- platform_set_drvdata(pdev, tmdev);
183
-
184
- return ret;
1068
+ return tsens_register(priv);
1851069 }
1861070
1871071 static int tsens_remove(struct platform_device *pdev)
1881072 {
189
- struct tsens_device *tmdev = platform_get_drvdata(pdev);
1073
+ struct tsens_priv *priv = platform_get_drvdata(pdev);
1901074
191
- if (tmdev->ops->disable)
192
- tmdev->ops->disable(tmdev);
1075
+ debugfs_remove_recursive(priv->debug_root);
1076
+ tsens_disable_irq(priv);
1077
+ if (priv->ops->disable)
1078
+ priv->ops->disable(priv);
1931079
1941080 return 0;
1951081 }