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

Commit 7ef51cac authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "regulator: cpr: Remove temperature based closed-loop enable/disable"

parents cf951a4d 0bcacf4f
Loading
Loading
Loading
Loading
+0 −17
Original line number Diff line number Diff line
@@ -709,19 +709,6 @@ Optional properties:
				The number of quadruples should be equal to the number of values specified in
				the qcom,cpr-aging-sensor-id property. This property is required if
				the qcom,cpr-aging-sensor-id property has been specified.
- qcom,cpr-thermal-sensor-id:	TSENS hardware sensor-id of the sensor which
				needs to be monitored.
- qcom,cpr-disable-temp-threshold:	The TSENS temperature threshold in degrees Celsius at which CPR
				closed-loop is disabled. CPR closed-loop will stay disabled as long as the
				temperature is below this threshold. This property is required
				only if 'qcom,cpr-thermal-sensor-id' is present.
- qcom,cpr-enable-temp-threshold:	The TSENS temperature threshold in degrees Celsius at which CPR
				closed-loop is enabled. CPR closed-loop will stay enabled above this
				temperature threshold. This property is required only if
				'qcom,cpr-thermal-sensor-id' is present.
- qcom,disable-closed-loop-in-pc:	Bool property to disable closed-loop CPR during
				power-collapse. This can be enabled only for single core
				designs. The property 'qcom,cpr-cpus' is required to enable this logic.
Example:
	apc_vreg_corner: regulator@f9018000 {
		status = "okay";
@@ -971,8 +958,4 @@ Example:
		qcom,cpr-fuse-aging-init-quot-diff =
				<101 0 8 0>,
				<101 8 8 0>;

		qcom,cpr-thermal-sensor-id = <9>;
		qcom,cpr-disable-temp-threshold = <5>;
		qcom,cpr-enable-temp-threshold = <10>;
	};
+9 −233
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -38,8 +38,6 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/cpr-regulator.h>
#include <linux/msm_thermal.h>
#include <linux/msm_tsens.h>
#include <soc/qcom/scm.h>

/* Register Offsets for RB-CPR and Bit Definitions */
@@ -287,7 +285,6 @@ struct cpr_regulator {
	int				corner;
	int				ceiling_max;
	struct dentry			*debugfs;
	struct device			*dev;

	/* eFuse parameters */
	phys_addr_t	efuse_addr;
@@ -319,14 +316,6 @@ struct cpr_regulator {
	/* mem-acc regulator */
	struct regulator	*mem_acc_vreg;

	/* thermal monitor */
	int			tsens_id;
	int			cpr_disable_temp_threshold;
	int			cpr_enable_temp_threshold;
	bool			cpr_disable_on_temperature;
	bool			cpr_thermal_disable;
	struct threshold_info	tsens_threshold_config;

	/* CPR parameters */
	u32		num_fuse_corners;
	u64		cpr_fuse_bits;
@@ -565,8 +554,7 @@ static u64 cpr_read_efuse_param(struct cpr_regulator *cpr_vreg, int row_start,

static bool cpr_is_allowed(struct cpr_regulator *cpr_vreg)
{
	if (cpr_vreg->cpr_fuse_disable || !cpr_vreg->enable ||
				cpr_vreg->cpr_thermal_disable)
	if (cpr_vreg->cpr_fuse_disable || !cpr_vreg->enable)
		return false;
	else
		return true;
@@ -5102,145 +5090,6 @@ static int cpr_vsens_init(struct platform_device *pdev,
	return rc;
}

static int cpr_disable_on_temp(struct cpr_regulator *cpr_vreg, bool disable)
{
	int rc = 0;

	mutex_lock(&cpr_vreg->cpr_mutex);

	if (cpr_vreg->cpr_fuse_disable ||
		(cpr_vreg->cpr_thermal_disable == disable))
		goto out;

	cpr_vreg->cpr_thermal_disable = disable;

	if (cpr_vreg->enable && cpr_vreg->corner) {
		if (disable) {
			cpr_debug(cpr_vreg, "Disabling CPR - below temperature threshold [%d]\n",
					cpr_vreg->cpr_disable_temp_threshold);
			/* disable CPR and force open-loop */
			cpr_ctl_disable(cpr_vreg);
			rc = cpr_regulator_set_voltage(cpr_vreg->rdev,
						cpr_vreg->corner, false);
			if (rc < 0)
				cpr_err(cpr_vreg, "Failed to set voltage, rc=%d\n",
						rc);
		} else {
			/* enable CPR */
			cpr_debug(cpr_vreg, "Enabling CPR - above temperature thresold [%d]\n",
					cpr_vreg->cpr_enable_temp_threshold);
			rc = cpr_regulator_set_voltage(cpr_vreg->rdev,
						cpr_vreg->corner, true);
			if (rc < 0)
				cpr_err(cpr_vreg, "Failed to set voltage, rc=%d\n",
						rc);
		}
	}
out:
	mutex_unlock(&cpr_vreg->cpr_mutex);
	return rc;
}

static void tsens_threshold_notify(struct therm_threshold *tsens_cb_data)
{
	struct threshold_info *info = tsens_cb_data->parent;
	struct cpr_regulator *cpr_vreg = container_of(info,
			struct cpr_regulator, tsens_threshold_config);
	int rc = 0;

	cpr_debug(cpr_vreg, "Triggered tsens-notification trip_type=%d for thermal_zone_id=%d\n",
		tsens_cb_data->trip_triggered, tsens_cb_data->sensor_id);

	switch (tsens_cb_data->trip_triggered) {
	case THERMAL_TRIP_CONFIGURABLE_HI:
		rc = cpr_disable_on_temp(cpr_vreg, false);
		if (rc < 0)
			cpr_err(cpr_vreg, "Failed to enable CPR, rc=%d\n", rc);
		break;
	case THERMAL_TRIP_CONFIGURABLE_LOW:
		rc = cpr_disable_on_temp(cpr_vreg, true);
		if (rc < 0)
			cpr_err(cpr_vreg, "Failed to disable CPR, rc=%d\n", rc);
		break;
	default:
		cpr_debug(cpr_vreg, "trip-type %d not supported\n",
				tsens_cb_data->trip_triggered);
		break;
	}

	if (tsens_cb_data->cur_state != tsens_cb_data->trip_triggered) {
		rc = sensor_mgr_set_threshold(tsens_cb_data->sensor_id,
						tsens_cb_data->threshold);
		if (rc < 0)
			cpr_err(cpr_vreg,
			"Failed to set temp. threshold, rc=%d\n", rc);
		else
			tsens_cb_data->cur_state =
				tsens_cb_data->trip_triggered;
	}
}

static int cpr_check_tsens(struct cpr_regulator *cpr_vreg)
{
	int rc = 0;
	struct tsens_device tsens_dev;
	unsigned long temp = 0;
	bool disable;

	if (tsens_is_ready() > 0) {
		tsens_dev.sensor_num = cpr_vreg->tsens_id;
		rc = tsens_get_temp(&tsens_dev, &temp);
		if (rc < 0) {
			cpr_err(cpr_vreg, "Faled to read tsens, rc=%d\n", rc);
			return rc;
		}

		disable = (int) temp <= cpr_vreg->cpr_disable_temp_threshold;
		rc = cpr_disable_on_temp(cpr_vreg, disable);
		if (rc)
			cpr_err(cpr_vreg, "Failed to %s CPR, rc=%d\n",
					disable ? "disable" : "enable", rc);
	}

	return rc;
}

static int cpr_thermal_init(struct cpr_regulator *cpr_vreg)
{
	int rc;
	struct device_node *of_node = cpr_vreg->dev->of_node;

	if (!of_find_property(of_node, "qcom,cpr-thermal-sensor-id", NULL))
		return 0;

	CPR_PROP_READ_U32(cpr_vreg, of_node, "cpr-thermal-sensor-id",
			  &cpr_vreg->tsens_id, rc);
	if (rc < 0)
		return rc;

	CPR_PROP_READ_U32(cpr_vreg, of_node, "cpr-disable-temp-threshold",
			  &cpr_vreg->cpr_disable_temp_threshold, rc);
	if (rc < 0)
		return rc;

	CPR_PROP_READ_U32(cpr_vreg, of_node, "cpr-enable-temp-threshold",
			  &cpr_vreg->cpr_enable_temp_threshold, rc);
	if (rc < 0)
		return rc;

	if (cpr_vreg->cpr_disable_temp_threshold >=
				cpr_vreg->cpr_enable_temp_threshold) {
		cpr_err(cpr_vreg, "Invalid temperature threshold cpr_disable_temp[%d] >= cpr_enable_temp[%d]\n",
				cpr_vreg->cpr_disable_temp_threshold,
				cpr_vreg->cpr_enable_temp_threshold);
		return -EINVAL;
	}

	cpr_vreg->cpr_disable_on_temperature = true;

	return 0;
}

static int cpr_init_cpr(struct platform_device *pdev,
			       struct cpr_regulator *cpr_vreg)
{
@@ -6067,7 +5916,13 @@ static int cpr_regulator_probe(struct platform_device *pdev)
		return -EINVAL;
	}

	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
	cpr_vreg = devm_kzalloc(&pdev->dev, sizeof(struct cpr_regulator),
				GFP_KERNEL);
	if (!cpr_vreg)
		return -ENOMEM;

	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
						&cpr_vreg->rdesc);
	if (!init_data) {
		dev_err(dev, "regulator init data is missing\n");
		return -EINVAL;
@@ -6078,14 +5933,6 @@ static int cpr_regulator_probe(struct platform_device *pdev)
			|= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS;
	}

	cpr_vreg = devm_kzalloc(&pdev->dev, sizeof(struct cpr_regulator),
				GFP_KERNEL);
	if (!cpr_vreg) {
		dev_err(dev, "Can't allocate cpr_regulator memory\n");
		return -ENOMEM;
	}

	cpr_vreg->dev = &pdev->dev;
	cpr_vreg->rdesc.name = init_data->constraints.name;
	if (cpr_vreg->rdesc.name == NULL) {
		dev_err(dev, "regulator-name missing\n");
@@ -6182,12 +6029,6 @@ static int cpr_regulator_probe(struct platform_device *pdev)
		return rc;
	}

	rc = cpr_thermal_init(cpr_vreg);
	if (rc) {
		cpr_err(cpr_vreg, "Thermal intialization failed rc=%d\n", rc);
		return rc;
	}

	if (of_property_read_bool(pdev->dev.of_node,
				"qcom,disable-closed-loop-in-pc")) {
		rc = cpr_init_pm_notification(cpr_vreg);
@@ -6247,17 +6088,6 @@ static int cpr_regulator_probe(struct platform_device *pdev)
	platform_set_drvdata(pdev, cpr_vreg);
	cpr_debugfs_init(cpr_vreg);

	if (cpr_vreg->cpr_disable_on_temperature) {
		rc = cpr_check_tsens(cpr_vreg);
		if (rc < 0) {
			cpr_err(cpr_vreg, "Unable to config CPR on tsens, rc=%d\n",
									rc);
			cpr_apc_exit(cpr_vreg);
			cpr_debugfs_remove(cpr_vreg);
			return rc;
		}
	}

	/* Register panic notification call back */
	cpr_vreg->panic_notifier.notifier_call = cpr_panic_callback;
	atomic_notifier_chain_register(&panic_notifier_list,
@@ -6293,10 +6123,6 @@ static int cpr_regulator_remove(struct platform_device *pdev)
		if (cpr_vreg->cpu_notifier.notifier_call)
			unregister_hotcpu_notifier(&cpr_vreg->cpu_notifier);

		if (cpr_vreg->cpr_disable_on_temperature)
			sensor_mgr_remove_threshold(
				&cpr_vreg->tsens_threshold_config);

		atomic_notifier_chain_unregister(&panic_notifier_list,
			&cpr_vreg->panic_notifier);

@@ -6325,56 +6151,6 @@ static struct platform_driver cpr_regulator_driver = {
	.resume		= cpr_regulator_resume,
};

static int initialize_tsens_monitor(struct cpr_regulator *cpr_vreg)
{
	int rc;

	rc = cpr_check_tsens(cpr_vreg);
	if (rc < 0) {
		cpr_err(cpr_vreg, "Unable to check tsens, rc=%d\n", rc);
		return rc;
	}

	rc = sensor_mgr_init_threshold(&cpr_vreg->tsens_threshold_config,
				cpr_vreg->tsens_id,
				cpr_vreg->cpr_enable_temp_threshold, /* high */
				cpr_vreg->cpr_disable_temp_threshold, /* low */
				tsens_threshold_notify);
	if (rc < 0) {
		cpr_err(cpr_vreg, "Failed to init tsens monitor, rc=%d\n", rc);
		return rc;
	}

	rc = sensor_mgr_convert_id_and_set_threshold(
			&cpr_vreg->tsens_threshold_config);
	if (rc < 0)
		cpr_err(cpr_vreg, "Failed to set tsens threshold, rc=%d\n",
					rc);

	return rc;
}

int __init cpr_regulator_late_init(void)
{
	int rc;
	struct cpr_regulator *cpr_vreg;

	mutex_lock(&cpr_regulator_list_mutex);

	list_for_each_entry(cpr_vreg, &cpr_regulator_list, list) {
		if (cpr_vreg->cpr_disable_on_temperature) {
			rc = initialize_tsens_monitor(cpr_vreg);
			if (rc)
				cpr_err(cpr_vreg, "Failed to initialize temperature monitor, rc=%d\n",
					rc);
		}
	}

	mutex_unlock(&cpr_regulator_list_mutex);
	return 0;
}
late_initcall(cpr_regulator_late_init);

/**
 * cpr_regulator_init() - register cpr-regulator driver
 *