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

Commit 3f355772 authored by Ivaylo Georgiev's avatar Ivaylo Georgiev
Browse files

Revert "ANDROID: GKI: Add devm_thermal_of_virtual_sensor_register API."



This reverts commit 3b108348.

This is a preparation change for merging android-4.19.110 into
msm-4.19 branch.

Retain existing virtual sensor thermal zone solution for thermal core.

Change-Id: I8972e71245ab9c85d84055255625affa6d22a555
Signed-off-by: default avatarIvaylo Georgiev <irgeorgiev@codeaurora.org>
parent 1984fffe
Loading
Loading
Loading
Loading
+23 −277
Original line number Diff line number Diff line
@@ -13,10 +13,6 @@
#include <linux/err.h>
#include <linux/export.h>
#include <linux/string.h>
#include <linux/list.h>

#define CREATE_TRACE_POINTS
#include <trace/events/thermal_virtual.h>

#include "thermal_core.h"

@@ -39,23 +35,6 @@ struct __thermal_bind_params {
	unsigned long max;
};

/**
 * struct __sensor_param - Holds individual sensor data
 * @sensor_data: sensor driver private data passed as input argument
 * @ops: sensor driver ops
 * @trip_high: last trip high value programmed in the sensor driver
 * @trip_low: last trip low value programmed in the sensor driver
 * @lock: mutex lock acquired before updating the trip temperatures
 * @first_tz: list head pointing the first thermal zone
 */
struct __sensor_param {
	void *sensor_data;
	const struct thermal_zone_of_device_ops *ops;
	int trip_high, trip_low;
	struct mutex lock;
	struct list_head first_tz;
};

/**
 * struct __thermal_zone - internal representation of a thermal zone
 * @mode: current thermal zone device mode (enabled/disabled)
@@ -63,14 +42,12 @@ struct __sensor_param {
 * @polling_delay: zone polling interval
 * @slope: slope of the temperature adjustment curve
 * @offset: offset of the temperature adjustment curve
 * @default_disable: Keep the thermal zone disabled by default
 * @tzd: thermal zone device pointer for this sensor
 * @ntrips: number of trip points
 * @trips: an array of trip points (0..ntrips - 1)
 * @num_tbps: number of thermal bind params
 * @tbps: an array of thermal bind params (0..num_tbps - 1)
 * @senps: sensor related parameters
 * @list: sibling thermal zone
 * @sensor_data: sensor private data used while reading temperature and trend
 * @ops: set of callbacks to handle the thermal zone based on DT
 */

struct __thermal_zone {
@@ -79,8 +56,6 @@ struct __thermal_zone {
	int polling_delay;
	int slope;
	int offset;
	struct thermal_zone_device *tzd;
	bool default_disable;

	/* trip data */
	int ntrips;
@@ -90,101 +65,22 @@ struct __thermal_zone {
	int num_tbps;
	struct __thermal_bind_params *tbps;

	struct list_head list;
	/* sensor interface */
	struct __sensor_param *senps;
};

/**
 * struct virtual_sensor - internal representation of a virtual thermal zone
 * @num_sensors - number of sensors this virtual sensor will reference to
 *		  estimate temperature
 * @tz - Array of thermal zones of the sensors this virtual sensor will use
 *	 to estimate temperature
 * @virt_tz - Virtual thermal zone pointer
 * @logic - aggregation logic to be used to estimate the temperature
 * @last_reading - last estimated temperature
 * @coefficients - array of coefficients to be used for weighted aggregation
 *		       logic
 * @avg_offset - offset value to be used for the weighted aggregation logic
 * @avg_denominator - denominator value to be used for the weighted aggregation
 *			logic
 */
struct virtual_sensor {
	int                        num_sensors;
	struct thermal_zone_device *tz[THERMAL_MAX_VIRT_SENSORS];
	struct thermal_zone_device *virt_tz;
	enum aggregation_logic     logic;
	int                        last_reading;
	int                        coefficients[THERMAL_MAX_VIRT_SENSORS];
	int                        avg_offset;
	int                        avg_denominator;
	void *sensor_data;
	const struct thermal_zone_of_device_ops *ops;
};


/***   DT thermal zone device callbacks   ***/

static int virt_sensor_read_temp(void *data, int *val)
{
	struct virtual_sensor *sens = data;
	int idx, temp = 0, ret = 0;

	for (idx = 0; idx < sens->num_sensors; idx++) {
		int sens_temp = 0;

		ret = thermal_zone_get_temp(sens->tz[idx], &sens_temp);
		if (ret) {
			pr_err("virt zone: sensor[%s] read error:%d\n",
				sens->tz[idx]->type, ret);
			return ret;
		}
		switch (sens->logic) {
		case VIRT_COUNT_THRESHOLD:
			if ((sens->coefficients[idx] < 0 &&
			     sens_temp < -sens->coefficients[idx]) ||
			    (sens->coefficients[idx] > 0 &&
			     sens_temp >= sens->coefficients[idx]))
				temp += 1;
			break;
		case VIRT_WEIGHTED_AVG:
			temp += sens_temp * sens->coefficients[idx];
			if (idx == (sens->num_sensors - 1))
				temp = (temp + sens->avg_offset)
					/ sens->avg_denominator;
			break;
		case VIRT_MAXIMUM:
			if (idx == 0)
				temp = INT_MIN;
			if (sens_temp > temp)
				temp = sens_temp;
			break;
		case VIRT_MINIMUM:
			if (idx == 0)
				temp = INT_MAX;
			if (sens_temp < temp)
				temp = sens_temp;
			break;
		default:
			break;
		}
		trace_virtual_temperature(sens->virt_tz, sens->tz[idx],
					sens_temp, temp);
	}

	sens->last_reading = *val = temp;

	return 0;
}

static int of_thermal_get_temp(struct thermal_zone_device *tz,
			       int *temp)
{
	struct __thermal_zone *data = tz->devdata;

	if (!data->senps || !data->senps->ops->get_temp)
	if (!data->ops->get_temp)
		return -EINVAL;

	return data->senps->ops->get_temp(data->senps->sensor_data, temp);
	return data->ops->get_temp(data->sensor_data, temp);
}

static int of_thermal_set_trips(struct thermal_zone_device *tz,
@@ -192,10 +88,10 @@ static int of_thermal_set_trips(struct thermal_zone_device *tz,
{
	struct __thermal_zone *data = tz->devdata;

	if (!data->senps || !data->senps->ops->set_trips)
	if (!data->ops || !data->ops->set_trips)
		return -EINVAL;

	return data->senps->ops->set_trips(data->senps->sensor_data, low, high);
	return data->ops->set_trips(data->sensor_data, low, high);
}

/**
@@ -278,10 +174,7 @@ static int of_thermal_set_emul_temp(struct thermal_zone_device *tz,
{
	struct __thermal_zone *data = tz->devdata;

	if (!data->senps || !data->senps->ops->set_emul_temp)
		return -EINVAL;

	return data->senps->ops->set_emul_temp(data->senps->sensor_data, temp);
	return data->ops->set_emul_temp(data->sensor_data, temp);
}

static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
@@ -289,11 +182,10 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
{
	struct __thermal_zone *data = tz->devdata;

	if (!data->senps || !data->senps->ops->get_trend)
	if (!data->ops->get_trend)
		return -EINVAL;

	return data->senps->ops->get_trend(data->senps->sensor_data,
					   trip, trend);
	return data->ops->get_trend(data->sensor_data, trip, trend);
}

static int of_thermal_bind(struct thermal_zone_device *thermal,
@@ -418,11 +310,10 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
	if (trip >= data->ntrips || trip < 0)
		return -EDOM;

	if (data->senps && data->senps->ops->set_trip_temp) {
	if (data->ops->set_trip_temp) {
		int ret;

		ret = data->senps->ops->set_trip_temp(data->senps->sensor_data,
						      trip, temp);
		ret = data->ops->set_trip_temp(data->sensor_data, trip, temp);
		if (ret)
			return ret;
	}
@@ -490,16 +381,12 @@ static struct thermal_zone_device_ops of_thermal_ops = {
	.unbind = of_thermal_unbind,
};

static struct thermal_zone_of_device_ops of_virt_ops = {
	.get_temp = virt_sensor_read_temp,
};

/***   sensor API   ***/

static struct thermal_zone_device *
thermal_zone_of_add_sensor(struct device_node *zone,
			   struct device_node *sensor,
			   struct __sensor_param *sens_param)
			   struct device_node *sensor, void *data,
			   const struct thermal_zone_of_device_ops *ops)
{
	struct thermal_zone_device *tzd;
	struct __thermal_zone *tz;
@@ -510,11 +397,12 @@ thermal_zone_of_add_sensor(struct device_node *zone,

	tz = tzd->devdata;

	if (!sens_param->ops)
	if (!ops)
		return ERR_PTR(-EINVAL);

	mutex_lock(&tzd->lock);
	tz->senps = sens_param;
	tz->ops = ops;
	tz->sensor_data = data;

	tzd->ops->get_temp = of_thermal_get_temp;
	tzd->ops->get_trend = of_thermal_get_trend;
@@ -523,10 +411,10 @@ thermal_zone_of_add_sensor(struct device_node *zone,
	 * The thermal zone core will calculate the window if they have set the
	 * optional set_trips pointer.
	 */
	if (sens_param->ops->set_trips)
	if (ops->set_trips)
		tzd->ops->set_trips = of_thermal_set_trips;

	if (sens_param->ops->set_emul_temp)
	if (ops->set_emul_temp)
		tzd->ops->set_emul_temp = of_thermal_set_emul_temp;

	mutex_unlock(&tzd->lock);
@@ -572,7 +460,6 @@ 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 __sensor_param *sens_param = NULL;

	np = of_find_node_by_name(NULL, "thermal-zones");
	if (!np)
@@ -583,13 +470,6 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,
		return ERR_PTR(-EINVAL);
	}

	sens_param = kzalloc(sizeof(*sens_param), GFP_KERNEL);
	if (!sens_param) {
		of_node_put(np);
		return ERR_PTR(-ENOMEM);
	}
	sens_param->sensor_data = data;
	sens_param->ops = ops;
	sensor_np = of_node_get(dev->of_node);

	for_each_available_child_of_node(np, child) {
@@ -614,7 +494,7 @@ 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);
							 data, ops);
			if (!IS_ERR(tzd))
				tzd->ops->set_mode(tzd, THERMAL_DEVICE_ENABLED);

@@ -628,8 +508,6 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,
	of_node_put(sensor_np);
	of_node_put(np);

	if (tzd == ERR_PTR(-ENODEV))
		kfree(sens_param);
	return tzd;
}
EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_register);
@@ -668,8 +546,8 @@ void thermal_zone_of_sensor_unregister(struct device *dev,
	tzd->ops->get_trend = NULL;
	tzd->ops->set_emul_temp = NULL;

	kfree(tz->senps);
	tz->senps = NULL;
	tz->ops = NULL;
	tz->sensor_data = NULL;
	mutex_unlock(&tzd->lock);
}
EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_unregister);
@@ -755,138 +633,6 @@ void devm_thermal_zone_of_sensor_unregister(struct device *dev,
}
EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_unregister);

/**
 * devm_thermal_of_virtual_sensor_register - Register a virtual sensor.
 *	Three types of virtual sensors are supported.
 *	1. Weighted aggregation type:
 *		Virtual sensor of this type calculates the weighted aggregation
 *		of sensor temperatures using the below formula,
 *		temp = (sensor_1_temp * coeff_1 + ... + sensor_n_temp * coeff_n)
 *			+ avg_offset / avg_denominator
 *		So the sensor drivers has to specify n+2 coefficients.
 *	2. Maximum type:
 *		Virtual sensors of this type will report the maximum of all
 *		sensor temperatures.
 *	3. Minimum type:
 *		Virtual sensors of this type will report the minimum of all
 *		sensor temperatures.
 *
 * @input arguments:
 * @dev: Virtual sensor driver device pointer.
 * @sensor_data: Virtual sensor data supported for the device.
 *
 * @return: Returns a virtual thermal zone pointer. Returns error if thermal
 * zone is not created. Returns -EAGAIN, if the sensor that is required for
 * this virtual sensor temperature estimation is not registered yet. The
 * sensor driver can try again later.
 */
struct thermal_zone_device *devm_thermal_of_virtual_sensor_register(
		struct device *dev,
		const struct virtual_sensor_data *sensor_data)
{
	int sens_idx = 0;
	struct virtual_sensor *sens;
	struct __thermal_zone *tz;
	struct thermal_zone_device **ptr;
	struct thermal_zone_device *tzd;
	struct __sensor_param *sens_param = NULL;
	enum thermal_device_mode mode;

	if (!dev || !sensor_data)
		return ERR_PTR(-EINVAL);

	tzd = thermal_zone_get_zone_by_name(
				sensor_data->virt_zone_name);
	if (IS_ERR(tzd)) {
		dev_dbg(dev, "sens:%s not available err: %ld\n",
				sensor_data->virt_zone_name,
				PTR_ERR(tzd));
		return tzd;
	}

	mutex_lock(&tzd->lock);
	/*
	 * Check if the virtual zone is registered and enabled.
	 * If so return the registered thermal zone.
	 */
	tzd->ops->get_mode(tzd, &mode);
	mutex_unlock(&tzd->lock);
	if (mode == THERMAL_DEVICE_ENABLED)
		return tzd;

	sens = devm_kzalloc(dev, sizeof(*sens), GFP_KERNEL);
	if (!sens)
		return ERR_PTR(-ENOMEM);

	sens->virt_tz = tzd;
	sens->logic = sensor_data->logic;
	sens->num_sensors = sensor_data->num_sensors;
	if ((sens->logic == VIRT_WEIGHTED_AVG) ||
	    (sens->logic == VIRT_COUNT_THRESHOLD)) {
		int coeff_ct = sensor_data->coefficient_ct;

		/*
		 * For weighted aggregation, sensor drivers has to specify
		 * n+2 coefficients.
		 */
		if (coeff_ct != sens->num_sensors) {
			dev_err(dev, "sens:%s invalid coefficient\n",
					sensor_data->virt_zone_name);
			return ERR_PTR(-EINVAL);
		}
		memcpy(sens->coefficients, sensor_data->coefficients,
			       coeff_ct * sizeof(*sens->coefficients));
		sens->avg_offset = sensor_data->avg_offset;
		sens->avg_denominator = sensor_data->avg_denominator;
	}

	for (sens_idx = 0; sens_idx < sens->num_sensors; sens_idx++) {
		sens->tz[sens_idx] = thermal_zone_get_zone_by_name(
					sensor_data->sensor_names[sens_idx]);
		if (IS_ERR(sens->tz[sens_idx])) {
			dev_err(dev, "sens:%s sensor[%s] fetch err:%ld\n",
				     sensor_data->virt_zone_name,
				     sensor_data->sensor_names[sens_idx],
				     PTR_ERR(sens->tz[sens_idx]));
			break;
		}
	}
	if (sens->num_sensors != sens_idx)
		return ERR_PTR(-EAGAIN);

	sens_param = kzalloc(sizeof(*sens_param), GFP_KERNEL);
	if (!sens_param)
		return ERR_PTR(-ENOMEM);
	sens_param->sensor_data = sens;
	sens_param->ops = &of_virt_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);

	mutex_lock(&tzd->lock);
	tz = tzd->devdata;
	tz->senps = sens_param;
	tzd->ops->get_temp = of_thermal_get_temp;
	list_add_tail(&tz->list, &sens_param->first_tz);
	mutex_unlock(&tzd->lock);

	ptr = devres_alloc(devm_thermal_zone_of_sensor_release, sizeof(*ptr),
			   GFP_KERNEL);
	if (!ptr)
		return ERR_PTR(-ENOMEM);

	*ptr = tzd;
	devres_add(dev, ptr);

	if (!tz->default_disable)
		tzd->ops->set_mode(tzd, THERMAL_DEVICE_ENABLED);

	return tzd;
}
EXPORT_SYMBOL(devm_thermal_of_virtual_sensor_register);


/***   functions parsing device tree nodes   ***/

/**
+0 −48
Original line number Diff line number Diff line
@@ -29,9 +29,6 @@
/* Default weight of a bound cooling device */
#define THERMAL_WEIGHT_DEFAULT 0

/* Max sensors that can be used for a single virtual thermalzone */
#define THERMAL_MAX_VIRT_SENSORS 10

/* use value, which < 0K, to indicate an invalid/uninitialized temperature */
#define THERMAL_TEMP_INVALID	-274000

@@ -384,40 +381,6 @@ struct thermal_trip {
	enum thermal_trip_type type;
};

/* Different aggregation logic supported for virtual sensors */
enum aggregation_logic {
	VIRT_WEIGHTED_AVG,
	VIRT_MAXIMUM,
	VIRT_MINIMUM,
	VIRT_COUNT_THRESHOLD,
	VIRT_AGGREGATION_NR,
};

/*
 * struct virtual_sensor_data - Data structure used to provide
 *			      information about the virtual zone.
 * @virt_zone_name - Virtual thermal zone name
 * @num_sensors - Number of sensors this virtual zone uses to compute
 *		  temperature
 * @sensor_names - Array of sensor names
 * @logic - Temperature aggregation logic to be used
 * @coefficients - Coefficients to be used for weighted average logic
 * @coefficient_ct - number of coefficients provided as input
 * @avg_offset - offset value to be used for the weighted aggregation logic
 * @avg_denominator - denominator value to be used for the weighted aggregation
 *			logic
 */
struct virtual_sensor_data {
	int                    num_sensors;
	char                   virt_zone_name[THERMAL_NAME_LENGTH];
	char                   *sensor_names[THERMAL_MAX_VIRT_SENSORS];
	enum aggregation_logic logic;
	int                    coefficients[THERMAL_MAX_VIRT_SENSORS];
	int                    coefficient_ct;
	int                    avg_offset;
	int                    avg_denominator;
};

/* Function declarations */
#ifdef CONFIG_THERMAL_OF
struct thermal_zone_device *
@@ -430,9 +393,6 @@ struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
		const struct thermal_zone_of_device_ops *ops);
void devm_thermal_zone_of_sensor_unregister(struct device *dev,
					    struct thermal_zone_device *tz);
struct thermal_zone_device *devm_thermal_of_virtual_sensor_register(
		struct device *dev,
		const struct virtual_sensor_data *sensor_data);
#else
static inline struct thermal_zone_device *
thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
@@ -460,14 +420,6 @@ void devm_thermal_zone_of_sensor_unregister(struct device *dev,
{
}

static inline
struct thermal_zone_device *devm_thermal_of_virtual_sensor_register(
		struct device *dev,
		const struct virtual_sensor_data *sensor_data)
{
	return ERR_PTR(-ENODEV);
}

#endif

#if IS_ENABLED(CONFIG_THERMAL)
+0 −46
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 */

#undef TRACE_SYSTEM
#define TRACE_SYSTEM thermal_virtual

#if !defined(_TRACE_VIRTUAL_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_VIRTUAL_H

#include <linux/thermal.h>
#include <linux/tracepoint.h>

TRACE_EVENT(virtual_temperature,

	TP_PROTO(struct thermal_zone_device *virt_tz,
		struct thermal_zone_device *tz, int sens_temp,
		int est_temp),

	TP_ARGS(virt_tz, tz, sens_temp, est_temp),

	TP_STRUCT__entry(
		__string(virt_zone, virt_tz->type)
		__string(therm_zone, tz->type)
		__field(int, sens_temp)
		__field(int, est_temp)
	),

	TP_fast_assign(
		__assign_str(virt_zone, virt_tz->type);
		__assign_str(therm_zone, tz->type);
		__entry->sens_temp = sens_temp;
		__entry->est_temp = est_temp;
	),

	TP_printk("virt_zone=%s zone=%s temp=%d virtual zone estimated temp=%d",
		__get_str(virt_zone), __get_str(therm_zone),
		__entry->sens_temp,
		__entry->est_temp)
);

#endif /* _TRACE_VIRTUAL_H */

/* This part must be outside protection */
#include <trace/define_trace.h>