]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd: Add an unwind for failures in amdgpu_device_ip_suspend_phase1()
authorMario Limonciello (AMD) <superm1@kernel.org>
Sun, 26 Oct 2025 04:29:37 +0000 (23:29 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 4 Nov 2025 16:53:04 +0000 (11:53 -0500)
If any hardware IPs involved with the first phase of suspend fail, unwind
all steps to restore back to original state.

Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

index 9f67c53633aaee07f1f4d26dc868c0a247c8d871..227ac93701753281c84504c692986e5b9f764b3c 100644 (file)
@@ -178,6 +178,7 @@ 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_phase3(struct amdgpu_device *adev);
 
 static void amdgpu_device_load_switch_state(struct amdgpu_device *adev);
 
@@ -3784,7 +3785,7 @@ static void amdgpu_device_delay_enable_gfx_off(struct work_struct *work)
  */
 static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev)
 {
-       int i, r;
+       int i, r, rec;
 
        amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
        amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
@@ -3807,10 +3808,23 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev)
 
                r = amdgpu_ip_block_suspend(&adev->ip_blocks[i]);
                if (r)
-                       return r;
+                       goto unwind;
        }
 
        return 0;
+unwind:
+       rec = amdgpu_device_ip_resume_phase3(adev);
+       if (rec)
+               dev_err(adev->dev,
+                       "amdgpu_device_ip_resume_phase3 failed during unwind: %d\n",
+                       rec);
+
+       amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_ALLOW);
+
+       amdgpu_device_set_pg_state(adev, AMD_PG_STATE_GATE);
+       amdgpu_device_set_cg_state(adev, AMD_CG_STATE_GATE);
+
+       return r;
 }
 
 /**