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

Commit bb2afa3f authored by Gopala Krishna Nuthaki's avatar Gopala Krishna Nuthaki
Browse files

drivers: thermal: Re-initialize Tsens controller interrupt configuration



If TSENS controller goes to bad state while reading temperature,
it invokes TSENS controller re-init code. After controller
re-init,it disable all interrupts and reset TSENS critical
interrupt related settings. It causes no threshold interrupt
or critical interrupt on post controller re-init and it might
lead to thermal run away issues.

Re-initialize Tsens controller interrupt configuration to enable
threshold interrupts and critical interrupt as part of TSENS
controller re-init routine.

Change-Id: I84b1218ce90ce8e4ae530f93db7c2b4277469781
Signed-off-by: default avatarGopala Krishna Nuthaki <gnuthaki@codeaurora.org>
parent 4fa2f91b
Loading
Loading
Loading
Loading
+70 −52
Original line number Original line Diff line number Diff line
@@ -83,12 +83,70 @@ static void msm_tsens_convert_temp(int last_temp, int *temp)
	*temp = last_temp * TSENS_TM_SCALE_DECI_MILLIDEG;
	*temp = last_temp * TSENS_TM_SCALE_DECI_MILLIDEG;
}
}


static int __tsens2xxx_hw_init(struct tsens_device *tmdev)
{
	void __iomem *srot_addr;
	void __iomem *sensor_int_mask_addr;
	unsigned int srot_val, crit_mask, crit_val;
	void __iomem *int_mask_addr;

	srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr + 0x4);
	srot_val = readl_relaxed(srot_addr);
	if (!(srot_val & TSENS_EN)) {
		pr_err("TSENS device is not enabled\n");
		return -ENODEV;
	}

	if (tmdev->ctrl_data->cycle_monitor) {
		sensor_int_mask_addr =
			TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr);
		crit_mask = readl_relaxed(sensor_int_mask_addr);
		crit_val = TSENS_TM_CRITICAL_CYCLE_MONITOR;
		if (tmdev->ctrl_data->cycle_compltn_monitor_mask)
			writel_relaxed((crit_mask | crit_val),
				(TSENS_TM_CRITICAL_INT_MASK
				(tmdev->tsens_tm_addr)));
		else
			writel_relaxed((crit_mask & ~crit_val),
				(TSENS_TM_CRITICAL_INT_MASK
				(tmdev->tsens_tm_addr)));
		/*Update critical cycle monitoring*/
		mb();
	}

	if (tmdev->ctrl_data->wd_bark) {
		sensor_int_mask_addr =
			TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr);
		crit_mask = readl_relaxed(sensor_int_mask_addr);
		crit_val = TSENS_TM_CRITICAL_WD_BARK;
		if (tmdev->ctrl_data->wd_bark_mask)
			writel_relaxed((crit_mask | crit_val),
			(TSENS_TM_CRITICAL_INT_MASK
			(tmdev->tsens_tm_addr)));
		else
			writel_relaxed((crit_mask & ~crit_val),
			(TSENS_TM_CRITICAL_INT_MASK
			(tmdev->tsens_tm_addr)));
		/*Update watchdog monitoring*/
		mb();
	}

	int_mask_addr = TSENS_TM_UPPER_LOWER_INT_MASK(tmdev->tsens_tm_addr);
	writel_relaxed(TSENS_TM_UPPER_LOWER_INT_DISABLE, int_mask_addr);

	writel_relaxed(TSENS_TM_CRITICAL_INT_EN |
		TSENS_TM_UPPER_INT_EN | TSENS_TM_LOWER_INT_EN,
		TSENS_TM_INT_EN(tmdev->tsens_tm_addr));

	return 0;
}

static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
{
{
	struct tsens_device *tmdev = NULL, *tmdev_itr;
	struct tsens_device *tmdev = NULL, *tmdev_itr;
	unsigned int code, ret, tsens_ret;
	unsigned int code, ret, tsens_ret;
	void __iomem *sensor_addr, *trdy;
	void __iomem *sensor_addr, *trdy;
	int last_temp = 0, last_temp2 = 0, last_temp3 = 0, count = 0;
	int rc = 0, last_temp = 0, last_temp2 = 0, last_temp3 = 0, count = 0;
	static atomic_t in_tsens_reinit;
	static atomic_t in_tsens_reinit;


	if (!sensor)
	if (!sensor)
@@ -172,6 +230,13 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
			/* Notify thermal fwk */
			/* Notify thermal fwk */
			list_for_each_entry(tmdev_itr,
			list_for_each_entry(tmdev_itr,
						&tsens_device_list, list) {
						&tsens_device_list, list) {
				rc = __tsens2xxx_hw_init(tmdev_itr);
				if (rc) {
					pr_err(
					"%s: Failed to re-initialize TSENS controller\n",
						__func__);
					BUG();
				}
				queue_work(tmdev_itr->tsens_reinit_work,
				queue_work(tmdev_itr->tsens_reinit_work,
					&tmdev_itr->therm_fwk_notify);
					&tmdev_itr->therm_fwk_notify);
			}
			}
@@ -713,58 +778,11 @@ static int tsens2xxx_hw_sensor_en(struct tsens_device *tmdev,


static int tsens2xxx_hw_init(struct tsens_device *tmdev)
static int tsens2xxx_hw_init(struct tsens_device *tmdev)
{
{
	void __iomem *srot_addr;
	int rc = 0;
	void __iomem *sensor_int_mask_addr;
	unsigned int srot_val, crit_mask, crit_val;
	void __iomem *int_mask_addr;

	srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr + 0x4);
	srot_val = readl_relaxed(srot_addr);
	if (!(srot_val & TSENS_EN)) {
		pr_err("TSENS device is not enabled\n");
		return -ENODEV;
	}

	if (tmdev->ctrl_data->cycle_monitor) {
		sensor_int_mask_addr =
			TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr);
		crit_mask = readl_relaxed(sensor_int_mask_addr);
		crit_val = TSENS_TM_CRITICAL_CYCLE_MONITOR;
		if (tmdev->ctrl_data->cycle_compltn_monitor_mask)
			writel_relaxed((crit_mask | crit_val),
				(TSENS_TM_CRITICAL_INT_MASK
				(tmdev->tsens_tm_addr)));
		else
			writel_relaxed((crit_mask & ~crit_val),
				(TSENS_TM_CRITICAL_INT_MASK
				(tmdev->tsens_tm_addr)));
		/*Update critical cycle monitoring*/
		mb();
	}

	if (tmdev->ctrl_data->wd_bark) {
		sensor_int_mask_addr =
			TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr);
		crit_mask = readl_relaxed(sensor_int_mask_addr);
		crit_val = TSENS_TM_CRITICAL_WD_BARK;
		if (tmdev->ctrl_data->wd_bark_mask)
			writel_relaxed((crit_mask | crit_val),
			(TSENS_TM_CRITICAL_INT_MASK
			(tmdev->tsens_tm_addr)));
		else
			writel_relaxed((crit_mask & ~crit_val),
			(TSENS_TM_CRITICAL_INT_MASK
			(tmdev->tsens_tm_addr)));
		/*Update watchdog monitoring*/
		mb();
	}

	int_mask_addr = TSENS_TM_UPPER_LOWER_INT_MASK(tmdev->tsens_tm_addr);
	writel_relaxed(TSENS_TM_UPPER_LOWER_INT_DISABLE, int_mask_addr);


	writel_relaxed(TSENS_TM_CRITICAL_INT_EN |
	rc = __tsens2xxx_hw_init(tmdev);
		TSENS_TM_UPPER_INT_EN | TSENS_TM_LOWER_INT_EN,
	if (rc)
		TSENS_TM_INT_EN(tmdev->tsens_tm_addr));
		return rc;


	spin_lock_init(&tmdev->tsens_crit_lock);
	spin_lock_init(&tmdev->tsens_crit_lock);
	spin_lock_init(&tmdev->tsens_upp_low_lock);
	spin_lock_init(&tmdev->tsens_upp_low_lock);