diff options
Diffstat (limited to 'drivers/thermal')
-rw-r--r-- | drivers/thermal/imx_thermal.c | 20 | ||||
-rw-r--r-- | drivers/thermal/intel_powerclamp.c | 11 | ||||
-rw-r--r-- | drivers/thermal/thermal_core.c | 3 |
3 files changed, 33 insertions, 1 deletions
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index 77a962f1837b..deab7baeeb72 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * | 7 | * |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/clk.h> | ||
10 | #include <linux/cpu_cooling.h> | 11 | #include <linux/cpu_cooling.h> |
11 | #include <linux/cpufreq.h> | 12 | #include <linux/cpufreq.h> |
12 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
@@ -73,6 +74,7 @@ struct imx_thermal_data { | |||
73 | unsigned long last_temp; | 74 | unsigned long last_temp; |
74 | bool irq_enabled; | 75 | bool irq_enabled; |
75 | int irq; | 76 | int irq; |
77 | struct clk *thermal_clk; | ||
76 | }; | 78 | }; |
77 | 79 | ||
78 | static void imx_set_alarm_temp(struct imx_thermal_data *data, | 80 | static void imx_set_alarm_temp(struct imx_thermal_data *data, |
@@ -457,6 +459,22 @@ static int imx_thermal_probe(struct platform_device *pdev) | |||
457 | return ret; | 459 | return ret; |
458 | } | 460 | } |
459 | 461 | ||
462 | data->thermal_clk = devm_clk_get(&pdev->dev, NULL); | ||
463 | if (IS_ERR(data->thermal_clk)) { | ||
464 | dev_warn(&pdev->dev, "failed to get thermal clk!\n"); | ||
465 | } else { | ||
466 | /* | ||
467 | * Thermal sensor needs clk on to get correct value, normally | ||
468 | * we should enable its clk before taking measurement and disable | ||
469 | * clk after measurement is done, but if alarm function is enabled, | ||
470 | * hardware will auto measure the temperature periodically, so we | ||
471 | * need to keep the clk always on for alarm function. | ||
472 | */ | ||
473 | ret = clk_prepare_enable(data->thermal_clk); | ||
474 | if (ret) | ||
475 | dev_warn(&pdev->dev, "failed to enable thermal clk: %d\n", ret); | ||
476 | } | ||
477 | |||
460 | /* Enable measurements at ~ 10 Hz */ | 478 | /* Enable measurements at ~ 10 Hz */ |
461 | regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ); | 479 | regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ); |
462 | measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */ | 480 | measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */ |
@@ -478,6 +496,8 @@ static int imx_thermal_remove(struct platform_device *pdev) | |||
478 | 496 | ||
479 | /* Disable measurements */ | 497 | /* Disable measurements */ |
480 | regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); | 498 | regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); |
499 | if (!IS_ERR(data->thermal_clk)) | ||
500 | clk_disable_unprepare(data->thermal_clk); | ||
481 | 501 | ||
482 | thermal_zone_device_unregister(data->tz); | 502 | thermal_zone_device_unregister(data->tz); |
483 | cpufreq_cooling_unregister(data->cdev); | 503 | cpufreq_cooling_unregister(data->cdev); |
diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c index 8f181b3f842b..67b608ef2cb2 100644 --- a/drivers/thermal/intel_powerclamp.c +++ b/drivers/thermal/intel_powerclamp.c | |||
@@ -206,6 +206,15 @@ static void find_target_mwait(void) | |||
206 | 206 | ||
207 | } | 207 | } |
208 | 208 | ||
209 | static bool has_pkg_state_counter(void) | ||
210 | { | ||
211 | u64 tmp; | ||
212 | return !rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &tmp) || | ||
213 | !rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &tmp) || | ||
214 | !rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &tmp) || | ||
215 | !rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &tmp); | ||
216 | } | ||
217 | |||
209 | static u64 pkg_state_counter(void) | 218 | static u64 pkg_state_counter(void) |
210 | { | 219 | { |
211 | u64 val; | 220 | u64 val; |
@@ -500,7 +509,7 @@ static int start_power_clamp(void) | |||
500 | struct task_struct *thread; | 509 | struct task_struct *thread; |
501 | 510 | ||
502 | /* check if pkg cstate counter is completely 0, abort in this case */ | 511 | /* check if pkg cstate counter is completely 0, abort in this case */ |
503 | if (!pkg_state_counter()) { | 512 | if (!has_pkg_state_counter()) { |
504 | pr_err("pkg cstate counter not functional, abort\n"); | 513 | pr_err("pkg cstate counter not functional, abort\n"); |
505 | return -EINVAL; | 514 | return -EINVAL; |
506 | } | 515 | } |
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index a621e90cbf40..338a88bf6662 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c | |||
@@ -781,6 +781,9 @@ emul_temp_store(struct device *dev, struct device_attribute *attr, | |||
781 | ret = tz->ops->set_emul_temp(tz, temperature); | 781 | ret = tz->ops->set_emul_temp(tz, temperature); |
782 | } | 782 | } |
783 | 783 | ||
784 | if (!ret) | ||
785 | thermal_zone_device_update(tz); | ||
786 | |||
784 | return ret ? ret : count; | 787 | return ret ? ret : count; |
785 | } | 788 | } |
786 | static DEVICE_ATTR(emul_temp, S_IWUSR, NULL, emul_temp_store); | 789 | static DEVICE_ATTR(emul_temp, S_IWUSR, NULL, emul_temp_store); |