summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Sabatier <s-sabatier1@ti.com>2012-04-24 16:20:57 -0500
committerPraneeth Bajjuri <praneeth@ti.com>2012-05-03 16:49:11 -0500
commit9d0225607080a4a654be64705d133ef68d3e6e8c (patch)
treed998486296861b1abec74d0bc6a433758f6276c1
parentca6fabb772d6e8ed6e40c7a76db765a51dda8f7d (diff)
downloadomap-omapzoom-9d0225607080a4a654be64705d133ef68d3e6e8c.tar.gz
TI thermal framework: added "case" temperature sensor
This patch adds the "case" temperature sensor to the thermal framework. This is an implementation of a temperature harvester based on the temperature coming from another thermal domain. The case sensor to be collecting temperature reports from another thermal domain, this way there is no dependency with a specif driver or register access. This fake sensor will be requesting from the thermal framework the temperature on a specific domain, either "cpu" or "pcb". The framework is assumed to have the zone properly setup with a proper sensor to report its temperature. On this patch, the source domain is set to be "cpu", meaning it will average the OMAP BG sensor. The way to specify which domain will be used as source is platform data. Thus, this fake sensor code can be reused, independently of the thermal domain designed to be the source of the case temperature management/control. The parameters that can change the behavior of this fake sensor can be changed via debug entries (currently in sysfs). The averaging window is implemented by means of a dummy circular buffer. Once the buffer is full, we do simple math addition and subtraction to keep the sum always reflecting the elements in the buffer. Change-Id: I6b6b74e1c815ac82e8b9922c5156dfefe93d2ff9 Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com> Signed-off-by: Sebastien Sabatier <s-sabatier1@ti.com> Signed-off-by: Radhesh Fadnis <radhesh.fadnis@ti.com>
-rw-r--r--arch/arm/mach-omap2/Makefile1
-rw-r--r--arch/arm/mach-omap2/case_temp_sensor_device.c76
-rw-r--r--arch/arm/plat-omap/include/plat/case_temperature_sensor.h36
-rw-r--r--drivers/staging/thermal_framework/Kconfig1
-rw-r--r--drivers/staging/thermal_framework/Makefile3
-rw-r--r--drivers/staging/thermal_framework/sensor/Kconfig10
-rw-r--r--drivers/staging/thermal_framework/sensor/Makefile4
-rw-r--r--drivers/staging/thermal_framework/sensor/case_temp_sensor.c435
8 files changed, 565 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 9cbb3961545b..6b9b76075e17 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_OMAP_SCM_DEV) += scm_device.o
obj-$(CONFIG_TWL4030_CORE) += omap_twl4030.o
obj-$(CONFIG_OMAP_TPS6236X) += omap_tps6236x.o
obj-$(CONFIG_MFD_PALMAS) += omap_palmas.o
+obj-$(CONFIG_CASE_TEMP_SENSOR) += case_temp_sensor_device.o
# SMP support ONLY available for OMAP4
obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
diff --git a/arch/arm/mach-omap2/case_temp_sensor_device.c b/arch/arm/mach-omap2/case_temp_sensor_device.c
new file mode 100644
index 000000000000..410fe5168dbc
--- /dev/null
+++ b/arch/arm/mach-omap2/case_temp_sensor_device.c
@@ -0,0 +1,76 @@
+/*
+ * Case Temperature sensor device file
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Sebastien Sabatier <s-sabatier1@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <plat/omap_device.h>
+#include "control.h"
+#include "pm.h"
+#include <plat/case_temperature_sensor.h>
+
+static int case_temp_sensor_dev_init(struct omap_hwmod *oh, void *user)
+{
+ struct case_temp_sensor_pdata *temp_sensor_pdata;
+ struct omap_device *od;
+ static int i;
+ int ret = 0;
+
+ temp_sensor_pdata =
+ kzalloc(sizeof(struct case_temp_sensor_pdata), GFP_KERNEL);
+ if (!temp_sensor_pdata) {
+ pr_err
+ ("%s: Unable to allocate memory for %s.Error!\n",
+ __func__, oh->name);
+ return -ENOMEM;
+ }
+
+ temp_sensor_pdata->name = "case_temp_sensor";
+ temp_sensor_pdata->source_domain = "cpu";
+
+ od = omap_device_build(temp_sensor_pdata->name, i, oh,
+ temp_sensor_pdata,
+ sizeof(*temp_sensor_pdata),
+ NULL, 0, 0);
+ if (IS_ERR(od)) {
+ pr_warning("%s: Could not build omap_device for %s: %s.\n\n",
+ __func__, temp_sensor_pdata->name, oh->name);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ i++;
+done:
+ kfree(temp_sensor_pdata);
+ return ret;
+}
+
+int __init case_devinit_temp_sensor(void)
+{
+ if (!(cpu_is_omap446x() || cpu_is_omap54xx()))
+ return 0;
+
+ return omap_hwmod_for_each_by_class("thermal_sensor",
+ case_temp_sensor_dev_init, NULL);
+}
+
+arch_initcall(case_devinit_temp_sensor);
diff --git a/arch/arm/plat-omap/include/plat/case_temperature_sensor.h b/arch/arm/plat-omap/include/plat/case_temperature_sensor.h
new file mode 100644
index 000000000000..e77c3e38ffa2
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/case_temperature_sensor.h
@@ -0,0 +1,36 @@
+/*
+ * OMAP446x Temperature sensor header file
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: J Keerthy <j-keerthy@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CASE_TEMPERATURE_SENSOR_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CASE_TEMPERATURE_SENSOR_H
+
+/*
+ * case_temp_sensor platform data
+ * @name - name
+ * @source_domain - name of the domain to fetch temperature
+ */
+struct case_temp_sensor_pdata {
+ char *name;
+ const char *source_domain;
+};
+
+#endif
diff --git a/drivers/staging/thermal_framework/Kconfig b/drivers/staging/thermal_framework/Kconfig
index 122bd3e9bd5d..b27dbdf2803a 100644
--- a/drivers/staging/thermal_framework/Kconfig
+++ b/drivers/staging/thermal_framework/Kconfig
@@ -26,3 +26,4 @@ config OMAP_THERMAL
processors.
source "drivers/staging/thermal_framework/governor/Kconfig"
+source "drivers/staging/thermal_framework/sensor/Kconfig"
diff --git a/drivers/staging/thermal_framework/Makefile b/drivers/staging/thermal_framework/Makefile
index bdae4d550c95..b709baa1995b 100644
--- a/drivers/staging/thermal_framework/Makefile
+++ b/drivers/staging/thermal_framework/Makefile
@@ -2,4 +2,5 @@
# Makefile for sensor chip drivers.
#
obj-$(CONFIG_THERMAL_FRAMEWORK) += thermal_framework.o \
- governor/
+ governor/ \
+ sensor/
diff --git a/drivers/staging/thermal_framework/sensor/Kconfig b/drivers/staging/thermal_framework/sensor/Kconfig
new file mode 100644
index 000000000000..78902eefc878
--- /dev/null
+++ b/drivers/staging/thermal_framework/sensor/Kconfig
@@ -0,0 +1,10 @@
+#
+# Thermal Temp sensor configuration
+#
+
+config CASE_TEMP_SENSOR
+ bool "Case temp sensor support"
+ depends on THERMAL_FRAMEWORK && OMAP_THERMAL
+ help
+ Enabling this config will give support for the case
+ temp sensor for the OMAP platform.
diff --git a/drivers/staging/thermal_framework/sensor/Makefile b/drivers/staging/thermal_framework/sensor/Makefile
new file mode 100644
index 000000000000..535927a5538c
--- /dev/null
+++ b/drivers/staging/thermal_framework/sensor/Makefile
@@ -0,0 +1,4 @@
+#
+# Makefile for sensor chip drivers.
+#
+obj-$(CONFIG_CASE_TEMP_SENSOR) += case_temp_sensor.o
diff --git a/drivers/staging/thermal_framework/sensor/case_temp_sensor.c b/drivers/staging/thermal_framework/sensor/case_temp_sensor.c
new file mode 100644
index 000000000000..751366a44d7d
--- /dev/null
+++ b/drivers/staging/thermal_framework/sensor/case_temp_sensor.c
@@ -0,0 +1,435 @@
+/*
+ * Case Temperature sensor driver file
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Sebastien Sabatier <s-sabatier1@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <plat/case_temperature_sensor.h>
+
+#include <linux/thermal_framework.h>
+
+#define REPORT_DELAY_MS 250
+#define AVERAGE_NUMBER_MAX 200
+#define OMAP_ADC_START_VALUE 530
+#define OMAP_ADC_END_VALUE 932
+#define INIT_T_HOT 20000
+#define INIT_T_COLD 19000
+
+/*
+ * case_temp_sensor structure
+ * @pdev - Platform device pointer
+ * @dev - device pointer
+ * @sensor_mutex - Mutex for sysfs, irq and PM
+ */
+struct case_temp_sensor {
+ struct device *dev;
+ struct mutex sensor_mutex;
+ struct thermal_dev *therm_fw;
+ char domain[10];
+ struct delayed_work case_sensor_work;
+ int work_delay;
+ int avg_is_valid;
+ int window_sum;
+ int sample_idx;
+ int threshold_hot;
+ int threshold_cold;
+ int hot_event;
+ int average_number;
+ int sensor_temp_table[AVERAGE_NUMBER_MAX];
+};
+
+static int case_read_average_temp(struct case_temp_sensor *temp_sensor,
+ const char *domain)
+{
+ int i;
+ int tmp;
+ int sensor_temp;
+
+ sensor_temp = thermal_lookup_temp(domain);
+
+ /* if on-die sensor does not report a correct value, then return */
+ if (sensor_temp < 0)
+ return -EINVAL;
+
+ if (temp_sensor->sample_idx == temp_sensor->average_number) {
+ temp_sensor->avg_is_valid = 1;
+ temp_sensor->sample_idx = 0;
+ }
+
+ tmp = temp_sensor->sensor_temp_table[temp_sensor->sample_idx];
+ temp_sensor->sensor_temp_table[temp_sensor->sample_idx++] = sensor_temp;
+ temp_sensor->window_sum += sensor_temp;
+
+ if (temp_sensor->avg_is_valid) {
+ temp_sensor->window_sum -= tmp;
+ tmp = temp_sensor->average_number;
+ } else {
+ tmp = temp_sensor->sample_idx;
+ }
+
+ for (i = 0; i < temp_sensor->average_number; i++) {
+ pr_debug("sensor_temp_table[%d] = %d\n", i,
+ temp_sensor->sensor_temp_table[i]);
+ }
+
+ return temp_sensor->window_sum / tmp;
+}
+
+static int case_report_temp(struct thermal_dev *tdev)
+{
+ struct platform_device *pdev = to_platform_device(tdev->dev);
+ struct case_temp_sensor_pdata *pd = pdev->dev.platform_data;
+ struct case_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
+ int current_temp;
+
+ current_temp = case_read_average_temp(temp_sensor, pd->source_domain);
+ temp_sensor->therm_fw->current_temp = current_temp;
+
+ pr_debug("%s: case temp %d valid %d\n", __func__,
+ temp_sensor->therm_fw->current_temp,
+ temp_sensor->avg_is_valid);
+ mutex_lock(&temp_sensor->sensor_mutex);
+ if ((temp_sensor->therm_fw->current_temp != -EINVAL) &&
+ (temp_sensor->avg_is_valid == 1)) {
+ /* if we are hot, keep sending reports, whatever is hotevent */
+ if (current_temp >= temp_sensor->threshold_hot) {
+ /* first update the zone, hotevent goes 0 */
+ mutex_unlock(&temp_sensor->sensor_mutex);
+ thermal_sensor_set_temp(temp_sensor->therm_fw);
+ mutex_lock(&temp_sensor->sensor_mutex);
+ kobject_uevent(&temp_sensor->dev->kobj, KOBJ_CHANGE);
+ /* now hotevent back to 1 until we reach cold thres */
+ temp_sensor->hot_event = 1;
+ }
+ if ((current_temp < temp_sensor->threshold_cold) &&
+ (temp_sensor->hot_event == 1)) {
+ mutex_unlock(&temp_sensor->sensor_mutex);
+ thermal_sensor_set_temp(temp_sensor->therm_fw);
+ mutex_lock(&temp_sensor->sensor_mutex);
+ kobject_uevent(&temp_sensor->dev->kobj, KOBJ_CHANGE);
+ temp_sensor->hot_event = 0;
+ }
+ }
+ mutex_unlock(&temp_sensor->sensor_mutex);
+
+ return temp_sensor->therm_fw->current_temp;
+}
+
+static int case_set_temp_thresh(struct thermal_dev *tdev, int min, int max)
+{
+ struct platform_device *pdev = to_platform_device(tdev->dev);
+ struct case_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
+
+ if (max < min) {
+ pr_err("%s:Min is greater then the max\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&temp_sensor->sensor_mutex);
+ temp_sensor->threshold_cold = min;
+ temp_sensor->threshold_hot = max;
+ temp_sensor->hot_event = 0;
+ pr_info("%s:threshold_cold %d, threshold_hot %d\n", __func__,
+ min, max);
+ mutex_unlock(&temp_sensor->sensor_mutex);
+
+ return 0;
+}
+
+static int case_report_avg_temp(struct thermal_dev *tdev)
+{
+ struct platform_device *pdev = to_platform_device(tdev->dev);
+ struct case_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
+
+ if (temp_sensor->avg_is_valid)
+ return temp_sensor->window_sum / temp_sensor->average_number;
+ else
+ return temp_sensor->window_sum / temp_sensor->sample_idx;
+}
+
+/*
+ * debugfs hook functions
+ */
+static int average_get(void *data, u64 *val)
+{
+ struct case_temp_sensor *temp_sensor = (struct case_temp_sensor *)data;
+ struct platform_device *pdev = to_platform_device(temp_sensor->dev);
+ struct case_temp_sensor_pdata *pd = pdev->dev.platform_data;
+
+ *val = case_read_average_temp(temp_sensor, pd->source_domain);
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(average_fops, average_get, NULL, "%llu\n");
+
+static int report_delay_get(void *data, u64 *val)
+{
+ struct case_temp_sensor *temp_sensor = (struct case_temp_sensor *)data;
+
+ *val = temp_sensor->work_delay;
+
+ return 0;
+}
+
+static int report_delay_set(void *data, u64 val)
+{
+ struct case_temp_sensor *temp_sensor = (struct case_temp_sensor *)data;
+
+ mutex_lock(&temp_sensor->sensor_mutex);
+ temp_sensor->work_delay = (int)val;
+ mutex_unlock(&temp_sensor->sensor_mutex);
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(report_delay_fops, report_delay_get,
+ report_delay_set, "%llu\n");
+
+static int average_number_get(void *data, u64 *val)
+{
+ struct case_temp_sensor *temp_sensor = (struct case_temp_sensor *)data;
+
+ *val = temp_sensor->average_number;
+
+ return 0;
+}
+
+static int average_number_set(void *data, u64 val)
+{
+ struct case_temp_sensor *temp_sensor = (struct case_temp_sensor *)data;
+
+ mutex_lock(&temp_sensor->sensor_mutex);
+ temp_sensor->average_number = (int)val;
+ mutex_unlock(&temp_sensor->sensor_mutex);
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(average_number_fops, average_number_get,
+ average_number_set, "%llu\n");
+
+static int case_sensor_register_debug_entries(struct thermal_dev *tdev,
+ struct dentry *d)
+{
+ struct platform_device *pdev = to_platform_device(tdev->dev);
+ struct case_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
+
+ (void) debugfs_create_file("average_temp",
+ S_IRUGO, d, temp_sensor,
+ &average_fops);
+ (void) debugfs_create_file("report_delay_ms",
+ S_IRUGO | S_IWUSR, d, temp_sensor,
+ &report_delay_fops);
+ (void) debugfs_create_file("average_number",
+ S_IRUGO | S_IWUSR, d, temp_sensor,
+ &average_number_fops);
+ return 0;
+}
+
+static struct thermal_dev_ops case_sensor_ops = {
+ .set_temp_thresh = case_set_temp_thresh,
+ .report_temp = case_report_avg_temp,
+#ifdef CONFIG_THERMAL_FRAMEWORK_DEBUG
+ .register_debug_entries = case_sensor_register_debug_entries,
+#endif
+};
+
+static void case_sensor_delayed_work_fn(struct work_struct *work)
+{
+ struct case_temp_sensor *temp_sensor =
+ container_of(work, struct case_temp_sensor,
+ case_sensor_work.work);
+
+ case_report_temp(temp_sensor->therm_fw);
+ schedule_delayed_work(&temp_sensor->case_sensor_work,
+ msecs_to_jiffies(temp_sensor->work_delay));
+}
+
+static int __devinit case_temp_sensor_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct case_temp_sensor_pdata *pdata = pdev->dev.platform_data;
+ struct case_temp_sensor *temp_sensor;
+ struct resource *mem;
+ int ret = 0;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
+ return -EINVAL;
+ }
+
+ temp_sensor = kzalloc(sizeof(struct case_temp_sensor), GFP_KERNEL);
+ if (!temp_sensor)
+ return -ENOMEM;
+
+ /* Init delayed work for Case sensor temperature */
+ INIT_DELAYED_WORK(&temp_sensor->case_sensor_work,
+ case_sensor_delayed_work_fn);
+
+ mutex_init(&temp_sensor->sensor_mutex);
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "%s:no mem resource\n", __func__);
+ ret = -EINVAL;
+ goto free_temp_sensor;
+ }
+
+ temp_sensor->dev = dev;
+
+ pm_runtime_enable(dev);
+
+ kobject_uevent(&pdev->dev.kobj, KOBJ_ADD);
+ platform_set_drvdata(pdev, temp_sensor);
+
+ temp_sensor->therm_fw = kzalloc(sizeof(struct thermal_dev), GFP_KERNEL);
+ if (temp_sensor->therm_fw) {
+ temp_sensor->therm_fw->name = "case_sensor";
+ temp_sensor->therm_fw->domain_name = "case";
+ temp_sensor->therm_fw->dev = temp_sensor->dev;
+ temp_sensor->therm_fw->dev_ops = &case_sensor_ops;
+ thermal_sensor_dev_register(temp_sensor->therm_fw);
+ } else {
+ dev_err(&pdev->dev, "%s:Cannot alloc memory for thermal fw\n",
+ __func__);
+ ret = -ENOMEM;
+ goto free_temp_sensor;
+ }
+
+ temp_sensor->threshold_hot = INIT_T_HOT;
+ temp_sensor->threshold_cold = INIT_T_COLD;
+ temp_sensor->hot_event = 0;
+ temp_sensor->average_number = 20;
+
+ temp_sensor->work_delay = REPORT_DELAY_MS;
+ schedule_work(&temp_sensor->case_sensor_work.work);
+
+ dev_info(&pdev->dev, "%s : '%s'\n", temp_sensor->therm_fw->name,
+ pdata->name);
+
+ return 0;
+free_temp_sensor:
+ mutex_destroy(&temp_sensor->sensor_mutex);
+ kfree(temp_sensor);
+ return ret;
+}
+
+static int __devexit case_temp_sensor_remove(struct platform_device *pdev)
+{
+ struct case_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
+
+ thermal_sensor_dev_unregister(temp_sensor->therm_fw);
+ kfree(temp_sensor->therm_fw);
+ kobject_uevent(&temp_sensor->dev->kobj, KOBJ_REMOVE);
+ cancel_delayed_work_sync(&temp_sensor->case_sensor_work);
+ platform_set_drvdata(pdev, NULL);
+ mutex_destroy(&temp_sensor->sensor_mutex);
+ kfree(temp_sensor);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int case_temp_sensor_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct case_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
+
+ cancel_delayed_work_sync(&temp_sensor->case_sensor_work);
+
+ return 0;
+}
+
+static int case_temp_sensor_resume(struct platform_device *pdev)
+{
+ struct case_temp_sensor *temp_sensor = platform_get_drvdata(pdev);
+
+ schedule_work(&temp_sensor->case_sensor_work.work);
+
+ return 0;
+}
+
+#else
+case_temp_sensor_suspend NULL
+case_temp_sensor_resume NULL
+
+#endif /* CONFIG_PM */
+
+static int case_temp_sensor_runtime_suspend(struct device *dev)
+{
+ struct case_temp_sensor *temp_sensor =
+ platform_get_drvdata(to_platform_device(dev));
+
+ cancel_delayed_work_sync(&temp_sensor->case_sensor_work);
+
+ return 0;
+}
+
+static int case_temp_sensor_runtime_resume(struct device *dev)
+{
+ struct case_temp_sensor *temp_sensor =
+ platform_get_drvdata(to_platform_device(dev));
+
+ schedule_work(&temp_sensor->case_sensor_work.work);
+
+ return 0;
+}
+
+static const struct dev_pm_ops case_temp_sensor_dev_pm_ops = {
+ .runtime_suspend = case_temp_sensor_runtime_suspend,
+ .runtime_resume = case_temp_sensor_runtime_resume,
+};
+
+static struct platform_driver case_temp_sensor_driver = {
+ .probe = case_temp_sensor_probe,
+ .remove = case_temp_sensor_remove,
+ .suspend = case_temp_sensor_suspend,
+ .resume = case_temp_sensor_resume,
+ .driver = {
+ .name = "case_temp_sensor",
+ .pm = &case_temp_sensor_dev_pm_ops,
+ },
+};
+
+int __init case_temp_sensor_init(void)
+{
+ return platform_driver_register(&case_temp_sensor_driver);
+}
+
+static void __exit case_temp_sensor_exit(void)
+{
+ platform_driver_unregister(&case_temp_sensor_driver);
+}
+
+module_init(case_temp_sensor_init);
+module_exit(case_temp_sensor_exit);
+
+MODULE_DESCRIPTION("Case Temperature Sensor Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Texas Instruments Inc");