Commit 4f2f2039 authored by Alex Deucher's avatar Alex Deucher Committed by Christian König

drm/radeon/pm: don't allow debugfs/sysfs access when PX card is off (v2)

When the PX card is off don't try and access it. Avoid hw access
to the card while it's off (e.g., reading back invalid temperature).

v2: be less strict

bug:
https://bugzilla.kernel.org/show_bug.cgi?id=76321Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
parent 24f47acc
...@@ -361,6 +361,11 @@ static ssize_t radeon_set_pm_profile(struct device *dev, ...@@ -361,6 +361,11 @@ static ssize_t radeon_set_pm_profile(struct device *dev,
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct radeon_device *rdev = ddev->dev_private; struct radeon_device *rdev = ddev->dev_private;
/* Can't set profile when the card is off */
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return -EINVAL;
mutex_lock(&rdev->pm.mutex); mutex_lock(&rdev->pm.mutex);
if (rdev->pm.pm_method == PM_METHOD_PROFILE) { if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
if (strncmp("default", buf, strlen("default")) == 0) if (strncmp("default", buf, strlen("default")) == 0)
...@@ -409,6 +414,13 @@ static ssize_t radeon_set_pm_method(struct device *dev, ...@@ -409,6 +414,13 @@ static ssize_t radeon_set_pm_method(struct device *dev,
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct radeon_device *rdev = ddev->dev_private; struct radeon_device *rdev = ddev->dev_private;
/* Can't set method when the card is off */
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON)) {
count = -EINVAL;
goto fail;
}
/* we don't support the legacy modes with dpm */ /* we don't support the legacy modes with dpm */
if (rdev->pm.pm_method == PM_METHOD_DPM) { if (rdev->pm.pm_method == PM_METHOD_DPM) {
count = -EINVAL; count = -EINVAL;
...@@ -446,6 +458,10 @@ static ssize_t radeon_get_dpm_state(struct device *dev, ...@@ -446,6 +458,10 @@ static ssize_t radeon_get_dpm_state(struct device *dev,
struct radeon_device *rdev = ddev->dev_private; struct radeon_device *rdev = ddev->dev_private;
enum radeon_pm_state_type pm = rdev->pm.dpm.user_state; enum radeon_pm_state_type pm = rdev->pm.dpm.user_state;
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return snprintf(buf, PAGE_SIZE, "off\n");
return snprintf(buf, PAGE_SIZE, "%s\n", return snprintf(buf, PAGE_SIZE, "%s\n",
(pm == POWER_STATE_TYPE_BATTERY) ? "battery" : (pm == POWER_STATE_TYPE_BATTERY) ? "battery" :
(pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance"); (pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance");
...@@ -459,6 +475,11 @@ static ssize_t radeon_set_dpm_state(struct device *dev, ...@@ -459,6 +475,11 @@ static ssize_t radeon_set_dpm_state(struct device *dev,
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct radeon_device *rdev = ddev->dev_private; struct radeon_device *rdev = ddev->dev_private;
/* Can't set dpm state when the card is off */
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return -EINVAL;
mutex_lock(&rdev->pm.mutex); mutex_lock(&rdev->pm.mutex);
if (strncmp("battery", buf, strlen("battery")) == 0) if (strncmp("battery", buf, strlen("battery")) == 0)
rdev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY; rdev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY;
...@@ -485,6 +506,10 @@ static ssize_t radeon_get_dpm_forced_performance_level(struct device *dev, ...@@ -485,6 +506,10 @@ static ssize_t radeon_get_dpm_forced_performance_level(struct device *dev,
struct radeon_device *rdev = ddev->dev_private; struct radeon_device *rdev = ddev->dev_private;
enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level; enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level;
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return snprintf(buf, PAGE_SIZE, "off\n");
return snprintf(buf, PAGE_SIZE, "%s\n", return snprintf(buf, PAGE_SIZE, "%s\n",
(level == RADEON_DPM_FORCED_LEVEL_AUTO) ? "auto" : (level == RADEON_DPM_FORCED_LEVEL_AUTO) ? "auto" :
(level == RADEON_DPM_FORCED_LEVEL_LOW) ? "low" : "high"); (level == RADEON_DPM_FORCED_LEVEL_LOW) ? "low" : "high");
...@@ -500,6 +525,11 @@ static ssize_t radeon_set_dpm_forced_performance_level(struct device *dev, ...@@ -500,6 +525,11 @@ static ssize_t radeon_set_dpm_forced_performance_level(struct device *dev,
enum radeon_dpm_forced_level level; enum radeon_dpm_forced_level level;
int ret = 0; int ret = 0;
/* Can't force performance level when the card is off */
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return -EINVAL;
mutex_lock(&rdev->pm.mutex); mutex_lock(&rdev->pm.mutex);
if (strncmp("low", buf, strlen("low")) == 0) { if (strncmp("low", buf, strlen("low")) == 0) {
level = RADEON_DPM_FORCED_LEVEL_LOW; level = RADEON_DPM_FORCED_LEVEL_LOW;
...@@ -538,8 +568,14 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev, ...@@ -538,8 +568,14 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev,
char *buf) char *buf)
{ {
struct radeon_device *rdev = dev_get_drvdata(dev); struct radeon_device *rdev = dev_get_drvdata(dev);
struct drm_device *ddev = rdev->ddev;
int temp; int temp;
/* Can't get temperature when the card is off */
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return -EINVAL;
if (rdev->asic->pm.get_temperature) if (rdev->asic->pm.get_temperature)
temp = radeon_get_temperature(rdev); temp = radeon_get_temperature(rdev);
else else
...@@ -1614,8 +1650,12 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data) ...@@ -1614,8 +1650,12 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev; struct drm_device *dev = node->minor->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct drm_device *ddev = rdev->ddev;
if (rdev->pm.dpm_enabled) { if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON)) {
seq_printf(m, "PX asic powered off\n");
} else if (rdev->pm.dpm_enabled) {
mutex_lock(&rdev->pm.mutex); mutex_lock(&rdev->pm.mutex);
if (rdev->asic->dpm.debugfs_print_current_performance_level) if (rdev->asic->dpm.debugfs_print_current_performance_level)
radeon_dpm_debugfs_print_current_performance_level(rdev, m); radeon_dpm_debugfs_print_current_performance_level(rdev, m);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment