Commit 2251aef6 authored by Eduardo Valentin's avatar Eduardo Valentin

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@gmail.com>
Cc: devicetree@vger.kernel.org
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Jean Delvare <jdelvare@suse.de>
Cc: linux-kernel@vger.kernel.org
Cc: linux-pm@vger.kernel.org
Cc: linux-tegra@vger.kernel.org
Cc: lm-sensors@lm-sensors.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Zhang Rui <rui.zhang@intel.com>
Acked-by: default avatarGuenter Roeck <linux@roeck-us.net>
Tested-by: default avatarMikko Perttunen <mikko.perttunen@kapsi.fi>
Reviewed-by: default avatarMikko Perttunen <mikko.perttunen@kapsi.fi>
Reviewed-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Reviewed-by: default avatarLukasz Majewski <l.majewski@samsung.com>
Signed-off-by: default avatarEduardo Valentin <edubezval@gmail.com>
parent 66fb8480
...@@ -176,6 +176,10 @@ static struct attribute *lm75_attrs[] = { ...@@ -176,6 +176,10 @@ static struct attribute *lm75_attrs[] = {
}; };
ATTRIBUTE_GROUPS(lm75); ATTRIBUTE_GROUPS(lm75);
static const struct thermal_zone_of_device_ops lm75_of_thermal_ops = {
.get_temp = lm75_read_temp,
};
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* device probe and removal */ /* device probe and removal */
...@@ -291,10 +295,9 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -291,10 +295,9 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (IS_ERR(data->hwmon_dev)) if (IS_ERR(data->hwmon_dev))
return PTR_ERR(data->hwmon_dev); return PTR_ERR(data->hwmon_dev);
data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, 0,
0,
data->hwmon_dev, data->hwmon_dev,
lm75_read_temp, NULL); &lm75_of_thermal_ops);
if (IS_ERR(data->tz)) if (IS_ERR(data->tz))
data->tz = NULL; data->tz = NULL;
......
...@@ -486,6 +486,10 @@ static const struct attribute_group ntc_attr_group = { ...@@ -486,6 +486,10 @@ static const struct attribute_group ntc_attr_group = {
.attrs = ntc_attributes, .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) static int ntc_thermistor_probe(struct platform_device *pdev)
{ {
const struct of_device_id *of_id = const struct of_device_id *of_id =
...@@ -579,7 +583,7 @@ static int ntc_thermistor_probe(struct platform_device *pdev) ...@@ -579,7 +583,7 @@ static int ntc_thermistor_probe(struct platform_device *pdev)
pdev_id->name); pdev_id->name);
data->tz = thermal_zone_of_sensor_register(data->dev, 0, data->dev, 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)) { if (IS_ERR(data->tz)) {
dev_dbg(&pdev->dev, "Failed to register to thermal fw.\n"); dev_dbg(&pdev->dev, "Failed to register to thermal fw.\n");
data->tz = NULL; data->tz = NULL;
......
...@@ -158,6 +158,10 @@ ATTRIBUTE_GROUPS(tmp102); ...@@ -158,6 +158,10 @@ ATTRIBUTE_GROUPS(tmp102);
#define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1) #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) #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, static int tmp102_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
...@@ -215,7 +219,7 @@ static int tmp102_probe(struct i2c_client *client, ...@@ -215,7 +219,7 @@ static int tmp102_probe(struct i2c_client *client,
} }
tmp102->hwmon_dev = hwmon_dev; tmp102->hwmon_dev = hwmon_dev;
tmp102->tz = thermal_zone_of_sensor_register(hwmon_dev, 0, 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)) if (IS_ERR(tmp102->tz))
tmp102->tz = NULL; tmp102->tz = NULL;
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/thermal.h>
#include "thermal_core.h" #include "thermal_core.h"
...@@ -77,8 +78,7 @@ struct __thermal_bind_params { ...@@ -77,8 +78,7 @@ struct __thermal_bind_params {
* @num_tbps: number of thermal bind params * @num_tbps: number of thermal bind params
* @tbps: an array of thermal bind params (0..num_tbps - 1) * @tbps: an array of thermal bind params (0..num_tbps - 1)
* @sensor_data: sensor private data used while reading temperature and trend * @sensor_data: sensor private data used while reading temperature and trend
* @get_temp: sensor callback to read temperature * @ops: set of callbacks to handle the thermal zone based on DT
* @get_trend: sensor callback to read temperature trend
*/ */
struct __thermal_zone { struct __thermal_zone {
...@@ -96,8 +96,7 @@ struct __thermal_zone { ...@@ -96,8 +96,7 @@ struct __thermal_zone {
/* sensor interface */ /* sensor interface */
void *sensor_data; void *sensor_data;
int (*get_temp)(void *, long *); const struct thermal_zone_of_device_ops *ops;
int (*get_trend)(void *, long *);
}; };
/*** DT thermal zone device callbacks ***/ /*** DT thermal zone device callbacks ***/
...@@ -107,10 +106,10 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz, ...@@ -107,10 +106,10 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz,
{ {
struct __thermal_zone *data = tz->devdata; struct __thermal_zone *data = tz->devdata;
if (!data->get_temp) if (!data->ops->get_temp)
return -EINVAL; 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, 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, ...@@ -120,10 +119,10 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
long dev_trend; long dev_trend;
int r; int r;
if (!data->get_trend) if (!data->ops->get_trend)
return -EINVAL; return -EINVAL;
r = data->get_trend(data->sensor_data, &dev_trend); r = data->ops->get_trend(data->sensor_data, &dev_trend);
if (r) if (r)
return r; return r;
...@@ -324,8 +323,7 @@ static struct thermal_zone_device_ops of_thermal_ops = { ...@@ -324,8 +323,7 @@ static struct thermal_zone_device_ops of_thermal_ops = {
static struct thermal_zone_device * static struct thermal_zone_device *
thermal_zone_of_add_sensor(struct device_node *zone, thermal_zone_of_add_sensor(struct device_node *zone,
struct device_node *sensor, void *data, struct device_node *sensor, void *data,
int (*get_temp)(void *, long *), const struct thermal_zone_of_device_ops *ops)
int (*get_trend)(void *, long *))
{ {
struct thermal_zone_device *tzd; struct thermal_zone_device *tzd;
struct __thermal_zone *tz; struct __thermal_zone *tz;
...@@ -336,9 +334,11 @@ thermal_zone_of_add_sensor(struct device_node *zone, ...@@ -336,9 +334,11 @@ thermal_zone_of_add_sensor(struct device_node *zone,
tz = tzd->devdata; tz = tzd->devdata;
if (!ops)
return ERR_PTR(-EINVAL);
mutex_lock(&tzd->lock); mutex_lock(&tzd->lock);
tz->get_temp = get_temp; tz->ops = ops;
tz->get_trend = get_trend;
tz->sensor_data = data; tz->sensor_data = data;
tzd->ops->get_temp = of_thermal_get_temp; tzd->ops->get_temp = of_thermal_get_temp;
...@@ -356,8 +356,7 @@ thermal_zone_of_add_sensor(struct device_node *zone, ...@@ -356,8 +356,7 @@ thermal_zone_of_add_sensor(struct device_node *zone,
* than one sensors * than one sensors
* @data: a private pointer (owned by the caller) that will be passed * @data: a private pointer (owned by the caller) that will be passed
* back, when a temperature reading is needed. * back, when a temperature reading is needed.
* @get_temp: a pointer to a function that reads the sensor temperature. * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp.
* @get_trend: a pointer to a function that reads the sensor temperature trend.
* *
* This function will search the list of thermal zones described in device * 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 * 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, ...@@ -382,9 +381,8 @@ thermal_zone_of_add_sensor(struct device_node *zone,
* check the return value with help of IS_ERR() helper. * check the return value with help of IS_ERR() helper.
*/ */
struct thermal_zone_device * struct thermal_zone_device *
thermal_zone_of_sensor_register(struct device *dev, int sensor_id, thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,
void *data, int (*get_temp)(void *, long *), const struct thermal_zone_of_device_ops *ops)
int (*get_trend)(void *, long *))
{ {
struct device_node *np, *child, *sensor_np; struct device_node *np, *child, *sensor_np;
struct thermal_zone_device *tzd = ERR_PTR(-ENODEV); struct thermal_zone_device *tzd = ERR_PTR(-ENODEV);
...@@ -426,9 +424,7 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, ...@@ -426,9 +424,7 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id,
if (sensor_specs.np == sensor_np && id == sensor_id) { if (sensor_specs.np == sensor_np && id == sensor_id) {
tzd = thermal_zone_of_add_sensor(child, sensor_np, tzd = thermal_zone_of_add_sensor(child, sensor_np,
data, data, ops);
get_temp,
get_trend);
of_node_put(sensor_specs.np); of_node_put(sensor_specs.np);
of_node_put(child); of_node_put(child);
goto exit; goto exit;
...@@ -476,8 +472,7 @@ void thermal_zone_of_sensor_unregister(struct device *dev, ...@@ -476,8 +472,7 @@ void thermal_zone_of_sensor_unregister(struct device *dev,
tzd->ops->get_temp = NULL; tzd->ops->get_temp = NULL;
tzd->ops->get_trend = NULL; tzd->ops->get_trend = NULL;
tz->get_temp = NULL; tz->ops = NULL;
tz->get_trend = NULL;
tz->sensor_data = NULL; tz->sensor_data = NULL;
mutex_unlock(&tzd->lock); mutex_unlock(&tzd->lock);
} }
......
...@@ -317,6 +317,10 @@ static int tegra_thermctl_get_temp(void *data, long *out_temp) ...@@ -317,6 +317,10 @@ static int tegra_thermctl_get_temp(void *data, long *out_temp)
return 0; 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[] = { static const struct of_device_id tegra_soctherm_of_match[] = {
{ .compatible = "nvidia,tegra124-soctherm" }, { .compatible = "nvidia,tegra124-soctherm" },
{ }, { },
...@@ -416,8 +420,7 @@ static int tegra_soctherm_probe(struct platform_device *pdev) ...@@ -416,8 +420,7 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
zone->shift = t124_thermctl_temp_zones[i].shift; zone->shift = t124_thermctl_temp_zones[i].shift;
tz = thermal_zone_of_sensor_register(&pdev->dev, i, zone, tz = thermal_zone_of_sensor_register(&pdev->dev, i, zone,
tegra_thermctl_get_temp, &tegra_of_thermal_ops);
NULL);
if (IS_ERR(tz)) { if (IS_ERR(tz)) {
err = PTR_ERR(tz); err = PTR_ERR(tz);
dev_err(&pdev->dev, "failed to register sensor: %d\n", dev_err(&pdev->dev, "failed to register sensor: %d\n",
......
...@@ -286,6 +286,11 @@ static int ti_thermal_get_crit_temp(struct thermal_zone_device *thermal, ...@@ -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); 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 = { static struct thermal_zone_device_ops ti_thermal_ops = {
.get_temp = ti_thermal_get_temp, .get_temp = ti_thermal_get_temp,
.get_trend = ti_thermal_get_trend, .get_trend = ti_thermal_get_trend,
...@@ -333,8 +338,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, ...@@ -333,8 +338,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
/* in case this is specified by DT */ /* in case this is specified by DT */
data->ti_thermal = thermal_zone_of_sensor_register(bgp->dev, id, data->ti_thermal = thermal_zone_of_sensor_register(bgp->dev, id,
data, __ti_thermal_get_temp, data, &ti_of_thermal_ops);
__ti_thermal_get_trend);
if (IS_ERR(data->ti_thermal)) { if (IS_ERR(data->ti_thermal)) {
/* Create thermal zone */ /* Create thermal zone */
data->ti_thermal = thermal_zone_device_register(domain, data->ti_thermal = thermal_zone_device_register(domain,
......
...@@ -289,19 +289,31 @@ struct thermal_genl_event { ...@@ -289,19 +289,31 @@ struct thermal_genl_event {
enum events 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 */ /* Function declarations */
#ifdef CONFIG_THERMAL_OF #ifdef CONFIG_THERMAL_OF
struct thermal_zone_device * struct thermal_zone_device *
thermal_zone_of_sensor_register(struct device *dev, int id, thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
void *data, int (*get_temp)(void *, long *), const struct thermal_zone_of_device_ops *ops);
int (*get_trend)(void *, long *));
void thermal_zone_of_sensor_unregister(struct device *dev, void thermal_zone_of_sensor_unregister(struct device *dev,
struct thermal_zone_device *tz); struct thermal_zone_device *tz);
#else #else
static inline struct thermal_zone_device * static inline struct thermal_zone_device *
thermal_zone_of_sensor_register(struct device *dev, int id, thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
void *data, int (*get_temp)(void *, long *), const struct thermal_zone_of_device_ops *ops)
int (*get_trend)(void *, long *))
{ {
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment