On Thu, 2013-02-07 at 17:13 -0800, Amit Daniel Kachhap wrote:
From: Jonghwa Lee jonghwa3@samsung.com
This patch introduces using temperature falling interrupt in exynos
thermal driver. Former patch, it only use polling way to check
whether if system themperature is fallen. However, exynos SOC also
provides temperature falling interrupt way to do same things by hw.
This feature is not supported in exynos4210.
Acked-by: Kukjin Kim kgene@samsung.com
Signed-off-by: Jonghwa Lee jonghwa3@samsung.com
Signed-off-by: Amit Daniel Kachhap amit.dan...@samsung.com
applied to thermal -next.
thanks,
rui
---
Hi,
Submitting these patches again as they got lost somewhere and was not merged.
Changes since V2:
* Rebased against Rui Zhang next tree.
* Added Kukjin Kim acked by.
Changes since V1: Used the new thermal trend type macro
All these patches are based on thermal maintainer next branch.
git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git thermal
drivers/thermal/exynos_thermal.c | 81
+++---
include/linux/platform_data/exynos_thermal.h |3 +
2 files changed, 49 insertions(+), 35 deletions(-)
diff --git a/drivers/thermal/exynos_thermal.c
b/drivers/thermal/exynos_thermal.c
index 3a1b01e..65f69cf 100644
--- a/drivers/thermal/exynos_thermal.c
+++ b/drivers/thermal/exynos_thermal.c
@@ -94,6 +94,7 @@
#define SENSOR_NAME_LEN 16
#define MAX_TRIP_COUNT 8
#define MAX_COOLING_DEVICE 4
+#define MAX_THRESHOLD_LEVS 4
#define ACTIVE_INTERVAL 500
#define IDLE_INTERVAL 1
@@ -133,6 +134,7 @@ struct exynos_tmu_data {
struct thermal_trip_point_conf {
int trip_val[MAX_TRIP_COUNT];
int trip_count;
+ u8 trigger_falling;
};
struct thermal_cooling_conf {
@@ -183,7 +185,8 @@ static int exynos_set_mode(struct thermal_zone_device
*thermal,
mutex_lock(th_zone-therm_dev-lock);
- if (mode == THERMAL_DEVICE_ENABLED)
+ if (mode == THERMAL_DEVICE_ENABLED
+ !th_zone-sensor_conf-trip_data.trigger_falling)
th_zone-therm_dev-polling_delay = IDLE_INTERVAL;
else
th_zone-therm_dev-polling_delay = 0;
@@ -447,7 +450,8 @@ static void exynos_report_trigger(void)
break;
}
- if (th_zone-mode == THERMAL_DEVICE_ENABLED) {
+ if (th_zone-mode == THERMAL_DEVICE_ENABLED
+ !th_zone-sensor_conf-trip_data.trigger_falling) {
if (i 0)
th_zone-therm_dev-polling_delay = ACTIVE_INTERVAL;
else
@@ -486,7 +490,8 @@ static int exynos_register_thermal(struct
thermal_sensor_conf *sensor_conf)
th_zone-therm_dev = thermal_zone_device_register(sensor_conf-name,
EXYNOS_ZONE_COUNT, 0, NULL, exynos_dev_ops, NULL, 0,
- IDLE_INTERVAL);
+ sensor_conf-trip_data.trigger_falling ?
+ 0 : IDLE_INTERVAL);
if (IS_ERR(th_zone-therm_dev)) {
pr_err(Failed to register thermal zone device\n);
@@ -593,8 +598,9 @@ static int exynos_tmu_initialize(struct platform_device
*pdev)
{
struct exynos_tmu_data *data = platform_get_drvdata(pdev);
struct exynos_tmu_platform_data *pdata = data-pdata;
- unsigned int status, trim_info, rising_threshold;
- int ret = 0, threshold_code;
+ unsigned int status, trim_info;
+ unsigned int rising_threshold = 0, falling_threshold = 0;
+ int ret = 0, threshold_code, i, trigger_levs = 0;
mutex_lock(data-lock);
clk_enable(data-clk);
@@ -619,6 +625,11 @@ static int exynos_tmu_initialize(struct platform_device
*pdev)
(data-temp_error2 != 0))
data-temp_error1 = pdata-efuse_value;
+ /* Count trigger levels to be enabled */
+ for (i = 0; i MAX_THRESHOLD_LEVS; i++)
+ if (pdata-trigger_levels[i])
+ trigger_levs++;
+
if (data-soc == SOC_ARCH_EXYNOS4210) {
/* Write temperature code for threshold */
threshold_code = temp_to_code(data, pdata-threshold);
@@ -628,44 +639,38 @@ static int exynos_tmu_initialize(struct platform_device
*pdev)
}
writeb(threshold_code,
data-base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
-
- writeb(pdata-trigger_levels[0],
- data-base + EXYNOS4210_TMU_REG_TRIG_LEVEL0);
- writeb(pdata-trigger_levels[1],
- data-base + EXYNOS4210_TMU_REG_TRIG_LEVEL1);
- writeb(pdata-trigger_levels[2],
- data-base + EXYNOS4210_TMU_REG_TRIG_LEVEL2);
- writeb(pdata-trigger_levels[3],
- data-base + EXYNOS4210_TMU_REG_TRIG_LEVEL3);
+ for (i = 0; i trigger_levs; i++)
+ writeb(pdata-trigger_levels[i],
+