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

Signed-off-by: Mario Limonciello (AMD) <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 36 ++++++++++++++++++++--
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index b9ea91b2c92f..5945f441d01e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -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;
 }
 
 /**
-- 
2.51.1

Reply via email to