hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/thermal/broadcom/brcmstb_thermal.c
....@@ -1,17 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Broadcom STB AVS TMON thermal sensor driver
34 *
45 * Copyright (c) 2015-2017 Broadcom
5
- *
6
- * This software is licensed under the terms of the GNU General Public
7
- * License version 2, as published by the Free Software Foundation, and
8
- * may be copied, distributed, and modified under those terms.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
156 */
167
178 #define DRV_NAME "brcmstb_thermal"
....@@ -111,18 +102,28 @@
111102 },
112103 };
113104
105
+struct brcmstb_thermal_params {
106
+ unsigned int offset;
107
+ unsigned int mult;
108
+ const struct thermal_zone_of_device_ops *of_ops;
109
+};
110
+
114111 struct brcmstb_thermal_priv {
115112 void __iomem *tmon_base;
116113 struct device *dev;
117114 struct thermal_zone_device *thermal;
115
+ /* Process specific thermal parameters used for calculations */
116
+ const struct brcmstb_thermal_params *temp_params;
118117 };
119118
120119 /* Convert a HW code to a temperature reading (millidegree celsius) */
121
-static inline int avs_tmon_code_to_temp(struct thermal_zone_device *tz,
120
+static inline int avs_tmon_code_to_temp(struct brcmstb_thermal_priv *priv,
122121 u32 code)
123122 {
124
- return (AVS_TMON_TEMP_OFFSET -
125
- (int)((code & AVS_TMON_TEMP_MAX) * AVS_TMON_TEMP_SLOPE));
123
+ int offset = priv->temp_params->offset;
124
+ int mult = priv->temp_params->mult;
125
+
126
+ return (offset - (int)((code & AVS_TMON_TEMP_MASK) * mult));
126127 }
127128
128129 /*
....@@ -131,21 +132,22 @@
131132 * @temp: temperature to convert
132133 * @low: if true, round toward the low side
133134 */
134
-static inline u32 avs_tmon_temp_to_code(struct thermal_zone_device *tz,
135
+static inline u32 avs_tmon_temp_to_code(struct brcmstb_thermal_priv *priv,
135136 int temp, bool low)
136137 {
138
+ int offset = priv->temp_params->offset;
139
+ int mult = priv->temp_params->mult;
140
+
137141 if (temp < AVS_TMON_TEMP_MIN)
138142 return AVS_TMON_TEMP_MAX; /* Maximum code value */
139143
140
- if (temp >= AVS_TMON_TEMP_OFFSET)
144
+ if (temp >= offset)
141145 return 0; /* Minimum code value */
142146
143147 if (low)
144
- return (u32)(DIV_ROUND_UP(AVS_TMON_TEMP_OFFSET - temp,
145
- AVS_TMON_TEMP_SLOPE));
148
+ return (u32)(DIV_ROUND_UP(offset - temp, mult));
146149 else
147
- return (u32)((AVS_TMON_TEMP_OFFSET - temp) /
148
- AVS_TMON_TEMP_SLOPE);
150
+ return (u32)((offset - temp) / mult);
149151 }
150152
151153 static int brcmstb_get_temp(void *data, int *temp)
....@@ -163,7 +165,7 @@
163165
164166 val = (val & AVS_TMON_STATUS_data_msk) >> AVS_TMON_STATUS_data_shift;
165167
166
- t = avs_tmon_code_to_temp(priv->thermal, val);
168
+ t = avs_tmon_code_to_temp(priv, val);
167169 if (t < 0)
168170 *temp = 0;
169171 else
....@@ -197,7 +199,7 @@
197199 val &= trip->reg_msk;
198200 val >>= trip->reg_shift;
199201
200
- return avs_tmon_code_to_temp(priv->thermal, val);
202
+ return avs_tmon_code_to_temp(priv, val);
201203 }
202204
203205 static void avs_tmon_set_trip_temp(struct brcmstb_thermal_priv *priv,
....@@ -210,7 +212,7 @@
210212 dev_dbg(priv->dev, "set temp %d to %d\n", type, temp);
211213
212214 /* round toward low temp for the low interrupt */
213
- val = avs_tmon_temp_to_code(priv->thermal, temp,
215
+ val = avs_tmon_temp_to_code(priv, temp,
214216 type == TMON_TRIP_TYPE_LOW);
215217
216218 val <<= trip->reg_shift;
....@@ -227,7 +229,7 @@
227229 u32 val;
228230
229231 val = __raw_readl(priv->tmon_base + AVS_TMON_TEMP_INT_CODE);
230
- return avs_tmon_code_to_temp(priv->thermal, val);
232
+ return avs_tmon_code_to_temp(priv, val);
231233 }
232234
233235 static irqreturn_t brcmstb_tmon_irq_thread(int irq, void *data)
....@@ -286,19 +288,37 @@
286288 return 0;
287289 }
288290
289
-static struct thermal_zone_of_device_ops of_ops = {
291
+static const struct thermal_zone_of_device_ops brcmstb_16nm_of_ops = {
292
+ .get_temp = brcmstb_get_temp,
293
+};
294
+
295
+static const struct brcmstb_thermal_params brcmstb_16nm_params = {
296
+ .offset = 457829,
297
+ .mult = 557,
298
+ .of_ops = &brcmstb_16nm_of_ops,
299
+};
300
+
301
+static const struct thermal_zone_of_device_ops brcmstb_28nm_of_ops = {
290302 .get_temp = brcmstb_get_temp,
291303 .set_trips = brcmstb_set_trips,
292304 };
293305
306
+static const struct brcmstb_thermal_params brcmstb_28nm_params = {
307
+ .offset = 410040,
308
+ .mult = 487,
309
+ .of_ops = &brcmstb_28nm_of_ops,
310
+};
311
+
294312 static const struct of_device_id brcmstb_thermal_id_table[] = {
295
- { .compatible = "brcm,avs-tmon" },
313
+ { .compatible = "brcm,avs-tmon-bcm7216", .data = &brcmstb_16nm_params },
314
+ { .compatible = "brcm,avs-tmon", .data = &brcmstb_28nm_params },
296315 {},
297316 };
298317 MODULE_DEVICE_TABLE(of, brcmstb_thermal_id_table);
299318
300319 static int brcmstb_thermal_probe(struct platform_device *pdev)
301320 {
321
+ const struct thermal_zone_of_device_ops *of_ops;
302322 struct thermal_zone_device *thermal;
303323 struct brcmstb_thermal_priv *priv;
304324 struct resource *res;
....@@ -308,6 +328,10 @@
308328 if (!priv)
309329 return -ENOMEM;
310330
331
+ priv->temp_params = of_device_get_match_data(&pdev->dev);
332
+ if (!priv->temp_params)
333
+ return -EINVAL;
334
+
311335 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
312336 priv->tmon_base = devm_ioremap_resource(&pdev->dev, res);
313337 if (IS_ERR(priv->tmon_base))
....@@ -315,8 +339,10 @@
315339
316340 priv->dev = &pdev->dev;
317341 platform_set_drvdata(pdev, priv);
342
+ of_ops = priv->temp_params->of_ops;
318343
319
- thermal = thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &of_ops);
344
+ thermal = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, priv,
345
+ of_ops);
320346 if (IS_ERR(thermal)) {
321347 ret = PTR_ERR(thermal);
322348 dev_err(&pdev->dev, "could not register sensor: %d\n", ret);
....@@ -326,42 +352,24 @@
326352 priv->thermal = thermal;
327353
328354 irq = platform_get_irq(pdev, 0);
329
- if (irq < 0) {
330
- dev_err(&pdev->dev, "could not get IRQ\n");
331
- ret = irq;
332
- goto err;
333
- }
334
- ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
335
- brcmstb_tmon_irq_thread, IRQF_ONESHOT,
336
- DRV_NAME, priv);
337
- if (ret < 0) {
338
- dev_err(&pdev->dev, "could not request IRQ: %d\n", ret);
339
- goto err;
355
+ if (irq >= 0) {
356
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
357
+ brcmstb_tmon_irq_thread,
358
+ IRQF_ONESHOT,
359
+ DRV_NAME, priv);
360
+ if (ret < 0) {
361
+ dev_err(&pdev->dev, "could not request IRQ: %d\n", ret);
362
+ return ret;
363
+ }
340364 }
341365
342366 dev_info(&pdev->dev, "registered AVS TMON of-sensor driver\n");
343
-
344
- return 0;
345
-
346
-err:
347
- thermal_zone_of_sensor_unregister(&pdev->dev, thermal);
348
- return ret;
349
-}
350
-
351
-static int brcmstb_thermal_exit(struct platform_device *pdev)
352
-{
353
- struct brcmstb_thermal_priv *priv = platform_get_drvdata(pdev);
354
- struct thermal_zone_device *thermal = priv->thermal;
355
-
356
- if (thermal)
357
- thermal_zone_of_sensor_unregister(&pdev->dev, priv->thermal);
358367
359368 return 0;
360369 }
361370
362371 static struct platform_driver brcmstb_thermal_driver = {
363372 .probe = brcmstb_thermal_probe,
364
- .remove = brcmstb_thermal_exit,
365373 .driver = {
366374 .name = DRV_NAME,
367375 .of_match_table = brcmstb_thermal_id_table,