[PATCH 7/9] drm: Disable vblank interrupt immediately when drm_vblank_offdelay==0

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Mon May 26 04:46:30 PDT 2014


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

Make drm_vblank_put() disable the vblank interrupt immediately when the
refcount drops to zero and drm_vblank_offdelay==0.

Currently drm_vblank_put() would just leave vblank interrupts enabled all
the time if drm_vblank_offdelay==0. In case someone might still want that
behaviour drm_vblank_offdelay is now signed and a negative value will
allow the user to keep vblank interrupts on all the time. Well, since
the first drm_vblank_get() anyway.

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 Documentation/DocBook/drm.tmpl          |  1 +
 drivers/gpu/drm/drm_irq.c               | 11 +++++++----
 drivers/gpu/drm/drm_stub.c              |  4 ++--
 drivers/gpu/drm/exynos/exynos_drm_drv.h |  2 +-
 include/drm/drmP.h                      |  2 +-
 5 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index 9574bf2..25632b0 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -2508,6 +2508,7 @@ void (*disable_vblank) (struct drm_device *dev, int crtc);</synopsis>
       by scheduling a timer. The delay is accessible through the vblankoffdelay
       module parameter or the <varname>drm_vblank_offdelay</varname> global
       variable and expressed in milliseconds. Its default value is 5000 ms.
+      Zero means disable immediately, and a negative value means never disable.
     </para>
     <para>
       When a vertical blanking interrupt occurs drivers only need to call the
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 54cb85d..54a56b2 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -978,10 +978,13 @@ void drm_vblank_put(struct drm_device *dev, int crtc)
 	BUG_ON(atomic_read(&dev->vblank[crtc].refcount) == 0);
 
 	/* Last user schedules interrupt disable */
-	if (atomic_dec_and_test(&dev->vblank[crtc].refcount) &&
-	    (drm_vblank_offdelay > 0))
-		mod_timer(&dev->vblank[crtc].disable_timer,
-			  jiffies + ((drm_vblank_offdelay * HZ)/1000));
+	if (atomic_dec_and_test(&dev->vblank[crtc].refcount)) {
+		if (drm_vblank_offdelay > 0)
+			mod_timer(&dev->vblank[crtc].disable_timer,
+				  jiffies + ((drm_vblank_offdelay * HZ)/1000));
+		else if (drm_vblank_offdelay == 0)
+			vblank_disable_fn((unsigned long)&dev->vblank[crtc]);
+	}
 }
 EXPORT_SYMBOL(drm_vblank_put);
 
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 3727ac8..8758f81 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -49,7 +49,7 @@ EXPORT_SYMBOL(drm_rnodes);
 unsigned int drm_universal_planes = 0;
 EXPORT_SYMBOL(drm_universal_planes);
 
-unsigned int drm_vblank_offdelay = 5000;    /* Default to 5000 msecs. */
+int drm_vblank_offdelay = 5000;    /* Default to 5000 msecs. */
 EXPORT_SYMBOL(drm_vblank_offdelay);
 
 unsigned int drm_timestamp_precision = 20;  /* Default to 20 usecs. */
@@ -66,7 +66,7 @@ MODULE_DESCRIPTION(CORE_DESC);
 MODULE_LICENSE("GPL and additional rights");
 MODULE_PARM_DESC(debug, "Enable debug output");
 MODULE_PARM_DESC(rnodes, "Enable experimental render nodes API");
-MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs]");
+MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] (< 0 means never disable)");
 MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
 MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps");
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index ce3e6a3..9734bec 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -40,7 +40,7 @@ struct drm_device;
 struct exynos_drm_overlay;
 struct drm_connector;
 
-extern unsigned int drm_vblank_offdelay;
+extern int drm_vblank_offdelay;
 
 /* this enumerates display type. */
 enum exynos_drm_output_type {
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 76ccaab..979a498 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1404,7 +1404,7 @@ extern unsigned int drm_debug;
 extern unsigned int drm_rnodes;
 extern unsigned int drm_universal_planes;
 
-extern unsigned int drm_vblank_offdelay;
+extern int drm_vblank_offdelay;
 extern unsigned int drm_timestamp_precision;
 extern unsigned int drm_timestamp_monotonic;
 
-- 
1.8.5.5



More information about the dri-devel mailing list