OSDN Git Service

drm/amdgpu: add helper function to do common ras_late_init/fini (v3)
authorHawking Zhang <Hawking.Zhang@amd.com>
Fri, 30 Aug 2019 05:29:18 +0000 (13:29 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 13 Sep 2019 22:11:04 +0000 (17:11 -0500)
In late_init for ras, the helper function will be used to
1). disable ras feature if the IP block is masked as disabled
2). send enable feature command if the ip block was masked as enabled
3). create debugfs/sysfs node per IP block
4). register interrupt handler

v2: check ih_info.cb to decide add interrupt handler or not

v3: add ras_late_fini for cleanup all the ras fs node and remove
interrupt handler

Signed-off-by: Hawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h

index f718010..0b466d1 100644 (file)
@@ -1566,6 +1566,78 @@ recovery_out:
        return -EINVAL;
 }
 
+/* helper function to handle common stuff in ip late init phase */
+int amdgpu_ras_late_init(struct amdgpu_device *adev,
+                        struct ras_common_if *ras_block,
+                        struct ras_fs_if *fs_info,
+                        struct ras_ih_if *ih_info)
+{
+       int r;
+
+       /* disable RAS feature per IP block if it is not supported */
+       if (!amdgpu_ras_is_supported(adev, ras_block->block)) {
+               amdgpu_ras_feature_enable_on_boot(adev, ras_block, 0);
+               return 0;
+       }
+
+       r = amdgpu_ras_feature_enable_on_boot(adev, ras_block, 1);
+       if (r) {
+               if (r == -EAGAIN) {
+                       /* request gpu reset. will run again */
+                       amdgpu_ras_request_reset_on_boot(adev,
+                                       ras_block->block);
+                       return 0;
+               } else if (adev->in_suspend || adev->in_gpu_reset) {
+                       /* in resume phase, if fail to enable ras,
+                        * clean up all ras fs nodes, and disable ras */
+                       goto cleanup;
+               } else
+                       return r;
+       }
+
+       /* in resume phase, no need to create ras fs node */
+       if (adev->in_suspend || adev->in_gpu_reset)
+               return 0;
+
+       if (ih_info->cb) {
+               r = amdgpu_ras_interrupt_add_handler(adev, ih_info);
+               if (r)
+                       goto interrupt;
+       }
+
+       amdgpu_ras_debugfs_create(adev, fs_info);
+
+       r = amdgpu_ras_sysfs_create(adev, fs_info);
+       if (r)
+               goto sysfs;
+
+       return 0;
+cleanup:
+       amdgpu_ras_sysfs_remove(adev, ras_block);
+sysfs:
+       amdgpu_ras_debugfs_remove(adev, ras_block);
+       if (ih_info->cb)
+               amdgpu_ras_interrupt_remove_handler(adev, ih_info);
+interrupt:
+       amdgpu_ras_feature_enable(adev, ras_block, 0);
+       return r;
+}
+
+/* helper function to remove ras fs node and interrupt handler */
+void amdgpu_ras_late_fini(struct amdgpu_device *adev,
+                         struct ras_common_if *ras_block,
+                         struct ras_ih_if *ih_info)
+{
+       if (!ras_block || !ih_info)
+               return;
+
+       amdgpu_ras_sysfs_remove(adev, ras_block);
+       amdgpu_ras_debugfs_remove(adev, ras_block);
+       if (ih_info->cb)
+                amdgpu_ras_interrupt_remove_handler(adev, ih_info);
+       amdgpu_ras_feature_enable(adev, ras_block, 0);
+}
+
 /* do some init work after IP late init as dependence.
  * and it runs in resume/gpu reset/booting up cases.
  */
index 6c76bb2..66b7152 100644 (file)
@@ -566,6 +566,13 @@ amdgpu_ras_error_to_ta(enum amdgpu_ras_error_type error) {
 int amdgpu_ras_init(struct amdgpu_device *adev);
 int amdgpu_ras_fini(struct amdgpu_device *adev);
 int amdgpu_ras_pre_fini(struct amdgpu_device *adev);
+int amdgpu_ras_late_init(struct amdgpu_device *adev,
+                        struct ras_common_if *ras_block,
+                        struct ras_fs_if *fs_info,
+                        struct ras_ih_if *ih_info);
+void amdgpu_ras_late_fini(struct amdgpu_device *adev,
+                         struct ras_common_if *ras_block,
+                         struct ras_ih_if *ih_info);
 
 int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
                struct ras_common_if *head, bool enable);