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

Commit 6c055b9c authored by Puranam V G Tejaswi's avatar Puranam V G Tejaswi
Browse files

msm: kgsl: check kgsl state before accessing device registers



In some unfortunate scenarios it is possible that dispatcher is
scheduled when kgsl state is not awake. Consider the scenario
when GMU stop failed. During subsequent wake, GMU boot failed and
watchdog interrupt has been received. In the handler GPU fault is
set and dipatcher_do_fault() is triggered. Here device registers
are accessed and kgsl state is slumber as previous wake failed.
So check kgsl state before accessing any register.

Change-Id: Ibbc2366e34d3351af997dcd68f7e749ef2869e55
Signed-off-by: default avatarPuranam V G Tejaswi <pvgtejas@codeaurora.org>
parent 743fc536
Loading
Loading
Loading
Loading
+17 −15
Original line number Diff line number Diff line
@@ -2098,6 +2098,22 @@ static int dispatcher_do_fault(struct adreno_device *adreno_dev)
	if (fault == 0)
		return 0;

	mutex_lock(&device->mutex);

	/*
	 * In the very unlikely case that the power is off, do nothing - the
	 * state will be reset on power up and everybody will be happy
	 */
	if (!kgsl_state_is_awake(device)) {
		mutex_unlock(&device->mutex);
		if (fault & ADRENO_SOFT_FAULT) {
			/* Clear the existing register values */
			memset(adreno_ft_regs_val, 0,
				adreno_ft_regs_num * sizeof(unsigned int));
		}
		return 0;
	}

	/* Mask all GMU interrupts */
	if (gmu_core_isenabled(device)) {
		adreno_write_gmureg(adreno_dev,
@@ -2110,17 +2126,6 @@ static int dispatcher_do_fault(struct adreno_device *adreno_dev)

	gx_on = gmu_core_dev_gx_is_on(device);

	/*
	 * In the very unlikely case that the power is off, do nothing - the
	 * state will be reset on power up and everybody will be happy
	 */

	if (!kgsl_state_is_awake(device) && (fault & ADRENO_SOFT_FAULT)) {
		/* Clear the existing register values */
		memset(adreno_ft_regs_val, 0,
				adreno_ft_regs_num * sizeof(unsigned int));
		return 0;
	}

	/*
	 * On A5xx and A6xx, read RBBM_STATUS3:SMMU_STALLED_ON_FAULT (BIT 24)
@@ -2133,10 +2138,9 @@ static int dispatcher_do_fault(struct adreno_device *adreno_dev)
		gx_on) {
		unsigned int val;

		mutex_lock(&device->mutex);
		adreno_readreg(adreno_dev, ADRENO_REG_RBBM_STATUS3, &val);
		mutex_unlock(&device->mutex);
		if (val & BIT(24)) {
			mutex_unlock(&device->mutex);
			dev_err(device->dev,
				"SMMU is stalled without a pagefault\n");
			return -EBUSY;
@@ -2153,8 +2157,6 @@ static int dispatcher_do_fault(struct adreno_device *adreno_dev)
	if (adreno_is_preemption_enabled(adreno_dev))
		del_timer_sync(&adreno_dev->preempt.timer);

	mutex_lock(&device->mutex);

	if (gx_on)
		adreno_readreg64(adreno_dev, ADRENO_REG_CP_RB_BASE,
			ADRENO_REG_CP_RB_BASE_HI, &base);