提交 190a3998 编写于 作者: L Linus Torvalds

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
...@@ -62,12 +62,16 @@ enum imx_thermal_trip { ...@@ -62,12 +62,16 @@ enum imx_thermal_trip {
#define IMX_POLLING_DELAY 2000 /* millisecond */ #define IMX_POLLING_DELAY 2000 /* millisecond */
#define IMX_PASSIVE_DELAY 1000 #define IMX_PASSIVE_DELAY 1000
#define FACTOR0 10000000
#define FACTOR1 15976
#define FACTOR2 4297157
struct imx_thermal_data { struct imx_thermal_data {
struct thermal_zone_device *tz; struct thermal_zone_device *tz;
struct thermal_cooling_device *cdev; struct thermal_cooling_device *cdev;
enum thermal_device_mode mode; enum thermal_device_mode mode;
struct regmap *tempmon; struct regmap *tempmon;
int c1, c2; /* See formula in imx_get_sensor_data() */ u32 c1, c2; /* See formula in imx_get_sensor_data() */
unsigned long temp_passive; unsigned long temp_passive;
unsigned long temp_critical; unsigned long temp_critical;
unsigned long alarm_temp; unsigned long alarm_temp;
...@@ -84,7 +88,7 @@ static void imx_set_alarm_temp(struct imx_thermal_data *data, ...@@ -84,7 +88,7 @@ static void imx_set_alarm_temp(struct imx_thermal_data *data,
int alarm_value; int alarm_value;
data->alarm_temp = alarm_temp; data->alarm_temp = alarm_temp;
alarm_value = (alarm_temp - data->c2) / data->c1; alarm_value = (data->c2 - alarm_temp) / data->c1;
regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_ALARM_VALUE_MASK); regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_ALARM_VALUE_MASK);
regmap_write(map, TEMPSENSE0 + REG_SET, alarm_value << regmap_write(map, TEMPSENSE0 + REG_SET, alarm_value <<
TEMPSENSE0_ALARM_VALUE_SHIFT); TEMPSENSE0_ALARM_VALUE_SHIFT);
...@@ -136,7 +140,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, unsigned long *temp) ...@@ -136,7 +140,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, unsigned long *temp)
n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT; n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT;
/* See imx_get_sensor_data() for formula derivation */ /* See imx_get_sensor_data() for formula derivation */
*temp = data->c2 + data->c1 * n_meas; *temp = data->c2 - n_meas * data->c1;
/* Update alarm value to next higher trip point */ /* Update alarm value to next higher trip point */
if (data->alarm_temp == data->temp_passive && *temp >= data->temp_passive) 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,6 +309,7 @@ static int imx_get_sensor_data(struct platform_device *pdev)
int t1, t2, n1, n2; int t1, t2, n1, n2;
int ret; int ret;
u32 val; u32 val;
u64 temp64;
map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
"fsl,tempmon-data"); "fsl,tempmon-data");
...@@ -330,6 +335,8 @@ static int imx_get_sensor_data(struct platform_device *pdev) ...@@ -330,6 +335,8 @@ static int imx_get_sensor_data(struct platform_device *pdev)
* [31:20] - sensor value @ 25C * [31:20] - sensor value @ 25C
* [19:8] - sensor value of hot * [19:8] - sensor value of hot
* [7:0] - hot temperature value * [7:0] - hot temperature value
* Use universal formula now and only need sensor value @ 25C
* slope = 0.4297157 - (0.0015976 * 25C fuse)
*/ */
n1 = val >> 20; n1 = val >> 20;
n2 = (val & 0xfff00) >> 8; n2 = (val & 0xfff00) >> 8;
...@@ -337,20 +344,26 @@ static int imx_get_sensor_data(struct platform_device *pdev) ...@@ -337,20 +344,26 @@ static int imx_get_sensor_data(struct platform_device *pdev)
t1 = 25; /* t1 always 25C */ t1 = 25; /* t1 always 25C */
/* /*
* Derived from linear interpolation, * Derived from linear interpolation:
* Tmeas = T2 + (Nmeas - N2) * (T1 - T2) / (N1 - N2) * slope = 0.4297157 - (0.0015976 * 25C fuse)
* slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0
* (Nmeas - n1) / (Tmeas - t1) = slope
* We want to reduce this down to the minimum computation necessary * We want to reduce this down to the minimum computation necessary
* for each temperature read. Also, we want Tmeas in millicelsius * for each temperature read. Also, we want Tmeas in millicelsius
* and we don't want to lose precision from integer division. So... * and we don't want to lose precision from integer division. So...
* milli_Tmeas = 1000 * T2 + 1000 * (Nmeas - N2) * (T1 - T2) / (N1 - N2) * Tmeas = (Nmeas - n1) / slope + t1
* Let constant c1 = 1000 * (T1 - T2) / (N1 - N2) * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1
* milli_Tmeas = (1000 * T2) + c1 * (Nmeas - N2) * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1
* milli_Tmeas = (1000 * T2) + (c1 * Nmeas) - (c1 * N2) * Let constant c1 = (-1000 / slope)
* Let constant c2 = (1000 * T2) - (c1 * N2) * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1
* milli_Tmeas = c2 + (c1 * Nmeas) * Let constant c2 = n1 *c1 + 1000 * t1
* milli_Tmeas = c2 - Nmeas * c1
*/ */
data->c1 = 1000 * (t1 - t2) / (n1 - n2); temp64 = FACTOR0;
data->c2 = 1000 * t2 - data->c1 * n2; temp64 *= 1000;
do_div(temp64, FACTOR1 * n1 - FACTOR2);
data->c1 = temp64;
data->c2 = n1 * data->c1 + 1000 * t1;
/* /*
* Set the default passive cooling trip point to 20 °C below the * Set the default passive cooling trip point to 20 °C below the
......
...@@ -299,12 +299,17 @@ static void _rcar_thermal_irq_ctrl(struct rcar_thermal_priv *priv, int enable) ...@@ -299,12 +299,17 @@ static void _rcar_thermal_irq_ctrl(struct rcar_thermal_priv *priv, int enable)
static void rcar_thermal_work(struct work_struct *work) static void rcar_thermal_work(struct work_struct *work)
{ {
struct rcar_thermal_priv *priv; struct rcar_thermal_priv *priv;
unsigned long cctemp, nctemp;
priv = container_of(work, struct rcar_thermal_priv, work.work); priv = container_of(work, struct rcar_thermal_priv, work.work);
rcar_thermal_get_temp(priv->zone, &cctemp);
rcar_thermal_update_temp(priv); rcar_thermal_update_temp(priv);
rcar_thermal_irq_enable(priv); rcar_thermal_irq_enable(priv);
thermal_zone_device_update(priv->zone);
rcar_thermal_get_temp(priv->zone, &nctemp);
if (nctemp != cctemp)
thermal_zone_device_update(priv->zone);
} }
static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status) static 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,7 +318,7 @@ static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status)
status = (status >> rcar_id_to_shift(priv)) & 0x3; status = (status >> rcar_id_to_shift(priv)) & 0x3;
if (status & 0x3) { if (status) {
dev_dbg(dev, "thermal%d %s%s\n", dev_dbg(dev, "thermal%d %s%s\n",
priv->id, priv->id,
(status & 0x2) ? "Rising " : "", (status & 0x2) ? "Rising " : "",
......
...@@ -1500,10 +1500,8 @@ static int ti_bandgap_resume(struct device *dev) ...@@ -1500,10 +1500,8 @@ static int ti_bandgap_resume(struct device *dev)
return ti_bandgap_restore_ctxt(bgp); return ti_bandgap_restore_ctxt(bgp);
} }
static const struct dev_pm_ops ti_bandgap_dev_pm_ops = { static SIMPLE_DEV_PM_OPS(ti_bandgap_dev_pm_ops, ti_bandgap_suspend,
SET_SYSTEM_SLEEP_PM_OPS(ti_bandgap_suspend, ti_bandgap_resume);
ti_bandgap_resume)
};
#define DEV_PM_OPS (&ti_bandgap_dev_pm_ops) #define DEV_PM_OPS (&ti_bandgap_dev_pm_ops)
#else #else
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册