Commit 1d611218 authored by Mario Limonciello (AMD)'s avatar Mario Limonciello (AMD) Committed by Alex Deucher
Browse files

drm/amd: Add an unwind for failures in amdgpu_device_ip_suspend_phase2()



If any hardware IPs involved with the second phase of suspend fail, unwind
all steps to restore back to original state.

Signed-off-by: default avatarMario Limonciello (AMD) <superm1@kernel.org>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6f4208f9
Loading
Loading
Loading
Loading
+33 −3
Original line number Diff line number Diff line
@@ -178,6 +178,9 @@ struct amdgpu_init_level amdgpu_init_minimal_xgmi = {
		BIT(AMD_IP_BLOCK_TYPE_COMMON) | BIT(AMD_IP_BLOCK_TYPE_IH) |
		BIT(AMD_IP_BLOCK_TYPE_PSP)
};

static int amdgpu_device_ip_resume_phase1(struct amdgpu_device *adev);
static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev);
static int amdgpu_device_ip_resume_phase3(struct amdgpu_device *adev);

static void amdgpu_device_load_switch_state(struct amdgpu_device *adev);
@@ -3840,7 +3843,7 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev)
 */
static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
{
	int i, r;
	int i, r, rec;

	if (adev->in_s0ix)
		amdgpu_dpm_gfx_state_change(adev, sGpuChangeState_D3Entry);
@@ -3903,7 +3906,7 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)

		r = amdgpu_ip_block_suspend(&adev->ip_blocks[i]);
		if (r)
			return r;
			goto unwind;

		/* handle putting the SMC in the appropriate state */
		if (!amdgpu_sriov_vf(adev)) {
@@ -3913,13 +3916,40 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
					dev_err(adev->dev,
						"SMC failed to set mp1 state %d, %d\n",
						adev->mp1_state, r);
					return r;
					goto unwind;
				}
			}
		}
	}

	return 0;
unwind:
	/* suspend phase 2 = resume phase 1 + resume phase 2 */
	rec = amdgpu_device_ip_resume_phase1(adev);
	if (rec) {
		dev_err(adev->dev,
			"amdgpu_device_ip_resume_phase1 failed during unwind: %d\n",
			rec);
		return r;
	}

	rec = amdgpu_device_fw_loading(adev);
	if (rec) {
		dev_err(adev->dev,
			"amdgpu_device_fw_loading failed during unwind: %d\n",
			rec);
		return r;
	}

	rec = amdgpu_device_ip_resume_phase2(adev);
	if (rec) {
		dev_err(adev->dev,
			"amdgpu_device_ip_resume_phase2 failed during unwind: %d\n",
			rec);
		return r;
	}

	return r;
}

/**