drm/radeon: add pm sysfs files late

They were added relatively early in the driver init process
which meant that in some cases the driver was not finished
initializing before external tools tried to use them which
could result in a crash depending on the timing.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
This commit is contained in:
Alex Deucher 2015-09-30 16:45:52 -04:00
Родитель ccf03d6995
Коммит 51a4726b04
2 изменённых файлов: 40 добавлений и 37 удалений

Просмотреть файл

@ -1633,18 +1633,8 @@ int radeon_modeset_init(struct radeon_device *rdev)
radeon_fbdev_init(rdev); radeon_fbdev_init(rdev);
drm_kms_helper_poll_init(rdev->ddev); drm_kms_helper_poll_init(rdev->ddev);
if (rdev->pm.dpm_enabled) { /* do pm late init */
/* do dpm late init */ ret = radeon_pm_late_init(rdev);
ret = radeon_pm_late_init(rdev);
if (ret) {
rdev->pm.dpm_enabled = false;
DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
}
/* set the dpm state for PX since there won't be
* a modeset to call this.
*/
radeon_pm_compute_clocks(rdev);
}
return 0; return 0;
} }

Просмотреть файл

@ -1326,14 +1326,6 @@ static int radeon_pm_init_old(struct radeon_device *rdev)
INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler); INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler);
if (rdev->pm.num_power_states > 1) { if (rdev->pm.num_power_states > 1) {
/* where's the best place to put these? */
ret = device_create_file(rdev->dev, &dev_attr_power_profile);
if (ret)
DRM_ERROR("failed to create device file for power profile\n");
ret = device_create_file(rdev->dev, &dev_attr_power_method);
if (ret)
DRM_ERROR("failed to create device file for power method\n");
if (radeon_debugfs_pm_init(rdev)) { if (radeon_debugfs_pm_init(rdev)) {
DRM_ERROR("Failed to register debugfs file for PM!\n"); DRM_ERROR("Failed to register debugfs file for PM!\n");
} }
@ -1391,20 +1383,6 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev)
goto dpm_failed; goto dpm_failed;
rdev->pm.dpm_enabled = true; rdev->pm.dpm_enabled = true;
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
if (ret)
DRM_ERROR("failed to create device file for dpm state\n");
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
if (ret)
DRM_ERROR("failed to create device file for dpm state\n");
/* XXX: these are noops for dpm but are here for backwards compat */
ret = device_create_file(rdev->dev, &dev_attr_power_profile);
if (ret)
DRM_ERROR("failed to create device file for power profile\n");
ret = device_create_file(rdev->dev, &dev_attr_power_method);
if (ret)
DRM_ERROR("failed to create device file for power method\n");
if (radeon_debugfs_pm_init(rdev)) { if (radeon_debugfs_pm_init(rdev)) {
DRM_ERROR("Failed to register debugfs file for dpm!\n"); DRM_ERROR("Failed to register debugfs file for dpm!\n");
} }
@ -1545,9 +1523,44 @@ int radeon_pm_late_init(struct radeon_device *rdev)
int ret = 0; int ret = 0;
if (rdev->pm.pm_method == PM_METHOD_DPM) { if (rdev->pm.pm_method == PM_METHOD_DPM) {
mutex_lock(&rdev->pm.mutex); if (rdev->pm.dpm_enabled) {
ret = radeon_dpm_late_enable(rdev); ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
mutex_unlock(&rdev->pm.mutex); if (ret)
DRM_ERROR("failed to create device file for dpm state\n");
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
if (ret)
DRM_ERROR("failed to create device file for dpm state\n");
/* XXX: these are noops for dpm but are here for backwards compat */
ret = device_create_file(rdev->dev, &dev_attr_power_profile);
if (ret)
DRM_ERROR("failed to create device file for power profile\n");
ret = device_create_file(rdev->dev, &dev_attr_power_method);
if (ret)
DRM_ERROR("failed to create device file for power method\n");
mutex_lock(&rdev->pm.mutex);
ret = radeon_dpm_late_enable(rdev);
mutex_unlock(&rdev->pm.mutex);
if (ret) {
rdev->pm.dpm_enabled = false;
DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
} else {
/* set the dpm state for PX since there won't be
* a modeset to call this.
*/
radeon_pm_compute_clocks(rdev);
}
}
} else {
if (rdev->pm.num_power_states > 1) {
/* where's the best place to put these? */
ret = device_create_file(rdev->dev, &dev_attr_power_profile);
if (ret)
DRM_ERROR("failed to create device file for power profile\n");
ret = device_create_file(rdev->dev, &dev_attr_power_method);
if (ret)
DRM_ERROR("failed to create device file for power method\n");
}
} }
return ret; return ret;
} }