thermal: of: improve of-thermal sensor registration API
authorEduardo Valentin <edubezval@gmail.com>
Sat, 8 Nov 2014 01:24:39 +0000 (21:24 -0400)
committerEduardo Valentin <edubezval@gmail.com>
Thu, 20 Nov 2014 14:44:54 +0000 (10:44 -0400)
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>
drivers/hwmon/lm75.c
drivers/hwmon/ntc_thermistor.c
drivers/hwmon/tmp102.c
drivers/thermal/of-thermal.c
drivers/thermal/tegra_soctherm.c
drivers/thermal/ti-soc-thermal/ti-thermal-common.c
include/linux/thermal.h

index d16dbb33a531792834a4ee2bd2dff078ec78f5c9..e7c8bf9093ead28c0946e40c07be4348afbfb1e8 100644 (file)
@@ -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;
 
index 4ff89b2482e48ae12a4f48d2dd269613e1f2c58b..bca8521c8a9bdaadce6041edd2837bc686209fbd 100644 (file)
@@ -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;
index 51719956cc03f52e5b25f5bb12b41725ebc3100e..ba9f478f64ee68e7092d9fa546663cd02a7cf2cb 100644 (file)
@@ -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;
 
index 62143ba3100182462861040ef3c28ce43ec45d00..b7982f0a6eaf42e6e6cb158158b079e5cb804820 100644 (file)
@@ -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;
        struct thermal_zone_device *tzd = ERR_PTR(-ENODEV);
@@ -426,9 +424,7 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id,
 
                if (sensor_specs.np == sensor_np && id == sensor_id) {
                        tzd = thermal_zone_of_add_sensor(child, sensor_np,
-                                                        data,
-                                                        get_temp,
-                                                        get_trend);
+                                                        data, ops);
                        of_node_put(sensor_specs.np);
                        of_node_put(child);
                        goto exit;
@@ -476,8 +472,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);
 }
index 70f7e9ef4355660d80618e67d0fe9cca82b56f29..9197fc05c5cc79abfaff06d9539e5cec9bf09ea5 100644 (file)
@@ -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",
index 9eec26dc0448907873a4832debe79dd9dd16450e..5fd03865e396e373d20e3c8e2dd54c79a26955ee 100644 (file)
@@ -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,
index ef90838b36a072eeed278789c9bbe625fabe32f1..5bc28a70014e889f6b609bfef612674c1824bfd7 100644 (file)
@@ -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;
 }