Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon/pm: don't walk the crtc list before it has been initialized (v2)

Avoids a crash in certain cases when thermal irqs are generated
before the display structures have been initialized.

v2: fix the vblank and vrefresh helpers as well

bug:
https://bugzilla.kernel.org/show_bug.cgi?id=73931

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org

authored by

Alex Deucher and committed by
Christian König
3ed9a335 cb3e4e7c

+35 -28
+19 -16
drivers/gpu/drm/radeon/r600_dpm.c
··· 158 158 u32 line_time_us, vblank_lines; 159 159 u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ 160 160 161 - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 162 - radeon_crtc = to_radeon_crtc(crtc); 163 - if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { 164 - line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) / 165 - radeon_crtc->hw_mode.clock; 166 - vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end - 167 - radeon_crtc->hw_mode.crtc_vdisplay + 168 - (radeon_crtc->v_border * 2); 169 - vblank_time_us = vblank_lines * line_time_us; 170 - break; 161 + if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { 162 + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 163 + radeon_crtc = to_radeon_crtc(crtc); 164 + if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { 165 + line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) / 166 + radeon_crtc->hw_mode.clock; 167 + vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end - 168 + radeon_crtc->hw_mode.crtc_vdisplay + 169 + (radeon_crtc->v_border * 2); 170 + vblank_time_us = vblank_lines * line_time_us; 171 + break; 172 + } 171 173 } 172 174 } 173 175 ··· 183 181 struct radeon_crtc *radeon_crtc; 184 182 u32 vrefresh = 0; 185 183 186 - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 187 - radeon_crtc = to_radeon_crtc(crtc); 188 - if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { 189 - vrefresh = radeon_crtc->hw_mode.vrefresh; 190 - break; 184 + if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { 185 + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 186 + radeon_crtc = to_radeon_crtc(crtc); 187 + if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { 188 + vrefresh = radeon_crtc->hw_mode.vrefresh; 189 + break; 190 + } 191 191 } 192 192 } 193 - 194 193 return vrefresh; 195 194 } 196 195
+16 -12
drivers/gpu/drm/radeon/radeon_pm.c
··· 1406 1406 1407 1407 rdev->pm.active_crtcs = 0; 1408 1408 rdev->pm.active_crtc_count = 0; 1409 - list_for_each_entry(crtc, 1410 - &ddev->mode_config.crtc_list, head) { 1411 - radeon_crtc = to_radeon_crtc(crtc); 1412 - if (radeon_crtc->enabled) { 1413 - rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id); 1414 - rdev->pm.active_crtc_count++; 1409 + if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { 1410 + list_for_each_entry(crtc, 1411 + &ddev->mode_config.crtc_list, head) { 1412 + radeon_crtc = to_radeon_crtc(crtc); 1413 + if (radeon_crtc->enabled) { 1414 + rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id); 1415 + rdev->pm.active_crtc_count++; 1416 + } 1415 1417 } 1416 1418 } 1417 1419 ··· 1480 1478 /* update active crtc counts */ 1481 1479 rdev->pm.dpm.new_active_crtcs = 0; 1482 1480 rdev->pm.dpm.new_active_crtc_count = 0; 1483 - list_for_each_entry(crtc, 1484 - &ddev->mode_config.crtc_list, head) { 1485 - radeon_crtc = to_radeon_crtc(crtc); 1486 - if (crtc->enabled) { 1487 - rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id); 1488 - rdev->pm.dpm.new_active_crtc_count++; 1481 + if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { 1482 + list_for_each_entry(crtc, 1483 + &ddev->mode_config.crtc_list, head) { 1484 + radeon_crtc = to_radeon_crtc(crtc); 1485 + if (crtc->enabled) { 1486 + rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id); 1487 + rdev->pm.dpm.new_active_crtc_count++; 1488 + } 1489 1489 } 1490 1490 } 1491 1491