diff options
author | Eduardo Valentin <edubezval@gmail.com> | 2014-11-07 20:24:39 -0500 |
---|---|---|
committer | Eduardo Valentin <edubezval@gmail.com> | 2014-11-20 09:44:54 -0500 |
commit | 2251aef64a38db60f4ae7a4a83f9203c6791f196 (patch) | |
tree | eb3fe5a0e6eb2c857f331ed39538a9fb2988939d | |
parent | 66fb84805134c39f00d7c2054c881faa50910390 (diff) |
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: Guenter Roeck <linux@roeck-us.net>
Tested-by: Mikko Perttunen <mikko.perttunen@kapsi.fi>
Reviewed-by: Mikko Perttunen <mikko.perttunen@kapsi.fi>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
-rw-r--r-- | drivers/hwmon/lm75.c | 9 | ||||
-rw-r--r-- | drivers/hwmon/ntc_thermistor.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/tmp102.c | 6 | ||||
-rw-r--r-- | drivers/thermal/of-thermal.c | 39 | ||||
-rw-r--r-- | drivers/thermal/tegra_soctherm.c | 7 | ||||
-rw-r--r-- | drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 8 | ||||
-rw-r--r-- | include/linux/thermal.h | 24 |
7 files changed, 62 insertions, 37 deletions
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index d16dbb33a531..e7c8bf9093ea 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -176,6 +176,10 @@ static struct attribute *lm75_attrs[] = { | |||
176 | }; | 176 | }; |
177 | ATTRIBUTE_GROUPS(lm75); | 177 | ATTRIBUTE_GROUPS(lm75); |
178 | 178 | ||
179 | static const struct thermal_zone_of_device_ops lm75_of_thermal_ops = { | ||
180 | .get_temp = lm75_read_temp, | ||
181 | }; | ||
182 | |||
179 | /*-----------------------------------------------------------------------*/ | 183 | /*-----------------------------------------------------------------------*/ |
180 | 184 | ||
181 | /* device probe and removal */ | 185 | /* device probe and removal */ |
@@ -291,10 +295,9 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
291 | if (IS_ERR(data->hwmon_dev)) | 295 | if (IS_ERR(data->hwmon_dev)) |
292 | return PTR_ERR(data->hwmon_dev); | 296 | return PTR_ERR(data->hwmon_dev); |
293 | 297 | ||
294 | data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, | 298 | data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, 0, |
295 | 0, | ||
296 | data->hwmon_dev, | 299 | data->hwmon_dev, |
297 | lm75_read_temp, NULL); | 300 | &lm75_of_thermal_ops); |
298 | if (IS_ERR(data->tz)) | 301 | if (IS_ERR(data->tz)) |
299 | data->tz = NULL; | 302 | data->tz = NULL; |
300 | 303 | ||
diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index 4ff89b2482e4..bca8521c8a9b 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 = { | |||
486 | .attrs = ntc_attributes, | 486 | .attrs = ntc_attributes, |
487 | }; | 487 | }; |
488 | 488 | ||
489 | static const struct thermal_zone_of_device_ops ntc_of_thermal_ops = { | ||
490 | .get_temp = ntc_read_temp, | ||
491 | }; | ||
492 | |||
489 | static int ntc_thermistor_probe(struct platform_device *pdev) | 493 | static int ntc_thermistor_probe(struct platform_device *pdev) |
490 | { | 494 | { |
491 | const struct of_device_id *of_id = | 495 | const struct of_device_id *of_id = |
@@ -579,7 +583,7 @@ static int ntc_thermistor_probe(struct platform_device *pdev) | |||
579 | pdev_id->name); | 583 | pdev_id->name); |
580 | 584 | ||
581 | data->tz = thermal_zone_of_sensor_register(data->dev, 0, data->dev, | 585 | data->tz = thermal_zone_of_sensor_register(data->dev, 0, data->dev, |
582 | ntc_read_temp, NULL); | 586 | &ntc_of_thermal_ops); |
583 | if (IS_ERR(data->tz)) { | 587 | if (IS_ERR(data->tz)) { |
584 | dev_dbg(&pdev->dev, "Failed to register to thermal fw.\n"); | 588 | dev_dbg(&pdev->dev, "Failed to register to thermal fw.\n"); |
585 | data->tz = NULL; | 589 | data->tz = NULL; |
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 51719956cc03..ba9f478f64ee 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c | |||
@@ -158,6 +158,10 @@ ATTRIBUTE_GROUPS(tmp102); | |||
158 | #define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1) | 158 | #define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1) |
159 | #define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL) | 159 | #define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL) |
160 | 160 | ||
161 | static const struct thermal_zone_of_device_ops tmp102_of_thermal_ops = { | ||
162 | .get_temp = tmp102_read_temp, | ||
163 | }; | ||
164 | |||
161 | static int tmp102_probe(struct i2c_client *client, | 165 | static int tmp102_probe(struct i2c_client *client, |
162 | const struct i2c_device_id *id) | 166 | const struct i2c_device_id *id) |
163 | { | 167 | { |
@@ -215,7 +219,7 @@ static int tmp102_probe(struct i2c_client *client, | |||
215 | } | 219 | } |
216 | tmp102->hwmon_dev = hwmon_dev; | 220 | tmp102->hwmon_dev = hwmon_dev; |
217 | tmp102->tz = thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev, | 221 | tmp102->tz = thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev, |
218 | tmp102_read_temp, NULL); | 222 | &tmp102_of_thermal_ops); |
219 | if (IS_ERR(tmp102->tz)) | 223 | if (IS_ERR(tmp102->tz)) |
220 | tmp102->tz = NULL; | 224 | tmp102->tz = NULL; |
221 | 225 | ||
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index 62143ba31001..b7982f0a6eaf 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/err.h> | 30 | #include <linux/err.h> |
31 | #include <linux/export.h> | 31 | #include <linux/export.h> |
32 | #include <linux/string.h> | 32 | #include <linux/string.h> |
33 | #include <linux/thermal.h> | ||
33 | 34 | ||
34 | #include "thermal_core.h" | 35 | #include "thermal_core.h" |
35 | 36 | ||
@@ -77,8 +78,7 @@ struct __thermal_bind_params { | |||
77 | * @num_tbps: number of thermal bind params | 78 | * @num_tbps: number of thermal bind params |
78 | * @tbps: an array of thermal bind params (0..num_tbps - 1) | 79 | * @tbps: an array of thermal bind params (0..num_tbps - 1) |
79 | * @sensor_data: sensor private data used while reading temperature and trend | 80 | * @sensor_data: sensor private data used while reading temperature and trend |
80 | * @get_temp: sensor callback to read temperature | 81 | * @ops: set of callbacks to handle the thermal zone based on DT |
81 | * @get_trend: sensor callback to read temperature trend | ||
82 | */ | 82 | */ |
83 | 83 | ||
84 | struct __thermal_zone { | 84 | struct __thermal_zone { |
@@ -96,8 +96,7 @@ struct __thermal_zone { | |||
96 | 96 | ||
97 | /* sensor interface */ | 97 | /* sensor interface */ |
98 | void *sensor_data; | 98 | void *sensor_data; |
99 | int (*get_temp)(void *, long *); | 99 | const struct thermal_zone_of_device_ops *ops; |
100 | int (*get_trend)(void *, long *); | ||
101 | }; | 100 | }; |
102 | 101 | ||
103 | /*** DT thermal zone device callbacks ***/ | 102 | /*** DT thermal zone device callbacks ***/ |
@@ -107,10 +106,10 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz, | |||
107 | { | 106 | { |
108 | struct __thermal_zone *data = tz->devdata; | 107 | struct __thermal_zone *data = tz->devdata; |
109 | 108 | ||
110 | if (!data->get_temp) | 109 | if (!data->ops->get_temp) |
111 | return -EINVAL; | 110 | return -EINVAL; |
112 | 111 | ||
113 | return data->get_temp(data->sensor_data, temp); | 112 | return data->ops->get_temp(data->sensor_data, temp); |
114 | } | 113 | } |
115 | 114 | ||
116 | static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, | 115 | 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 | long dev_trend; | 119 | long dev_trend; |
121 | int r; | 120 | int r; |
122 | 121 | ||
123 | if (!data->get_trend) | 122 | if (!data->ops->get_trend) |
124 | return -EINVAL; | 123 | return -EINVAL; |
125 | 124 | ||
126 | r = data->get_trend(data->sensor_data, &dev_trend); | 125 | r = data->ops->get_trend(data->sensor_data, &dev_trend); |
127 | if (r) | 126 | if (r) |
128 | return r; | 127 | return r; |
129 | 128 | ||
@@ -324,8 +323,7 @@ static struct thermal_zone_device_ops of_thermal_ops = { | |||
324 | static struct thermal_zone_device * | 323 | static struct thermal_zone_device * |
325 | thermal_zone_of_add_sensor(struct device_node *zone, | 324 | thermal_zone_of_add_sensor(struct device_node *zone, |
326 | struct device_node *sensor, void *data, | 325 | struct device_node *sensor, void *data, |
327 | int (*get_temp)(void *, long *), | 326 | const struct thermal_zone_of_device_ops *ops) |
328 | int (*get_trend)(void *, long *)) | ||
329 | { | 327 | { |
330 | struct thermal_zone_device *tzd; | 328 | struct thermal_zone_device *tzd; |
331 | struct __thermal_zone *tz; | 329 | struct __thermal_zone *tz; |
@@ -336,9 +334,11 @@ thermal_zone_of_add_sensor(struct device_node *zone, | |||
336 | 334 | ||
337 | tz = tzd->devdata; | 335 | tz = tzd->devdata; |
338 | 336 | ||
337 | if (!ops) | ||
338 | return ERR_PTR(-EINVAL); | ||
339 | |||
339 | mutex_lock(&tzd->lock); | 340 | mutex_lock(&tzd->lock); |
340 | tz->get_temp = get_temp; | 341 | tz->ops = ops; |
341 | tz->get_trend = get_trend; | ||
342 | tz->sensor_data = data; | 342 | tz->sensor_data = data; |
343 | 343 | ||
344 | tzd->ops->get_temp = of_thermal_get_temp; | 344 | tzd->ops->get_temp = of_thermal_get_temp; |
@@ -356,8 +356,7 @@ thermal_zone_of_add_sensor(struct device_node *zone, | |||
356 | * than one sensors | 356 | * than one sensors |
357 | * @data: a private pointer (owned by the caller) that will be passed | 357 | * @data: a private pointer (owned by the caller) that will be passed |
358 | * back, when a temperature reading is needed. | 358 | * back, when a temperature reading is needed. |
359 | * @get_temp: a pointer to a function that reads the sensor temperature. | 359 | * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp. |
360 | * @get_trend: a pointer to a function that reads the sensor temperature trend. | ||
361 | * | 360 | * |
362 | * This function will search the list of thermal zones described in device | 361 | * This function will search the list of thermal zones described in device |
363 | * tree and look for the zone that refer to the sensor device pointed by | 362 | * 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 | * check the return value with help of IS_ERR() helper. | 381 | * check the return value with help of IS_ERR() helper. |
383 | */ | 382 | */ |
384 | struct thermal_zone_device * | 383 | struct thermal_zone_device * |
385 | thermal_zone_of_sensor_register(struct device *dev, int sensor_id, | 384 | thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data, |
386 | void *data, int (*get_temp)(void *, long *), | 385 | const struct thermal_zone_of_device_ops *ops) |
387 | int (*get_trend)(void *, long *)) | ||
388 | { | 386 | { |
389 | struct device_node *np, *child, *sensor_np; | 387 | struct device_node *np, *child, *sensor_np; |
390 | struct thermal_zone_device *tzd = ERR_PTR(-ENODEV); | 388 | struct thermal_zone_device *tzd = ERR_PTR(-ENODEV); |
@@ -426,9 +424,7 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, | |||
426 | 424 | ||
427 | if (sensor_specs.np == sensor_np && id == sensor_id) { | 425 | if (sensor_specs.np == sensor_np && id == sensor_id) { |
428 | tzd = thermal_zone_of_add_sensor(child, sensor_np, | 426 | tzd = thermal_zone_of_add_sensor(child, sensor_np, |
429 | data, | 427 | data, ops); |
430 | get_temp, | ||
431 | get_trend); | ||
432 | of_node_put(sensor_specs.np); | 428 | of_node_put(sensor_specs.np); |
433 | of_node_put(child); | 429 | of_node_put(child); |
434 | goto exit; | 430 | goto exit; |
@@ -476,8 +472,7 @@ void thermal_zone_of_sensor_unregister(struct device *dev, | |||
476 | tzd->ops->get_temp = NULL; | 472 | tzd->ops->get_temp = NULL; |
477 | tzd->ops->get_trend = NULL; | 473 | tzd->ops->get_trend = NULL; |
478 | 474 | ||
479 | tz->get_temp = NULL; | 475 | tz->ops = NULL; |
480 | tz->get_trend = NULL; | ||
481 | tz->sensor_data = NULL; | 476 | tz->sensor_data = NULL; |
482 | mutex_unlock(&tzd->lock); | 477 | mutex_unlock(&tzd->lock); |
483 | } | 478 | } |
diff --git a/drivers/thermal/tegra_soctherm.c b/drivers/thermal/tegra_soctherm.c index 70f7e9ef4355..9197fc05c5cc 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) | |||
317 | return 0; | 317 | return 0; |
318 | } | 318 | } |
319 | 319 | ||
320 | static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = { | ||
321 | .get_temp = tegra_thermctl_get_temp, | ||
322 | }; | ||
323 | |||
320 | static const struct of_device_id tegra_soctherm_of_match[] = { | 324 | static const struct of_device_id tegra_soctherm_of_match[] = { |
321 | { .compatible = "nvidia,tegra124-soctherm" }, | 325 | { .compatible = "nvidia,tegra124-soctherm" }, |
322 | { }, | 326 | { }, |
@@ -416,8 +420,7 @@ static int tegra_soctherm_probe(struct platform_device *pdev) | |||
416 | zone->shift = t124_thermctl_temp_zones[i].shift; | 420 | zone->shift = t124_thermctl_temp_zones[i].shift; |
417 | 421 | ||
418 | tz = thermal_zone_of_sensor_register(&pdev->dev, i, zone, | 422 | tz = thermal_zone_of_sensor_register(&pdev->dev, i, zone, |
419 | tegra_thermctl_get_temp, | 423 | &tegra_of_thermal_ops); |
420 | NULL); | ||
421 | if (IS_ERR(tz)) { | 424 | if (IS_ERR(tz)) { |
422 | err = PTR_ERR(tz); | 425 | err = PTR_ERR(tz); |
423 | dev_err(&pdev->dev, "failed to register sensor: %d\n", | 426 | 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 9eec26dc0448..5fd03865e396 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, | |||
286 | return ti_thermal_get_trip_temp(thermal, OMAP_TRIP_NUMBER - 1, temp); | 286 | return ti_thermal_get_trip_temp(thermal, OMAP_TRIP_NUMBER - 1, temp); |
287 | } | 287 | } |
288 | 288 | ||
289 | static const struct thermal_zone_of_device_ops ti_of_thermal_ops = { | ||
290 | .get_temp = __ti_thermal_get_temp, | ||
291 | .get_trend = __ti_thermal_get_trend, | ||
292 | }; | ||
293 | |||
289 | static struct thermal_zone_device_ops ti_thermal_ops = { | 294 | static struct thermal_zone_device_ops ti_thermal_ops = { |
290 | .get_temp = ti_thermal_get_temp, | 295 | .get_temp = ti_thermal_get_temp, |
291 | .get_trend = ti_thermal_get_trend, | 296 | .get_trend = ti_thermal_get_trend, |
@@ -333,8 +338,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, | |||
333 | 338 | ||
334 | /* in case this is specified by DT */ | 339 | /* in case this is specified by DT */ |
335 | data->ti_thermal = thermal_zone_of_sensor_register(bgp->dev, id, | 340 | data->ti_thermal = thermal_zone_of_sensor_register(bgp->dev, id, |
336 | data, __ti_thermal_get_temp, | 341 | data, &ti_of_thermal_ops); |
337 | __ti_thermal_get_trend); | ||
338 | if (IS_ERR(data->ti_thermal)) { | 342 | if (IS_ERR(data->ti_thermal)) { |
339 | /* Create thermal zone */ | 343 | /* Create thermal zone */ |
340 | data->ti_thermal = thermal_zone_device_register(domain, | 344 | data->ti_thermal = thermal_zone_device_register(domain, |
diff --git a/include/linux/thermal.h b/include/linux/thermal.h index ef90838b36a0..5bc28a70014e 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h | |||
@@ -289,19 +289,31 @@ struct thermal_genl_event { | |||
289 | enum events event; | 289 | enum events event; |
290 | }; | 290 | }; |
291 | 291 | ||
292 | /** | ||
293 | * struct thermal_zone_of_device_ops - scallbacks for handling DT based zones | ||
294 | * | ||
295 | * Mandatory: | ||
296 | * @get_temp: a pointer to a function that reads the sensor temperature. | ||
297 | * | ||
298 | * Optional: | ||
299 | * @get_trend: a pointer to a function that reads the sensor temperature trend. | ||
300 | */ | ||
301 | struct thermal_zone_of_device_ops { | ||
302 | int (*get_temp)(void *, long *); | ||
303 | int (*get_trend)(void *, long *); | ||
304 | }; | ||
305 | |||
292 | /* Function declarations */ | 306 | /* Function declarations */ |
293 | #ifdef CONFIG_THERMAL_OF | 307 | #ifdef CONFIG_THERMAL_OF |
294 | struct thermal_zone_device * | 308 | struct thermal_zone_device * |
295 | thermal_zone_of_sensor_register(struct device *dev, int id, | 309 | thermal_zone_of_sensor_register(struct device *dev, int id, void *data, |
296 | void *data, int (*get_temp)(void *, long *), | 310 | const struct thermal_zone_of_device_ops *ops); |
297 | int (*get_trend)(void *, long *)); | ||
298 | void thermal_zone_of_sensor_unregister(struct device *dev, | 311 | void thermal_zone_of_sensor_unregister(struct device *dev, |
299 | struct thermal_zone_device *tz); | 312 | struct thermal_zone_device *tz); |
300 | #else | 313 | #else |
301 | static inline struct thermal_zone_device * | 314 | static inline struct thermal_zone_device * |
302 | thermal_zone_of_sensor_register(struct device *dev, int id, | 315 | thermal_zone_of_sensor_register(struct device *dev, int id, void *data, |
303 | void *data, int (*get_temp)(void *, long *), | 316 | const struct thermal_zone_of_device_ops *ops) |
304 | int (*get_trend)(void *, long *)) | ||
305 | { | 317 | { |
306 | return NULL; | 318 | return NULL; |
307 | } | 319 | } |