thermal: msm_thermal: Define and implement device tree bindings
Define device tree bindings for MSM_THERMAL driver, and implement
matching code to make the driver abide to these bindings.
Change-Id: I6ed08a09f45f8748841cf44db601f28659e49d9c
Signed-off-by: Eugene Seah <eseah@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
new file mode 100644
index 0000000..5d1fafb
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
@@ -0,0 +1,34 @@
+MSM thermal driver (MSM_THERMAL)
+
+MSM_THERMAL is a kernel platform driver which regulates thermal conditions
+on the device during kernel boot. The goal of MSM_THERMAL is to prevent the
+temperature of the system from exceeding a thermal limit at which it cannot
+operate. Examples are CPU junction thermal limit, or POP memory thermal limit.
+The MSM_THERMAL driver polls the TSENS sensor hardware during boot, and
+reduces the maximum CPU frequency allowed in steps, to limit power/thermal
+output when a threshold temperature is crossed. It restores the maximum CPU
+frequency allowed in the same stepwise fashion when the threshold temperature
+(with hysteresis gap) is cleared.
+
+The devicetree representation of the MSM_THERMAL block should be:
+
+Required properties
+
+- compatible: "qcom,msm-thermal"
+- qcom,sensor-id: The id of the TSENS sensor polled for temperature.
+ Typically the sensor closest to CPU0.
+- qcom,poll-ms: Sampling interval to read sensor, in ms.
+- qcom,limit-temp: Threshold temperature to start stepping CPU down, in degC.
+- qcom,temp-hysteresis: Degrees below threshold temperature to step CPU up.
+- qcom,freq-step: Number of frequency steps to take on each CPU mitigation.
+
+Example:
+
+ qcom,msm-thermal {
+ compatible = "qcom,msm-thermal";
+ qcom,sensor-id = <0>;
+ qcom,poll-ms = <250>;
+ qcom,limit-temp = <60>;
+ qcom,temp-hysteresis = <10>;
+ qcom,freq-step = <2>;
+ };
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 0575d80..2dd2592 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -21,6 +21,8 @@
#include <linux/cpufreq.h>
#include <linux/msm_tsens.h>
#include <linux/msm_thermal.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
#include <mach/cpufreq.h>
static int enabled;
@@ -176,7 +178,7 @@
module_param_cb(enabled, &module_ops, &enabled, 0644);
MODULE_PARM_DESC(enabled, "enforce thermal limit on cpu");
-int __init msm_thermal_init(struct msm_thermal_data *pdata)
+int __devinit msm_thermal_init(struct msm_thermal_data *pdata)
{
int ret = 0;
@@ -190,3 +192,64 @@
return ret;
}
+
+static int __devinit msm_thermal_dev_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ char *key = NULL;
+ struct device_node *node = pdev->dev.of_node;
+ struct msm_thermal_data data;
+
+ memset(&data, 0, sizeof(struct msm_thermal_data));
+ key = "qcom,sensor-id";
+ ret = of_property_read_u32(node, key, &data.sensor_id);
+ if (ret)
+ goto fail;
+ WARN_ON(data.sensor_id >= TSENS_MAX_SENSORS);
+
+ key = "qcom,poll-ms";
+ ret = of_property_read_u32(node, key, &data.poll_ms);
+ if (ret)
+ goto fail;
+
+ key = "qcom,limit-temp";
+ ret = of_property_read_u32(node, key, &data.limit_temp_degC);
+ if (ret)
+ goto fail;
+
+ key = "qcom,temp-hysteresis";
+ ret = of_property_read_u32(node, key, &data.temp_hysteresis_degC);
+ if (ret)
+ goto fail;
+
+ key = "qcom,freq-step";
+ ret = of_property_read_u32(node, key, &data.freq_step);
+
+fail:
+ if (ret)
+ pr_err("%s: Failed reading node=%s, key=%s\n",
+ __func__, node->full_name, key);
+ else
+ ret = msm_thermal_init(&data);
+
+ return ret;
+}
+
+static struct of_device_id msm_thermal_match_table[] = {
+ {.compatible = "qcom,msm-thermal"},
+ {},
+};
+
+static struct platform_driver msm_thermal_device_driver = {
+ .probe = msm_thermal_dev_probe,
+ .driver = {
+ .name = "msm-thermal",
+ .owner = THIS_MODULE,
+ .of_match_table = msm_thermal_match_table,
+ },
+};
+
+int __init msm_thermal_device_init(void)
+{
+ return platform_driver_register(&msm_thermal_device_driver);
+}
diff --git a/include/linux/msm_thermal.h b/include/linux/msm_thermal.h
index 47a8753..8b7bb7c 100644
--- a/include/linux/msm_thermal.h
+++ b/include/linux/msm_thermal.h
@@ -24,11 +24,16 @@
#ifdef CONFIG_THERMAL_MONITOR
extern int msm_thermal_init(struct msm_thermal_data *pdata);
+extern int msm_thermal_device_init(void);
#else
static inline int msm_thermal_init(struct msm_thermal_data *pdata)
{
return -ENOSYS;
}
+static inline int msm_thermal_device_init(void)
+{
+ return -ENOSYS;
+}
#endif
#endif /*__MSM_THERMAL_H*/