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

Commit 5df36ce3 authored by Manaf Meethalavalappu Pallikunhi's avatar Manaf Meethalavalappu Pallikunhi
Browse files

drivers: thermal: call TSENS re-init only when register is ready to update



If TSENS controller reset pin is held asserted for long duration
and the same time if TSENS software detects TSENS reset and tries
to re-initialize TSENS controller, TSENS initialization may not
reflect in TSENS register due to reset pin is held asserted.

Invoke TSENS re-init routine only if software is able to write
TSENS register successfully. It makes sure that TSENS re-init
routine is able to re-initialize TSENS controller.

Add a check whether TSENS is re-enabled or not on post TSENS re-init.
If it is not re-enabled, re-try TSENS re-init routine.

Change-Id: Ia0d9b794b47854d269438ccfd9967cf7112aa5e5
Signed-off-by: default avatarManaf Meethalavalappu Pallikunhi <manafm@codeaurora.org>
Signed-off-by: default avatarGopala Krishna Nuthaki <gnuthaki@codeaurora.org>
parent e3e20132
Loading
Loading
Loading
Loading
+73 −32
Original line number Diff line number Diff line
@@ -69,7 +69,6 @@

#define TSENS_INIT_ID	0x5
#define TSENS_RECOVERY_LOOP_COUNT 5
#define TSENS_RE_INIT_MAX_COUNT   5

static void msm_tsens_convert_temp(int last_temp, int *temp)
{
@@ -185,6 +184,7 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
		 */
		if (tmdev->tsens_reinit_wa) {
			struct scm_desc desc = { 0 };
			int scm_cnt = 0, reg_write_cnt = 0;

			if (atomic_read(&in_tsens_reinit)) {
				pr_err("%s: tsens re-init is in progress\n",
@@ -198,13 +198,31 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
				tmdev->ops->dbg(tmdev, 0,
					TSENS_DBG_LOG_BUS_ID_DATA, NULL);

			if (tmdev->tsens_reinit_cnt >=
					TSENS_RE_INIT_MAX_COUNT) {
			while (1) {
				/*
				 * Invoke scm call only if SW register write is
				 * reflecting in controller. If not, wait for
				 * 2 ms and then retry.
				 */
				if (reg_write_cnt >= 100) {
					msleep(100);
					pr_err(
				"%s: TSENS not recovered after %d re-init\n",
					__func__, tmdev->tsens_reinit_cnt);
					"%s: Tsens write is failed. cnt:%d\n",
						__func__, reg_write_cnt);
					BUG();
				}
				writel_relaxed(BIT(2),
					TSENS_TM_INT_EN(tmdev->tsens_tm_addr));
				code = readl_relaxed(
					TSENS_TM_INT_EN(tmdev->tsens_tm_addr));
				if (!(code & BIT(2))) {
					udelay(2000);
					TSENS_DBG(tmdev, "%s cnt:%d\n",
					"Re-try TSENS write prior to scm",
						reg_write_cnt++);
					continue;
				}
				reg_write_cnt = 0;

				/* Make an scm call to re-init TSENS */
				TSENS_DBG(tmdev, "%s",
@@ -214,29 +232,53 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
				TSENS_DBG(tmdev, "%s",
						"return from scm call\n");
				if (ret) {
					msleep(100);
					pr_err("%s: scm call failed %d\n",
						__func__, ret);
					BUG();
				}
				tsens_ret = desc.ret[0];
				if (tsens_ret) {
				pr_err("%s: scm call failed to init tsens %d\n",
					msleep(100);
					pr_err("%s: scm call failed, ret:%d\n",
						__func__, tsens_ret);
					BUG();
				}
			tmdev->tsens_reinit_cnt++;
			atomic_set(&in_tsens_reinit, 0);

			/* Notify thermal fwk */
				scm_cnt++;
				rc = 0;
				list_for_each_entry(tmdev_itr,
						&tsens_device_list, list) {
					rc = __tsens2xxx_hw_init(tmdev_itr);
					if (rc) {
						pr_err(
					"%s: Failed to re-initialize TSENS controller\n",
						"%s: TSENS hw_init error\n",
							__func__);
						break;
					}
				}

				if (!rc)
					break;

				if (scm_cnt >= 100) {
					msleep(100);
					pr_err(
					"%s: Tsens is not up after %d scm\n",
						__func__, scm_cnt);
					BUG();
				}
				udelay(2000);
				TSENS_DBG(tmdev, "%s cnt:%d\n",
					"Re-try TSENS scm call", scm_cnt);
			}

			tmdev->tsens_reinit_cnt++;
			atomic_set(&in_tsens_reinit, 0);

			/* Notify thermal fwk */
			list_for_each_entry(tmdev_itr,
						&tsens_device_list, list) {
				queue_work(tmdev_itr->tsens_reinit_work,
					&tmdev_itr->therm_fwk_notify);
			}
@@ -251,7 +293,6 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
sensor_read:

	tmdev->trdy_fail_ctr = 0;
	tmdev->tsens_reinit_cnt = 0;

	code = readl_relaxed_no_log(sensor_addr +
			(sensor->hw_id << TSENS_STATUS_ADDR_OFFSET));