sctp: walk the list of asoc safely
[linux/fpc-iii.git] / drivers / thermal / qcom / tsens-v2.c
blob44da02f594ac04edfe6f8096f8dcc0756a11ce54
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
4 * Copyright (c) 2018, Linaro Limited
5 */
7 #include <linux/regmap.h>
8 #include <linux/bitops.h>
9 #include "tsens.h"
11 #define STATUS_OFFSET 0xa0
12 #define LAST_TEMP_MASK 0xfff
13 #define STATUS_VALID_BIT BIT(21)
15 static int get_temp_tsens_v2(struct tsens_device *tmdev, int id, int *temp)
17 struct tsens_sensor *s = &tmdev->sensor[id];
18 u32 code;
19 unsigned int status_reg;
20 u32 last_temp = 0, last_temp2 = 0, last_temp3 = 0;
21 int ret;
23 status_reg = tmdev->tm_offset + STATUS_OFFSET + s->hw_id * 4;
24 ret = regmap_read(tmdev->map, status_reg, &code);
25 if (ret)
26 return ret;
27 last_temp = code & LAST_TEMP_MASK;
28 if (code & STATUS_VALID_BIT)
29 goto done;
31 /* Try a second time */
32 ret = regmap_read(tmdev->map, status_reg, &code);
33 if (ret)
34 return ret;
35 if (code & STATUS_VALID_BIT) {
36 last_temp = code & LAST_TEMP_MASK;
37 goto done;
38 } else {
39 last_temp2 = code & LAST_TEMP_MASK;
42 /* Try a third/last time */
43 ret = regmap_read(tmdev->map, status_reg, &code);
44 if (ret)
45 return ret;
46 if (code & STATUS_VALID_BIT) {
47 last_temp = code & LAST_TEMP_MASK;
48 goto done;
49 } else {
50 last_temp3 = code & LAST_TEMP_MASK;
53 if (last_temp == last_temp2)
54 last_temp = last_temp2;
55 else if (last_temp2 == last_temp3)
56 last_temp = last_temp3;
57 done:
58 /* Convert temperature from deciCelsius to milliCelsius */
59 *temp = sign_extend32(last_temp, fls(LAST_TEMP_MASK) - 1) * 100;
61 return 0;
64 static const struct tsens_ops ops_generic_v2 = {
65 .init = init_common,
66 .get_temp = get_temp_tsens_v2,
69 const struct tsens_data data_tsens_v2 = {
70 .ops = &ops_generic_v2,
73 /* Kept around for backward compatibility with old msm8996.dtsi */
74 const struct tsens_data data_8996 = {
75 .num_sensors = 13,
76 .ops = &ops_generic_v2,