.. | .. |
---|
3 | 3 | // Copyright 2013 Freescale Semiconductor, Inc. |
---|
4 | 4 | |
---|
5 | 5 | #include <linux/clk.h> |
---|
6 | | -#include <linux/cpu.h> |
---|
7 | 6 | #include <linux/cpufreq.h> |
---|
8 | 7 | #include <linux/cpu_cooling.h> |
---|
9 | 8 | #include <linux/delay.h> |
---|
10 | | -#include <linux/device.h> |
---|
11 | | -#include <linux/init.h> |
---|
12 | 9 | #include <linux/interrupt.h> |
---|
13 | 10 | #include <linux/io.h> |
---|
14 | | -#include <linux/kernel.h> |
---|
15 | 11 | #include <linux/mfd/syscon.h> |
---|
16 | 12 | #include <linux/module.h> |
---|
17 | 13 | #include <linux/of.h> |
---|
18 | 14 | #include <linux/of_device.h> |
---|
19 | | -#include <linux/platform_device.h> |
---|
20 | 15 | #include <linux/regmap.h> |
---|
21 | | -#include <linux/slab.h> |
---|
22 | 16 | #include <linux/thermal.h> |
---|
23 | | -#include <linux/types.h> |
---|
24 | 17 | #include <linux/nvmem-consumer.h> |
---|
| 18 | +#include <linux/pm_runtime.h> |
---|
25 | 19 | |
---|
26 | 20 | #define REG_SET 0x4 |
---|
27 | 21 | #define REG_CLR 0x8 |
---|
.. | .. |
---|
201 | 195 | }; |
---|
202 | 196 | |
---|
203 | 197 | struct imx_thermal_data { |
---|
| 198 | + struct device *dev; |
---|
204 | 199 | struct cpufreq_policy *policy; |
---|
205 | 200 | struct thermal_zone_device *tz; |
---|
206 | 201 | struct thermal_cooling_device *cdev; |
---|
207 | | - enum thermal_device_mode mode; |
---|
208 | 202 | struct regmap *tempmon; |
---|
209 | 203 | u32 c1, c2; /* See formula in imx_init_calib() */ |
---|
210 | 204 | int temp_passive; |
---|
.. | .. |
---|
260 | 254 | const struct thermal_soc_data *soc_data = data->socdata; |
---|
261 | 255 | struct regmap *map = data->tempmon; |
---|
262 | 256 | unsigned int n_meas; |
---|
263 | | - bool wait; |
---|
264 | 257 | u32 val; |
---|
| 258 | + int ret; |
---|
265 | 259 | |
---|
266 | | - if (data->mode == THERMAL_DEVICE_ENABLED) { |
---|
267 | | - /* Check if a measurement is currently in progress */ |
---|
268 | | - regmap_read(map, soc_data->temp_data, &val); |
---|
269 | | - wait = !(val & soc_data->temp_valid_mask); |
---|
270 | | - } else { |
---|
271 | | - /* |
---|
272 | | - * Every time we measure the temperature, we will power on the |
---|
273 | | - * temperature sensor, enable measurements, take a reading, |
---|
274 | | - * disable measurements, power off the temperature sensor. |
---|
275 | | - */ |
---|
276 | | - regmap_write(map, soc_data->sensor_ctrl + REG_CLR, |
---|
277 | | - soc_data->power_down_mask); |
---|
278 | | - regmap_write(map, soc_data->sensor_ctrl + REG_SET, |
---|
279 | | - soc_data->measure_temp_mask); |
---|
280 | | - |
---|
281 | | - wait = true; |
---|
282 | | - } |
---|
283 | | - |
---|
284 | | - /* |
---|
285 | | - * According to the temp sensor designers, it may require up to ~17us |
---|
286 | | - * to complete a measurement. |
---|
287 | | - */ |
---|
288 | | - if (wait) |
---|
289 | | - usleep_range(20, 50); |
---|
| 260 | + ret = pm_runtime_resume_and_get(data->dev); |
---|
| 261 | + if (ret < 0) |
---|
| 262 | + return ret; |
---|
290 | 263 | |
---|
291 | 264 | regmap_read(map, soc_data->temp_data, &val); |
---|
292 | | - |
---|
293 | | - if (data->mode != THERMAL_DEVICE_ENABLED) { |
---|
294 | | - regmap_write(map, soc_data->sensor_ctrl + REG_CLR, |
---|
295 | | - soc_data->measure_temp_mask); |
---|
296 | | - regmap_write(map, soc_data->sensor_ctrl + REG_SET, |
---|
297 | | - soc_data->power_down_mask); |
---|
298 | | - } |
---|
299 | 265 | |
---|
300 | 266 | if ((val & soc_data->temp_valid_mask) == 0) { |
---|
301 | 267 | dev_dbg(&tz->device, "temp measurement never finished\n"); |
---|
.. | .. |
---|
335 | 301 | enable_irq(data->irq); |
---|
336 | 302 | } |
---|
337 | 303 | |
---|
338 | | - return 0; |
---|
339 | | -} |
---|
340 | | - |
---|
341 | | -static int imx_get_mode(struct thermal_zone_device *tz, |
---|
342 | | - enum thermal_device_mode *mode) |
---|
343 | | -{ |
---|
344 | | - struct imx_thermal_data *data = tz->devdata; |
---|
345 | | - |
---|
346 | | - *mode = data->mode; |
---|
| 304 | + pm_runtime_put(data->dev); |
---|
347 | 305 | |
---|
348 | 306 | return 0; |
---|
349 | 307 | } |
---|
350 | 308 | |
---|
351 | | -static int imx_set_mode(struct thermal_zone_device *tz, |
---|
352 | | - enum thermal_device_mode mode) |
---|
| 309 | +static int imx_change_mode(struct thermal_zone_device *tz, |
---|
| 310 | + enum thermal_device_mode mode) |
---|
353 | 311 | { |
---|
354 | 312 | struct imx_thermal_data *data = tz->devdata; |
---|
355 | | - struct regmap *map = data->tempmon; |
---|
356 | | - const struct thermal_soc_data *soc_data = data->socdata; |
---|
357 | 313 | |
---|
358 | 314 | if (mode == THERMAL_DEVICE_ENABLED) { |
---|
359 | | - tz->polling_delay = IMX_POLLING_DELAY; |
---|
360 | | - tz->passive_delay = IMX_PASSIVE_DELAY; |
---|
361 | | - |
---|
362 | | - regmap_write(map, soc_data->sensor_ctrl + REG_CLR, |
---|
363 | | - soc_data->power_down_mask); |
---|
364 | | - regmap_write(map, soc_data->sensor_ctrl + REG_SET, |
---|
365 | | - soc_data->measure_temp_mask); |
---|
| 315 | + pm_runtime_get(data->dev); |
---|
366 | 316 | |
---|
367 | 317 | if (!data->irq_enabled) { |
---|
368 | 318 | data->irq_enabled = true; |
---|
369 | 319 | enable_irq(data->irq); |
---|
370 | 320 | } |
---|
371 | 321 | } else { |
---|
372 | | - regmap_write(map, soc_data->sensor_ctrl + REG_CLR, |
---|
373 | | - soc_data->measure_temp_mask); |
---|
374 | | - regmap_write(map, soc_data->sensor_ctrl + REG_SET, |
---|
375 | | - soc_data->power_down_mask); |
---|
376 | | - |
---|
377 | | - tz->polling_delay = 0; |
---|
378 | | - tz->passive_delay = 0; |
---|
| 322 | + pm_runtime_put(data->dev); |
---|
379 | 323 | |
---|
380 | 324 | if (data->irq_enabled) { |
---|
381 | 325 | disable_irq(data->irq); |
---|
382 | 326 | data->irq_enabled = false; |
---|
383 | 327 | } |
---|
384 | 328 | } |
---|
385 | | - |
---|
386 | | - data->mode = mode; |
---|
387 | | - thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); |
---|
388 | 329 | |
---|
389 | 330 | return 0; |
---|
390 | 331 | } |
---|
.. | .. |
---|
419 | 360 | int temp) |
---|
420 | 361 | { |
---|
421 | 362 | struct imx_thermal_data *data = tz->devdata; |
---|
| 363 | + int ret; |
---|
| 364 | + |
---|
| 365 | + ret = pm_runtime_resume_and_get(data->dev); |
---|
| 366 | + if (ret < 0) |
---|
| 367 | + return ret; |
---|
422 | 368 | |
---|
423 | 369 | /* do not allow changing critical threshold */ |
---|
424 | 370 | if (trip == IMX_TRIP_CRITICAL) |
---|
.. | .. |
---|
431 | 377 | data->temp_passive = temp; |
---|
432 | 378 | |
---|
433 | 379 | imx_set_alarm_temp(data, temp); |
---|
| 380 | + |
---|
| 381 | + pm_runtime_put(data->dev); |
---|
434 | 382 | |
---|
435 | 383 | return 0; |
---|
436 | 384 | } |
---|
.. | .. |
---|
474 | 422 | .bind = imx_bind, |
---|
475 | 423 | .unbind = imx_unbind, |
---|
476 | 424 | .get_temp = imx_get_temp, |
---|
477 | | - .get_mode = imx_get_mode, |
---|
478 | | - .set_mode = imx_set_mode, |
---|
| 425 | + .change_mode = imx_change_mode, |
---|
479 | 426 | .get_trip_type = imx_get_trip_type, |
---|
480 | 427 | .get_trip_temp = imx_get_trip_temp, |
---|
481 | 428 | .get_crit_temp = imx_get_crit_temp, |
---|
.. | .. |
---|
648 | 595 | }; |
---|
649 | 596 | MODULE_DEVICE_TABLE(of, of_imx_thermal_match); |
---|
650 | 597 | |
---|
| 598 | +#ifdef CONFIG_CPU_FREQ |
---|
651 | 599 | /* |
---|
652 | 600 | * Create cooling device in case no #cooling-cells property is available in |
---|
653 | 601 | * CPU node |
---|
654 | 602 | */ |
---|
655 | 603 | static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) |
---|
656 | 604 | { |
---|
657 | | - struct device_node *np = of_get_cpu_node(data->policy->cpu, NULL); |
---|
658 | | - int ret; |
---|
| 605 | + struct device_node *np; |
---|
| 606 | + int ret = 0; |
---|
| 607 | + |
---|
| 608 | + data->policy = cpufreq_cpu_get(0); |
---|
| 609 | + if (!data->policy) { |
---|
| 610 | + pr_debug("%s: CPUFreq policy not found\n", __func__); |
---|
| 611 | + return -EPROBE_DEFER; |
---|
| 612 | + } |
---|
| 613 | + |
---|
| 614 | + np = of_get_cpu_node(data->policy->cpu, NULL); |
---|
659 | 615 | |
---|
660 | 616 | if (!np || !of_find_property(np, "#cooling-cells", NULL)) { |
---|
661 | 617 | data->cdev = cpufreq_cooling_register(data->policy); |
---|
662 | 618 | if (IS_ERR(data->cdev)) { |
---|
663 | 619 | ret = PTR_ERR(data->cdev); |
---|
664 | 620 | cpufreq_cpu_put(data->policy); |
---|
665 | | - return ret; |
---|
666 | 621 | } |
---|
667 | 622 | } |
---|
668 | 623 | |
---|
| 624 | + of_node_put(np); |
---|
| 625 | + |
---|
| 626 | + return ret; |
---|
| 627 | +} |
---|
| 628 | + |
---|
| 629 | +static void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data) |
---|
| 630 | +{ |
---|
| 631 | + cpufreq_cooling_unregister(data->cdev); |
---|
| 632 | + cpufreq_cpu_put(data->policy); |
---|
| 633 | +} |
---|
| 634 | + |
---|
| 635 | +#else |
---|
| 636 | + |
---|
| 637 | +static inline int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) |
---|
| 638 | +{ |
---|
669 | 639 | return 0; |
---|
670 | 640 | } |
---|
| 641 | + |
---|
| 642 | +static inline void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data) |
---|
| 643 | +{ |
---|
| 644 | +} |
---|
| 645 | +#endif |
---|
671 | 646 | |
---|
672 | 647 | static int imx_thermal_probe(struct platform_device *pdev) |
---|
673 | 648 | { |
---|
.. | .. |
---|
679 | 654 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |
---|
680 | 655 | if (!data) |
---|
681 | 656 | return -ENOMEM; |
---|
| 657 | + |
---|
| 658 | + data->dev = &pdev->dev; |
---|
682 | 659 | |
---|
683 | 660 | map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon"); |
---|
684 | 661 | if (IS_ERR(map)) { |
---|
.. | .. |
---|
715 | 692 | |
---|
716 | 693 | if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) { |
---|
717 | 694 | ret = imx_init_from_nvmem_cells(pdev); |
---|
718 | | - if (ret == -EPROBE_DEFER) |
---|
719 | | - return ret; |
---|
720 | | - if (ret) { |
---|
721 | | - dev_err(&pdev->dev, "failed to init from nvmem: %d\n", |
---|
722 | | - ret); |
---|
723 | | - return ret; |
---|
724 | | - } |
---|
| 695 | + if (ret) |
---|
| 696 | + return dev_err_probe(&pdev->dev, ret, |
---|
| 697 | + "failed to init from nvmem\n"); |
---|
725 | 698 | } else { |
---|
726 | 699 | ret = imx_init_from_tempmon_data(pdev); |
---|
727 | 700 | if (ret) { |
---|
728 | | - dev_err(&pdev->dev, "failed to init from from fsl,tempmon-data\n"); |
---|
| 701 | + dev_err(&pdev->dev, "failed to init from fsl,tempmon-data\n"); |
---|
729 | 702 | return ret; |
---|
730 | 703 | } |
---|
731 | 704 | } |
---|
.. | .. |
---|
743 | 716 | regmap_write(map, data->socdata->sensor_ctrl + REG_SET, |
---|
744 | 717 | data->socdata->power_down_mask); |
---|
745 | 718 | |
---|
746 | | - data->policy = cpufreq_cpu_get(0); |
---|
747 | | - if (!data->policy) { |
---|
748 | | - pr_debug("%s: CPUFreq policy not found\n", __func__); |
---|
749 | | - return -EPROBE_DEFER; |
---|
750 | | - } |
---|
751 | | - |
---|
752 | 719 | ret = imx_thermal_register_legacy_cooling(data); |
---|
753 | | - if (ret) { |
---|
754 | | - dev_err(&pdev->dev, |
---|
755 | | - "failed to register cpufreq cooling device: %d\n", ret); |
---|
756 | | - return ret; |
---|
757 | | - } |
---|
| 720 | + if (ret) |
---|
| 721 | + return dev_err_probe(&pdev->dev, ret, |
---|
| 722 | + "failed to register cpufreq cooling device\n"); |
---|
758 | 723 | |
---|
759 | 724 | data->thermal_clk = devm_clk_get(&pdev->dev, NULL); |
---|
760 | 725 | if (IS_ERR(data->thermal_clk)) { |
---|
.. | .. |
---|
762 | 727 | if (ret != -EPROBE_DEFER) |
---|
763 | 728 | dev_err(&pdev->dev, |
---|
764 | 729 | "failed to get thermal clk: %d\n", ret); |
---|
765 | | - cpufreq_cooling_unregister(data->cdev); |
---|
766 | | - cpufreq_cpu_put(data->policy); |
---|
767 | | - return ret; |
---|
| 730 | + goto legacy_cleanup; |
---|
768 | 731 | } |
---|
769 | 732 | |
---|
770 | 733 | /* |
---|
.. | .. |
---|
777 | 740 | ret = clk_prepare_enable(data->thermal_clk); |
---|
778 | 741 | if (ret) { |
---|
779 | 742 | dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret); |
---|
780 | | - cpufreq_cooling_unregister(data->cdev); |
---|
781 | | - cpufreq_cpu_put(data->policy); |
---|
782 | | - return ret; |
---|
| 743 | + goto legacy_cleanup; |
---|
783 | 744 | } |
---|
784 | 745 | |
---|
785 | 746 | data->tz = thermal_zone_device_register("imx_thermal_zone", |
---|
.. | .. |
---|
792 | 753 | ret = PTR_ERR(data->tz); |
---|
793 | 754 | dev_err(&pdev->dev, |
---|
794 | 755 | "failed to register thermal zone device %d\n", ret); |
---|
795 | | - clk_disable_unprepare(data->thermal_clk); |
---|
796 | | - cpufreq_cooling_unregister(data->cdev); |
---|
797 | | - cpufreq_cpu_put(data->policy); |
---|
798 | | - return ret; |
---|
| 756 | + goto clk_disable; |
---|
799 | 757 | } |
---|
800 | 758 | |
---|
801 | 759 | dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC" |
---|
.. | .. |
---|
818 | 776 | data->socdata->power_down_mask); |
---|
819 | 777 | regmap_write(map, data->socdata->sensor_ctrl + REG_SET, |
---|
820 | 778 | data->socdata->measure_temp_mask); |
---|
| 779 | + /* After power up, we need a delay before first access can be done. */ |
---|
| 780 | + usleep_range(20, 50); |
---|
| 781 | + |
---|
| 782 | + /* the core was configured and enabled just before */ |
---|
| 783 | + pm_runtime_set_active(&pdev->dev); |
---|
| 784 | + pm_runtime_enable(data->dev); |
---|
| 785 | + |
---|
| 786 | + ret = pm_runtime_resume_and_get(data->dev); |
---|
| 787 | + if (ret < 0) |
---|
| 788 | + goto disable_runtime_pm; |
---|
821 | 789 | |
---|
822 | 790 | data->irq_enabled = true; |
---|
823 | | - data->mode = THERMAL_DEVICE_ENABLED; |
---|
| 791 | + ret = thermal_zone_device_enable(data->tz); |
---|
| 792 | + if (ret) |
---|
| 793 | + goto thermal_zone_unregister; |
---|
824 | 794 | |
---|
825 | 795 | ret = devm_request_threaded_irq(&pdev->dev, data->irq, |
---|
826 | 796 | imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread, |
---|
827 | 797 | 0, "imx_thermal", data); |
---|
828 | 798 | if (ret < 0) { |
---|
829 | 799 | dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret); |
---|
830 | | - clk_disable_unprepare(data->thermal_clk); |
---|
831 | | - thermal_zone_device_unregister(data->tz); |
---|
832 | | - cpufreq_cooling_unregister(data->cdev); |
---|
833 | | - cpufreq_cpu_put(data->policy); |
---|
834 | | - return ret; |
---|
| 800 | + goto thermal_zone_unregister; |
---|
835 | 801 | } |
---|
836 | 802 | |
---|
| 803 | + pm_runtime_put(data->dev); |
---|
| 804 | + |
---|
837 | 805 | return 0; |
---|
| 806 | + |
---|
| 807 | +thermal_zone_unregister: |
---|
| 808 | + thermal_zone_device_unregister(data->tz); |
---|
| 809 | +disable_runtime_pm: |
---|
| 810 | + pm_runtime_put_noidle(data->dev); |
---|
| 811 | + pm_runtime_disable(data->dev); |
---|
| 812 | +clk_disable: |
---|
| 813 | + clk_disable_unprepare(data->thermal_clk); |
---|
| 814 | +legacy_cleanup: |
---|
| 815 | + imx_thermal_unregister_legacy_cooling(data); |
---|
| 816 | + |
---|
| 817 | + return ret; |
---|
838 | 818 | } |
---|
839 | 819 | |
---|
840 | 820 | static int imx_thermal_remove(struct platform_device *pdev) |
---|
841 | 821 | { |
---|
842 | 822 | struct imx_thermal_data *data = platform_get_drvdata(pdev); |
---|
843 | | - struct regmap *map = data->tempmon; |
---|
844 | 823 | |
---|
845 | | - /* Disable measurements */ |
---|
846 | | - regmap_write(map, data->socdata->sensor_ctrl + REG_SET, |
---|
847 | | - data->socdata->power_down_mask); |
---|
848 | | - if (!IS_ERR(data->thermal_clk)) |
---|
849 | | - clk_disable_unprepare(data->thermal_clk); |
---|
| 824 | + pm_runtime_put_noidle(data->dev); |
---|
| 825 | + pm_runtime_disable(data->dev); |
---|
850 | 826 | |
---|
851 | 827 | thermal_zone_device_unregister(data->tz); |
---|
852 | | - cpufreq_cooling_unregister(data->cdev); |
---|
853 | | - cpufreq_cpu_put(data->policy); |
---|
| 828 | + imx_thermal_unregister_legacy_cooling(data); |
---|
854 | 829 | |
---|
855 | 830 | return 0; |
---|
856 | 831 | } |
---|
857 | 832 | |
---|
858 | | -#ifdef CONFIG_PM_SLEEP |
---|
859 | | -static int imx_thermal_suspend(struct device *dev) |
---|
| 833 | +static int __maybe_unused imx_thermal_suspend(struct device *dev) |
---|
860 | 834 | { |
---|
861 | 835 | struct imx_thermal_data *data = dev_get_drvdata(dev); |
---|
862 | | - struct regmap *map = data->tempmon; |
---|
| 836 | + int ret; |
---|
863 | 837 | |
---|
864 | 838 | /* |
---|
865 | 839 | * Need to disable thermal sensor, otherwise, when thermal core |
---|
866 | 840 | * try to get temperature before thermal sensor resume, a wrong |
---|
867 | 841 | * temperature will be read as the thermal sensor is powered |
---|
868 | | - * down. |
---|
| 842 | + * down. This is done in change_mode() operation called from |
---|
| 843 | + * thermal_zone_device_disable() |
---|
869 | 844 | */ |
---|
870 | | - regmap_write(map, data->socdata->sensor_ctrl + REG_CLR, |
---|
871 | | - data->socdata->measure_temp_mask); |
---|
872 | | - regmap_write(map, data->socdata->sensor_ctrl + REG_SET, |
---|
873 | | - data->socdata->power_down_mask); |
---|
874 | | - data->mode = THERMAL_DEVICE_DISABLED; |
---|
| 845 | + ret = thermal_zone_device_disable(data->tz); |
---|
| 846 | + if (ret) |
---|
| 847 | + return ret; |
---|
| 848 | + |
---|
| 849 | + return pm_runtime_force_suspend(data->dev); |
---|
| 850 | +} |
---|
| 851 | + |
---|
| 852 | +static int __maybe_unused imx_thermal_resume(struct device *dev) |
---|
| 853 | +{ |
---|
| 854 | + struct imx_thermal_data *data = dev_get_drvdata(dev); |
---|
| 855 | + int ret; |
---|
| 856 | + |
---|
| 857 | + ret = pm_runtime_force_resume(data->dev); |
---|
| 858 | + if (ret) |
---|
| 859 | + return ret; |
---|
| 860 | + /* Enabled thermal sensor after resume */ |
---|
| 861 | + return thermal_zone_device_enable(data->tz); |
---|
| 862 | +} |
---|
| 863 | + |
---|
| 864 | +static int __maybe_unused imx_thermal_runtime_suspend(struct device *dev) |
---|
| 865 | +{ |
---|
| 866 | + struct imx_thermal_data *data = dev_get_drvdata(dev); |
---|
| 867 | + const struct thermal_soc_data *socdata = data->socdata; |
---|
| 868 | + struct regmap *map = data->tempmon; |
---|
| 869 | + int ret; |
---|
| 870 | + |
---|
| 871 | + ret = regmap_write(map, socdata->sensor_ctrl + REG_CLR, |
---|
| 872 | + socdata->measure_temp_mask); |
---|
| 873 | + if (ret) |
---|
| 874 | + return ret; |
---|
| 875 | + |
---|
| 876 | + ret = regmap_write(map, socdata->sensor_ctrl + REG_SET, |
---|
| 877 | + socdata->power_down_mask); |
---|
| 878 | + if (ret) |
---|
| 879 | + return ret; |
---|
| 880 | + |
---|
875 | 881 | clk_disable_unprepare(data->thermal_clk); |
---|
876 | 882 | |
---|
877 | 883 | return 0; |
---|
878 | 884 | } |
---|
879 | 885 | |
---|
880 | | -static int imx_thermal_resume(struct device *dev) |
---|
| 886 | +static int __maybe_unused imx_thermal_runtime_resume(struct device *dev) |
---|
881 | 887 | { |
---|
882 | 888 | struct imx_thermal_data *data = dev_get_drvdata(dev); |
---|
| 889 | + const struct thermal_soc_data *socdata = data->socdata; |
---|
883 | 890 | struct regmap *map = data->tempmon; |
---|
884 | 891 | int ret; |
---|
885 | 892 | |
---|
886 | 893 | ret = clk_prepare_enable(data->thermal_clk); |
---|
887 | 894 | if (ret) |
---|
888 | 895 | return ret; |
---|
889 | | - /* Enabled thermal sensor after resume */ |
---|
890 | | - regmap_write(map, data->socdata->sensor_ctrl + REG_CLR, |
---|
891 | | - data->socdata->power_down_mask); |
---|
892 | | - regmap_write(map, data->socdata->sensor_ctrl + REG_SET, |
---|
893 | | - data->socdata->measure_temp_mask); |
---|
894 | | - data->mode = THERMAL_DEVICE_ENABLED; |
---|
| 896 | + |
---|
| 897 | + ret = regmap_write(map, socdata->sensor_ctrl + REG_CLR, |
---|
| 898 | + socdata->power_down_mask); |
---|
| 899 | + if (ret) |
---|
| 900 | + return ret; |
---|
| 901 | + |
---|
| 902 | + ret = regmap_write(map, socdata->sensor_ctrl + REG_SET, |
---|
| 903 | + socdata->measure_temp_mask); |
---|
| 904 | + if (ret) |
---|
| 905 | + return ret; |
---|
| 906 | + |
---|
| 907 | + /* |
---|
| 908 | + * According to the temp sensor designers, it may require up to ~17us |
---|
| 909 | + * to complete a measurement. |
---|
| 910 | + */ |
---|
| 911 | + usleep_range(20, 50); |
---|
895 | 912 | |
---|
896 | 913 | return 0; |
---|
897 | 914 | } |
---|
898 | | -#endif |
---|
899 | 915 | |
---|
900 | | -static SIMPLE_DEV_PM_OPS(imx_thermal_pm_ops, |
---|
901 | | - imx_thermal_suspend, imx_thermal_resume); |
---|
| 916 | +static const struct dev_pm_ops imx_thermal_pm_ops = { |
---|
| 917 | + SET_SYSTEM_SLEEP_PM_OPS(imx_thermal_suspend, imx_thermal_resume) |
---|
| 918 | + SET_RUNTIME_PM_OPS(imx_thermal_runtime_suspend, |
---|
| 919 | + imx_thermal_runtime_resume, NULL) |
---|
| 920 | +}; |
---|
902 | 921 | |
---|
903 | 922 | static struct platform_driver imx_thermal = { |
---|
904 | 923 | .driver = { |
---|