summaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-10 12:15:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-10 12:15:46 -0400
commit190a3998be3ede25d6145e187d6d321f504d28fb (patch)
treead5d6ec7d701b2af054e4922502810908226c0d3 /drivers/thermal
parent4162877d3ffa900b618c369c490c7faa6af60e47 (diff)
parent9477165ec525d47abb1cb6523698e0cd89d65ddb (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
Pull thermal management updates from Zhang Rui: "We only have a couple of fixes/cleanups for platform thermal drivers this time. Specifics: - rcar thermal driver: avoid updating the thermal zone in case an IRQ was triggered but the temperature didn't effectively change. From Patrick Titiano. - update the imx thermal driver' formula of converting thermal sensor' raw date to real temperature in degree C. From Anson Huang. - trivial code cleanups of ti soc thermal and rcar thermal driver from Jingoo Han and Patrick Titiano" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: thermal: rcar-thermal: update thermal zone only when temperature changes thermal: rcar-thermal: fix same mask applied twice thermal: ti-soc-thermal: Use SIMPLE_DEV_PM_OPS macro thermal: imx: update formula for thermal sensor
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/imx_thermal.c39
-rw-r--r--drivers/thermal/rcar_thermal.c9
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-bandgap.c6
3 files changed, 35 insertions, 19 deletions
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 45af765a3198..a99c63152b8d 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -62,12 +62,16 @@ enum imx_thermal_trip {
62#define IMX_POLLING_DELAY 2000 /* millisecond */ 62#define IMX_POLLING_DELAY 2000 /* millisecond */
63#define IMX_PASSIVE_DELAY 1000 63#define IMX_PASSIVE_DELAY 1000
64 64
65#define FACTOR0 10000000
66#define FACTOR1 15976
67#define FACTOR2 4297157
68
65struct imx_thermal_data { 69struct imx_thermal_data {
66 struct thermal_zone_device *tz; 70 struct thermal_zone_device *tz;
67 struct thermal_cooling_device *cdev; 71 struct thermal_cooling_device *cdev;
68 enum thermal_device_mode mode; 72 enum thermal_device_mode mode;
69 struct regmap *tempmon; 73 struct regmap *tempmon;
70 int c1, c2; /* See formula in imx_get_sensor_data() */ 74 u32 c1, c2; /* See formula in imx_get_sensor_data() */
71 unsigned long temp_passive; 75 unsigned long temp_passive;
72 unsigned long temp_critical; 76 unsigned long temp_critical;
73 unsigned long alarm_temp; 77 unsigned long alarm_temp;
@@ -84,7 +88,7 @@ static void imx_set_alarm_temp(struct imx_thermal_data *data,
84 int alarm_value; 88 int alarm_value;
85 89
86 data->alarm_temp = alarm_temp; 90 data->alarm_temp = alarm_temp;
87 alarm_value = (alarm_temp - data->c2) / data->c1; 91 alarm_value = (data->c2 - alarm_temp) / data->c1;
88 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_ALARM_VALUE_MASK); 92 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_ALARM_VALUE_MASK);
89 regmap_write(map, TEMPSENSE0 + REG_SET, alarm_value << 93 regmap_write(map, TEMPSENSE0 + REG_SET, alarm_value <<
90 TEMPSENSE0_ALARM_VALUE_SHIFT); 94 TEMPSENSE0_ALARM_VALUE_SHIFT);
@@ -136,7 +140,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, unsigned long *temp)
136 n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT; 140 n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT;
137 141
138 /* See imx_get_sensor_data() for formula derivation */ 142 /* See imx_get_sensor_data() for formula derivation */
139 *temp = data->c2 + data->c1 * n_meas; 143 *temp = data->c2 - n_meas * data->c1;
140 144
141 /* Update alarm value to next higher trip point */ 145 /* Update alarm value to next higher trip point */
142 if (data->alarm_temp == data->temp_passive && *temp >= data->temp_passive) 146 if (data->alarm_temp == data->temp_passive && *temp >= data->temp_passive)
@@ -305,6 +309,7 @@ static int imx_get_sensor_data(struct platform_device *pdev)
305 int t1, t2, n1, n2; 309 int t1, t2, n1, n2;
306 int ret; 310 int ret;
307 u32 val; 311 u32 val;
312 u64 temp64;
308 313
309 map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 314 map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
310 "fsl,tempmon-data"); 315 "fsl,tempmon-data");
@@ -330,6 +335,8 @@ static int imx_get_sensor_data(struct platform_device *pdev)
330 * [31:20] - sensor value @ 25C 335 * [31:20] - sensor value @ 25C
331 * [19:8] - sensor value of hot 336 * [19:8] - sensor value of hot
332 * [7:0] - hot temperature value 337 * [7:0] - hot temperature value
338 * Use universal formula now and only need sensor value @ 25C
339 * slope = 0.4297157 - (0.0015976 * 25C fuse)
333 */ 340 */
334 n1 = val >> 20; 341 n1 = val >> 20;
335 n2 = (val & 0xfff00) >> 8; 342 n2 = (val & 0xfff00) >> 8;
@@ -337,20 +344,26 @@ static int imx_get_sensor_data(struct platform_device *pdev)
337 t1 = 25; /* t1 always 25C */ 344 t1 = 25; /* t1 always 25C */
338 345
339 /* 346 /*
340 * Derived from linear interpolation, 347 * Derived from linear interpolation:
341 * Tmeas = T2 + (Nmeas - N2) * (T1 - T2) / (N1 - N2) 348 * slope = 0.4297157 - (0.0015976 * 25C fuse)
349 * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0
350 * (Nmeas - n1) / (Tmeas - t1) = slope
342 * We want to reduce this down to the minimum computation necessary 351 * We want to reduce this down to the minimum computation necessary
343 * for each temperature read. Also, we want Tmeas in millicelsius 352 * for each temperature read. Also, we want Tmeas in millicelsius
344 * and we don't want to lose precision from integer division. So... 353 * and we don't want to lose precision from integer division. So...
345 * milli_Tmeas = 1000 * T2 + 1000 * (Nmeas - N2) * (T1 - T2) / (N1 - N2) 354 * Tmeas = (Nmeas - n1) / slope + t1
346 * Let constant c1 = 1000 * (T1 - T2) / (N1 - N2) 355 * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1
347 * milli_Tmeas = (1000 * T2) + c1 * (Nmeas - N2) 356 * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1
348 * milli_Tmeas = (1000 * T2) + (c1 * Nmeas) - (c1 * N2) 357 * Let constant c1 = (-1000 / slope)
349 * Let constant c2 = (1000 * T2) - (c1 * N2) 358 * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1
350 * milli_Tmeas = c2 + (c1 * Nmeas) 359 * Let constant c2 = n1 *c1 + 1000 * t1
360 * milli_Tmeas = c2 - Nmeas * c1
351 */ 361 */
352 data->c1 = 1000 * (t1 - t2) / (n1 - n2); 362 temp64 = FACTOR0;
353 data->c2 = 1000 * t2 - data->c1 * n2; 363 temp64 *= 1000;
364 do_div(temp64, FACTOR1 * n1 - FACTOR2);
365 data->c1 = temp64;
366 data->c2 = n1 * data->c1 + 1000 * t1;
354 367
355 /* 368 /*
356 * Set the default passive cooling trip point to 20 °C below the 369 * Set the default passive cooling trip point to 20 °C below the
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index 79a09d02bbca..5a37940b02c9 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -299,12 +299,17 @@ static void _rcar_thermal_irq_ctrl(struct rcar_thermal_priv *priv, int enable)
299static void rcar_thermal_work(struct work_struct *work) 299static void rcar_thermal_work(struct work_struct *work)
300{ 300{
301 struct rcar_thermal_priv *priv; 301 struct rcar_thermal_priv *priv;
302 unsigned long cctemp, nctemp;
302 303
303 priv = container_of(work, struct rcar_thermal_priv, work.work); 304 priv = container_of(work, struct rcar_thermal_priv, work.work);
304 305
306 rcar_thermal_get_temp(priv->zone, &cctemp);
305 rcar_thermal_update_temp(priv); 307 rcar_thermal_update_temp(priv);
306 rcar_thermal_irq_enable(priv); 308 rcar_thermal_irq_enable(priv);
307 thermal_zone_device_update(priv->zone); 309
310 rcar_thermal_get_temp(priv->zone, &nctemp);
311 if (nctemp != cctemp)
312 thermal_zone_device_update(priv->zone);
308} 313}
309 314
310static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status) 315static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status)
@@ -313,7 +318,7 @@ static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status)
313 318
314 status = (status >> rcar_id_to_shift(priv)) & 0x3; 319 status = (status >> rcar_id_to_shift(priv)) & 0x3;
315 320
316 if (status & 0x3) { 321 if (status) {
317 dev_dbg(dev, "thermal%d %s%s\n", 322 dev_dbg(dev, "thermal%d %s%s\n",
318 priv->id, 323 priv->id,
319 (status & 0x2) ? "Rising " : "", 324 (status & 0x2) ? "Rising " : "",
diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
index 74c0e3474d6e..3ab12ee359b7 100644
--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
@@ -1500,10 +1500,8 @@ static int ti_bandgap_resume(struct device *dev)
1500 1500
1501 return ti_bandgap_restore_ctxt(bgp); 1501 return ti_bandgap_restore_ctxt(bgp);
1502} 1502}
1503static const struct dev_pm_ops ti_bandgap_dev_pm_ops = { 1503static SIMPLE_DEV_PM_OPS(ti_bandgap_dev_pm_ops, ti_bandgap_suspend,
1504 SET_SYSTEM_SLEEP_PM_OPS(ti_bandgap_suspend, 1504 ti_bandgap_resume);
1505 ti_bandgap_resume)
1506};
1507 1505
1508#define DEV_PM_OPS (&ti_bandgap_dev_pm_ops) 1506#define DEV_PM_OPS (&ti_bandgap_dev_pm_ops)
1509#else 1507#else