]> Git Repo - J-linux.git/blob - drivers/thermal/qcom/tsens.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[J-linux.git] / drivers / thermal / qcom / tsens.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2015, The Linux Foundation. All rights reserved.
4  * Copyright (c) 2019, 2020, Linaro Ltd.
5  */
6
7 #include <linux/debugfs.h>
8 #include <linux/err.h>
9 #include <linux/io.h>
10 #include <linux/module.h>
11 #include <linux/nvmem-consumer.h>
12 #include <linux/of.h>
13 #include <linux/of_address.h>
14 #include <linux/of_platform.h>
15 #include <linux/mfd/syscon.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm.h>
18 #include <linux/regmap.h>
19 #include <linux/slab.h>
20 #include <linux/thermal.h>
21 #include "../thermal_hwmon.h"
22 #include "tsens.h"
23
24 /**
25  * struct tsens_irq_data - IRQ status and temperature violations
26  * @up_viol:        upper threshold violated
27  * @up_thresh:      upper threshold temperature value
28  * @up_irq_mask:    mask register for upper threshold irqs
29  * @up_irq_clear:   clear register for uppper threshold irqs
30  * @low_viol:       lower threshold violated
31  * @low_thresh:     lower threshold temperature value
32  * @low_irq_mask:   mask register for lower threshold irqs
33  * @low_irq_clear:  clear register for lower threshold irqs
34  * @crit_viol:      critical threshold violated
35  * @crit_thresh:    critical threshold temperature value
36  * @crit_irq_mask:  mask register for critical threshold irqs
37  * @crit_irq_clear: clear register for critical threshold irqs
38  *
39  * Structure containing data about temperature threshold settings and
40  * irq status if they were violated.
41  */
42 struct tsens_irq_data {
43         u32 up_viol;
44         int up_thresh;
45         u32 up_irq_mask;
46         u32 up_irq_clear;
47         u32 low_viol;
48         int low_thresh;
49         u32 low_irq_mask;
50         u32 low_irq_clear;
51         u32 crit_viol;
52         u32 crit_thresh;
53         u32 crit_irq_mask;
54         u32 crit_irq_clear;
55 };
56
57 char *qfprom_read(struct device *dev, const char *cname)
58 {
59         struct nvmem_cell *cell;
60         ssize_t data;
61         char *ret;
62
63         cell = nvmem_cell_get(dev, cname);
64         if (IS_ERR(cell))
65                 return ERR_CAST(cell);
66
67         ret = nvmem_cell_read(cell, &data);
68         nvmem_cell_put(cell);
69
70         return ret;
71 }
72
73 int tsens_read_calibration(struct tsens_priv *priv, int shift, u32 *p1, u32 *p2, bool backup)
74 {
75         u32 mode;
76         u32 base1, base2;
77         char name[] = "sXX_pY_backup"; /* s10_p1_backup */
78         int i, ret;
79
80         if (priv->num_sensors > MAX_SENSORS)
81                 return -EINVAL;
82
83         ret = snprintf(name, sizeof(name), "mode%s", backup ? "_backup" : "");
84         if (ret < 0)
85                 return ret;
86
87         ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &mode);
88         if (ret == -ENOENT)
89                 dev_warn(priv->dev, "Please migrate to separate nvmem cells for calibration data\n");
90         if (ret < 0)
91                 return ret;
92
93         dev_dbg(priv->dev, "calibration mode is %d\n", mode);
94
95         ret = snprintf(name, sizeof(name), "base1%s", backup ? "_backup" : "");
96         if (ret < 0)
97                 return ret;
98
99         ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &base1);
100         if (ret < 0)
101                 return ret;
102
103         ret = snprintf(name, sizeof(name), "base2%s", backup ? "_backup" : "");
104         if (ret < 0)
105                 return ret;
106
107         ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &base2);
108         if (ret < 0)
109                 return ret;
110
111         for (i = 0; i < priv->num_sensors; i++) {
112                 ret = snprintf(name, sizeof(name), "s%d_p1%s", priv->sensor[i].hw_id,
113                                backup ? "_backup" : "");
114                 if (ret < 0)
115                         return ret;
116
117                 ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p1[i]);
118                 if (ret)
119                         return ret;
120
121                 ret = snprintf(name, sizeof(name), "s%d_p2%s", priv->sensor[i].hw_id,
122                                backup ? "_backup" : "");
123                 if (ret < 0)
124                         return ret;
125
126                 ret = nvmem_cell_read_variable_le_u32(priv->dev, name, &p2[i]);
127                 if (ret)
128                         return ret;
129         }
130
131         switch (mode) {
132         case ONE_PT_CALIB:
133                 for (i = 0; i < priv->num_sensors; i++)
134                         p1[i] = p1[i] + (base1 << shift);
135                 break;
136         case TWO_PT_CALIB:
137                 for (i = 0; i < priv->num_sensors; i++)
138                         p2[i] = (p2[i] + base2) << shift;
139                 fallthrough;
140         case ONE_PT_CALIB2:
141                 for (i = 0; i < priv->num_sensors; i++)
142                         p1[i] = (p1[i] + base1) << shift;
143                 break;
144         default:
145                 dev_dbg(priv->dev, "calibrationless mode\n");
146                 for (i = 0; i < priv->num_sensors; i++) {
147                         p1[i] = 500;
148                         p2[i] = 780;
149                 }
150         }
151
152         return mode;
153 }
154
155 int tsens_calibrate_nvmem(struct tsens_priv *priv, int shift)
156 {
157         u32 p1[MAX_SENSORS], p2[MAX_SENSORS];
158         int mode;
159
160         mode = tsens_read_calibration(priv, shift, p1, p2, false);
161         if (mode < 0)
162                 return mode;
163
164         compute_intercept_slope(priv, p1, p2, mode);
165
166         return 0;
167 }
168
169 int tsens_calibrate_common(struct tsens_priv *priv)
170 {
171         return tsens_calibrate_nvmem(priv, 2);
172 }
173
174 static u32 tsens_read_cell(const struct tsens_single_value *cell, u8 len, u32 *data0, u32 *data1)
175 {
176         u32 val;
177         u32 *data = cell->blob ? data1 : data0;
178
179         if (cell->shift + len <= 32) {
180                 val = data[cell->idx] >> cell->shift;
181         } else {
182                 u8 part = 32 - cell->shift;
183
184                 val = data[cell->idx] >> cell->shift;
185                 val |= data[cell->idx + 1] << part;
186         }
187
188         return val & ((1 << len) - 1);
189 }
190
191 int tsens_read_calibration_legacy(struct tsens_priv *priv,
192                                   const struct tsens_legacy_calibration_format *format,
193                                   u32 *p1, u32 *p2,
194                                   u32 *cdata0, u32 *cdata1)
195 {
196         u32 mode, invalid;
197         u32 base1, base2;
198         int i;
199
200         mode = tsens_read_cell(&format->mode, 2, cdata0, cdata1);
201         invalid = tsens_read_cell(&format->invalid, 1, cdata0, cdata1);
202         if (invalid)
203                 mode = NO_PT_CALIB;
204         dev_dbg(priv->dev, "calibration mode is %d\n", mode);
205
206         base1 = tsens_read_cell(&format->base[0], format->base_len, cdata0, cdata1);
207         base2 = tsens_read_cell(&format->base[1], format->base_len, cdata0, cdata1);
208
209         for (i = 0; i < priv->num_sensors; i++) {
210                 p1[i] = tsens_read_cell(&format->sp[i][0], format->sp_len, cdata0, cdata1);
211                 p2[i] = tsens_read_cell(&format->sp[i][1], format->sp_len, cdata0, cdata1);
212         }
213
214         switch (mode) {
215         case ONE_PT_CALIB:
216                 for (i = 0; i < priv->num_sensors; i++)
217                         p1[i] = p1[i] + (base1 << format->base_shift);
218                 break;
219         case TWO_PT_CALIB:
220                 for (i = 0; i < priv->num_sensors; i++)
221                         p2[i] = (p2[i] + base2) << format->base_shift;
222                 fallthrough;
223         case ONE_PT_CALIB2:
224                 for (i = 0; i < priv->num_sensors; i++)
225                         p1[i] = (p1[i] + base1) << format->base_shift;
226                 break;
227         default:
228                 dev_dbg(priv->dev, "calibrationless mode\n");
229                 for (i = 0; i < priv->num_sensors; i++) {
230                         p1[i] = 500;
231                         p2[i] = 780;
232                 }
233         }
234
235         return mode;
236 }
237
238 /*
239  * Use this function on devices where slope and offset calculations
240  * depend on calibration data read from qfprom. On others the slope
241  * and offset values are derived from tz->tzp->slope and tz->tzp->offset
242  * resp.
243  */
244 void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
245                              u32 *p2, u32 mode)
246 {
247         int i;
248         int num, den;
249
250         for (i = 0; i < priv->num_sensors; i++) {
251                 dev_dbg(priv->dev,
252                         "%s: sensor%d - data_point1:%#x data_point2:%#x\n",
253                         __func__, i, p1[i], p2[i]);
254
255                 if (!priv->sensor[i].slope)
256                         priv->sensor[i].slope = SLOPE_DEFAULT;
257                 if (mode == TWO_PT_CALIB) {
258                         /*
259                          * slope (m) = adc_code2 - adc_code1 (y2 - y1)/
260                          *      temp_120_degc - temp_30_degc (x2 - x1)
261                          */
262                         num = p2[i] - p1[i];
263                         num *= SLOPE_FACTOR;
264                         den = CAL_DEGC_PT2 - CAL_DEGC_PT1;
265                         priv->sensor[i].slope = num / den;
266                 }
267
268                 priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
269                                 (CAL_DEGC_PT1 *
270                                 priv->sensor[i].slope);
271                 dev_dbg(priv->dev, "%s: offset:%d\n", __func__,
272                         priv->sensor[i].offset);
273         }
274 }
275
276 static inline u32 degc_to_code(int degc, const struct tsens_sensor *s)
277 {
278         u64 code = div_u64(((u64)degc * s->slope + s->offset), SLOPE_FACTOR);
279
280         pr_debug("%s: raw_code: 0x%llx, degc:%d\n", __func__, code, degc);
281         return clamp_val(code, THRESHOLD_MIN_ADC_CODE, THRESHOLD_MAX_ADC_CODE);
282 }
283
284 static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
285 {
286         int degc, num, den;
287
288         num = (adc_code * SLOPE_FACTOR) - s->offset;
289         den = s->slope;
290
291         if (num > 0)
292                 degc = num + (den / 2);
293         else if (num < 0)
294                 degc = num - (den / 2);
295         else
296                 degc = num;
297
298         degc /= den;
299
300         return degc;
301 }
302
303 /**
304  * tsens_hw_to_mC - Return sign-extended temperature in mCelsius.
305  * @s:     Pointer to sensor struct
306  * @field: Index into regmap_field array pointing to temperature data
307  *
308  * This function handles temperature returned in ADC code or deciCelsius
309  * depending on IP version.
310  *
311  * Return: Temperature in milliCelsius on success, a negative errno will
312  * be returned in error cases
313  */
314 static int tsens_hw_to_mC(const struct tsens_sensor *s, int field)
315 {
316         struct tsens_priv *priv = s->priv;
317         u32 resolution;
318         u32 temp = 0;
319         int ret;
320
321         resolution = priv->fields[LAST_TEMP_0].msb -
322                 priv->fields[LAST_TEMP_0].lsb;
323
324         ret = regmap_field_read(priv->rf[field], &temp);
325         if (ret)
326                 return ret;
327
328         /* Convert temperature from ADC code to milliCelsius */
329         if (priv->feat->adc)
330                 return code_to_degc(temp, s) * 1000;
331
332         /* deciCelsius -> milliCelsius along with sign extension */
333         return sign_extend32(temp, resolution) * 100;
334 }
335
336 /**
337  * tsens_mC_to_hw - Convert temperature to hardware register value
338  * @s: Pointer to sensor struct
339  * @temp: temperature in milliCelsius to be programmed to hardware
340  *
341  * This function outputs the value to be written to hardware in ADC code
342  * or deciCelsius depending on IP version.
343  *
344  * Return: ADC code or temperature in deciCelsius.
345  */
346 static int tsens_mC_to_hw(const struct tsens_sensor *s, int temp)
347 {
348         struct tsens_priv *priv = s->priv;
349
350         /* milliC to adc code */
351         if (priv->feat->adc)
352                 return degc_to_code(temp / 1000, s);
353
354         /* milliC to deciC */
355         return temp / 100;
356 }
357
358 static inline enum tsens_ver tsens_version(struct tsens_priv *priv)
359 {
360         return priv->feat->ver_major;
361 }
362
363 static void tsens_set_interrupt_v1(struct tsens_priv *priv, u32 hw_id,
364                                    enum tsens_irq_type irq_type, bool enable)
365 {
366         u32 index = 0;
367
368         switch (irq_type) {
369         case UPPER:
370                 index = UP_INT_CLEAR_0 + hw_id;
371                 break;
372         case LOWER:
373                 index = LOW_INT_CLEAR_0 + hw_id;
374                 break;
375         case CRITICAL:
376                 /* No critical interrupts before v2 */
377                 return;
378         }
379         regmap_field_write(priv->rf[index], enable ? 0 : 1);
380 }
381
382 static void tsens_set_interrupt_v2(struct tsens_priv *priv, u32 hw_id,
383                                    enum tsens_irq_type irq_type, bool enable)
384 {
385         u32 index_mask = 0, index_clear = 0;
386
387         /*
388          * To enable the interrupt flag for a sensor:
389          *    - clear the mask bit
390          * To disable the interrupt flag for a sensor:
391          *    - Mask further interrupts for this sensor
392          *    - Write 1 followed by 0 to clear the interrupt
393          */
394         switch (irq_type) {
395         case UPPER:
396                 index_mask  = UP_INT_MASK_0 + hw_id;
397                 index_clear = UP_INT_CLEAR_0 + hw_id;
398                 break;
399         case LOWER:
400                 index_mask  = LOW_INT_MASK_0 + hw_id;
401                 index_clear = LOW_INT_CLEAR_0 + hw_id;
402                 break;
403         case CRITICAL:
404                 index_mask  = CRIT_INT_MASK_0 + hw_id;
405                 index_clear = CRIT_INT_CLEAR_0 + hw_id;
406                 break;
407         }
408
409         if (enable) {
410                 regmap_field_write(priv->rf[index_mask], 0);
411         } else {
412                 regmap_field_write(priv->rf[index_mask],  1);
413                 regmap_field_write(priv->rf[index_clear], 1);
414                 regmap_field_write(priv->rf[index_clear], 0);
415         }
416 }
417
418 /**
419  * tsens_set_interrupt - Set state of an interrupt
420  * @priv: Pointer to tsens controller private data
421  * @hw_id: Hardware ID aka. sensor number
422  * @irq_type: irq_type from enum tsens_irq_type
423  * @enable: false = disable, true = enable
424  *
425  * Call IP-specific function to set state of an interrupt
426  *
427  * Return: void
428  */
429 static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id,
430                                 enum tsens_irq_type irq_type, bool enable)
431 {
432         dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__,
433                 irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW",
434                 enable ? "en" : "dis");
435         if (tsens_version(priv) > VER_1_X)
436                 tsens_set_interrupt_v2(priv, hw_id, irq_type, enable);
437         else
438                 tsens_set_interrupt_v1(priv, hw_id, irq_type, enable);
439 }
440
441 /**
442  * tsens_threshold_violated - Check if a sensor temperature violated a preset threshold
443  * @priv: Pointer to tsens controller private data
444  * @hw_id: Hardware ID aka. sensor number
445  * @d: Pointer to irq state data
446  *
447  * Return: 0 if threshold was not violated, 1 if it was violated and negative
448  * errno in case of errors
449  */
450 static int tsens_threshold_violated(struct tsens_priv *priv, u32 hw_id,
451                                     struct tsens_irq_data *d)
452 {
453         int ret;
454
455         ret = regmap_field_read(priv->rf[UPPER_STATUS_0 + hw_id], &d->up_viol);
456         if (ret)
457                 return ret;
458         ret = regmap_field_read(priv->rf[LOWER_STATUS_0 + hw_id], &d->low_viol);
459         if (ret)
460                 return ret;
461
462         if (priv->feat->crit_int) {
463                 ret = regmap_field_read(priv->rf[CRITICAL_STATUS_0 + hw_id],
464                                         &d->crit_viol);
465                 if (ret)
466                         return ret;
467         }
468
469         if (d->up_viol || d->low_viol || d->crit_viol)
470                 return 1;
471
472         return 0;
473 }
474
475 static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id,
476                                 const struct tsens_sensor *s,
477                                 struct tsens_irq_data *d)
478 {
479         int ret;
480
481         ret = regmap_field_read(priv->rf[UP_INT_CLEAR_0 + hw_id], &d->up_irq_clear);
482         if (ret)
483                 return ret;
484         ret = regmap_field_read(priv->rf[LOW_INT_CLEAR_0 + hw_id], &d->low_irq_clear);
485         if (ret)
486                 return ret;
487         if (tsens_version(priv) > VER_1_X) {
488                 ret = regmap_field_read(priv->rf[UP_INT_MASK_0 + hw_id], &d->up_irq_mask);
489                 if (ret)
490                         return ret;
491                 ret = regmap_field_read(priv->rf[LOW_INT_MASK_0 + hw_id], &d->low_irq_mask);
492                 if (ret)
493                         return ret;
494                 ret = regmap_field_read(priv->rf[CRIT_INT_CLEAR_0 + hw_id],
495                                         &d->crit_irq_clear);
496                 if (ret)
497                         return ret;
498                 ret = regmap_field_read(priv->rf[CRIT_INT_MASK_0 + hw_id],
499                                         &d->crit_irq_mask);
500                 if (ret)
501                         return ret;
502
503                 d->crit_thresh = tsens_hw_to_mC(s, CRIT_THRESH_0 + hw_id);
504         } else {
505                 /* No mask register on older TSENS */
506                 d->up_irq_mask = 0;
507                 d->low_irq_mask = 0;
508                 d->crit_irq_clear = 0;
509                 d->crit_irq_mask = 0;
510                 d->crit_thresh = 0;
511         }
512
513         d->up_thresh  = tsens_hw_to_mC(s, UP_THRESH_0 + hw_id);
514         d->low_thresh = tsens_hw_to_mC(s, LOW_THRESH_0 + hw_id);
515
516         dev_dbg(priv->dev, "[%u] %s%s: status(%u|%u|%u) | clr(%u|%u|%u) | mask(%u|%u|%u)\n",
517                 hw_id, __func__,
518                 (d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",
519                 d->low_viol, d->up_viol, d->crit_viol,
520                 d->low_irq_clear, d->up_irq_clear, d->crit_irq_clear,
521                 d->low_irq_mask, d->up_irq_mask, d->crit_irq_mask);
522         dev_dbg(priv->dev, "[%u] %s%s: thresh: (%d:%d:%d)\n", hw_id, __func__,
523                 (d->up_viol || d->low_viol || d->crit_viol) ? "(V)" : "",
524                 d->low_thresh, d->up_thresh, d->crit_thresh);
525
526         return 0;
527 }
528
529 static inline u32 masked_irq(u32 hw_id, u32 mask, enum tsens_ver ver)
530 {
531         if (ver > VER_1_X)
532                 return mask & (1 << hw_id);
533
534         /* v1, v0.1 don't have a irq mask register */
535         return 0;
536 }
537
538 /**
539  * tsens_critical_irq_thread() - Threaded handler for critical interrupts
540  * @irq: irq number
541  * @data: tsens controller private data
542  *
543  * Check FSM watchdog bark status and clear if needed.
544  * Check all sensors to find ones that violated their critical threshold limits.
545  * Clear and then re-enable the interrupt.
546  *
547  * The level-triggered interrupt might deassert if the temperature returned to
548  * within the threshold limits by the time the handler got scheduled. We
549  * consider the irq to have been handled in that case.
550  *
551  * Return: IRQ_HANDLED
552  */
553 static irqreturn_t tsens_critical_irq_thread(int irq, void *data)
554 {
555         struct tsens_priv *priv = data;
556         struct tsens_irq_data d;
557         int temp, ret, i;
558         u32 wdog_status, wdog_count;
559
560         if (priv->feat->has_watchdog) {
561                 ret = regmap_field_read(priv->rf[WDOG_BARK_STATUS],
562                                         &wdog_status);
563                 if (ret)
564                         return ret;
565
566                 if (wdog_status) {
567                         /* Clear WDOG interrupt */
568                         regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 1);
569                         regmap_field_write(priv->rf[WDOG_BARK_CLEAR], 0);
570                         ret = regmap_field_read(priv->rf[WDOG_BARK_COUNT],
571                                                 &wdog_count);
572                         if (ret)
573                                 return ret;
574                         if (wdog_count)
575                                 dev_dbg(priv->dev, "%s: watchdog count: %d\n",
576                                         __func__, wdog_count);
577
578                         /* Fall through to handle critical interrupts if any */
579                 }
580         }
581
582         for (i = 0; i < priv->num_sensors; i++) {
583                 const struct tsens_sensor *s = &priv->sensor[i];
584                 u32 hw_id = s->hw_id;
585
586                 if (!s->tzd)
587                         continue;
588                 if (!tsens_threshold_violated(priv, hw_id, &d))
589                         continue;
590                 ret = get_temp_tsens_valid(s, &temp);
591                 if (ret) {
592                         dev_err(priv->dev, "[%u] %s: error reading sensor\n",
593                                 hw_id, __func__);
594                         continue;
595                 }
596
597                 tsens_read_irq_state(priv, hw_id, s, &d);
598                 if (d.crit_viol &&
599                     !masked_irq(hw_id, d.crit_irq_mask, tsens_version(priv))) {
600                         /* Mask critical interrupts, unused on Linux */
601                         tsens_set_interrupt(priv, hw_id, CRITICAL, false);
602                 }
603         }
604
605         return IRQ_HANDLED;
606 }
607
608 /**
609  * tsens_irq_thread - Threaded interrupt handler for uplow interrupts
610  * @irq: irq number
611  * @data: tsens controller private data
612  *
613  * Check all sensors to find ones that violated their threshold limits. If the
614  * temperature is still outside the limits, call thermal_zone_device_update() to
615  * update the thresholds, else re-enable the interrupts.
616  *
617  * The level-triggered interrupt might deassert if the temperature returned to
618  * within the threshold limits by the time the handler got scheduled. We
619  * consider the irq to have been handled in that case.
620  *
621  * Return: IRQ_HANDLED
622  */
623 static irqreturn_t tsens_irq_thread(int irq, void *data)
624 {
625         struct tsens_priv *priv = data;
626         struct tsens_irq_data d;
627         int i;
628
629         for (i = 0; i < priv->num_sensors; i++) {
630                 const struct tsens_sensor *s = &priv->sensor[i];
631                 u32 hw_id = s->hw_id;
632
633                 if (!s->tzd)
634                         continue;
635                 if (!tsens_threshold_violated(priv, hw_id, &d))
636                         continue;
637
638                 thermal_zone_device_update(s->tzd, THERMAL_EVENT_UNSPECIFIED);
639
640                 if (tsens_version(priv) < VER_0_1) {
641                         /* Constraint: There is only 1 interrupt control register for all
642                          * 11 temperature sensor. So monitoring more than 1 sensor based
643                          * on interrupts will yield inconsistent result. To overcome this
644                          * issue we will monitor only sensor 0 which is the master sensor.
645                          */
646                         break;
647                 }
648         }
649
650         return IRQ_HANDLED;
651 }
652
653 /**
654  * tsens_combined_irq_thread() - Threaded interrupt handler for combined interrupts
655  * @irq: irq number
656  * @data: tsens controller private data
657  *
658  * Handle the combined interrupt as if it were 2 separate interrupts, so call the
659  * critical handler first and then the up/low one.
660  *
661  * Return: IRQ_HANDLED
662  */
663 static irqreturn_t tsens_combined_irq_thread(int irq, void *data)
664 {
665         irqreturn_t ret;
666
667         ret = tsens_critical_irq_thread(irq, data);
668         if (ret != IRQ_HANDLED)
669                 return ret;
670
671         return tsens_irq_thread(irq, data);
672 }
673
674 static int tsens_set_trips(struct thermal_zone_device *tz, int low, int high)
675 {
676         struct tsens_sensor *s = thermal_zone_device_priv(tz);
677         struct tsens_priv *priv = s->priv;
678         struct device *dev = priv->dev;
679         struct tsens_irq_data d;
680         unsigned long flags;
681         int high_val, low_val, cl_high, cl_low;
682         u32 hw_id = s->hw_id;
683
684         if (tsens_version(priv) < VER_0_1) {
685                 /* Pre v0.1 IP had a single register for each type of interrupt
686                  * and thresholds
687                  */
688                 hw_id = 0;
689         }
690
691         dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",
692                 hw_id, __func__, low, high);
693
694         cl_high = clamp_val(high, priv->feat->trip_min_temp, priv->feat->trip_max_temp);
695         cl_low  = clamp_val(low, priv->feat->trip_min_temp, priv->feat->trip_max_temp);
696
697         high_val = tsens_mC_to_hw(s, cl_high);
698         low_val  = tsens_mC_to_hw(s, cl_low);
699
700         spin_lock_irqsave(&priv->ul_lock, flags);
701
702         tsens_read_irq_state(priv, hw_id, s, &d);
703
704         /* Write the new thresholds and clear the status */
705         regmap_field_write(priv->rf[LOW_THRESH_0 + hw_id], low_val);
706         regmap_field_write(priv->rf[UP_THRESH_0 + hw_id], high_val);
707         tsens_set_interrupt(priv, hw_id, LOWER, true);
708         tsens_set_interrupt(priv, hw_id, UPPER, true);
709
710         spin_unlock_irqrestore(&priv->ul_lock, flags);
711
712         dev_dbg(dev, "[%u] %s: (%d:%d)->(%d:%d)\n",
713                 hw_id, __func__, d.low_thresh, d.up_thresh, cl_low, cl_high);
714
715         return 0;
716 }
717
718 static int tsens_enable_irq(struct tsens_priv *priv)
719 {
720         int ret;
721         int val = tsens_version(priv) > VER_1_X ? 7 : 1;
722
723         ret = regmap_field_write(priv->rf[INT_EN], val);
724         if (ret < 0)
725                 dev_err(priv->dev, "%s: failed to enable interrupts\n",
726                         __func__);
727
728         return ret;
729 }
730
731 static void tsens_disable_irq(struct tsens_priv *priv)
732 {
733         regmap_field_write(priv->rf[INT_EN], 0);
734 }
735
736 int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)
737 {
738         struct tsens_priv *priv = s->priv;
739         int hw_id = s->hw_id;
740         u32 temp_idx = LAST_TEMP_0 + hw_id;
741         u32 valid_idx = VALID_0 + hw_id;
742         u32 valid;
743         int ret;
744
745         /* VER_0 doesn't have VALID bit */
746         if (tsens_version(priv) == VER_0)
747                 goto get_temp;
748
749         /* Valid bit is 0 for 6 AHB clock cycles.
750          * At 19.2MHz, 1 AHB clock is ~60ns.
751          * We should enter this loop very, very rarely.
752          * Wait 1 us since it's the min of poll_timeout macro.
753          * Old value was 400 ns.
754          */
755         ret = regmap_field_read_poll_timeout(priv->rf[valid_idx], valid,
756                                              valid, 1, 20 * USEC_PER_MSEC);
757         if (ret)
758                 return ret;
759
760 get_temp:
761         /* Valid bit is set, OK to read the temperature */
762         *temp = tsens_hw_to_mC(s, temp_idx);
763
764         return 0;
765 }
766
767 int get_temp_common(const struct tsens_sensor *s, int *temp)
768 {
769         struct tsens_priv *priv = s->priv;
770         int hw_id = s->hw_id;
771         int last_temp = 0, ret, trdy;
772         unsigned long timeout;
773
774         timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
775         do {
776                 if (tsens_version(priv) == VER_0) {
777                         ret = regmap_field_read(priv->rf[TRDY], &trdy);
778                         if (ret)
779                                 return ret;
780                         if (!trdy)
781                                 continue;
782                 }
783
784                 ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp);
785                 if (ret)
786                         return ret;
787
788                 *temp = code_to_degc(last_temp, s) * 1000;
789
790                 return 0;
791         } while (time_before(jiffies, timeout));
792
793         return -ETIMEDOUT;
794 }
795
796 #ifdef CONFIG_DEBUG_FS
797 static int dbg_sensors_show(struct seq_file *s, void *data)
798 {
799         struct platform_device *pdev = s->private;
800         struct tsens_priv *priv = platform_get_drvdata(pdev);
801         int i;
802
803         seq_printf(s, "max: %2d\nnum: %2d\n\n",
804                    priv->feat->max_sensors, priv->num_sensors);
805
806         seq_puts(s, "      id    slope   offset\n--------------------------\n");
807         for (i = 0;  i < priv->num_sensors; i++) {
808                 seq_printf(s, "%8d %8d %8d\n", priv->sensor[i].hw_id,
809                            priv->sensor[i].slope, priv->sensor[i].offset);
810         }
811
812         return 0;
813 }
814
815 static int dbg_version_show(struct seq_file *s, void *data)
816 {
817         struct platform_device *pdev = s->private;
818         struct tsens_priv *priv = platform_get_drvdata(pdev);
819         u32 maj_ver, min_ver, step_ver;
820         int ret;
821
822         if (tsens_version(priv) > VER_0_1) {
823                 ret = regmap_field_read(priv->rf[VER_MAJOR], &maj_ver);
824                 if (ret)
825                         return ret;
826                 ret = regmap_field_read(priv->rf[VER_MINOR], &min_ver);
827                 if (ret)
828                         return ret;
829                 ret = regmap_field_read(priv->rf[VER_STEP], &step_ver);
830                 if (ret)
831                         return ret;
832                 seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver);
833         } else {
834                 seq_printf(s, "0.%d.0\n", priv->feat->ver_major);
835         }
836
837         return 0;
838 }
839
840 DEFINE_SHOW_ATTRIBUTE(dbg_version);
841 DEFINE_SHOW_ATTRIBUTE(dbg_sensors);
842
843 static void tsens_debug_init(struct platform_device *pdev)
844 {
845         struct tsens_priv *priv = platform_get_drvdata(pdev);
846
847         priv->debug_root = debugfs_lookup("tsens", NULL);
848         if (!priv->debug_root)
849                 priv->debug_root = debugfs_create_dir("tsens", NULL);
850
851         /* A directory for each instance of the TSENS IP */
852         priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root);
853         debugfs_create_file("version", 0444, priv->debug, pdev, &dbg_version_fops);
854         debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops);
855 }
856 #else
857 static inline void tsens_debug_init(struct platform_device *pdev) {}
858 #endif
859
860 static const struct regmap_config tsens_config = {
861         .name           = "tm",
862         .reg_bits       = 32,
863         .val_bits       = 32,
864         .reg_stride     = 4,
865 };
866
867 static const struct regmap_config tsens_srot_config = {
868         .name           = "srot",
869         .reg_bits       = 32,
870         .val_bits       = 32,
871         .reg_stride     = 4,
872 };
873
874 int __init init_common(struct tsens_priv *priv)
875 {
876         void __iomem *tm_base, *srot_base;
877         struct device *dev = priv->dev;
878         u32 ver_minor;
879         struct resource *res;
880         u32 enabled;
881         int ret, i, j;
882         struct platform_device *op = of_find_device_by_node(priv->dev->of_node);
883
884         if (!op)
885                 return -EINVAL;
886
887         if (op->num_resources > 1) {
888                 /* DT with separate SROT and TM address space */
889                 priv->tm_offset = 0;
890                 res = platform_get_resource(op, IORESOURCE_MEM, 1);
891                 srot_base = devm_ioremap_resource(dev, res);
892                 if (IS_ERR(srot_base)) {
893                         ret = PTR_ERR(srot_base);
894                         goto err_put_device;
895                 }
896
897                 priv->srot_map = devm_regmap_init_mmio(dev, srot_base,
898                                                        &tsens_srot_config);
899                 if (IS_ERR(priv->srot_map)) {
900                         ret = PTR_ERR(priv->srot_map);
901                         goto err_put_device;
902                 }
903         } else {
904                 /* old DTs where SROT and TM were in a contiguous 2K block */
905                 priv->tm_offset = 0x1000;
906         }
907
908         if (tsens_version(priv) >= VER_0_1) {
909                 res = platform_get_resource(op, IORESOURCE_MEM, 0);
910                 tm_base = devm_ioremap_resource(dev, res);
911                 if (IS_ERR(tm_base)) {
912                         ret = PTR_ERR(tm_base);
913                         goto err_put_device;
914                 }
915
916                 priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);
917         } else { /* VER_0 share the same gcc regs using a syscon */
918                 struct device *parent = priv->dev->parent;
919
920                 if (parent)
921                         priv->tm_map = syscon_node_to_regmap(parent->of_node);
922         }
923
924         if (IS_ERR_OR_NULL(priv->tm_map)) {
925                 if (!priv->tm_map)
926                         ret = -ENODEV;
927                 else
928                         ret = PTR_ERR(priv->tm_map);
929                 goto err_put_device;
930         }
931
932         /* VER_0 have only tm_map */
933         if (!priv->srot_map)
934                 priv->srot_map = priv->tm_map;
935
936         if (tsens_version(priv) > VER_0_1) {
937                 for (i = VER_MAJOR; i <= VER_STEP; i++) {
938                         priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map,
939                                                               priv->fields[i]);
940                         if (IS_ERR(priv->rf[i])) {
941                                 ret = PTR_ERR(priv->rf[i]);
942                                 goto err_put_device;
943                         }
944                 }
945                 ret = regmap_field_read(priv->rf[VER_MINOR], &ver_minor);
946                 if (ret)
947                         goto err_put_device;
948         }
949
950         priv->rf[TSENS_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
951                                                      priv->fields[TSENS_EN]);
952         if (IS_ERR(priv->rf[TSENS_EN])) {
953                 ret = PTR_ERR(priv->rf[TSENS_EN]);
954                 goto err_put_device;
955         }
956         /* in VER_0 TSENS need to be explicitly enabled */
957         if (tsens_version(priv) == VER_0)
958                 regmap_field_write(priv->rf[TSENS_EN], 1);
959
960         ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
961         if (ret)
962                 goto err_put_device;
963         if (!enabled) {
964                 dev_err(dev, "%s: device not enabled\n", __func__);
965                 ret = -ENODEV;
966                 goto err_put_device;
967         }
968
969         priv->rf[SENSOR_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
970                                                       priv->fields[SENSOR_EN]);
971         if (IS_ERR(priv->rf[SENSOR_EN])) {
972                 ret = PTR_ERR(priv->rf[SENSOR_EN]);
973                 goto err_put_device;
974         }
975         priv->rf[INT_EN] = devm_regmap_field_alloc(dev, priv->tm_map,
976                                                    priv->fields[INT_EN]);
977         if (IS_ERR(priv->rf[INT_EN])) {
978                 ret = PTR_ERR(priv->rf[INT_EN]);
979                 goto err_put_device;
980         }
981
982         priv->rf[TSENS_SW_RST] =
983                 devm_regmap_field_alloc(dev, priv->srot_map, priv->fields[TSENS_SW_RST]);
984         if (IS_ERR(priv->rf[TSENS_SW_RST])) {
985                 ret = PTR_ERR(priv->rf[TSENS_SW_RST]);
986                 goto err_put_device;
987         }
988
989         priv->rf[TRDY] = devm_regmap_field_alloc(dev, priv->tm_map, priv->fields[TRDY]);
990         if (IS_ERR(priv->rf[TRDY])) {
991                 ret = PTR_ERR(priv->rf[TRDY]);
992                 goto err_put_device;
993         }
994
995         /* This loop might need changes if enum regfield_ids is reordered */
996         for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) {
997                 for (i = 0; i < priv->feat->max_sensors; i++) {
998                         int idx = j + i;
999
1000                         priv->rf[idx] = devm_regmap_field_alloc(dev,
1001                                                                 priv->tm_map,
1002                                                                 priv->fields[idx]);
1003                         if (IS_ERR(priv->rf[idx])) {
1004                                 ret = PTR_ERR(priv->rf[idx]);
1005                                 goto err_put_device;
1006                         }
1007                 }
1008         }
1009
1010         if (priv->feat->crit_int || tsens_version(priv) < VER_0_1) {
1011                 /* Loop might need changes if enum regfield_ids is reordered */
1012                 for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) {
1013                         for (i = 0; i < priv->feat->max_sensors; i++) {
1014                                 int idx = j + i;
1015
1016                                 priv->rf[idx] =
1017                                         devm_regmap_field_alloc(dev,
1018                                                                 priv->tm_map,
1019                                                                 priv->fields[idx]);
1020                                 if (IS_ERR(priv->rf[idx])) {
1021                                         ret = PTR_ERR(priv->rf[idx]);
1022                                         goto err_put_device;
1023                                 }
1024                         }
1025                 }
1026         }
1027
1028         if (tsens_version(priv) > VER_1_X &&  ver_minor > 2) {
1029                 /* Watchdog is present only on v2.3+ */
1030                 priv->feat->has_watchdog = 1;
1031                 for (i = WDOG_BARK_STATUS; i <= CC_MON_MASK; i++) {
1032                         priv->rf[i] = devm_regmap_field_alloc(dev, priv->tm_map,
1033                                                               priv->fields[i]);
1034                         if (IS_ERR(priv->rf[i])) {
1035                                 ret = PTR_ERR(priv->rf[i]);
1036                                 goto err_put_device;
1037                         }
1038                 }
1039                 /*
1040                  * Watchdog is already enabled, unmask the bark.
1041                  * Disable cycle completion monitoring
1042                  */
1043                 regmap_field_write(priv->rf[WDOG_BARK_MASK], 0);
1044                 regmap_field_write(priv->rf[CC_MON_MASK], 1);
1045         }
1046
1047         spin_lock_init(&priv->ul_lock);
1048
1049         /* VER_0 interrupt doesn't need to be enabled */
1050         if (tsens_version(priv) >= VER_0_1)
1051                 tsens_enable_irq(priv);
1052
1053 err_put_device:
1054         put_device(&op->dev);
1055         return ret;
1056 }
1057
1058 static int tsens_get_temp(struct thermal_zone_device *tz, int *temp)
1059 {
1060         struct tsens_sensor *s = thermal_zone_device_priv(tz);
1061         struct tsens_priv *priv = s->priv;
1062
1063         return priv->ops->get_temp(s, temp);
1064 }
1065
1066 static int  __maybe_unused tsens_suspend(struct device *dev)
1067 {
1068         struct tsens_priv *priv = dev_get_drvdata(dev);
1069
1070         if (priv->ops && priv->ops->suspend)
1071                 return priv->ops->suspend(priv);
1072
1073         return 0;
1074 }
1075
1076 static int __maybe_unused tsens_resume(struct device *dev)
1077 {
1078         struct tsens_priv *priv = dev_get_drvdata(dev);
1079
1080         if (priv->ops && priv->ops->resume)
1081                 return priv->ops->resume(priv);
1082
1083         return 0;
1084 }
1085
1086 static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
1087
1088 static const struct of_device_id tsens_table[] = {
1089         {
1090                 .compatible = "qcom,ipq8064-tsens",
1091                 .data = &data_8960,
1092         }, {
1093                 .compatible = "qcom,ipq8074-tsens",
1094                 .data = &data_ipq8074,
1095         }, {
1096                 .compatible = "qcom,mdm9607-tsens",
1097                 .data = &data_9607,
1098         }, {
1099                 .compatible = "qcom,msm8916-tsens",
1100                 .data = &data_8916,
1101         }, {
1102                 .compatible = "qcom,msm8939-tsens",
1103                 .data = &data_8939,
1104         }, {
1105                 .compatible = "qcom,msm8956-tsens",
1106                 .data = &data_8956,
1107         }, {
1108                 .compatible = "qcom,msm8960-tsens",
1109                 .data = &data_8960,
1110         }, {
1111                 .compatible = "qcom,msm8974-tsens",
1112                 .data = &data_8974,
1113         }, {
1114                 .compatible = "qcom,msm8976-tsens",
1115                 .data = &data_8976,
1116         }, {
1117                 .compatible = "qcom,msm8996-tsens",
1118                 .data = &data_8996,
1119         }, {
1120                 .compatible = "qcom,tsens-v1",
1121                 .data = &data_tsens_v1,
1122         }, {
1123                 .compatible = "qcom,tsens-v2",
1124                 .data = &data_tsens_v2,
1125         },
1126         {}
1127 };
1128 MODULE_DEVICE_TABLE(of, tsens_table);
1129
1130 static const struct thermal_zone_device_ops tsens_of_ops = {
1131         .get_temp = tsens_get_temp,
1132         .set_trips = tsens_set_trips,
1133 };
1134
1135 static int tsens_register_irq(struct tsens_priv *priv, char *irqname,
1136                               irq_handler_t thread_fn)
1137 {
1138         struct platform_device *pdev;
1139         int ret, irq;
1140
1141         pdev = of_find_device_by_node(priv->dev->of_node);
1142         if (!pdev)
1143                 return -ENODEV;
1144
1145         irq = platform_get_irq_byname(pdev, irqname);
1146         if (irq < 0) {
1147                 ret = irq;
1148                 /* For old DTs with no IRQ defined */
1149                 if (irq == -ENXIO)
1150                         ret = 0;
1151         } else {
1152                 /* VER_0 interrupt is TRIGGER_RISING, VER_0_1 and up is ONESHOT */
1153                 if (tsens_version(priv) == VER_0)
1154                         ret = devm_request_threaded_irq(&pdev->dev, irq,
1155                                                         thread_fn, NULL,
1156                                                         IRQF_TRIGGER_RISING,
1157                                                         dev_name(&pdev->dev),
1158                                                         priv);
1159                 else
1160                         ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
1161                                                         thread_fn, IRQF_ONESHOT,
1162                                                         dev_name(&pdev->dev),
1163                                                         priv);
1164
1165                 if (ret)
1166                         dev_err(&pdev->dev, "%s: failed to get irq\n",
1167                                 __func__);
1168                 else
1169                         enable_irq_wake(irq);
1170         }
1171
1172         put_device(&pdev->dev);
1173         return ret;
1174 }
1175
1176 static int tsens_register(struct tsens_priv *priv)
1177 {
1178         int i, ret;
1179         struct thermal_zone_device *tzd;
1180
1181         for (i = 0;  i < priv->num_sensors; i++) {
1182                 priv->sensor[i].priv = priv;
1183                 tzd = devm_thermal_of_zone_register(priv->dev, priv->sensor[i].hw_id,
1184                                                     &priv->sensor[i],
1185                                                     &tsens_of_ops);
1186                 if (IS_ERR(tzd))
1187                         continue;
1188                 priv->sensor[i].tzd = tzd;
1189                 if (priv->ops->enable)
1190                         priv->ops->enable(priv, i);
1191
1192                 if (devm_thermal_add_hwmon_sysfs(priv->dev, tzd))
1193                         dev_warn(priv->dev,
1194                                  "Failed to add hwmon sysfs attributes\n");
1195         }
1196
1197         /* VER_0 require to set MIN and MAX THRESH
1198          * These 2 regs are set using the:
1199          * - CRIT_THRESH_0 for MAX THRESH hardcoded to 120°C
1200          * - CRIT_THRESH_1 for MIN THRESH hardcoded to   0°C
1201          */
1202         if (tsens_version(priv) < VER_0_1) {
1203                 regmap_field_write(priv->rf[CRIT_THRESH_0],
1204                                    tsens_mC_to_hw(priv->sensor, 120000));
1205
1206                 regmap_field_write(priv->rf[CRIT_THRESH_1],
1207                                    tsens_mC_to_hw(priv->sensor, 0));
1208         }
1209
1210         if (priv->feat->combo_int) {
1211                 ret = tsens_register_irq(priv, "combined",
1212                                          tsens_combined_irq_thread);
1213         } else {
1214                 ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);
1215                 if (ret < 0)
1216                         return ret;
1217
1218                 if (priv->feat->crit_int)
1219                         ret = tsens_register_irq(priv, "critical",
1220                                                  tsens_critical_irq_thread);
1221         }
1222
1223         return ret;
1224 }
1225
1226 static int tsens_probe(struct platform_device *pdev)
1227 {
1228         int ret, i;
1229         struct device *dev;
1230         struct device_node *np;
1231         struct tsens_priv *priv;
1232         const struct tsens_plat_data *data;
1233         const struct of_device_id *id;
1234         u32 num_sensors;
1235
1236         if (pdev->dev.of_node)
1237                 dev = &pdev->dev;
1238         else
1239                 dev = pdev->dev.parent;
1240
1241         np = dev->of_node;
1242
1243         id = of_match_node(tsens_table, np);
1244         if (id)
1245                 data = id->data;
1246         else
1247                 data = &data_8960;
1248
1249         num_sensors = data->num_sensors;
1250
1251         if (np)
1252                 of_property_read_u32(np, "#qcom,sensors", &num_sensors);
1253
1254         if (num_sensors <= 0) {
1255                 dev_err(dev, "%s: invalid number of sensors\n", __func__);
1256                 return -EINVAL;
1257         }
1258
1259         priv = devm_kzalloc(dev,
1260                              struct_size(priv, sensor, num_sensors),
1261                              GFP_KERNEL);
1262         if (!priv)
1263                 return -ENOMEM;
1264
1265         priv->dev = dev;
1266         priv->num_sensors = num_sensors;
1267         priv->ops = data->ops;
1268         for (i = 0;  i < priv->num_sensors; i++) {
1269                 if (data->hw_ids)
1270                         priv->sensor[i].hw_id = data->hw_ids[i];
1271                 else
1272                         priv->sensor[i].hw_id = i;
1273         }
1274         priv->feat = data->feat;
1275         priv->fields = data->fields;
1276
1277         platform_set_drvdata(pdev, priv);
1278
1279         if (!priv->ops || !priv->ops->init || !priv->ops->get_temp)
1280                 return -EINVAL;
1281
1282         ret = priv->ops->init(priv);
1283         if (ret < 0) {
1284                 dev_err(dev, "%s: init failed\n", __func__);
1285                 return ret;
1286         }
1287
1288         if (priv->ops->calibrate) {
1289                 ret = priv->ops->calibrate(priv);
1290                 if (ret < 0) {
1291                         if (ret != -EPROBE_DEFER)
1292                                 dev_err(dev, "%s: calibration failed\n", __func__);
1293                         return ret;
1294                 }
1295         }
1296
1297         ret = tsens_register(priv);
1298         if (!ret)
1299                 tsens_debug_init(pdev);
1300
1301         return ret;
1302 }
1303
1304 static int tsens_remove(struct platform_device *pdev)
1305 {
1306         struct tsens_priv *priv = platform_get_drvdata(pdev);
1307
1308         debugfs_remove_recursive(priv->debug_root);
1309         tsens_disable_irq(priv);
1310         if (priv->ops->disable)
1311                 priv->ops->disable(priv);
1312
1313         return 0;
1314 }
1315
1316 static struct platform_driver tsens_driver = {
1317         .probe = tsens_probe,
1318         .remove = tsens_remove,
1319         .driver = {
1320                 .name = "qcom-tsens",
1321                 .pm     = &tsens_pm_ops,
1322                 .of_match_table = tsens_table,
1323         },
1324 };
1325 module_platform_driver(tsens_driver);
1326
1327 MODULE_LICENSE("GPL v2");
1328 MODULE_DESCRIPTION("QCOM Temperature Sensor driver");
1329 MODULE_ALIAS("platform:qcom-tsens");
This page took 0.109106 seconds and 4 git commands to generate.