DF-3645 / fix.diff
--- a/sys/dev/drm/radeon/ci_dpm.c +++ b/sys/dev/drm/radeon/ci_dpm.c @@ -5666,6 +5666,8 @@ static int ci_parse_power_table(struct radeon_device *rdev) err_free_ps: for (i = 0; i < rdev->pm.dpm.num_ps; i++) kfree(rdev->pm.dpm.ps[i].ps_priv); kfree(rdev->pm.dpm.ps); + rdev->pm.dpm.ps = NULL; + rdev->pm.dpm.num_ps = 0; return ret; } @@ -5703,6 +5705,10 @@ void ci_dpm_fini(struct radeon_device *rdev) for (i = 0; i < rdev->pm.dpm.num_ps; i++) { kfree(rdev->pm.dpm.ps[i].ps_priv); } kfree(rdev->pm.dpm.ps); kfree(rdev->pm.dpm.priv); + rdev->pm.dpm.ps = NULL; + rdev->pm.dpm.num_ps = 0; + rdev->pm.dpm.priv = NULL; kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries); r600_free_extended_power_table(rdev); } @@ -5762,21 +5768,25 @@ int ci_dpm_init(struct radeon_device *rdev) ret = ci_get_vbios_boot_values(rdev, &pi->vbios_boot_state); if (ret) { kfree(rdev->pm.dpm.priv); + rdev->pm.dpm.priv = NULL; return ret; } ret = r600_get_platform_caps(rdev); if (ret) { kfree(rdev->pm.dpm.priv); + rdev->pm.dpm.priv = NULL; return ret; } ret = r600_parse_extended_power_table(rdev); if (ret) { kfree(rdev->pm.dpm.priv); + rdev->pm.dpm.priv = NULL; return ret; } ret = ci_parse_power_table(rdev); if (ret) { kfree(rdev->pm.dpm.priv); + rdev->pm.dpm.priv = NULL; r600_free_extended_power_table(rdev); return ret; } --- a/sys/dev/drm/radeon/radeon_pm.c +++ b/sys/dev/drm/radeon/radeon_pm.c @@ -1445,7 +1445,11 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev) INIT_WORK(&rdev->pm.dpm.thermal.work, radeon_dpm_thermal_work_handler); mutex_lock(&rdev->pm.mutex); - radeon_dpm_init(rdev); + ret = radeon_dpm_init(rdev); + if (ret) { + mutex_unlock(&rdev->pm.mutex); + goto dpm_failed; + } rdev->pm.dpm.current_ps = rdev->pm.dpm.requested_ps = rdev->pm.dpm.boot_ps; |