summaryrefslogtreecommitdiff
path: root/drivers/misc/therm_est.c
diff options
context:
space:
mode:
authorJoshua Primero <jprimero@nvidia.com>2012-08-23 16:34:34 -0700
committerMrutyunjay Sawant <msawant@nvidia.com>2012-08-29 07:17:13 -0700
commit4f2776dd6705cf78be19c86b2c67385768ba0631 (patch)
tree4654a944fef752e11f01711805a0b5bcb1e4f6b7 /drivers/misc/therm_est.c
parent604cda21d79ed168e9863f0122eb0c23fa1a901b (diff)
drivers: misc: therm_est: Refactored therm_est
1) Registered therm_est as a platform driver. 2) Driver now registers with linux thermal framework on it's own. 3) Allow the driver to connect with one passive cooling device Change-Id: If37ad1c142a9be0dee3e844b3ffb435cfebeaf01 Signed-off-by: Joshua Primero <jprimero@nvidia.com> Reviewed-on: http://git-master/r/127671 GVS: Gerrit_Virtual_Submit Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com>
Diffstat (limited to 'drivers/misc/therm_est.c')
-rw-r--r--drivers/misc/therm_est.c189
1 files changed, 135 insertions, 54 deletions
diff --git a/drivers/misc/therm_est.c b/drivers/misc/therm_est.c
index e67fc664c7af..d222f5f66289 100644
--- a/drivers/misc/therm_est.c
+++ b/drivers/misc/therm_est.c
@@ -14,6 +14,7 @@
*
*/
+#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/cpufreq.h>
#include <linux/delay.h>
@@ -27,34 +28,22 @@
#include <linux/slab.h>
#include <linux/syscalls.h>
#include <linux/therm_est.h>
-
-int therm_est_get_temp(struct therm_estimator *est, long *temp)
-{
- *temp = est->cur_temp;
- return 0;
-}
-
-int therm_est_set_limits(struct therm_estimator *est,
- long lo_limit,
- long hi_limit)
-{
- est->therm_est_lo_limit = lo_limit;
- est->therm_est_hi_limit = hi_limit;
- return 0;
-}
-
-int therm_est_set_alert(struct therm_estimator *est,
- void (*cb)(void *),
- void *cb_data)
-{
- if ((!cb) || est->callback)
- BUG();
-
- est->callback = cb;
- est->callback_data = cb_data;
-
- return 0;
-}
+#include <linux/thermal.h>
+#include <linux/module.h>
+
+struct therm_estimator {
+ long cur_temp;
+ long polling_period;
+ struct workqueue_struct *workqueue;
+ struct delayed_work therm_est_work;
+ long toffset;
+ int ntemp;
+ int ndevs;
+ struct therm_est_subdevice *devs;
+ struct thermal_zone_device *thz;
+ struct thermal_cooling_device *cdev;
+ long trip_temp;
+};
static void therm_est_work_func(struct work_struct *work)
{
@@ -68,16 +57,16 @@ static void therm_est_work_func(struct work_struct *work)
therm_est_work);
for (i = 0; i < est->ndevs; i++) {
- if (est->devs[i]->get_temp(est->devs[i]->dev_data, &temp))
+ if (est->devs[i].get_temp(est->devs[i].dev_data, &temp))
continue;
- est->devs[i]->hist[(est->ntemp % HIST_LEN)] = temp;
+ est->devs[i].hist[(est->ntemp % HIST_LEN)] = temp;
}
for (i = 0; i < est->ndevs; i++) {
for (j = 0; j < HIST_LEN; j++) {
index = (est->ntemp - j + HIST_LEN) % HIST_LEN;
- sum += est->devs[i]->hist[index] *
- est->devs[i]->coeffs[j];
+ sum += est->devs[i].hist[index] *
+ est->devs[i].coeffs[j];
}
}
@@ -85,46 +74,101 @@ static void therm_est_work_func(struct work_struct *work)
est->ntemp++;
- if (est->callback && ((est->cur_temp >= est->therm_est_hi_limit) ||
- (est->cur_temp <= est->therm_est_lo_limit)))
- est->callback(est->callback_data);
+ if (est->cur_temp >= est->trip_temp)
+ if (est->thz && !est->thz->passive)
+ thermal_zone_device_update(est->thz);
queue_delayed_work(est->workqueue, &est->therm_est_work,
msecs_to_jiffies(est->polling_period));
}
-struct therm_estimator *therm_est_register(
- struct therm_est_subdevice **devs,
- int ndevs,
- long toffset,
- long polling_period)
+static int therm_est_bind(struct thermal_zone_device *thz,
+ struct thermal_cooling_device *cdev)
+{
+ struct therm_estimator *est = thz->devdata;
+
+ if (cdev == est->cdev)
+ thermal_zone_bind_cooling_device(thz, 0, cdev);
+
+ return 0;
+}
+
+static int therm_est_unbind(struct thermal_zone_device *thz,
+ struct thermal_cooling_device *cdev)
+{
+ struct therm_estimator *est = thz->devdata;
+
+ if (cdev == est->cdev)
+ thermal_zone_unbind_cooling_device(thz, 0, cdev);
+
+ return 0;
+}
+
+static int therm_est_get_trip_type(struct thermal_zone_device *thz,
+ int trip,
+ enum thermal_trip_type *type)
+{
+ *type = THERMAL_TRIP_PASSIVE;
+ return 0;
+}
+
+static int therm_est_get_trip_temp(struct thermal_zone_device *thz,
+ int trip,
+ unsigned long *temp)
+{
+ struct therm_estimator *est = thz->devdata;
+
+ *temp = est->trip_temp;
+
+ return 0;
+}
+
+static int therm_est_get_temp(struct thermal_zone_device *thz,
+ unsigned long *temp)
+{
+ struct therm_estimator *est = thz->devdata;
+ *temp = est->cur_temp;
+ return 0;
+}
+
+static struct thermal_zone_device_ops therm_est_ops = {
+ .bind = therm_est_bind,
+ .unbind = therm_est_unbind,
+ .get_trip_type = therm_est_get_trip_type,
+ .get_trip_temp = therm_est_get_trip_temp,
+ .get_temp = therm_est_get_temp,
+};
+
+static int __devinit therm_est_probe(struct platform_device *pdev)
{
int i, j;
long temp;
struct therm_estimator *est;
struct therm_est_subdevice *dev;
+ struct therm_est_data *data;
est = kzalloc(sizeof(struct therm_estimator), GFP_KERNEL);
if (IS_ERR_OR_NULL(est))
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, est);
+
+ data = pdev->dev.platform_data;
- est->devs = devs;
- est->ndevs = ndevs;
- est->toffset = toffset;
- est->polling_period = polling_period;
+ est->devs = data->devs;
+ est->ndevs = data->ndevs;
+ est->toffset = data->toffset;
+ est->polling_period = data->polling_period;
/* initialize history */
- for (i = 0; i < ndevs; i++) {
- dev = est->devs[i];
+ for (i = 0; i < data->ndevs; i++) {
+ dev = &est->devs[i];
- if (dev->get_temp(dev->dev_data, &temp)) {
- kfree(est);
- return ERR_PTR(-EINVAL);
- }
+ if (dev->get_temp(dev->dev_data, &temp))
+ goto err;
- for (j = 0; j < HIST_LEN; j++) {
+ for (j = 0; j < HIST_LEN; j++)
dev->hist[j] = temp;
- }
}
est->workqueue = alloc_workqueue("therm_est",
@@ -135,5 +179,42 @@ struct therm_estimator *therm_est_register(
&est->therm_est_work,
msecs_to_jiffies(est->polling_period));
- return est;
+ est->cdev = data->cdev;
+ est->trip_temp = data->trip_temp;
+
+ est->thz = thermal_zone_device_register("therm_est",
+ 1,
+ est,
+ &therm_est_ops,
+ data->tc1,
+ data->tc2,
+ data->passive_delay,
+ 0);
+ if (IS_ERR_OR_NULL(est->thz))
+ goto err;
+
+ return 0;
+err:
+ kfree(est);
+ return -EINVAL;
+}
+
+static int __devexit therm_est_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver therm_est_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "therm_est",
+ },
+ .probe = therm_est_probe,
+ .remove = __devexit_p(therm_est_remove),
+};
+
+static int __init therm_est_driver_init(void)
+{
+ return platform_driver_register(&therm_est_driver);
}
+module_init(therm_est_driver_init);