If a device supports runtime pm, then pm_runtime_get_if_active returns 0 if a device is not active and 1 if already active. However, if a device doesn't support runtime pm, the API returns -EINVAL. A device not supporting runtime pm implies it's not affected by runtime pm and it's active. Hence no need to get() to increment usage count. Remove < 0 return value check. Also, ignore runpm state to determine active status. If the device is already in suspend state, disallow access. Signed-off-by: Lijo Lazar <lijo.lazar@xxxxxxx> --- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 0fe0b798f559..e4ab28785bd0 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -100,15 +100,18 @@ const char * const amdgpu_pp_profile_name[] = { /** * amdgpu_pm_dev_state_check - Check if device can be accessed. * @adev: Target device. + * @runpm: Check runpm status for suspend state checks. * * Checks the state of the @adev for access. Return 0 if the device is * accessible or a negative error code otherwise. */ -static int amdgpu_pm_dev_state_check(struct amdgpu_device *adev) +static int amdgpu_pm_dev_state_check(struct amdgpu_device *adev, bool runpm) { + bool runpm_check = runpm ? adev->in_runpm : false; + if (amdgpu_in_reset(adev)) return -EPERM; - if (adev->in_suspend && !adev->in_runpm) + if (adev->in_suspend && !runpm_check) return -EPERM; return 0; @@ -126,7 +129,7 @@ static int amdgpu_pm_get_access(struct amdgpu_device *adev) { int ret; - ret = amdgpu_pm_dev_state_check(adev); + ret = amdgpu_pm_dev_state_check(adev, true); if (ret) return ret; @@ -145,13 +148,18 @@ static int amdgpu_pm_get_access_if_active(struct amdgpu_device *adev) { int ret; - ret = amdgpu_pm_dev_state_check(adev); + /* Ignore runpm status. If device is in suspended state, deny access */ + ret = amdgpu_pm_dev_state_check(adev, false); if (ret) return ret; + /* + * Allow only if device is active. If runpm is disabled also, as in + * kernels without CONFIG_PM, allow access. + */ ret = pm_runtime_get_if_active(adev->dev); - if (ret <= 0) - return ret ?: -EPERM; + if (!ret) + return -EPERM; return 0; } @@ -469,7 +477,7 @@ static ssize_t amdgpu_get_pp_force_state(struct device *dev, struct amdgpu_device *adev = drm_to_adev(ddev); int ret; - ret = amdgpu_pm_dev_state_check(adev); + ret = amdgpu_pm_dev_state_check(adev, true); if (ret) return ret; @@ -1562,7 +1570,7 @@ static ssize_t amdgpu_get_unique_id(struct device *dev, struct amdgpu_device *adev = drm_to_adev(ddev); int r; - r = amdgpu_pm_dev_state_check(adev); + r = amdgpu_pm_dev_state_check(adev, true); if (r) return r; if (adev->unique_id) @@ -2150,7 +2158,7 @@ static ssize_t amdgpu_get_pm_policy_attr(struct device *dev, policy_attr = container_of(attr, struct amdgpu_pm_policy_attr, dev_attr); - r = amdgpu_pm_dev_state_check(adev); + r = amdgpu_pm_dev_state_check(adev, true); if (r) return r; @@ -4674,7 +4682,7 @@ static ssize_t amdgpu_pm_prv_buffer_read(struct file *f, char __user *buf, void *smu_prv_buf; int ret = 0; - ret = amdgpu_pm_dev_state_check(adev); + ret = amdgpu_pm_dev_state_check(adev, true); if (ret) return ret; -- 2.25.1