[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1416492733-1624-2-git-send-email-edubezval@gmail.com>
Date: Thu, 20 Nov 2014 10:12:13 -0400
From: Eduardo Valentin <edubezval@...il.com>
To: Guenter Roeck <linux@...ck-us.net>,
Linux PM <linux-pm@...r.kernel.org>
Cc: Caesar Wang <caesar.wang@...k-chips.com>, Wei Ni <wni@...dia.com>,
Lukasz Majewski <l.majewski@...sung.com>,
Mikko Perttunen <mikko.perttunen@...si.fi>,
Eduardo Valentin <edubezval@...il.com>,
Alexandre Courbot <gnurou@...il.com>,
devicetree@...r.kernel.org, Grant Likely <grant.likely@...aro.org>,
Jean Delvare <jdelvare@...e.de>, linux-kernel@...r.kernel.org,
linux-tegra@...r.kernel.org, lm-sensors@...sensors.org,
Rob Herring <robh+dt@...nel.org>,
Stephen Warren <swarren@...dotorg.org>,
Thierry Reding <thierry.reding@...il.com>,
Zhang Rui <rui.zhang@...el.com>
Subject: [PATCHv5 1/1] thermal: of: improve of-thermal sensor registration API
Different drivers request API extensions in of-thermal. For this reason,
additional callbacks are required to fit the new drivers needs.
The current API implementation expects the registering sensor driver
to provide a get_temp and get_trend callbacks as function parameters.
As the amount of callbacks is growing, this patch changes the existing
implementation to use a .ops field to hold all the of thermal callbacks
to sensor drivers.
This patch also changes the existing of-thermal users to fit the new
API design. No functional change is introduced in this patch.
Cc: Alexandre Courbot <gnurou@...il.com>
Cc: devicetree@...r.kernel.org
Cc: Grant Likely <grant.likely@...aro.org>
Cc: Guenter Roeck <linux@...ck-us.net>
Cc: Jean Delvare <jdelvare@...e.de>
Cc: linux-kernel@...r.kernel.org
Cc: linux-pm@...r.kernel.org
Cc: linux-tegra@...r.kernel.org
Cc: lm-sensors@...sensors.org
Cc: Rob Herring <robh+dt@...nel.org>
Cc: Stephen Warren <swarren@...dotorg.org>
Cc: Thierry Reding <thierry.reding@...il.com>
Cc: Zhang Rui <rui.zhang@...el.com>
Tested-by: Mikko Perttunen <mikko.perttunen@...si.fi>
Reviewed-by: Mikko Perttunen <mikko.perttunen@...si.fi>
Reviewed-by: Alexandre Courbot <acourbot@...dia.com>
Reviewed-by: Lukasz Majewski <l.majewski@...sung.com>
Signed-off-by: Eduardo Valentin <edubezval@...il.com>
---
drivers/hwmon/lm75.c | 9 +++--
drivers/hwmon/ntc_thermistor.c | 6 +++-
drivers/hwmon/tmp102.c | 6 +++-
drivers/thermal/of-thermal.c | 39 ++++++++++------------
drivers/thermal/tegra_soctherm.c | 7 ++--
drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 8 +++--
include/linux/thermal.h | 24 +++++++++----
7 files changed, 62 insertions(+), 37 deletions(-)
---
Difference from V4:
- Corrected comment about which callbacks are currently mandatory.
- Fixed compilation error when !CONFIG_OF_THERMAL.
Difference from V3:
- Keep the same behavior regarding callback checks.
Change in behavior may be sent in a separate patch.
Difference from V2:
- Fix wrong assignment in tegra driver.
Difference from V1:
- Fix error handling when .get_trend is not provided.
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index d16dbb3..e7c8bf9 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -176,6 +176,10 @@ static struct attribute *lm75_attrs[] = {
};
ATTRIBUTE_GROUPS(lm75);
+static const struct thermal_zone_of_device_ops lm75_of_thermal_ops = {
+ .get_temp = lm75_read_temp,
+};
+
/*-----------------------------------------------------------------------*/
/* device probe and removal */
@@ -291,10 +295,9 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (IS_ERR(data->hwmon_dev))
return PTR_ERR(data->hwmon_dev);
- data->tz = thermal_zone_of_sensor_register(data->hwmon_dev,
- 0,
+ data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, 0,
data->hwmon_dev,
- lm75_read_temp, NULL);
+ &lm75_of_thermal_ops);
if (IS_ERR(data->tz))
data->tz = NULL;
diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c
index 4ff89b2..bca8521c8 100644
--- a/drivers/hwmon/ntc_thermistor.c
+++ b/drivers/hwmon/ntc_thermistor.c
@@ -486,6 +486,10 @@ static const struct attribute_group ntc_attr_group = {
.attrs = ntc_attributes,
};
+static const struct thermal_zone_of_device_ops ntc_of_thermal_ops = {
+ .get_temp = ntc_read_temp,
+};
+
static int ntc_thermistor_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
@@ -579,7 +583,7 @@ static int ntc_thermistor_probe(struct platform_device *pdev)
pdev_id->name);
data->tz = thermal_zone_of_sensor_register(data->dev, 0, data->dev,
- ntc_read_temp, NULL);
+ &ntc_of_thermal_ops);
if (IS_ERR(data->tz)) {
dev_dbg(&pdev->dev, "Failed to register to thermal fw.\n");
data->tz = NULL;
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c
index 5171995..ba9f478 100644
--- a/drivers/hwmon/tmp102.c
+++ b/drivers/hwmon/tmp102.c
@@ -158,6 +158,10 @@ ATTRIBUTE_GROUPS(tmp102);
#define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1)
#define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL)
+static const struct thermal_zone_of_device_ops tmp102_of_thermal_ops = {
+ .get_temp = tmp102_read_temp,
+};
+
static int tmp102_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -215,7 +219,7 @@ static int tmp102_probe(struct i2c_client *client,
}
tmp102->hwmon_dev = hwmon_dev;
tmp102->tz = thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev,
- tmp102_read_temp, NULL);
+ &tmp102_of_thermal_ops);
if (IS_ERR(tmp102->tz))
tmp102->tz = NULL;
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index f8eb625..b6e7a26 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -30,6 +30,7 @@
#include <linux/err.h>
#include <linux/export.h>
#include <linux/string.h>
+#include <linux/thermal.h>
#include "thermal_core.h"
@@ -77,8 +78,7 @@ struct __thermal_bind_params {
* @num_tbps: number of thermal bind params
* @tbps: an array of thermal bind params (0..num_tbps - 1)
* @sensor_data: sensor private data used while reading temperature and trend
- * @get_temp: sensor callback to read temperature
- * @get_trend: sensor callback to read temperature trend
+ * @ops: set of callbacks to handle the thermal zone based on DT
*/
struct __thermal_zone {
@@ -96,8 +96,7 @@ struct __thermal_zone {
/* sensor interface */
void *sensor_data;
- int (*get_temp)(void *, long *);
- int (*get_trend)(void *, long *);
+ const struct thermal_zone_of_device_ops *ops;
};
/*** DT thermal zone device callbacks ***/
@@ -107,10 +106,10 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz,
{
struct __thermal_zone *data = tz->devdata;
- if (!data->get_temp)
+ if (!data->ops->get_temp)
return -EINVAL;
- return data->get_temp(data->sensor_data, temp);
+ return data->ops->get_temp(data->sensor_data, temp);
}
static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
@@ -120,10 +119,10 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
long dev_trend;
int r;
- if (!data->get_trend)
+ if (!data->ops->get_trend)
return -EINVAL;
- r = data->get_trend(data->sensor_data, &dev_trend);
+ r = data->ops->get_trend(data->sensor_data, &dev_trend);
if (r)
return r;
@@ -324,8 +323,7 @@ static struct thermal_zone_device_ops of_thermal_ops = {
static struct thermal_zone_device *
thermal_zone_of_add_sensor(struct device_node *zone,
struct device_node *sensor, void *data,
- int (*get_temp)(void *, long *),
- int (*get_trend)(void *, long *))
+ const struct thermal_zone_of_device_ops *ops)
{
struct thermal_zone_device *tzd;
struct __thermal_zone *tz;
@@ -336,9 +334,11 @@ thermal_zone_of_add_sensor(struct device_node *zone,
tz = tzd->devdata;
+ if (!ops)
+ return ERR_PTR(-EINVAL);
+
mutex_lock(&tzd->lock);
- tz->get_temp = get_temp;
- tz->get_trend = get_trend;
+ tz->ops = ops;
tz->sensor_data = data;
tzd->ops->get_temp = of_thermal_get_temp;
@@ -356,8 +356,7 @@ thermal_zone_of_add_sensor(struct device_node *zone,
* than one sensors
* @data: a private pointer (owned by the caller) that will be passed
* back, when a temperature reading is needed.
- * @get_temp: a pointer to a function that reads the sensor temperature.
- * @get_trend: a pointer to a function that reads the sensor temperature trend.
+ * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp.
*
* This function will search the list of thermal zones described in device
* tree and look for the zone that refer to the sensor device pointed by
@@ -382,9 +381,8 @@ thermal_zone_of_add_sensor(struct device_node *zone,
* check the return value with help of IS_ERR() helper.
*/
struct thermal_zone_device *
-thermal_zone_of_sensor_register(struct device *dev, int sensor_id,
- void *data, int (*get_temp)(void *, long *),
- int (*get_trend)(void *, long *))
+thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,
+ const struct thermal_zone_of_device_ops *ops)
{
struct device_node *np, *child, *sensor_np;
@@ -424,9 +422,7 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id,
if (sensor_specs.np == sensor_np && id == sensor_id) {
of_node_put(np);
return thermal_zone_of_add_sensor(child, sensor_np,
- data,
- get_temp,
- get_trend);
+ data, ops);
}
}
of_node_put(np);
@@ -468,8 +464,7 @@ void thermal_zone_of_sensor_unregister(struct device *dev,
tzd->ops->get_temp = NULL;
tzd->ops->get_trend = NULL;
- tz->get_temp = NULL;
- tz->get_trend = NULL;
+ tz->ops = NULL;
tz->sensor_data = NULL;
mutex_unlock(&tzd->lock);
}
diff --git a/drivers/thermal/tegra_soctherm.c b/drivers/thermal/tegra_soctherm.c
index 70f7e9e..9197fc0 100644
--- a/drivers/thermal/tegra_soctherm.c
+++ b/drivers/thermal/tegra_soctherm.c
@@ -317,6 +317,10 @@ static int tegra_thermctl_get_temp(void *data, long *out_temp)
return 0;
}
+static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
+ .get_temp = tegra_thermctl_get_temp,
+};
+
static const struct of_device_id tegra_soctherm_of_match[] = {
{ .compatible = "nvidia,tegra124-soctherm" },
{ },
@@ -416,8 +420,7 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
zone->shift = t124_thermctl_temp_zones[i].shift;
tz = thermal_zone_of_sensor_register(&pdev->dev, i, zone,
- tegra_thermctl_get_temp,
- NULL);
+ &tegra_of_thermal_ops);
if (IS_ERR(tz)) {
err = PTR_ERR(tz);
dev_err(&pdev->dev, "failed to register sensor: %d\n",
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
index 9eec26d..5fd0386 100644
--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
@@ -286,6 +286,11 @@ static int ti_thermal_get_crit_temp(struct thermal_zone_device *thermal,
return ti_thermal_get_trip_temp(thermal, OMAP_TRIP_NUMBER - 1, temp);
}
+static const struct thermal_zone_of_device_ops ti_of_thermal_ops = {
+ .get_temp = __ti_thermal_get_temp,
+ .get_trend = __ti_thermal_get_trend,
+};
+
static struct thermal_zone_device_ops ti_thermal_ops = {
.get_temp = ti_thermal_get_temp,
.get_trend = ti_thermal_get_trend,
@@ -333,8 +338,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
/* in case this is specified by DT */
data->ti_thermal = thermal_zone_of_sensor_register(bgp->dev, id,
- data, __ti_thermal_get_temp,
- __ti_thermal_get_trend);
+ data, &ti_of_thermal_ops);
if (IS_ERR(data->ti_thermal)) {
/* Create thermal zone */
data->ti_thermal = thermal_zone_device_register(domain,
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index ef90838..5bc28a7 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -289,19 +289,31 @@ struct thermal_genl_event {
enum events event;
};
+/**
+ * struct thermal_zone_of_device_ops - scallbacks for handling DT based zones
+ *
+ * Mandatory:
+ * @get_temp: a pointer to a function that reads the sensor temperature.
+ *
+ * Optional:
+ * @get_trend: a pointer to a function that reads the sensor temperature trend.
+ */
+struct thermal_zone_of_device_ops {
+ int (*get_temp)(void *, long *);
+ int (*get_trend)(void *, long *);
+};
+
/* Function declarations */
#ifdef CONFIG_THERMAL_OF
struct thermal_zone_device *
-thermal_zone_of_sensor_register(struct device *dev, int id,
- void *data, int (*get_temp)(void *, long *),
- int (*get_trend)(void *, long *));
+thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
+ const struct thermal_zone_of_device_ops *ops);
void thermal_zone_of_sensor_unregister(struct device *dev,
struct thermal_zone_device *tz);
#else
static inline struct thermal_zone_device *
-thermal_zone_of_sensor_register(struct device *dev, int id,
- void *data, int (*get_temp)(void *, long *),
- int (*get_trend)(void *, long *))
+thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
+ const struct thermal_zone_of_device_ops *ops)
{
return NULL;
}
--
2.1.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists