Loading and unloading the amdgpu module in TTY mode is successful at
first glance, but attempting to turn off the system after this action
results in a kernel panic. Sometimes, after trying to run load/unload
multiple times, the user may also encounter other issues. The easiest
way to reproduce this issue is by running the IGT test amd_module_load.

The load/unload issue was introduced by commit 3d5470c97314
("drm/amd/display/dm: add support for OEM i2c bus"), which added support
for OEM i2c. In the original commit, the new I2C adapter is registered
in the initialization function, but it is not deleted in the removal
operation. As a result, when the removal function tries to free the data
struct for the OEM I2C, it has issues. This commit addresses the issue
by checking if the OEM I2C has been initialized; If so, it also
unregisters the I2C adapter before attempting to free it.

Fixes: 3d5470c97314 ("drm/amd/display/dm: add support for OEM i2c bus")
Signed-off-by: Rodrigo Siqueira <sique...@igalia.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

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 242f98564261..6ce51f81ba44 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3007,7 +3007,10 @@ static int dm_hw_fini(struct amdgpu_ip_block *ip_block)
 {
        struct amdgpu_device *adev = ip_block->adev;
 
-       kfree(adev->dm.oem_i2c);
+       if (adev->dm.oem_i2c && adev->dm.oem_i2c->oem) {
+               i2c_del_adapter(&adev->dm.oem_i2c->base);
+               kfree(adev->dm.oem_i2c);
+       }
 
        amdgpu_dm_hpd_fini(adev);
 
-- 
2.50.1

Reply via email to