From eb2ed66fe56f30c6ea841ac11681a2f51049b221 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 29 Jan 2015 01:09:24 +0200 Subject: [PATCH] drm/irq: Don't disable vblank interrupts when already disabled MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The .enable_vblank() operation is only called when vblank interrupts are disabled, but no similar check exists when disabling vblank interrupts. This leads to .disable_vblank() being called with vblank interrupts already disabled and the device possibly runtime suspended. As the operation is called with a spinlock held drivers can't runtime resume the device there and thus must avoid touching device registers in that case, requiring vblank refcounting. As the DRM core tracks whether vblank interrupts are enabled just skip the .disable_vblank() call when the interrupts are already disabled. Signed-off-by: Laurent Pinchart Reviewed-by: Michel Dänzer Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 75647e7..10574a0 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -185,8 +185,15 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) return; } - dev->driver->disable_vblank(dev, crtc); - vblank->enabled = false; + /* + * Only disable vblank interrupts if they're enabled. This avoids + * calling the ->disable_vblank() operation in atomic context with the + * hardware potentially runtime suspended. + */ + if (vblank->enabled) { + dev->driver->disable_vblank(dev, crtc); + vblank->enabled = false; + } /* No further vblank irq's will be processed after * this point. Get current hardware vblank count and -- 2.7.4