]> git.ipfire.org Git - thirdparty/linux.git/blame - drivers/thermal/st/stm_thermal.c
thermal: stm32: read factory settings inside stm_thermal_prepare
[thirdparty/linux.git] / drivers / thermal / st / stm_thermal.c
CommitLineData
1d693155
DHS
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
4 * Author: David Hernandez Sanchez <david.hernandezsanchez@st.com> for
5 * STMicroelectronics.
6 */
7
8#include <linux/clk.h>
9#include <linux/clk-provider.h>
10#include <linux/delay.h>
11#include <linux/err.h>
12#include <linux/interrupt.h>
13#include <linux/io.h>
14#include <linux/iopoll.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_address.h>
18#include <linux/of_device.h>
19#include <linux/platform_device.h>
20#include <linux/thermal.h>
21
22#include "../thermal_core.h"
23#include "../thermal_hwmon.h"
24
25/* DTS register offsets */
26#define DTS_CFGR1_OFFSET 0x0
27#define DTS_T0VALR1_OFFSET 0x8
28#define DTS_RAMPVALR_OFFSET 0X10
29#define DTS_ITR1_OFFSET 0x14
30#define DTS_DR_OFFSET 0x1C
31#define DTS_SR_OFFSET 0x20
32#define DTS_ITENR_OFFSET 0x24
33#define DTS_CIFR_OFFSET 0x28
34
35/* DTS_CFGR1 register mask definitions */
36#define HSREF_CLK_DIV_MASK GENMASK(30, 24)
37#define TS1_SMP_TIME_MASK GENMASK(19, 16)
38#define TS1_INTRIG_SEL_MASK GENMASK(11, 8)
39
40/* DTS_T0VALR1 register mask definitions */
41#define TS1_T0_MASK GENMASK(17, 16)
42#define TS1_FMT0_MASK GENMASK(15, 0)
43
44/* DTS_RAMPVALR register mask definitions */
45#define TS1_RAMP_COEFF_MASK GENMASK(15, 0)
46
47/* DTS_ITR1 register mask definitions */
48#define TS1_HITTHD_MASK GENMASK(31, 16)
49#define TS1_LITTHD_MASK GENMASK(15, 0)
50
51/* DTS_DR register mask definitions */
52#define TS1_MFREQ_MASK GENMASK(15, 0)
53
54/* Less significant bit position definitions */
55#define TS1_T0_POS 16
56#define TS1_SMP_TIME_POS 16
57#define TS1_HITTHD_POS 16
58#define HSREF_CLK_DIV_POS 24
59
60/* DTS_CFGR1 bit definitions */
61#define TS1_EN BIT(0)
62#define TS1_START BIT(4)
63#define REFCLK_SEL BIT(20)
64#define REFCLK_LSE REFCLK_SEL
65#define Q_MEAS_OPT BIT(21)
66#define CALIBRATION_CONTROL Q_MEAS_OPT
67
68/* DTS_SR bit definitions */
69#define TS_RDY BIT(15)
70/* Bit definitions below are common for DTS_SR, DTS_ITENR and DTS_CIFR */
71#define HIGH_THRESHOLD BIT(2)
72#define LOW_THRESHOLD BIT(1)
73
74/* Constants */
75#define ADJUST 100
76#define ONE_MHZ 1000000
77#define POLL_TIMEOUT 5000
78#define STARTUP_TIME 40
79#define TS1_T0_VAL0 30
80#define TS1_T0_VAL1 130
81#define NO_HW_TRIG 0
82
83/* The Thermal Framework expects millidegrees */
84#define mcelsius(temp) ((temp) * 1000)
85
86/* The Sensor expects oC degrees */
87#define celsius(temp) ((temp) / 1000)
88
89struct stm_thermal_sensor {
90 struct device *dev;
91 struct thermal_zone_device *th_dev;
92 enum thermal_device_mode mode;
93 struct clk *clk;
94 int high_temp;
95 int low_temp;
96 int temp_critical;
97 int temp_passive;
98 unsigned int low_temp_enabled;
99 int num_trips;
100 int irq;
101 unsigned int irq_enabled;
102 void __iomem *base;
103 int t0, fmt0, ramp_coeff;
104};
105
106static irqreturn_t stm_thermal_alarm_irq(int irq, void *sdata)
107{
108 struct stm_thermal_sensor *sensor = sdata;
109
110 disable_irq_nosync(irq);
111 sensor->irq_enabled = false;
112
113 return IRQ_WAKE_THREAD;
114}
115
116static irqreturn_t stm_thermal_alarm_irq_thread(int irq, void *sdata)
117{
118 u32 value;
119 struct stm_thermal_sensor *sensor = sdata;
120
121 /* read IT reason in SR and clear flags */
122 value = readl_relaxed(sensor->base + DTS_SR_OFFSET);
123
124 if ((value & LOW_THRESHOLD) == LOW_THRESHOLD)
125 writel_relaxed(LOW_THRESHOLD, sensor->base + DTS_CIFR_OFFSET);
126
127 if ((value & HIGH_THRESHOLD) == HIGH_THRESHOLD)
128 writel_relaxed(HIGH_THRESHOLD, sensor->base + DTS_CIFR_OFFSET);
129
130 thermal_zone_device_update(sensor->th_dev, THERMAL_EVENT_UNSPECIFIED);
131
132 return IRQ_HANDLED;
133}
134
135static int stm_sensor_power_on(struct stm_thermal_sensor *sensor)
136{
137 int ret;
138 u32 value;
139
140 /* Enable sensor */
141 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
142 value |= TS1_EN;
143 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
144
145 /*
146 * The DTS block can be enabled by setting TSx_EN bit in
147 * DTS_CFGRx register. It requires a startup time of
148 * 40μs. Use 5 ms as arbitrary timeout.
149 */
150 ret = readl_poll_timeout(sensor->base + DTS_SR_OFFSET,
151 value, (value & TS_RDY),
152 STARTUP_TIME, POLL_TIMEOUT);
153 if (ret)
154 return ret;
155
156 /* Start continuous measuring */
157 value = readl_relaxed(sensor->base +
158 DTS_CFGR1_OFFSET);
159 value |= TS1_START;
160 writel_relaxed(value, sensor->base +
161 DTS_CFGR1_OFFSET);
162
163 return 0;
164}
165
166static int stm_sensor_power_off(struct stm_thermal_sensor *sensor)
167{
168 u32 value;
169
170 /* Stop measuring */
171 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
172 value &= ~TS1_START;
173 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
174
175 /* Ensure stop is taken into account */
176 usleep_range(STARTUP_TIME, POLL_TIMEOUT);
177
178 /* Disable sensor */
179 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
180 value &= ~TS1_EN;
181 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
182
183 /* Ensure disable is taken into account */
184 return readl_poll_timeout(sensor->base + DTS_SR_OFFSET, value,
185 !(value & TS_RDY),
186 STARTUP_TIME, POLL_TIMEOUT);
187}
188
189static int stm_thermal_calibration(struct stm_thermal_sensor *sensor)
190{
191 u32 value, clk_freq;
192 u32 prescaler;
193
194 /* Figure out prescaler value for PCLK during calibration */
195 clk_freq = clk_get_rate(sensor->clk);
196 if (!clk_freq)
197 return -EINVAL;
198
199 prescaler = 0;
200 clk_freq /= ONE_MHZ;
201 if (clk_freq) {
202 while (prescaler <= clk_freq)
203 prescaler++;
204 }
205
206 value = readl_relaxed(sensor->base + DTS_CFGR1_OFFSET);
207
208 /* Clear prescaler */
209 value &= ~HSREF_CLK_DIV_MASK;
210
211 /* Set prescaler. pclk_freq/prescaler < 1MHz */
212 value |= (prescaler << HSREF_CLK_DIV_POS);
213
214 /* Select PCLK as reference clock */
215 value &= ~REFCLK_SEL;
216
217 /* Set maximal sampling time for better precision */
218 value |= TS1_SMP_TIME_MASK;
219
220 /* Measure with calibration */
221 value &= ~CALIBRATION_CONTROL;
222
223 /* select trigger */
224 value &= ~TS1_INTRIG_SEL_MASK;
225 value |= NO_HW_TRIG;
226
227 writel_relaxed(value, sensor->base + DTS_CFGR1_OFFSET);
228
229 return 0;
230}
231
232/* Fill in DTS structure with factory sensor values */
233static int stm_thermal_read_factory_settings(struct stm_thermal_sensor *sensor)
234{
235 /* Retrieve engineering calibration temperature */
236 sensor->t0 = readl_relaxed(sensor->base + DTS_T0VALR1_OFFSET) &
237 TS1_T0_MASK;
238 if (!sensor->t0)
239 sensor->t0 = TS1_T0_VAL0;
240 else
241 sensor->t0 = TS1_T0_VAL1;
242
243 /* Retrieve fmt0 and put it on Hz */
244 sensor->fmt0 = ADJUST * readl_relaxed(sensor->base + DTS_T0VALR1_OFFSET)
245 & TS1_FMT0_MASK;
246
247 /* Retrieve ramp coefficient */
248 sensor->ramp_coeff = readl_relaxed(sensor->base + DTS_RAMPVALR_OFFSET) &
249 TS1_RAMP_COEFF_MASK;
250
251 if (!sensor->fmt0 || !sensor->ramp_coeff) {
252 dev_err(sensor->dev, "%s: wrong setting\n", __func__);
253 return -EINVAL;
254 }
255
256 dev_dbg(sensor->dev, "%s: T0 = %doC, FMT0 = %dHz, RAMP_COEFF = %dHz/oC",
257 __func__, sensor->t0, sensor->fmt0, sensor->ramp_coeff);
258
259 return 0;
260}
261
262static int stm_thermal_calculate_threshold(struct stm_thermal_sensor *sensor,
263 int temp, u32 *th)
264{
265 int freqM;
266 u32 sampling_time;
267
268 /* Retrieve the number of periods to sample */
269 sampling_time = (readl_relaxed(sensor->base + DTS_CFGR1_OFFSET) &
270 TS1_SMP_TIME_MASK) >> TS1_SMP_TIME_POS;
271
272 /* Figure out the CLK_PTAT frequency for a given temperature */
273 freqM = ((temp - sensor->t0) * sensor->ramp_coeff)
274 + sensor->fmt0;
275
276 dev_dbg(sensor->dev, "%s: freqM for threshold = %d Hz",
277 __func__, freqM);
278
279 /* Figure out the threshold sample number */
280 *th = clk_get_rate(sensor->clk);
281 if (!*th)
282 return -EINVAL;
283
284 *th = *th / freqM;
285
286 *th *= sampling_time;
287
288 return 0;
289}
290
291static int stm_thermal_set_threshold(struct stm_thermal_sensor *sensor)
292{
293 u32 value, th;
294 int ret;
295
296 value = readl_relaxed(sensor->base + DTS_ITR1_OFFSET);
297
298 /* Erase threshold content */
299 value &= ~(TS1_LITTHD_MASK | TS1_HITTHD_MASK);
300
301 /* Retrieve the sample threshold number th for a given temperature */
302 ret = stm_thermal_calculate_threshold(sensor, sensor->high_temp, &th);
303 if (ret)
304 return ret;
305
306 value |= th & TS1_LITTHD_MASK;
307
308 if (sensor->low_temp_enabled) {
309 /* Retrieve the sample threshold */
310 ret = stm_thermal_calculate_threshold(sensor, sensor->low_temp,
311 &th);
312 if (ret)
313 return ret;
314
315 value |= (TS1_HITTHD_MASK & (th << TS1_HITTHD_POS));
316 }
317
318 /* Write value on the Low interrupt threshold */
319 writel_relaxed(value, sensor->base + DTS_ITR1_OFFSET);
320
321 return 0;
322}
323
324/* Disable temperature interrupt */
325static int stm_disable_irq(struct stm_thermal_sensor *sensor)
326{
327 u32 value;
328
329 /* Disable IT generation for low and high thresholds */
330 value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET);
331 writel_relaxed(value & ~(LOW_THRESHOLD | HIGH_THRESHOLD),
332 sensor->base + DTS_ITENR_OFFSET);
333
334 dev_dbg(sensor->dev, "%s: IT disabled on sensor side", __func__);
335
336 return 0;
337}
338
339/* Enable temperature interrupt */
340static int stm_enable_irq(struct stm_thermal_sensor *sensor)
341{
342 u32 value;
343
344 /*
345 * Code below enables High temperature threshold using a low threshold
346 * sampling value
347 */
348
349 /* Make sure LOW_THRESHOLD IT is clear before enabling */
350 writel_relaxed(LOW_THRESHOLD, sensor->base + DTS_CIFR_OFFSET);
351
352 /* Enable IT generation for low threshold */
353 value = readl_relaxed(sensor->base + DTS_ITENR_OFFSET);
354 value |= LOW_THRESHOLD;
355
356 /* Enable the low temperature threshold if needed */
357 if (sensor->low_temp_enabled) {
358 /* Make sure HIGH_THRESHOLD IT is clear before enabling */
359 writel_relaxed(HIGH_THRESHOLD, sensor->base + DTS_CIFR_OFFSET);
360
361 /* Enable IT generation for high threshold */
362 value |= HIGH_THRESHOLD;
363 }
364
365 /* Enable thresholds */
366 writel_relaxed(value, sensor->base + DTS_ITENR_OFFSET);
367
368 dev_dbg(sensor->dev, "%s: IT enabled on sensor side", __func__);
369
370 return 0;
371}
372
373static int stm_thermal_update_threshold(struct stm_thermal_sensor *sensor)
374{
375 int ret;
376
377 sensor->mode = THERMAL_DEVICE_DISABLED;
378
379 ret = stm_sensor_power_off(sensor);
380 if (ret)
381 return ret;
382
383 ret = stm_disable_irq(sensor);
384 if (ret)
385 return ret;
386
387 ret = stm_thermal_set_threshold(sensor);
388 if (ret)
389 return ret;
390
391 ret = stm_enable_irq(sensor);
392 if (ret)
393 return ret;
394
395 ret = stm_sensor_power_on(sensor);
396 if (ret)
397 return ret;
398
399 sensor->mode = THERMAL_DEVICE_ENABLED;
400
401 return 0;
402}
403
404/* Callback to get temperature from HW */
405static int stm_thermal_get_temp(void *data, int *temp)
406{
407 struct stm_thermal_sensor *sensor = data;
408 u32 sampling_time;
409 int freqM, ret;
410
411 if (sensor->mode != THERMAL_DEVICE_ENABLED)
412 return -EAGAIN;
413
414 /* Retrieve the number of samples */
415 ret = readl_poll_timeout(sensor->base + DTS_DR_OFFSET, freqM,
416 (freqM & TS1_MFREQ_MASK), STARTUP_TIME,
417 POLL_TIMEOUT);
418
419 if (ret)
420 return ret;
421
422 if (!freqM)
423 return -ENODATA;
424
425 /* Retrieve the number of periods sampled */
426 sampling_time = (readl_relaxed(sensor->base + DTS_CFGR1_OFFSET) &
427 TS1_SMP_TIME_MASK) >> TS1_SMP_TIME_POS;
428
429 /* Figure out the number of samples per period */
430 freqM /= sampling_time;
431
432 /* Figure out the CLK_PTAT frequency */
433 freqM = clk_get_rate(sensor->clk) / freqM;
434 if (!freqM)
435 return -EINVAL;
436
437 dev_dbg(sensor->dev, "%s: freqM=%d\n", __func__, freqM);
438
439 /* Figure out the temperature in mili celsius */
440 *temp = mcelsius(sensor->t0 + ((freqM - sensor->fmt0) /
441 sensor->ramp_coeff));
442
443 dev_dbg(sensor->dev, "%s: temperature = %d millicelsius",
444 __func__, *temp);
445
446 /* Update thresholds */
447 if (sensor->num_trips > 1) {
448 /* Update alarm threshold value to next higher trip point */
449 if (sensor->high_temp == sensor->temp_passive &&
450 celsius(*temp) >= sensor->temp_passive) {
451 sensor->high_temp = sensor->temp_critical;
452 sensor->low_temp = sensor->temp_passive;
453 sensor->low_temp_enabled = true;
454 ret = stm_thermal_update_threshold(sensor);
455 if (ret)
456 return ret;
457 }
458
459 if (sensor->high_temp == sensor->temp_critical &&
460 celsius(*temp) < sensor->temp_passive) {
461 sensor->high_temp = sensor->temp_passive;
462 sensor->low_temp_enabled = false;
463 ret = stm_thermal_update_threshold(sensor);
464 if (ret)
465 return ret;
466 }
467
468 /*
469 * Re-enable alarm IRQ if temperature below critical
470 * temperature
471 */
472 if (!sensor->irq_enabled &&
473 (celsius(*temp) < sensor->temp_critical)) {
474 sensor->irq_enabled = true;
475 enable_irq(sensor->irq);
476 }
477 }
478
479 return 0;
480}
481
482/* Registers DTS irq to be visible by GIC */
483static int stm_register_irq(struct stm_thermal_sensor *sensor)
484{
485 struct device *dev = sensor->dev;
486 struct platform_device *pdev = to_platform_device(dev);
487 int ret;
488
489 sensor->irq = platform_get_irq(pdev, 0);
490 if (sensor->irq < 0) {
491 dev_err(dev, "%s: Unable to find IRQ\n", __func__);
492 return sensor->irq;
493 }
494
495 ret = devm_request_threaded_irq(dev, sensor->irq,
496 stm_thermal_alarm_irq,
497 stm_thermal_alarm_irq_thread,
498 IRQF_ONESHOT,
499 dev->driver->name, sensor);
500 if (ret) {
501 dev_err(dev, "%s: Failed to register IRQ %d\n", __func__,
502 sensor->irq);
503 return ret;
504 }
505
506 sensor->irq_enabled = true;
507
508 dev_dbg(dev, "%s: thermal IRQ registered", __func__);
509
510 return 0;
511}
512
513static int stm_thermal_sensor_off(struct stm_thermal_sensor *sensor)
514{
515 int ret;
516
517 ret = stm_sensor_power_off(sensor);
518 if (ret)
519 return ret;
520
521 clk_disable_unprepare(sensor->clk);
522
523 return 0;
524}
525
526static int stm_thermal_prepare(struct stm_thermal_sensor *sensor)
527{
528 int ret;
529 struct device *dev = sensor->dev;
530
531 ret = clk_prepare_enable(sensor->clk);
532 if (ret)
533 return ret;
534
3c9d0820
DHS
535 ret = stm_thermal_read_factory_settings(sensor);
536 if (ret)
537 goto thermal_unprepare;
538
1d693155
DHS
539 ret = stm_thermal_calibration(sensor);
540 if (ret)
541 goto thermal_unprepare;
542
543 /* Set threshold(s) for IRQ */
544 ret = stm_thermal_set_threshold(sensor);
545 if (ret)
546 goto thermal_unprepare;
547
548 ret = stm_enable_irq(sensor);
549 if (ret)
550 goto thermal_unprepare;
551
552 ret = stm_sensor_power_on(sensor);
553 if (ret) {
554 dev_err(dev, "%s: failed to power on sensor\n", __func__);
555 goto irq_disable;
556 }
557
558 return 0;
559
560irq_disable:
561 stm_disable_irq(sensor);
562
563thermal_unprepare:
564 clk_disable_unprepare(sensor->clk);
565
566 return ret;
567}
568
569#ifdef CONFIG_PM_SLEEP
570static int stm_thermal_suspend(struct device *dev)
571{
572 int ret;
573 struct platform_device *pdev = to_platform_device(dev);
574 struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
575
576 ret = stm_thermal_sensor_off(sensor);
577 if (ret)
578 return ret;
579
580 sensor->mode = THERMAL_DEVICE_DISABLED;
581
582 return 0;
583}
584
585static int stm_thermal_resume(struct device *dev)
586{
587 int ret;
588 struct platform_device *pdev = to_platform_device(dev);
589 struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
590
591 ret = stm_thermal_prepare(sensor);
592 if (ret)
593 return ret;
594
595 sensor->mode = THERMAL_DEVICE_ENABLED;
596
597 return 0;
598}
599#endif /* CONFIG_PM_SLEEP */
600
601SIMPLE_DEV_PM_OPS(stm_thermal_pm_ops, stm_thermal_suspend, stm_thermal_resume);
602
603static const struct thermal_zone_of_device_ops stm_tz_ops = {
604 .get_temp = stm_thermal_get_temp,
605};
606
607static const struct of_device_id stm_thermal_of_match[] = {
608 { .compatible = "st,stm32-thermal"},
609 { /* sentinel */ }
610};
611MODULE_DEVICE_TABLE(of, stm_thermal_of_match);
612
613static int stm_thermal_probe(struct platform_device *pdev)
614{
615 struct stm_thermal_sensor *sensor;
616 struct resource *res;
617 const struct thermal_trip *trip;
618 void __iomem *base;
619 int ret, i;
620
621 if (!pdev->dev.of_node) {
622 dev_err(&pdev->dev, "%s: device tree node not found\n",
623 __func__);
624 return -EINVAL;
625 }
626
627 sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);
628 if (!sensor)
629 return -ENOMEM;
630
631 platform_set_drvdata(pdev, sensor);
632
633 sensor->dev = &pdev->dev;
634
635 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
636 base = devm_ioremap_resource(&pdev->dev, res);
637 if (IS_ERR(base))
638 return PTR_ERR(base);
639
640 /* Populate sensor */
641 sensor->base = base;
642
1d693155
DHS
643 sensor->clk = devm_clk_get(&pdev->dev, "pclk");
644 if (IS_ERR(sensor->clk)) {
645 dev_err(&pdev->dev, "%s: failed to fetch PCLK clock\n",
646 __func__);
647 return PTR_ERR(sensor->clk);
648 }
649
650 /* Register IRQ into GIC */
651 ret = stm_register_irq(sensor);
652 if (ret)
653 return ret;
654
655 sensor->th_dev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0,
656 sensor,
657 &stm_tz_ops);
658
659 if (IS_ERR(sensor->th_dev)) {
660 dev_err(&pdev->dev, "%s: thermal zone sensor registering KO\n",
661 __func__);
662 ret = PTR_ERR(sensor->th_dev);
663 return ret;
664 }
665
666 if (!sensor->th_dev->ops->get_crit_temp) {
667 /* Critical point must be provided */
668 ret = -EINVAL;
669 goto err_tz;
670 }
671
672 ret = sensor->th_dev->ops->get_crit_temp(sensor->th_dev,
673 &sensor->temp_critical);
674 if (ret) {
675 dev_err(&pdev->dev,
676 "Not able to read critical_temp: %d\n", ret);
677 goto err_tz;
678 }
679
680 sensor->temp_critical = celsius(sensor->temp_critical);
681
682 /* Set thresholds for IRQ */
683 sensor->high_temp = sensor->temp_critical;
684
685 trip = of_thermal_get_trip_points(sensor->th_dev);
686 sensor->num_trips = of_thermal_get_ntrips(sensor->th_dev);
687
688 /* Find out passive temperature if it exists */
689 for (i = (sensor->num_trips - 1); i >= 0; i--) {
690 if (trip[i].type == THERMAL_TRIP_PASSIVE) {
691 sensor->temp_passive = celsius(trip[i].temperature);
692 /* Update high temperature threshold */
693 sensor->high_temp = sensor->temp_passive;
694 }
695 }
696
697 /*
698 * Ensure low_temp_enabled flag is disabled.
699 * By disabling low_temp_enabled, low threshold IT will not be
700 * configured neither enabled because it is not needed as high
701 * threshold is set on the lowest temperature trip point after
702 * probe.
703 */
704 sensor->low_temp_enabled = false;
705
706 /* Configure and enable HW sensor */
707 ret = stm_thermal_prepare(sensor);
708 if (ret) {
709 dev_err(&pdev->dev,
710 "Not able to enable sensor: %d\n", ret);
711 goto err_tz;
712 }
713
714 /*
715 * Thermal_zone doesn't enable hwmon as default,
716 * enable it here
717 */
718 sensor->th_dev->tzp->no_hwmon = false;
719 ret = thermal_add_hwmon_sysfs(sensor->th_dev);
720 if (ret)
721 goto err_tz;
722
723 sensor->mode = THERMAL_DEVICE_ENABLED;
724
725 dev_info(&pdev->dev, "%s: Driver initialized successfully\n",
726 __func__);
727
728 return 0;
729
730err_tz:
731 thermal_zone_of_sensor_unregister(&pdev->dev, sensor->th_dev);
732 return ret;
733}
734
735static int stm_thermal_remove(struct platform_device *pdev)
736{
737 struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
738
739 stm_thermal_sensor_off(sensor);
740 thermal_remove_hwmon_sysfs(sensor->th_dev);
741 thermal_zone_of_sensor_unregister(&pdev->dev, sensor->th_dev);
742
743 return 0;
744}
745
746static struct platform_driver stm_thermal_driver = {
747 .driver = {
748 .name = "stm_thermal",
749 .pm = &stm_thermal_pm_ops,
750 .of_match_table = stm_thermal_of_match,
751 },
752 .probe = stm_thermal_probe,
753 .remove = stm_thermal_remove,
754};
755module_platform_driver(stm_thermal_driver);
756
757MODULE_DESCRIPTION("STMicroelectronics STM32 Thermal Sensor Driver");
758MODULE_AUTHOR("David Hernandez Sanchez <david.hernandezsanchez@st.com>");
759MODULE_LICENSE("GPL v2");
760MODULE_ALIAS("platform:stm_thermal");