[PATCH v3 2/3] thermal: of: Add devm_thermal_of_zone_register_with_params() variant

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Commit b1ae92dcfa8e ("thermal: core: Make struct thermal_zone_device
definition internal") moved the thermal_zone_device struct from global
thermal.h to internal thermal_core.h making the internal variables of
the struct not accessible from the user drivers (without inclusing
thermal_core.h).

One case where the internal variables might be needed is for the
thermal_zone_params in the context of OF probe.

In such case a thermal driver might have default params that can only be
parsed at runtime (example present in EFUSE or derived from other values)
and wants to update the values in the thermal_zone_params for the
thermal device. (to use the helper like get_slope() or get_offset())

To account for this scenario, introduce a variant of
devm_thermal_of_zone_register(),
devm_thermal_of_zone_register_with_params(), that takes and additional
variable and permits to register the thermal device with default
thermal_zone_params.

To follow OF implementation, these params are only treated as default
params and are ignored if a related one is defined in DT. (example a
slope or offset value defined in DT have priority to the default one
passed in a thermal_device_params struct)

This permits to support both implementation, use the helpers and expose
these values in sysfs.

Signed-off-by: Christian Marangi <ansuelsmth@xxxxxxxxx>
---
Changes v3:
- Add this patch

 drivers/thermal/thermal_of.c | 67 +++++++++++++++++++++++++++++-------
 include/linux/thermal.h      | 13 +++++++
 2 files changed, 68 insertions(+), 12 deletions(-)

diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
index aa34b6e82e26..c9a65eb9ee1e 100644
--- a/drivers/thermal/thermal_of.c
+++ b/drivers/thermal/thermal_of.c
@@ -250,7 +250,7 @@ static void thermal_of_parameters_init(struct device_node *np,
 {
 	int coef[2];
 	int ncoef = ARRAY_SIZE(coef);
-	int prop, ret;
+	int prop;
 
 	tzp->no_hwmon = true;
 
@@ -262,14 +262,11 @@ static void thermal_of_parameters_init(struct device_node *np,
 	 * thermal zone. Thus, we are considering only the first two
 	 * values as slope and offset.
 	 */
-	ret = of_property_read_u32_array(np, "coefficients", coef, ncoef);
-	if (ret) {
-		coef[0] = 1;
-		coef[1] = 0;
+	if (!of_property_read_u32_array(np, "coefficients", coef, ncoef)) {
+		tzp->slope = coef[0];
+		tzp->offset = coef[1];
 	}
 
-	tzp->slope = coef[0];
-	tzp->offset = coef[1];
 }
 
 static struct device_node *thermal_of_zone_get_by_name(struct thermal_zone_device *tz)
@@ -458,10 +455,15 @@ static void thermal_of_zone_unregister(struct thermal_zone_device *tz)
  * zone properties and registers new thermal zone with those
  * properties.
  *
+ * The passed thermal zone params are treated as default values and ignored if
+ * the related property is found in DT. (DT params have priority to
+ * default values)
+ *
  * @sensor: A device node pointer corresponding to the sensor in the device tree
  * @id: An integer as sensor identifier
  * @data: A private data to be stored in the thermal zone dedicated private area
  * @ops: A set of thermal sensor ops
+ * @tzp: a pointer to the default thermal zone params structure associated with the sensor
  *
  * Return: a valid thermal zone structure pointer on success.
  *	- EINVAL: if the device tree thermal description is malformed
@@ -469,12 +471,12 @@ static void thermal_of_zone_unregister(struct thermal_zone_device *tz)
  *	- Other negative errors are returned by the underlying called functions
  */
 static struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor, int id, void *data,
-							    const struct thermal_zone_device_ops *ops)
+							    const struct thermal_zone_device_ops *ops,
+							    struct thermal_zone_params *tzp)
 {
 	struct thermal_zone_device_ops of_ops = *ops;
 	struct thermal_zone_device *tz;
 	struct thermal_trip *trips;
-	struct thermal_zone_params tzp = {};
 	struct device_node *np;
 	const char *action;
 	int delay, pdelay;
@@ -500,7 +502,7 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node *
 		goto out_kfree_trips;
 	}
 
-	thermal_of_parameters_init(np, &tzp);
+	thermal_of_parameters_init(np, tzp);
 
 	of_ops.bind = thermal_of_bind;
 	of_ops.unbind = thermal_of_unbind;
@@ -511,7 +513,7 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node *
 			of_ops.critical = thermal_zone_device_critical_reboot;
 
 	tz = thermal_zone_device_register_with_trips(np->name, trips, ntrips,
-						     data, &of_ops, &tzp,
+						     data, &of_ops, tzp,
 						     pdelay, delay);
 	if (IS_ERR(tz)) {
 		ret = PTR_ERR(tz);
@@ -566,6 +568,7 @@ static int devm_thermal_of_zone_match(struct device *dev, void *res,
 struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, int sensor_id, void *data,
 							  const struct thermal_zone_device_ops *ops)
 {
+	struct thermal_zone_params tzp = { .slope = 1 };
 	struct thermal_zone_device **ptr, *tzd;
 
 	ptr = devres_alloc(devm_thermal_of_zone_release, sizeof(*ptr),
@@ -573,7 +576,7 @@ struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, in
 	if (!ptr)
 		return ERR_PTR(-ENOMEM);
 
-	tzd = thermal_of_zone_register(dev->of_node, sensor_id, data, ops);
+	tzd = thermal_of_zone_register(dev->of_node, sensor_id, data, ops, &tzp);
 	if (IS_ERR(tzd)) {
 		devres_free(ptr);
 		return tzd;
@@ -586,6 +589,46 @@ struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, in
 }
 EXPORT_SYMBOL_GPL(devm_thermal_of_zone_register);
 
+/**
+ * devm_thermal_of_zone_register_with_params - register a thermal tied with the sensor life cycle
+ *					       with default params
+ *
+ * This function is the device version of the thermal_of_zone_register() function.
+ *
+ * @dev: a device structure pointer to sensor to be tied with the thermal zone OF life cycle
+ * @sensor_id: the sensor identifier
+ * @data: a pointer to a private data to be stored in the thermal zone 'devdata' field
+ * @ops: a pointer to the ops structure associated with the sensor
+ * @tzp: a pointer to the default thermal zone params structure associated with the sensor
+ *
+ * The thermal zone params are treated as default values and ignored if the related property is
+ * found in DT. (DT params have priority to default values)
+ */
+struct thermal_zone_device *devm_thermal_of_zone_register_with_params(struct device *dev, int sensor_id,
+								      void *data,
+								      const struct thermal_zone_device_ops *ops,
+								      struct thermal_zone_params *tzp)
+{
+	struct thermal_zone_device **ptr, *tzd;
+
+	ptr = devres_alloc(devm_thermal_of_zone_release, sizeof(*ptr),
+			   GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	tzd = thermal_of_zone_register(dev->of_node, sensor_id, data, ops, tzp);
+	if (IS_ERR(tzd)) {
+		devres_free(ptr);
+		return tzd;
+	}
+
+	*ptr = tzd;
+	devres_add(dev, ptr);
+
+	return tzd;
+}
+EXPORT_SYMBOL_GPL(devm_thermal_of_zone_register_with_params);
+
 /**
  * devm_thermal_of_zone_unregister - Resource managed version of
  *				thermal_of_zone_unregister().
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index f1155c0439c4..8130e111210d 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -180,6 +180,10 @@ struct thermal_zone_params {
 #ifdef CONFIG_THERMAL_OF
 struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, int id, void *data,
 							  const struct thermal_zone_device_ops *ops);
+struct thermal_zone_device *devm_thermal_of_zone_register_with_params(struct device *dev, int id,
+								      void *data,
+								      const struct thermal_zone_device_ops *ops,
+								      struct thermal_zone_params *tzp);
 
 void devm_thermal_of_zone_unregister(struct device *dev, struct thermal_zone_device *tz);
 
@@ -192,6 +196,15 @@ struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, in
 	return ERR_PTR(-ENOTSUPP);
 }
 
+static inline
+struct thermal_zone_device *devm_thermal_of_zone_register_with_params(struct device *dev, int id,
+								      void *data,
+								      const struct thermal_zone_device_ops *ops,
+								      struct thermal_zone_params *tzp)
+{
+	return ERR_PTR(-ENOTSUPP);
+}
+
 static inline void devm_thermal_of_zone_unregister(struct device *dev,
 						   struct thermal_zone_device *tz)
 {
-- 
2.45.2





[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux