AMDGPU_INFO_xxx has lots of different queries, and only a small number of them actually reaches out to the GPU. This commit extract the amdgpu_info_ioctl implementation to a helper function, and then wrap it with the runtime pm logic each query type needs. Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 94 ++++++++++++++++++++----- 2 files changed, 80 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index d21d5af7f187..f51f121d804e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -2871,6 +2871,8 @@ long amdgpu_drm_ioctl(struct file *filp, if (is_driver_ioctl) { switch (nr - DRM_COMMAND_BASE) { + /* amdgpu_info_ioctl will resume the device if it needs to. */ + case DRM_AMDGPU_INFO: /* These 4 only operate on kernel data structure. */ case DRM_AMDGPU_VM: case DRM_AMDGPU_SCHED: diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 260cd0ad286d..b32ff6e1baaf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -543,22 +543,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, return 0; } -/* - * Userspace get information ioctl - */ -/** - * amdgpu_info_ioctl - answer a device specific request. - * - * @dev: drm device pointer - * @data: request object - * @filp: drm filp - * - * This function is used to pass device specific parameters to the userspace - * drivers. Examples include: pci device id, pipeline parms, tiling params, - * etc. (all asics). - * Returns 0 on success, -EINVAL on failure. - */ -int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) +static int amdgpu_info(struct drm_device *dev, void *data, struct drm_file *filp) { struct amdgpu_device *adev = drm_to_adev(dev); struct drm_amdgpu_info *info = data; @@ -1278,6 +1263,83 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return 0; } +/* + * Userspace get information ioctl + */ +/** + * amdgpu_info_ioctl - answer a device specific request. + * + * @dev: drm device pointer + * @data: request object + * @filp: drm filp + * + * This function is used to pass device specific parameters to the userspace + * drivers. Examples include: pci device id, pipeline parms, tiling params, + * etc. (all asics). + * Returns 0 on success, -EINVAL on failure. + */ +int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) +{ + struct drm_amdgpu_info *info = data; + bool need_runtime_pm; + int ret; + + if (!info->return_size || !info->return_pointer) + return -EINVAL; + + switch (info->query) { + case AMDGPU_INFO_ACCEL_WORKING: + case AMDGPU_INFO_CRTC_FROM_ID: + case AMDGPU_INFO_HW_IP_INFO: + case AMDGPU_INFO_HW_IP_COUNT: + case AMDGPU_INFO_FW_VERSION: + case AMDGPU_INFO_NUM_BYTES_MOVED: + case AMDGPU_INFO_NUM_EVICTIONS: + case AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS: + case AMDGPU_INFO_VRAM_USAGE: + case AMDGPU_INFO_VIS_VRAM_USAGE: + case AMDGPU_INFO_GTT_USAGE: + case AMDGPU_INFO_GDS_CONFIG: + case AMDGPU_INFO_VRAM_GTT: + case AMDGPU_INFO_MEMORY: + case AMDGPU_INFO_VCE_CLOCK_TABLE: + case AMDGPU_INFO_VBIOS: + case AMDGPU_INFO_NUM_HANDLES: + case AMDGPU_INFO_VRAM_LOST_COUNTER: + case AMDGPU_INFO_RAS_ENABLED_FEATURES: + case AMDGPU_INFO_VIDEO_CAPS: + case AMDGPU_INFO_MAX_IBS: + case AMDGPU_INFO_GPUVM_FAULT: + need_runtime_pm = false; + break; + + case AMDGPU_INFO_TIMESTAMP: + case AMDGPU_INFO_READ_MMR_REG: + case AMDGPU_INFO_DEV_INFO: + case AMDGPU_INFO_SENSOR: + need_runtime_pm = true; + break; + default: + DRM_DEBUG_KMS("Invalid request %d\n", info->query); + return -EINVAL; + } + + if (need_runtime_pm) { + ret = pm_runtime_get_sync(dev->dev); + if (ret < 0) + goto put_pm; + } + + ret = amdgpu_info(dev, data, filp); + +put_pm: + if (need_runtime_pm) { + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); + } + + return ret; +} /* * Outdated mess for old drm with Xorg being in charge (void function now). -- 2.40.1