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 at amd.com>
> Cc: stable at vger.kernel.org
> ---
>  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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 828 bytes
Desc: This is a digitally signed message part
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20140521/48eac60b/attachment.sig>

Reply via email to