On Mon, May 26, 2014 at 02:46:30PM +0300, ville.syrjala@xxxxxxxxxxxxxxx wrote: > From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > > 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@xxxxxxxxxxxxxxx> I think what we actually want is a new dev->vblank_is_race_free or something which is a boolean. Then we can keep the drm_vblank_offdelay as-is and seletively kill the entire logic for drivers where this works correctly. -Daniel > --- > 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 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx