When a drm_crtc structure is destroyed with drm_crtc_cleanup(), the DRM core does not turn off the crtc first and neither do the drivers. With nouveau, radeon and amdgpu, this causes a runtime pm ref to be leaked on driver unload if at least one crtc was enabled. (See usage of have_disp_power_ref in nouveau_crtc_set_config(), radeon_crtc_set_config() and amdgpu_crtc_set_config()). Fixes: 5addcf0a5f0f ("nouveau: add runtime PM support (v0.9)") Cc: Dave Airlie <airlied@xxxxxxxxxx> Tested-by: Karol Herbst <nouveau@xxxxxxxxxxxxxx> Signed-off-by: Lukas Wunner <lukas@xxxxxxxxx> --- drivers/gpu/drm/drm_crtc.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index d2a6d95..0cd6f00 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -716,12 +716,23 @@ EXPORT_SYMBOL(drm_crtc_init_with_planes); * * This function cleans up @crtc and removes it from the DRM mode setting * core. Note that the function does *not* free the crtc structure itself, - * this is the responsibility of the caller. + * this is the responsibility of the caller. If @crtc is currently enabled, + * it is turned off first. */ void drm_crtc_cleanup(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; + if (crtc->enabled) { + struct drm_mode_set modeset = { + .crtc = crtc, + }; + + drm_modeset_lock_all(dev); + drm_mode_set_config_internal(&modeset); + drm_modeset_unlock_all(dev); + } + kfree(crtc->gamma_store); crtc->gamma_store = NULL; -- 2.8.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel