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

Ben Hutchings ben at decadent.org.uk
Tue May 20 18:31:04 PDT 2014


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>


More information about the dri-devel mailing list