Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+35 -19
+26 -13
drivers/thermal/imx_thermal.c
··· 62 62 #define IMX_POLLING_DELAY 2000 /* millisecond */ 63 63 #define IMX_PASSIVE_DELAY 1000 64 64 65 + #define FACTOR0 10000000 66 + #define FACTOR1 15976 67 + #define FACTOR2 4297157 68 + 65 69 struct imx_thermal_data { 66 70 struct thermal_zone_device *tz; 67 71 struct thermal_cooling_device *cdev; 68 72 enum thermal_device_mode mode; 69 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 75 unsigned long temp_passive; 72 76 unsigned long temp_critical; 73 77 unsigned long alarm_temp; ··· 88 84 int alarm_value; 89 85 90 86 data->alarm_temp = alarm_temp; 91 - alarm_value = (alarm_temp - data->c2) / data->c1; 87 + alarm_value = (data->c2 - alarm_temp) / data->c1; 92 88 regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_ALARM_VALUE_MASK); 93 89 regmap_write(map, TEMPSENSE0 + REG_SET, alarm_value << 94 90 TEMPSENSE0_ALARM_VALUE_SHIFT); ··· 140 136 n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT; 141 137 142 138 /* See imx_get_sensor_data() for formula derivation */ 143 - *temp = data->c2 + data->c1 * n_meas; 139 + *temp = data->c2 - n_meas * data->c1; 144 140 145 141 /* Update alarm value to next higher trip point */ 146 142 if (data->alarm_temp == data->temp_passive && *temp >= data->temp_passive) ··· 309 305 int t1, t2, n1, n2; 310 306 int ret; 311 307 u32 val; 308 + u64 temp64; 312 309 313 310 map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 314 311 "fsl,tempmon-data"); ··· 335 330 * [31:20] - sensor value @ 25C 336 331 * [19:8] - sensor value of hot 337 332 * [7:0] - hot temperature value 333 + * Use universal formula now and only need sensor value @ 25C 334 + * slope = 0.4297157 - (0.0015976 * 25C fuse) 338 335 */ 339 336 n1 = val >> 20; 340 337 n2 = (val & 0xfff00) >> 8; ··· 344 337 t1 = 25; /* t1 always 25C */ 345 338 346 339 /* 347 - * Derived from linear interpolation, 348 - * Tmeas = T2 + (Nmeas - N2) * (T1 - T2) / (N1 - N2) 340 + * Derived from linear interpolation: 341 + * slope = 0.4297157 - (0.0015976 * 25C fuse) 342 + * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0 343 + * (Nmeas - n1) / (Tmeas - t1) = slope 349 344 * We want to reduce this down to the minimum computation necessary 350 345 * for each temperature read. Also, we want Tmeas in millicelsius 351 346 * and we don't want to lose precision from integer division. So... 352 - * milli_Tmeas = 1000 * T2 + 1000 * (Nmeas - N2) * (T1 - T2) / (N1 - N2) 353 - * Let constant c1 = 1000 * (T1 - T2) / (N1 - N2) 354 - * milli_Tmeas = (1000 * T2) + c1 * (Nmeas - N2) 355 - * milli_Tmeas = (1000 * T2) + (c1 * Nmeas) - (c1 * N2) 356 - * Let constant c2 = (1000 * T2) - (c1 * N2) 357 - * milli_Tmeas = c2 + (c1 * Nmeas) 347 + * Tmeas = (Nmeas - n1) / slope + t1 348 + * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1 349 + * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1 350 + * Let constant c1 = (-1000 / slope) 351 + * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1 352 + * Let constant c2 = n1 *c1 + 1000 * t1 353 + * milli_Tmeas = c2 - Nmeas * c1 358 354 */ 359 - data->c1 = 1000 * (t1 - t2) / (n1 - n2); 360 - data->c2 = 1000 * t2 - data->c1 * n2; 355 + temp64 = FACTOR0; 356 + temp64 *= 1000; 357 + do_div(temp64, FACTOR1 * n1 - FACTOR2); 358 + data->c1 = temp64; 359 + data->c2 = n1 * data->c1 + 1000 * t1; 361 360 362 361 /* 363 362 * Set the default passive cooling trip point to 20 °C below the
+7 -2
drivers/thermal/rcar_thermal.c
··· 299 299 static void rcar_thermal_work(struct work_struct *work) 300 300 { 301 301 struct rcar_thermal_priv *priv; 302 + unsigned long cctemp, nctemp; 302 303 303 304 priv = container_of(work, struct rcar_thermal_priv, work.work); 304 305 306 + rcar_thermal_get_temp(priv->zone, &cctemp); 305 307 rcar_thermal_update_temp(priv); 306 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 310 315 static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status) ··· 318 313 319 314 status = (status >> rcar_id_to_shift(priv)) & 0x3; 320 315 321 - if (status & 0x3) { 316 + if (status) { 322 317 dev_dbg(dev, "thermal%d %s%s\n", 323 318 priv->id, 324 319 (status & 0x2) ? "Rising " : "",
+2 -4
drivers/thermal/ti-soc-thermal/ti-bandgap.c
··· 1500 1500 1501 1501 return ti_bandgap_restore_ctxt(bgp); 1502 1502 } 1503 - static const struct dev_pm_ops ti_bandgap_dev_pm_ops = { 1504 - SET_SYSTEM_SLEEP_PM_OPS(ti_bandgap_suspend, 1505 - ti_bandgap_resume) 1506 - }; 1503 + static SIMPLE_DEV_PM_OPS(ti_bandgap_dev_pm_ops, ti_bandgap_suspend, 1504 + ti_bandgap_resume); 1507 1505 1508 1506 #define DEV_PM_OPS (&ti_bandgap_dev_pm_ops) 1509 1507 #else