aboutsummaryrefslogtreecommitdiff
path: root/drivers/thermal/rcar_thermal.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thermal/rcar_thermal.c')
-rw-r--r--drivers/thermal/rcar_thermal.c58
1 files changed, 37 insertions, 21 deletions
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index 2cc5b6115e3..8803e693fe6 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -24,6 +24,7 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/reboot.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
@@ -298,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)
{
struct rcar_thermal_priv *priv;
+ unsigned long cctemp, nctemp;
priv = container_of(work, struct rcar_thermal_priv, work.work);
+ rcar_thermal_get_temp(priv->zone, &cctemp);
rcar_thermal_update_temp(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)
@@ -312,7 +318,7 @@ static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status)
status = (status >> rcar_id_to_shift(priv)) & 0x3;
- if (status & 0x3) {
+ if (status) {
dev_dbg(dev, "thermal%d %s%s\n",
priv->id,
(status & 0x2) ? "Rising " : "",
@@ -368,15 +374,16 @@ static int rcar_thermal_probe(struct platform_device *pdev)
int idle = IDLE_INTERVAL;
common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
- if (!common) {
- dev_err(dev, "Could not allocate common\n");
+ if (!common)
return -ENOMEM;
- }
INIT_LIST_HEAD(&common->head);
spin_lock_init(&common->lock);
common->dev = dev;
+ pm_runtime_enable(dev);
+ pm_runtime_get_sync(dev);
+
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (irq) {
int ret;
@@ -385,11 +392,6 @@ static int rcar_thermal_probe(struct platform_device *pdev)
* platform has IRQ support.
* Then, drier use common register
*/
- res = platform_get_resource(pdev, IORESOURCE_MEM, mres++);
- if (!res) {
- dev_err(dev, "Could not get platform resource\n");
- return -ENODEV;
- }
ret = devm_request_irq(dev, irq->start, rcar_thermal_irq, 0,
dev_name(dev), common);
@@ -401,6 +403,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
/*
* rcar_has_irq_support() will be enabled
*/
+ res = platform_get_resource(pdev, IORESOURCE_MEM, mres++);
common->base = devm_ioremap_resource(dev, res);
if (IS_ERR(common->base))
return PTR_ERR(common->base);
@@ -408,7 +411,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
/* enable temperature comparation */
rcar_thermal_common_write(common, ENR, 0x00030303);
- idle = 0; /* polling delaye is not needed */
+ idle = 0; /* polling delay is not needed */
}
for (i = 0;; i++) {
@@ -418,13 +421,15 @@ static int rcar_thermal_probe(struct platform_device *pdev)
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv) {
- dev_err(dev, "Could not allocate priv\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto error_unregister;
}
priv->base = devm_ioremap_resource(dev, res);
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
+ if (IS_ERR(priv->base)) {
+ ret = PTR_ERR(priv->base);
+ goto error_unregister;
+ }
priv->common = common;
priv->id = i;
@@ -443,21 +448,27 @@ static int rcar_thermal_probe(struct platform_device *pdev)
goto error_unregister;
}
- list_move_tail(&priv->list, &common->head);
-
if (rcar_has_irq_support(priv))
rcar_thermal_irq_enable(priv);
+
+ list_move_tail(&priv->list, &common->head);
}
platform_set_drvdata(pdev, common);
- dev_info(dev, "%d sensor proved\n", i);
+ dev_info(dev, "%d sensor probed\n", i);
return 0;
error_unregister:
- rcar_thermal_for_each_priv(priv, common)
+ rcar_thermal_for_each_priv(priv, common) {
thermal_zone_device_unregister(priv->zone);
+ if (rcar_has_irq_support(priv))
+ rcar_thermal_irq_disable(priv);
+ }
+
+ pm_runtime_put(dev);
+ pm_runtime_disable(dev);
return ret;
}
@@ -465,12 +476,17 @@ error_unregister:
static int rcar_thermal_remove(struct platform_device *pdev)
{
struct rcar_thermal_common *common = platform_get_drvdata(pdev);
+ struct device *dev = &pdev->dev;
struct rcar_thermal_priv *priv;
- rcar_thermal_for_each_priv(priv, common)
+ rcar_thermal_for_each_priv(priv, common) {
thermal_zone_device_unregister(priv->zone);
+ if (rcar_has_irq_support(priv))
+ rcar_thermal_irq_disable(priv);
+ }
- platform_set_drvdata(pdev, NULL);
+ pm_runtime_put(dev);
+ pm_runtime_disable(dev);
return 0;
}