Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eaa42a57 authored by Hridya Valsaraju's avatar Hridya Valsaraju
Browse files

ANDROID: GKI: drivers: of-thermal: Relate thermal zones using same sensor



A sensor may need to be monitored by two or more thermal governors to
deploy different mitigation strategies to control the device temperature.
To achieve this the sensors driver has to register the same sensor as
multiple thermal zones and then let the different governors monitor and
mitigate. The sensor driver should handle the aggregation of thresholds,
trip notification and synchronization between thermal zones.

Add support in of-thermal to create and handle sibling thermal zones.
Thermal zones that share the same sensor are siblings. To establish a
relationship between then the sibling zones, a sensor meta data is shared
across multiple sibling thermal zones. This meta data will aid in
traversing through all the sibling thermal zones.

Test: build
Bug: 149945768
Signed-off-by: default avatarRam Chandrasekar <rkumbako@codeaurora.org>
Change-Id: I2e26d71ca30927dfa23b58e00a7de246bfebb274
(cherry picked commit from 8a12149c)
Fixes: 3b108348 ("ANDROID: GKI: Add devm_thermal_of_virtual_sensor_register API.")
[hridya: partial cherry-pick from snapshot]
Signed-off-by: default avatarHridya Valsaraju <hridya@google.com>
parent ac3798c2
Loading
Loading
Loading
Loading
+44 −19
Original line number Diff line number Diff line
@@ -649,6 +649,7 @@ thermal_zone_of_add_sensor(struct device_node *zone,
	if (sens_param->ops->set_emul_temp)
		tzd->ops->set_emul_temp = of_thermal_set_emul_temp;

	list_add_tail(&tz->list, &sens_param->first_tz);
	mutex_unlock(&tzd->lock);

	return tzd;
@@ -683,7 +684,9 @@ thermal_zone_of_add_sensor(struct device_node *zone,
 * that refer to it.
 *
 * Return: On success returns a valid struct thermal_zone_device,
 * otherwise, it returns a corresponding ERR_PTR(). Caller must
 * otherwise, it returns a corresponding ERR_PTR(). Incase there are multiple
 * thermal zones referencing the same sensor, the return value will be
 * thermal_zone_device pointer of the first thermal zone. Caller must
 * check the return value with help of IS_ERR() helper.
 */
struct thermal_zone_device *
@@ -692,6 +695,7 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,
{
	struct device_node *np, *child, *sensor_np;
	struct thermal_zone_device *tzd = ERR_PTR(-ENODEV);
	struct thermal_zone_device *first_tzd = NULL;
	struct __sensor_param *sens_param = NULL;

	np = of_find_node_by_name(NULL, "thermal-zones");
@@ -710,11 +714,16 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,
	}
	sens_param->sensor_data = data;
	sens_param->ops = ops;
	INIT_LIST_HEAD(&sens_param->first_tz);
	sens_param->trip_high = INT_MAX;
	sens_param->trip_low = INT_MIN;
	mutex_init(&sens_param->lock);
	sensor_np = of_node_get(dev->of_node);

	for_each_available_child_of_node(np, child) {
		struct of_phandle_args sensor_specs;
		int ret, id;
		struct __thermal_zone *tz;

		/* For now, thermal framework supports only 1 sensor per zone */
		ret = of_parse_phandle_with_args(child, "thermal-sensors",
@@ -735,22 +744,25 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,
		if (sensor_specs.np == sensor_np && id == sensor_id) {
			tzd = thermal_zone_of_add_sensor(child, sensor_np,
							 sens_param);
			if (!IS_ERR(tzd))
				tzd->ops->set_mode(tzd, THERMAL_DEVICE_ENABLED);

			of_node_put(sensor_specs.np);
			of_node_put(child);
			goto exit;
			if (!IS_ERR(tzd)) {
				if (!first_tzd)
					first_tzd = tzd;
				tz = tzd->devdata;
				if (!tz->default_disable)
					tzd->ops->set_mode(tzd,
						THERMAL_DEVICE_ENABLED);
			}
		}
		of_node_put(sensor_specs.np);
	}
exit:
	of_node_put(sensor_np);
	of_node_put(np);

	if (tzd == ERR_PTR(-ENODEV))
	if (!first_tzd) {
		first_tzd = ERR_PTR(-ENODEV);
		kfree(sens_param);
	return tzd;
	}
	return first_tzd;
}
EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_register);

@@ -772,7 +784,9 @@ EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_register);
void thermal_zone_of_sensor_unregister(struct device *dev,
				       struct thermal_zone_device *tzd)
{
	struct __thermal_zone *tz;
	struct __thermal_zone *tz, *next;
	struct thermal_zone_device *pos;
	struct list_head *head;

	if (!dev || !tzd || !tzd->devdata)
		return;
@@ -783,14 +797,20 @@ void thermal_zone_of_sensor_unregister(struct device *dev,
	if (!tz)
		return;

	mutex_lock(&tzd->lock);
	tzd->ops->get_temp = NULL;
	tzd->ops->get_trend = NULL;
	tzd->ops->set_emul_temp = NULL;
	head = &tz->senps->first_tz;
	list_for_each_entry_safe(tz, next, head, list) {
		pos = tz->tzd;
		mutex_lock(&pos->lock);
		pos->ops->get_temp = NULL;
		pos->ops->get_trend = NULL;
		pos->ops->set_emul_temp = NULL;

		list_del(&tz->list);
		if (list_empty(&tz->senps->first_tz))
			kfree(tz->senps);
		tz->senps = NULL;
	mutex_unlock(&tzd->lock);
		mutex_unlock(&pos->lock);
	}
}
EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_unregister);

@@ -1191,6 +1211,7 @@ __init *thermal_of_build_thermal_zone(struct device_node *np)
	if (!tz)
		return ERR_PTR(-ENOMEM);

	INIT_LIST_HEAD(&tz->list);
	ret = of_property_read_u32(np, "polling-delay-passive", &prop);
	if (ret < 0) {
		pr_err("missing polling-delay-passive property\n");
@@ -1207,6 +1228,8 @@ __init *thermal_of_build_thermal_zone(struct device_node *np)

	tz->is_wakeable = of_property_read_bool(np,
					"wake-capable-sensor");
	tz->default_disable = of_property_read_bool(np,
					"disable-thermal-zone");
	/*
	 * REVIST: for now, the thermal framework supports only
	 * one sensor per thermal zone. Thus, we are considering
@@ -1383,7 +1406,9 @@ int __init of_parse_thermal_zones(void)
			kfree(ops);
			of_thermal_free_zone(tz);
			/* attempting to build remaining zones still */
			continue;
		}
		tz->tzd = zone;
	}
	of_node_put(np);