diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2014-04-15 12:44:33 -0400 |
---|---|---|
committer | Christian König <christian.koenig@amd.com> | 2014-04-22 10:51:19 -0400 |
commit | 3ed9a335cfc64b2c83545f341cdddf2347b12b97 (patch) | |
tree | 36079e60371cc6f7b68916e518dd20077f33cc31 /drivers/gpu | |
parent | cb3e4e7c59e4b43ac378631f6101f5c8de3a27a5 (diff) |
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
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/r600_dpm.c | 35 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 28 |
2 files changed, 35 insertions, 28 deletions
diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c index cbf7e3269f84..9c61b74ef441 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.c +++ b/drivers/gpu/drm/radeon/r600_dpm.c | |||
@@ -158,16 +158,18 @@ u32 r600_dpm_get_vblank_time(struct radeon_device *rdev) | |||
158 | u32 line_time_us, vblank_lines; | 158 | u32 line_time_us, vblank_lines; |
159 | u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ | 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) { | 161 | if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { |
162 | radeon_crtc = to_radeon_crtc(crtc); | 162 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
163 | if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { | 163 | radeon_crtc = to_radeon_crtc(crtc); |
164 | line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) / | 164 | if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { |
165 | radeon_crtc->hw_mode.clock; | 165 | line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) / |
166 | vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end - | 166 | radeon_crtc->hw_mode.clock; |
167 | radeon_crtc->hw_mode.crtc_vdisplay + | 167 | vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end - |
168 | (radeon_crtc->v_border * 2); | 168 | radeon_crtc->hw_mode.crtc_vdisplay + |
169 | vblank_time_us = vblank_lines * line_time_us; | 169 | (radeon_crtc->v_border * 2); |
170 | break; | 170 | vblank_time_us = vblank_lines * line_time_us; |
171 | break; | ||
172 | } | ||
171 | } | 173 | } |
172 | } | 174 | } |
173 | 175 | ||
@@ -181,14 +183,15 @@ u32 r600_dpm_get_vrefresh(struct radeon_device *rdev) | |||
181 | struct radeon_crtc *radeon_crtc; | 183 | struct radeon_crtc *radeon_crtc; |
182 | u32 vrefresh = 0; | 184 | u32 vrefresh = 0; |
183 | 185 | ||
184 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 186 | if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { |
185 | radeon_crtc = to_radeon_crtc(crtc); | 187 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
186 | if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { | 188 | radeon_crtc = to_radeon_crtc(crtc); |
187 | vrefresh = radeon_crtc->hw_mode.vrefresh; | 189 | if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { |
188 | break; | 190 | vrefresh = radeon_crtc->hw_mode.vrefresh; |
191 | break; | ||
192 | } | ||
189 | } | 193 | } |
190 | } | 194 | } |
191 | |||
192 | return vrefresh; | 195 | return vrefresh; |
193 | } | 196 | } |
194 | 197 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index d79895aebc59..6fac8efe8340 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -1406,12 +1406,14 @@ static void radeon_pm_compute_clocks_old(struct radeon_device *rdev) | |||
1406 | 1406 | ||
1407 | rdev->pm.active_crtcs = 0; | 1407 | rdev->pm.active_crtcs = 0; |
1408 | rdev->pm.active_crtc_count = 0; | 1408 | rdev->pm.active_crtc_count = 0; |
1409 | list_for_each_entry(crtc, | 1409 | if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { |
1410 | &ddev->mode_config.crtc_list, head) { | 1410 | list_for_each_entry(crtc, |
1411 | radeon_crtc = to_radeon_crtc(crtc); | 1411 | &ddev->mode_config.crtc_list, head) { |
1412 | if (radeon_crtc->enabled) { | 1412 | radeon_crtc = to_radeon_crtc(crtc); |
1413 | rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id); | 1413 | if (radeon_crtc->enabled) { |
1414 | rdev->pm.active_crtc_count++; | 1414 | rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id); |
1415 | rdev->pm.active_crtc_count++; | ||
1416 | } | ||
1415 | } | 1417 | } |
1416 | } | 1418 | } |
1417 | 1419 | ||
@@ -1478,12 +1480,14 @@ static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev) | |||
1478 | /* update active crtc counts */ | 1480 | /* update active crtc counts */ |
1479 | rdev->pm.dpm.new_active_crtcs = 0; | 1481 | rdev->pm.dpm.new_active_crtcs = 0; |
1480 | rdev->pm.dpm.new_active_crtc_count = 0; | 1482 | rdev->pm.dpm.new_active_crtc_count = 0; |
1481 | list_for_each_entry(crtc, | 1483 | if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { |
1482 | &ddev->mode_config.crtc_list, head) { | 1484 | list_for_each_entry(crtc, |
1483 | radeon_crtc = to_radeon_crtc(crtc); | 1485 | &ddev->mode_config.crtc_list, head) { |
1484 | if (crtc->enabled) { | 1486 | radeon_crtc = to_radeon_crtc(crtc); |
1485 | rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id); | 1487 | if (crtc->enabled) { |
1486 | rdev->pm.dpm.new_active_crtc_count++; | 1488 | rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id); |
1489 | rdev->pm.dpm.new_active_crtc_count++; | ||
1490 | } | ||
1487 | } | 1491 | } |
1488 | } | 1492 | } |
1489 | 1493 | ||