[PATCH 2/2] drm/amd/display: refine error handling for dm_dmub_sw_init()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



To avoid potential memory leaks, refine error handling for
dm_dmub_sw_init().

Signed-off-by: Lang Yu <lang.yu@xxxxxxx>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 37 ++++++++++++++-----
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 8f6766542c73..ef6800dc0215 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1890,19 +1890,19 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
 
 	default:
 		/* ASIC doesn't support DMUB. */
-		return 0;
+		return -EINVAL;
 	}
 
 	r = request_firmware_direct(&adev->dm.dmub_fw, fw_name_dmub, adev->dev);
 	if (r) {
 		DRM_ERROR("DMUB firmware loading failed: %d\n", r);
-		return 0;
+		return r;
 	}
 
 	r = amdgpu_ucode_validate(adev->dm.dmub_fw);
 	if (r) {
 		DRM_ERROR("Couldn't validate DMUB firmware: %d\n", r);
-		return 0;
+		goto release_firmware;
 	}
 
 	hdr = (const struct dmcub_firmware_header_v1_0 *)adev->dm.dmub_fw->data;
@@ -1926,7 +1926,8 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
 
 	if (!dmub_srv) {
 		DRM_ERROR("Failed to allocate DMUB service!\n");
-		return -ENOMEM;
+		r = -ENOMEM;
+		goto release_firmware;
 	}
 
 	memset(&create_params, 0, sizeof(create_params));
@@ -1939,7 +1940,8 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
 	status = dmub_srv_create(dmub_srv, &create_params);
 	if (status != DMUB_STATUS_OK) {
 		DRM_ERROR("Error creating DMUB service: %d\n", status);
-		return -EINVAL;
+		r = -EINVAL;
+		goto free_dmub_srv;
 	}
 
 	/* Calculate the size of all the regions for the DMUB service. */
@@ -1963,7 +1965,8 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
 
 	if (status != DMUB_STATUS_OK) {
 		DRM_ERROR("Error calculating DMUB region info: %d\n", status);
-		return -EINVAL;
+		r = -EINVAL;
+		goto free_dmub_srv;
 	}
 
 	/*
@@ -1975,8 +1978,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
 				    &adev->dm.dmub_bo_gpu_addr,
 				    &adev->dm.dmub_bo_cpu_addr);
 	if (r)
-		return r;
-
+		goto free_dmub_srv;
 	/* Rebase the regions on the framebuffer address. */
 	memset(&fb_params, 0, sizeof(fb_params));
 	fb_params.cpu_addr = adev->dm.dmub_bo_cpu_addr;
@@ -1990,16 +1992,31 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
 	if (!fb_info) {
 		DRM_ERROR(
 			"Failed to allocate framebuffer info for DMUB service!\n");
-		return -ENOMEM;
+		r =  -ENOMEM;
+		goto free_dmub_bo;
 	}
 
 	status = dmub_srv_calc_fb_info(dmub_srv, &fb_params, fb_info);
 	if (status != DMUB_STATUS_OK) {
 		DRM_ERROR("Error calculating DMUB FB info: %d\n", status);
-		return -EINVAL;
+		r = -EINVAL;
+		goto free_dmub_bo;
 	}
 
 	return 0;
+
+free_dmub_bo:
+	amdgpu_bo_free_kernel(&adev->dm.dmub_bo,
+			      &adev->dm.dmub_bo_gpu_addr,
+			      &adev->dm.dmub_bo_cpu_addr);
+free_dmub_srv:
+	kfree(adev->dm.dmub_srv);
+	adev->dm.dmub_srv = NULL;
+release_firmware:
+	release_firmware(adev->dm.dmub_fw);
+	adev->dm.dmub_fw = NULL;
+
+	return r;
 }
 
 static int dm_sw_init(void *handle)
-- 
2.25.1




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux