On Mon, 2014-05-19 at 19:21 -0400, Alex Deucher wrote: > 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=76321 I count 8 copies of the same condition. It seems like it deserves to be a function. Ben. > Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > --- > drivers/gpu/drm/radeon/radeon_pm.c | 42 +++++++++++++++++++++++++++++++++++++- > 1 file changed, 41 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c > index f30b842..53d6e1b 100644 > --- a/drivers/gpu/drm/radeon/radeon_pm.c > +++ b/drivers/gpu/drm/radeon/radeon_pm.c > @@ -361,6 +361,11 @@ static ssize_t radeon_set_pm_profile(struct device *dev, > struct drm_device *ddev = dev_get_drvdata(dev); > 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); > if (rdev->pm.pm_method == PM_METHOD_PROFILE) { > if (strncmp("default", buf, strlen("default")) == 0) > @@ -409,6 +414,13 @@ static ssize_t radeon_set_pm_method(struct device *dev, > struct drm_device *ddev = dev_get_drvdata(dev); > 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 */ > if (rdev->pm.pm_method == PM_METHOD_DPM) { > count = -EINVAL; > @@ -446,6 +458,10 @@ static ssize_t radeon_get_dpm_state(struct device *dev, > struct radeon_device *rdev = ddev->dev_private; > 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", > (pm == POWER_STATE_TYPE_BATTERY) ? "battery" : > (pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance"); > @@ -459,6 +475,11 @@ static ssize_t radeon_set_dpm_state(struct device *dev, > struct drm_device *ddev = dev_get_drvdata(dev); > 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); > if (strncmp("battery", buf, strlen("battery")) == 0) > 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, > struct radeon_device *rdev = ddev->dev_private; > 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", > (level == RADEON_DPM_FORCED_LEVEL_AUTO) ? "auto" : > (level == RADEON_DPM_FORCED_LEVEL_LOW) ? "low" : "high"); > @@ -500,6 +525,11 @@ static ssize_t radeon_set_dpm_forced_performance_level(struct device *dev, > enum radeon_dpm_forced_level level; > 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); > if (strncmp("low", buf, strlen("low")) == 0) { > level = RADEON_DPM_FORCED_LEVEL_LOW; > @@ -538,8 +568,14 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev, > char *buf) > { > struct radeon_device *rdev = dev_get_drvdata(dev); > + struct drm_device *ddev = rdev->ddev; > 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) > temp = radeon_get_temperature(rdev); > else > @@ -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_device *dev = node->minor->dev; > 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); > if (rdev->asic->dpm.debugfs_print_current_performance_level) > radeon_dpm_debugfs_print_current_performance_level(rdev, m); -- Ben Hutchings Life would be so much easier if we could look at the source code.
Attachment:
signature.asc
Description: This is a digitally signed message part