diff options
Diffstat (limited to 'drivers/char/drm')
-rw-r--r-- | drivers/char/drm/drm.h | 4 | ||||
-rw-r--r-- | drivers/char/drm/drm_irq.c | 16 |
2 files changed, 13 insertions, 7 deletions
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h index 07a699029c3e..3f28a1551621 100644 --- a/drivers/char/drm/drm.h +++ b/drivers/char/drm/drm.h | |||
@@ -487,12 +487,14 @@ typedef struct drm_irq_busid { | |||
487 | typedef enum { | 487 | typedef enum { |
488 | _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ | 488 | _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ |
489 | _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ | 489 | _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ |
490 | _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ | ||
490 | _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ | 491 | _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ |
491 | _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ | 492 | _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ |
492 | } drm_vblank_seq_type_t; | 493 | } drm_vblank_seq_type_t; |
493 | 494 | ||
494 | #define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) | 495 | #define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) |
495 | #define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY) | 496 | #define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \ |
497 | _DRM_VBLANK_NEXTONMISS) | ||
496 | 498 | ||
497 | struct drm_wait_vblank_request { | 499 | struct drm_wait_vblank_request { |
498 | drm_vblank_seq_type_t type; | 500 | drm_vblank_seq_type_t type; |
diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c index b08608a9f026..78aae5b35c62 100644 --- a/drivers/char/drm/drm_irq.c +++ b/drivers/char/drm/drm_irq.c | |||
@@ -250,8 +250,7 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) | |||
250 | drm_wait_vblank_t vblwait; | 250 | drm_wait_vblank_t vblwait; |
251 | struct timeval now; | 251 | struct timeval now; |
252 | int ret = 0; | 252 | int ret = 0; |
253 | unsigned int flags; | 253 | unsigned int flags, seq; |
254 | atomic_t *seq; | ||
255 | 254 | ||
256 | if (!dev->irq) | 255 | if (!dev->irq) |
257 | return -EINVAL; | 256 | return -EINVAL; |
@@ -273,12 +272,12 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) | |||
273 | DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL)) | 272 | DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL)) |
274 | return -EINVAL; | 273 | return -EINVAL; |
275 | 274 | ||
276 | seq = (flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 : | 275 | seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 |
277 | &dev->vbl_received; | 276 | : &dev->vbl_received); |
278 | 277 | ||
279 | switch (vblwait.request.type & _DRM_VBLANK_TYPES_MASK) { | 278 | switch (vblwait.request.type & _DRM_VBLANK_TYPES_MASK) { |
280 | case _DRM_VBLANK_RELATIVE: | 279 | case _DRM_VBLANK_RELATIVE: |
281 | vblwait.request.sequence += atomic_read(seq); | 280 | vblwait.request.sequence += seq; |
282 | vblwait.request.type &= ~_DRM_VBLANK_RELATIVE; | 281 | vblwait.request.type &= ~_DRM_VBLANK_RELATIVE; |
283 | case _DRM_VBLANK_ABSOLUTE: | 282 | case _DRM_VBLANK_ABSOLUTE: |
284 | break; | 283 | break; |
@@ -286,13 +285,18 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) | |||
286 | return -EINVAL; | 285 | return -EINVAL; |
287 | } | 286 | } |
288 | 287 | ||
288 | if ((flags & _DRM_VBLANK_NEXTONMISS) && | ||
289 | (seq - vblwait.request.sequence) <= (1<<23)) { | ||
290 | vblwait.request.sequence = seq + 1; | ||
291 | } | ||
292 | |||
289 | if (flags & _DRM_VBLANK_SIGNAL) { | 293 | if (flags & _DRM_VBLANK_SIGNAL) { |
290 | unsigned long irqflags; | 294 | unsigned long irqflags; |
291 | drm_vbl_sig_t *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY) | 295 | drm_vbl_sig_t *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY) |
292 | ? &dev->vbl_sigs2 : &dev->vbl_sigs; | 296 | ? &dev->vbl_sigs2 : &dev->vbl_sigs; |
293 | drm_vbl_sig_t *vbl_sig; | 297 | drm_vbl_sig_t *vbl_sig; |
294 | 298 | ||
295 | vblwait.reply.sequence = atomic_read(seq); | 299 | vblwait.reply.sequence = seq; |
296 | 300 | ||
297 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 301 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
298 | 302 | ||