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

Commit 41038b1c authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drivers: thermal: use zero C status as sensor value instead of min temp"

parents 1186f5a2 09b2ed6d
Loading
Loading
Loading
Loading
+17 −17
Original line number Diff line number Diff line
@@ -25,11 +25,11 @@ static int tsens_get_temp(void *data, int *temp)
	return tmdev->ops->get_temp(s, temp);
}

static int tsens_get_min_temp(void *data, int *temp)
static int tsens_get_zeroc_status(void *data, int *status)
{
	struct tsens_sensor *s = data;

	return tsens_2xxx_get_min_temp(s, temp);
	return tsens_2xxx_get_zeroc_status(s, status);
}

static int tsens_set_trip_temp(void *data, int low_temp, int high_temp)
@@ -108,7 +108,7 @@ static struct thermal_zone_of_device_ops tsens_tm_thermal_zone_ops = {
};

static struct thermal_zone_of_device_ops tsens_tm_min_thermal_zone_ops = {
	.get_temp = tsens_get_min_temp,
	.get_temp = tsens_get_zeroc_status,
};

static int get_device_tree_data(struct platform_device *pdev,
@@ -119,7 +119,7 @@ static int get_device_tree_data(struct platform_device *pdev,
	const struct tsens_data *data;
	int rc = 0;
	struct resource *res_tsens_mem;
	u32 min_temp_id;
	u32 zeroc_id;

	if (!of_match_node(tsens_table, of_node)) {
		pr_err("Need to read SoC specific fuse map\n");
@@ -195,10 +195,10 @@ static int get_device_tree_data(struct platform_device *pdev,
		}
	}

	if (!of_property_read_u32(of_node, "0C-sensor-num", &min_temp_id))
		tmdev->min_temp_sensor_id = (int)min_temp_id;
	if (!of_property_read_u32(of_node, "0C-sensor-num", &zeroc_id))
		tmdev->zeroc_sensor_id = (int)zeroc_id;
	else
		tmdev->min_temp_sensor_id = MIN_TEMP_DEF_OFFSET;
		tmdev->zeroc_sensor_id = MIN_TEMP_DEF_OFFSET;

	tmdev->tsens_reinit_wa =
		of_property_read_bool(of_node, "tsens-reinit-wa");
@@ -232,14 +232,14 @@ static int tsens_thermal_zone_register(struct tsens_device *tmdev)
		return -ENODEV;
	}

	if (tmdev->min_temp_sensor_id != MIN_TEMP_DEF_OFFSET) {
		tmdev->min_temp.tmdev = tmdev;
		tmdev->min_temp.hw_id = tmdev->min_temp_sensor_id;
		tmdev->min_temp.tzd =
	if (tmdev->zeroc_sensor_id != MIN_TEMP_DEF_OFFSET) {
		tmdev->zeroc.tmdev = tmdev;
		tmdev->zeroc.hw_id = tmdev->zeroc_sensor_id;
		tmdev->zeroc.tzd =
			devm_thermal_zone_of_sensor_register(
			&tmdev->pdev->dev, tmdev->min_temp_sensor_id,
			&tmdev->min_temp, &tsens_tm_min_thermal_zone_ops);
		if (IS_ERR(tmdev->min_temp.tzd))
			&tmdev->pdev->dev, tmdev->zeroc_sensor_id,
			&tmdev->zeroc, &tsens_tm_min_thermal_zone_ops);
		if (IS_ERR(tmdev->zeroc.tzd))
			pr_err("Error registering min temp sensor\n");
	}

@@ -275,8 +275,8 @@ static void tsens_therm_fwk_notify(struct work_struct *work)
				tmdev->sensor[i].tzd, temp);
		}
	}
	if (tmdev->min_temp_sensor_id != MIN_TEMP_DEF_OFFSET) {
		rc = tsens_get_temp(&tmdev->min_temp, &temp);
	if (tmdev->zeroc_sensor_id != MIN_TEMP_DEF_OFFSET) {
		rc = tsens_get_zeroc_status(&tmdev->zeroc, &temp);
		if (rc) {
			pr_err("%s: Error:%d reading temp sensor:%d\n",
				   __func__, rc, i);
@@ -284,7 +284,7 @@ static void tsens_therm_fwk_notify(struct work_struct *work)
		}
		TSENS_DBG(tmdev, "Calling trip_temp for sensor %d\n", i);
		of_thermal_handle_trip_temp(tmdev->dev,
			tmdev->min_temp.tzd, temp);
			tmdev->zeroc.tzd, temp);
	}
}

+9 −0
Original line number Diff line number Diff line
@@ -127,3 +127,12 @@ config REGULATOR_COOLING_DEVICE
	  on a particular regulator. This mitigation device will be used by low
	  temperature reliability rules to mitigate a regulator at nominal
	  voltage.

config QTI_RPM_SMD_COOLING_DEVICE
	tristate "Qualcomm Technologies Inc. RPM SMD cooling device driver"
	depends on MSM_RPM_SMD && THERMAL_OF
	help
	  This implements a mitigation device to send temperature band
	  level to RPM hardware via SMD protocol. This mitigation device
	  will be used by temperature reliability rules to restrict a
	  railway at predefined voltage corner using RPM hardware.
+1 −0
Original line number Diff line number Diff line
@@ -20,3 +20,4 @@ obj-$(CONFIG_QTI_CPU_VOLTAGE_COOLING_DEVICE) += cpu_voltage_cooling.o
obj-$(CONFIG_QTI_POLICY_ENGINE_SENSOR) += policy_engine.o
obj-${CONFIG_QTI_SDPM_CLOCK_MONITOR} += sdpm_clk.o
obj-$(CONFIG_REGULATOR_COOLING_DEVICE) += regulator_cdev.o
obj-$(CONFIG_QTI_RPM_SMD_COOLING_DEVICE) += rpm_smd_cooling_device.o
+200 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt) "%s:%s " fmt, KBUILD_MODNAME, __func__

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>
#include <linux/err.h>
#include <soc/qcom/rpm-smd.h>

#define RPM_SMD_CDEV_DRIVER   "rpm-smd-cooling-device"
#define RPM_SMD_RES_TYPE       0x6d726874
#define RPM_SMD_RES_ID         0
#define RPM_SMD_KEY            1

enum rpm_smd_temp_band {
	RPM_SMD_COLD_CRITICAL = 1,
	RPM_SMD_COLD,
	RPM_SMD_COOL,
	RPM_SMD_NORMAL,
	RPM_SMD_WARM,
	RPM_SMD_HOT,
	RPM_SMD_HOT_CRITICAL,
	RPM_SMD_TEMP_MAX_NR,
};

struct rpm_smd_cdev {
	struct thermal_cooling_device	*cool_dev;
	char				dev_name[THERMAL_NAME_LENGTH];
	unsigned int			state;
	struct msm_rpm_request		*rpm_handle;
};

static int rpm_smd_send_request_to_rpm(struct rpm_smd_cdev *rpm_smd_dev,
			unsigned int state)
{
	unsigned int band;
	int msg_id, ret;

	if (!rpm_smd_dev || !rpm_smd_dev->rpm_handle) {
		pr_err("Invalid RPM SMD handle\n");
		return -EINVAL;
	}

	if (rpm_smd_dev->state == state)
		return 0;

	/* if state is zero, then send RPM_SMD_NORMAL band */
	if (!state)
		band = RPM_SMD_NORMAL;
	else
		band = state;

	ret = msm_rpm_add_kvp_data(rpm_smd_dev->rpm_handle, RPM_SMD_KEY,
		(const uint8_t *)&band, (int)sizeof(band));
	if (ret) {
		pr_err("Adding KVP data failed. err:%d\n", ret);
		return ret;
	}

	msg_id = msm_rpm_send_request(rpm_smd_dev->rpm_handle);
	if (!msg_id) {
		pr_err("RPM SMD send request failed\n");
		return -ENXIO;
	}

	ret = msm_rpm_wait_for_ack(msg_id);
	if (ret) {
		pr_err("RPM SMD wait for ACK failed. err:%d\n", ret);
		return ret;
	}
	rpm_smd_dev->state = state;

	pr_debug("Requested RPM SMD band:%d for %s\n", band,
		rpm_smd_dev->dev_name);

	return ret;
}

static int rpm_smd_get_max_state(struct thermal_cooling_device *cdev,
				 unsigned long *state)
{
	*state = RPM_SMD_TEMP_MAX_NR - 1;

	return 0;
}

static int rpm_smd_set_cur_state(struct thermal_cooling_device *cdev,
				 unsigned long state)
{
	struct rpm_smd_cdev *rpm_smd_dev = cdev->devdata;
	int ret = 0;

	if (state > (RPM_SMD_TEMP_MAX_NR - 1))
		state = RPM_SMD_TEMP_MAX_NR - 1;

	ret = rpm_smd_send_request_to_rpm(rpm_smd_dev, (unsigned int)state);
	if (ret)
		return ret;

	return ret;
}

static int rpm_smd_get_cur_state(struct thermal_cooling_device *cdev,
				 unsigned long *state)
{
	struct rpm_smd_cdev *rpm_smd_dev = cdev->devdata;

	*state = rpm_smd_dev->state;

	return 0;
}

static struct thermal_cooling_device_ops rpm_smd_device_ops = {
	.get_max_state = rpm_smd_get_max_state,
	.get_cur_state = rpm_smd_get_cur_state,
	.set_cur_state = rpm_smd_set_cur_state,
};

static int rpm_smd_cdev_remove(struct platform_device *pdev)
{
	struct rpm_smd_cdev *rpm_smd_dev =
		(struct rpm_smd_cdev *)dev_get_drvdata(&pdev->dev);

	if (rpm_smd_dev) {
		if (rpm_smd_dev->cool_dev)
			thermal_cooling_device_unregister(
					rpm_smd_dev->cool_dev);

		rpm_smd_send_request_to_rpm(rpm_smd_dev, RPM_SMD_NORMAL);
		msm_rpm_free_request(rpm_smd_dev->rpm_handle);
	}

	return 0;
}

static int rpm_smd_cdev_probe(struct platform_device *pdev)
{
	struct rpm_smd_cdev *rpm_smd_dev;
	int ret = 0;
	struct device_node *np;

	np = dev_of_node(&pdev->dev);
	if (!np) {
		dev_err(&pdev->dev,
			"of node not available for rpm smd cooling device\n");
		return -EINVAL;
	}

	rpm_smd_dev = devm_kzalloc(&pdev->dev, sizeof(*rpm_smd_dev),
					GFP_KERNEL);
	if (!rpm_smd_dev)
		return -ENOMEM;

	rpm_smd_dev->rpm_handle = msm_rpm_create_request(MSM_RPM_CTX_ACTIVE_SET,
			RPM_SMD_RES_TYPE, RPM_SMD_RES_ID, 1);
	if (!rpm_smd_dev->rpm_handle) {
		dev_err(&pdev->dev, "Creating RPM SMD request handle failed\n");
		return -ENXIO;
	}

	strlcpy(rpm_smd_dev->dev_name, np->name, THERMAL_NAME_LENGTH);

	/* Be pro-active and mitigate till we get first vote from TF */
	rpm_smd_send_request_to_rpm(rpm_smd_dev, RPM_SMD_COLD);

	rpm_smd_dev->cool_dev = thermal_of_cooling_device_register(
					np, rpm_smd_dev->dev_name, rpm_smd_dev,
					&rpm_smd_device_ops);
	if (IS_ERR(rpm_smd_dev->cool_dev)) {
		ret = PTR_ERR(rpm_smd_dev->cool_dev);
		dev_err(&pdev->dev, "rpm_smd cdev register err:%d\n", ret);
		rpm_smd_dev->cool_dev = NULL;
		return ret;
	}

	dev_set_drvdata(&pdev->dev, rpm_smd_dev);

	return ret;
}

static const struct of_device_id rpm_smd_cdev_of_match[] = {
	{.compatible = "qcom,rpm-smd-cooling-device", },
	{},
};

static struct platform_driver rpm_smd_cdev_driver = {
	.driver = {
		.name = RPM_SMD_CDEV_DRIVER,
		.of_match_table = rpm_smd_cdev_of_match,
	},
	.probe = rpm_smd_cdev_probe,
	.remove = rpm_smd_cdev_remove,
};

builtin_platform_driver(rpm_smd_cdev_driver);
MODULE_LICENSE("GPL v2");
+4 −4
Original line number Diff line number Diff line
@@ -216,8 +216,8 @@ struct tsens_device {
	const struct tsens_data		*ctrl_data;
	struct tsens_mtc_sysfs  mtcsys;
	int				trdy_fail_ctr;
	struct tsens_sensor		min_temp;
	u8				min_temp_sensor_id;
	struct tsens_sensor		zeroc;
	u8				zeroc_sensor_id;
	struct workqueue_struct		*tsens_reinit_work;
	struct work_struct		therm_fwk_notify;
	bool				tsens_reinit_wa;
@@ -233,7 +233,7 @@ extern struct list_head tsens_device_list;
extern int calibrate_8937(struct tsens_device *tmdev);
extern int calibrate_405(struct tsens_device *tmdev);

extern int tsens_2xxx_get_min_temp(
		struct tsens_sensor *sensor, int *temp);
extern int tsens_2xxx_get_zeroc_status(
		struct tsens_sensor *sensor, int *status);

#endif /* __QCOM_TSENS_H__ */
Loading