]> git.ipfire.org Git - thirdparty/linux.git/blob - drivers/thermal/st/stm_thermal.c
47623da0f91b031f8155147573785dd911568e9c
[thirdparty/linux.git] / drivers / thermal / st / stm_thermal.c
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
89 struct 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
106 static 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
116 static 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
135 static 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
166 static 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
189 static 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 */
233 static 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
262 static 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
291 static 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 */
325 static 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 */
340 static 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
373 static 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 */
405 static 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 */
483 static 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
513 static 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
526 static 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
535 ret = stm_thermal_calibration(sensor);
536 if (ret)
537 goto thermal_unprepare;
538
539 /* Set threshold(s) for IRQ */
540 ret = stm_thermal_set_threshold(sensor);
541 if (ret)
542 goto thermal_unprepare;
543
544 ret = stm_enable_irq(sensor);
545 if (ret)
546 goto thermal_unprepare;
547
548 ret = stm_sensor_power_on(sensor);
549 if (ret) {
550 dev_err(dev, "%s: failed to power on sensor\n", __func__);
551 goto irq_disable;
552 }
553
554 return 0;
555
556 irq_disable:
557 stm_disable_irq(sensor);
558
559 thermal_unprepare:
560 clk_disable_unprepare(sensor->clk);
561
562 return ret;
563 }
564
565 #ifdef CONFIG_PM_SLEEP
566 static int stm_thermal_suspend(struct device *dev)
567 {
568 int ret;
569 struct platform_device *pdev = to_platform_device(dev);
570 struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
571
572 ret = stm_thermal_sensor_off(sensor);
573 if (ret)
574 return ret;
575
576 sensor->mode = THERMAL_DEVICE_DISABLED;
577
578 return 0;
579 }
580
581 static int stm_thermal_resume(struct device *dev)
582 {
583 int ret;
584 struct platform_device *pdev = to_platform_device(dev);
585 struct stm_thermal_sensor *sensor = platform_get_drvdata(pdev);
586
587 ret = stm_thermal_prepare(sensor);
588 if (ret)
589 return ret;
590
591 sensor->mode = THERMAL_DEVICE_ENABLED;
592
593 return 0;
594 }
595 #endif /* CONFIG_PM_SLEEP */
596
597 SIMPLE_DEV_PM_OPS(stm_thermal_pm_ops, stm_thermal_suspend, stm_thermal_resume);
598
599 static const struct thermal_zone_of_device_ops stm_tz_ops = {
600 .get_temp = stm_thermal_get_temp,
601 };
602
603 static const struct of_device_id stm_thermal_of_match[] = {
604 { .compatible = "st,stm32-thermal"},
605 { /* sentinel */ }
606 };
607 MODULE_DEVICE_TABLE(of, stm_thermal_of_match);
608
609 static int stm_thermal_probe(struct platform_device *pdev)
610 {
611 struct stm_thermal_sensor *sensor;
612 struct resource *res;
613 const struct thermal_trip *trip;
614 void __iomem *base;
615 int ret, i;
616
617 if (!pdev->dev.of_node) {
618 dev_err(&pdev->dev, "%s: device tree node not found\n",
619 __func__);
620 return -EINVAL;
621 }
622
623 sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);
624 if (!sensor)
625 return -ENOMEM;
626
627 platform_set_drvdata(pdev, sensor);
628
629 sensor->dev = &pdev->dev;
630
631 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
632 base = devm_ioremap_resource(&pdev->dev, res);
633 if (IS_ERR(base))
634 return PTR_ERR(base);
635
636 /* Populate sensor */
637 sensor->base = base;
638
639 ret = stm_thermal_read_factory_settings(sensor);
640 if (ret)
641 return ret;
642
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
730 err_tz:
731 thermal_zone_of_sensor_unregister(&pdev->dev, sensor->th_dev);
732 return ret;
733 }
734
735 static 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
746 static 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 };
755 module_platform_driver(stm_thermal_driver);
756
757 MODULE_DESCRIPTION("STMicroelectronics STM32 Thermal Sensor Driver");
758 MODULE_AUTHOR("David Hernandez Sanchez <david.hernandezsanchez@st.com>");
759 MODULE_LICENSE("GPL v2");
760 MODULE_ALIAS("platform:stm_thermal");