From: François Tigeot Date: Tue, 22 Apr 2014 18:18:43 +0000 (+0200) Subject: drm: Use the Linux timer API X-Git-Tag: v3.9.0~118 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/7ae74336555d1fa65b993d2dc35d3d122568b7c4 drm: Use the Linux timer API Reduce differences with Linux 3.8.13 --- diff --git a/sys/dev/drm/drm_irq.c b/sys/dev/drm/drm_irq.c index 817c95a3e6..e143a9334a 100644 --- a/sys/dev/drm/drm_irq.c +++ b/sys/dev/drm/drm_irq.c @@ -33,6 +33,7 @@ #include #include +#include #include MALLOC_DEFINE(DRM_MEM_VBLANK, "drm_vblank", "DRM VBLANK Handling Data"); @@ -298,7 +299,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) lockmgr(&dev->vblank_time_lock, LK_RELEASE); } -static void vblank_disable_fn(void * arg) +static void vblank_disable_fn(unsigned long arg) { struct drm_device *dev = (struct drm_device *)arg; int i; @@ -323,9 +324,9 @@ void drm_vblank_cleanup(struct drm_device *dev) if (dev->num_crtcs == 0) return; - callout_stop(&dev->vblank_disable_callout); + del_timer_sync(&dev->vblank_disable_timer); - vblank_disable_fn(dev); + vblank_disable_fn((unsigned long)dev); drm_free(dev->_vblank_count, DRM_MEM_VBLANK); drm_free(dev->vblank_refcount, DRM_MEM_VBLANK); @@ -337,19 +338,21 @@ void drm_vblank_cleanup(struct drm_device *dev) dev->num_crtcs = 0; } +EXPORT_SYMBOL(drm_vblank_cleanup); int drm_vblank_init(struct drm_device *dev, int num_crtcs) { int i; - callout_init_mp(&dev->vblank_disable_callout); -#if 0 - mtx_init(&dev->vbl_lock, "drmvbl", NULL, MTX_DEF); -#endif + setup_timer(&dev->vblank_disable_timer, vblank_disable_fn, + (unsigned long)dev); lockinit(&dev->vblank_time_lock, "drmvtl", 0, LK_CANRECURSE); dev->num_crtcs = num_crtcs; + dev->vbl_queue = kmalloc(sizeof(wait_queue_head_t) * num_crtcs, + DRM_MEM_VBLANK, M_WAITOK); + dev->_vblank_count = kmalloc(sizeof(atomic_t) * num_crtcs, DRM_MEM_VBLANK, M_WAITOK); dev->vblank_refcount = kmalloc(sizeof(atomic_t) * num_crtcs, @@ -374,6 +377,7 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) /* Zero per-crtc vblank stuff */ for (i = 0; i < num_crtcs; i++) { + init_waitqueue_head(&dev->vbl_queue[i]); atomic_set(&dev->_vblank_count[i], 0); atomic_set(&dev->vblank_refcount[i], 0); } @@ -381,6 +385,7 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) dev->vblank_disable_allowed = 0; return 0; } +EXPORT_SYMBOL(drm_vblank_init); void drm_calc_timestamping_constants(struct drm_crtc *crtc) @@ -866,16 +871,15 @@ int drm_vblank_get(struct drm_device *dev, int crtc) */ void drm_vblank_put(struct drm_device *dev, int crtc) { - KASSERT(atomic_read(&dev->vblank_refcount[crtc]) != 0, - ("Too many drm_vblank_put for crtc %d", crtc)); + BUG_ON(atomic_read(&dev->vblank_refcount[crtc]) == 0); /* Last user schedules interrupt disable */ if (atomic_dec_and_test(&dev->vblank_refcount[crtc]) && (drm_vblank_offdelay > 0)) - callout_reset(&dev->vblank_disable_callout, - (drm_vblank_offdelay * DRM_HZ) / 1000, - vblank_disable_fn, dev); + mod_timer(&dev->vblank_disable_timer, + jiffies + ((drm_vblank_offdelay * DRM_HZ)/1000)); } +EXPORT_SYMBOL(drm_vblank_put); void drm_vblank_off(struct drm_device *dev, int crtc) { diff --git a/sys/dev/drm/include/drm/drmP.h b/sys/dev/drm/include/drm/drmP.h index 8f41afae4b..6564ddc089 100644 --- a/sys/dev/drm/include/drm/drmP.h +++ b/sys/dev/drm/include/drm/drmP.h @@ -98,6 +98,7 @@ #include #include #include +#include #include #include @@ -1004,8 +1005,15 @@ struct drm_device { void *drm_ttm_bdev; + /* + * At load time, disabling the vblank interrupt won't be allowed since + * old clients may not call the modeset ioctl and therefore misbehave. + * Once the modeset ioctl *has* been called though, we can safely + * disable them when unused. + */ int vblank_disable_allowed; + wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */ atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */ struct timeval *_vblank_time; /**< timestamp of current vblank_count (drivers must alloc right number of fields) */ struct lock vblank_time_lock; /**< Protects vblank count and time updates during vblank enable/disable */ @@ -1017,10 +1025,13 @@ struct drm_device { once per disable */ int *vblank_inmodeset; /* Display driver is setting mode */ u32 *last_vblank_wait; /* Last vblank seqno waited per CRTC */ - struct callout vblank_disable_callout; + struct timer_list vblank_disable_timer; u32 max_vblank_count; /**< size of vblank counter register */ + /** + * List of events + */ struct list_head vblank_event_list; struct lock event_lock;