summaryrefslogtreecommitdiffstats
path: root/drivers/thermal/rcar_thermal.c
diff options
context:
space:
mode:
authorkuninori.morimoto.gx@renesas.com <kuninori.morimoto.gx@renesas.com>2012-12-03 03:48:41 +0100
committerZhang Rui <rui.zhang@intel.com>2013-01-04 08:37:45 +0100
commitd2a73e225d113fdccd80373ad9aeb2b58b32a30b (patch)
treeaf255ad70f782ef6a32cde24df5f94522414f531 /drivers/thermal/rcar_thermal.c
parentThermal: exynos: Add sysfs node supporting exynos's emulation mode. (diff)
downloadlinux-d2a73e225d113fdccd80373ad9aeb2b58b32a30b.tar.xz
linux-d2a73e225d113fdccd80373ad9aeb2b58b32a30b.zip
thermal: rcar: add .get_trip_type/temp and .notify support
This patch adds .get_trip_type(), .get_trip_temp(), and .notify() on rcar_thermal_zone_ops. Driver will try platform power OFF if it reached to critical temperature. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Diffstat (limited to 'drivers/thermal/rcar_thermal.c')
-rw-r--r--drivers/thermal/rcar_thermal.c68
1 files changed, 65 insertions, 3 deletions
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
index 90db951725da..89979ff10e27 100644
--- a/drivers/thermal/rcar_thermal.c
+++ b/drivers/thermal/rcar_thermal.c
@@ -22,10 +22,13 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/reboot.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/thermal.h>
+#define IDLE_INTERVAL 5000
+
#define THSCR 0x2c
#define THSSR 0x30
@@ -176,8 +179,66 @@ static int rcar_thermal_get_temp(struct thermal_zone_device *zone,
return 0;
}
+static int rcar_thermal_get_trip_type(struct thermal_zone_device *zone,
+ int trip, enum thermal_trip_type *type)
+{
+ struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
+
+ /* see rcar_thermal_get_temp() */
+ switch (trip) {
+ case 0: /* +90 <= temp */
+ *type = THERMAL_TRIP_CRITICAL;
+ break;
+ default:
+ dev_err(priv->dev, "rcar driver trip error\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rcar_thermal_get_trip_temp(struct thermal_zone_device *zone,
+ int trip, unsigned long *temp)
+{
+ struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
+
+ /* see rcar_thermal_get_temp() */
+ switch (trip) {
+ case 0: /* +90 <= temp */
+ *temp = MCELSIUS(90);
+ break;
+ default:
+ dev_err(priv->dev, "rcar driver trip error\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rcar_thermal_notify(struct thermal_zone_device *zone,
+ int trip, enum thermal_trip_type type)
+{
+ struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone);
+
+ switch (type) {
+ case THERMAL_TRIP_CRITICAL:
+ /* FIXME */
+ dev_warn(priv->dev,
+ "Thermal reached to critical temperature\n");
+ machine_power_off();
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static struct thermal_zone_device_ops rcar_thermal_zone_ops = {
- .get_temp = rcar_thermal_get_temp,
+ .get_temp = rcar_thermal_get_temp,
+ .get_trip_type = rcar_thermal_get_trip_type,
+ .get_trip_temp = rcar_thermal_get_trip_temp,
+ .notify = rcar_thermal_notify,
};
/*
@@ -211,8 +272,9 @@ static int rcar_thermal_probe(struct platform_device *pdev)
return -ENOMEM;
}
- zone = thermal_zone_device_register("rcar_thermal", 0, 0, priv,
- &rcar_thermal_zone_ops, NULL, 0, 0);
+ zone = thermal_zone_device_register("rcar_thermal", 1, 0, priv,
+ &rcar_thermal_zone_ops, NULL, 0,
+ IDLE_INTERVAL);
if (IS_ERR(zone)) {
dev_err(&pdev->dev, "thermal zone device is NULL\n");
return PTR_ERR(zone);