• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * \file drm_irq.c
3  * IRQ support
4  *
5  * \author Rickard E. (Rik) Faith <faith@valinux.com>
6  * \author Gareth Hughes <gareth@valinux.com>
7  */
8 
9 /*
10  * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
11  *
12  * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
13  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14  * All Rights Reserved.
15  *
16  * Permission is hereby granted, free of charge, to any person obtaining a
17  * copy of this software and associated documentation files (the "Software"),
18  * to deal in the Software without restriction, including without limitation
19  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20  * and/or sell copies of the Software, and to permit persons to whom the
21  * Software is furnished to do so, subject to the following conditions:
22  *
23  * The above copyright notice and this permission notice (including the next
24  * paragraph) shall be included in all copies or substantial portions of the
25  * Software.
26  *
27  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
30  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33  * OTHER DEALINGS IN THE SOFTWARE.
34  */
35 
36 #include "drmP.h"
37 
38 #include <linux/interrupt.h>	/* For task queue support */
39 
40 /**
41  * Get interrupt from bus id.
42  *
43  * \param inode device inode.
44  * \param file_priv DRM file private.
45  * \param cmd command.
46  * \param arg user argument, pointing to a drm_irq_busid structure.
47  * \return zero on success or a negative number on failure.
48  *
49  * Finds the PCI device with the specified bus id and gets its IRQ number.
50  * This IOCTL is deprecated, and will now return EINVAL for any busid not equal
51  * to that of the device that this DRM instance attached to.
52  */
drm_irq_by_busid(struct drm_device * dev,void * data,struct drm_file * file_priv)53 int drm_irq_by_busid(struct drm_device *dev, void *data,
54 		     struct drm_file *file_priv)
55 {
56 	struct drm_irq_busid *p = data;
57 
58 	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
59 		return -EINVAL;
60 
61 	if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
62 	    (p->busnum & 0xff) != dev->pdev->bus->number ||
63 	    p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
64 		return -EINVAL;
65 
66 	p->irq = dev->pdev->irq;
67 
68 	DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
69 		  p->irq);
70 
71 	return 0;
72 }
73 
vblank_disable_fn(unsigned long arg)74 static void vblank_disable_fn(unsigned long arg)
75 {
76 	struct drm_device *dev = (struct drm_device *)arg;
77 	unsigned long irqflags;
78 	int i;
79 
80 	if (!dev->vblank_disable_allowed)
81 		return;
82 
83 	for (i = 0; i < dev->num_crtcs; i++) {
84 		spin_lock_irqsave(&dev->vbl_lock, irqflags);
85 		if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
86 		    dev->vblank_enabled[i]) {
87 			DRM_DEBUG("disabling vblank on crtc %d\n", i);
88 			dev->last_vblank[i] =
89 				dev->driver->get_vblank_counter(dev, i);
90 			dev->driver->disable_vblank(dev, i);
91 			dev->vblank_enabled[i] = 0;
92 		}
93 		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
94 	}
95 }
96 
drm_vblank_cleanup(struct drm_device * dev)97 void drm_vblank_cleanup(struct drm_device *dev)
98 {
99 	/* Bail if the driver didn't call drm_vblank_init() */
100 	if (dev->num_crtcs == 0)
101 		return;
102 
103 	del_timer(&dev->vblank_disable_timer);
104 
105 	vblank_disable_fn((unsigned long)dev);
106 
107 	drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs,
108 		 DRM_MEM_DRIVER);
109 	drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
110 		 dev->num_crtcs, DRM_MEM_DRIVER);
111 	drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
112 		 dev->num_crtcs, DRM_MEM_DRIVER);
113 	drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) *
114 		 dev->num_crtcs, DRM_MEM_DRIVER);
115 	drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs,
116 		 DRM_MEM_DRIVER);
117 	drm_free(dev->last_vblank_wait,
118 		 sizeof(*dev->last_vblank_wait) * dev->num_crtcs,
119 		 DRM_MEM_DRIVER);
120 	drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) *
121 		 dev->num_crtcs, DRM_MEM_DRIVER);
122 
123 	dev->num_crtcs = 0;
124 }
125 
drm_vblank_init(struct drm_device * dev,int num_crtcs)126 int drm_vblank_init(struct drm_device *dev, int num_crtcs)
127 {
128 	int i, ret = -ENOMEM;
129 
130 	setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
131 		    (unsigned long)dev);
132 	spin_lock_init(&dev->vbl_lock);
133 	dev->num_crtcs = num_crtcs;
134 
135 	dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
136 				   DRM_MEM_DRIVER);
137 	if (!dev->vbl_queue)
138 		goto err;
139 
140 	dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
141 				      DRM_MEM_DRIVER);
142 	if (!dev->_vblank_count)
143 		goto err;
144 
145 	dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs,
146 					 DRM_MEM_DRIVER);
147 	if (!dev->vblank_refcount)
148 		goto err;
149 
150 	dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int),
151 					 DRM_MEM_DRIVER);
152 	if (!dev->vblank_enabled)
153 		goto err;
154 
155 	dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
156 	if (!dev->last_vblank)
157 		goto err;
158 
159 	dev->last_vblank_wait = drm_calloc(num_crtcs, sizeof(u32),
160 					   DRM_MEM_DRIVER);
161 	if (!dev->last_vblank_wait)
162 		goto err;
163 
164 	dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int),
165 					 DRM_MEM_DRIVER);
166 	if (!dev->vblank_inmodeset)
167 		goto err;
168 
169 	/* Zero per-crtc vblank stuff */
170 	for (i = 0; i < num_crtcs; i++) {
171 		init_waitqueue_head(&dev->vbl_queue[i]);
172 		atomic_set(&dev->_vblank_count[i], 0);
173 		atomic_set(&dev->vblank_refcount[i], 0);
174 	}
175 
176 	dev->vblank_disable_allowed = 0;
177 
178 	return 0;
179 
180 err:
181 	drm_vblank_cleanup(dev);
182 	return ret;
183 }
184 EXPORT_SYMBOL(drm_vblank_init);
185 
186 /**
187  * Install IRQ handler.
188  *
189  * \param dev DRM device.
190  *
191  * Initializes the IRQ related data. Installs the handler, calling the driver
192  * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
193  * before and after the installation.
194  */
drm_irq_install(struct drm_device * dev)195 int drm_irq_install(struct drm_device *dev)
196 {
197 	int ret = 0;
198 	unsigned long sh_flags = 0;
199 
200 	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
201 		return -EINVAL;
202 
203 	if (dev->pdev->irq == 0)
204 		return -EINVAL;
205 
206 	mutex_lock(&dev->struct_mutex);
207 
208 	/* Driver must have been initialized */
209 	if (!dev->dev_private) {
210 		mutex_unlock(&dev->struct_mutex);
211 		return -EINVAL;
212 	}
213 
214 	if (dev->irq_enabled) {
215 		mutex_unlock(&dev->struct_mutex);
216 		return -EBUSY;
217 	}
218 	dev->irq_enabled = 1;
219 	mutex_unlock(&dev->struct_mutex);
220 
221 	DRM_DEBUG("irq=%d\n", dev->pdev->irq);
222 
223 	/* Before installing handler */
224 	dev->driver->irq_preinstall(dev);
225 
226 	/* Install handler */
227 	if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
228 		sh_flags = IRQF_SHARED;
229 
230 	ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler,
231 			  sh_flags, dev->devname, dev);
232 
233 	if (ret < 0) {
234 		mutex_lock(&dev->struct_mutex);
235 		dev->irq_enabled = 0;
236 		mutex_unlock(&dev->struct_mutex);
237 		return ret;
238 	}
239 
240 	/* After installing handler */
241 	ret = dev->driver->irq_postinstall(dev);
242 	if (ret < 0) {
243 		mutex_lock(&dev->struct_mutex);
244 		dev->irq_enabled = 0;
245 		mutex_unlock(&dev->struct_mutex);
246 	}
247 
248 	return ret;
249 }
250 EXPORT_SYMBOL(drm_irq_install);
251 
252 /**
253  * Uninstall the IRQ handler.
254  *
255  * \param dev DRM device.
256  *
257  * Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq.
258  */
drm_irq_uninstall(struct drm_device * dev)259 int drm_irq_uninstall(struct drm_device * dev)
260 {
261 	unsigned long irqflags;
262 	int irq_enabled, i;
263 
264 	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
265 		return -EINVAL;
266 
267 	mutex_lock(&dev->struct_mutex);
268 	irq_enabled = dev->irq_enabled;
269 	dev->irq_enabled = 0;
270 	mutex_unlock(&dev->struct_mutex);
271 
272 	/*
273 	 * Wake up any waiters so they don't hang.
274 	 */
275 	spin_lock_irqsave(&dev->vbl_lock, irqflags);
276 	for (i = 0; i < dev->num_crtcs; i++) {
277 		DRM_WAKEUP(&dev->vbl_queue[i]);
278 		dev->vblank_enabled[i] = 0;
279 		dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i);
280 	}
281 	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
282 
283 	if (!irq_enabled)
284 		return -EINVAL;
285 
286 	DRM_DEBUG("irq=%d\n", dev->pdev->irq);
287 
288 	dev->driver->irq_uninstall(dev);
289 
290 	free_irq(dev->pdev->irq, dev);
291 
292 	return 0;
293 }
294 EXPORT_SYMBOL(drm_irq_uninstall);
295 
296 /**
297  * IRQ control ioctl.
298  *
299  * \param inode device inode.
300  * \param file_priv DRM file private.
301  * \param cmd command.
302  * \param arg user argument, pointing to a drm_control structure.
303  * \return zero on success or a negative number on failure.
304  *
305  * Calls irq_install() or irq_uninstall() according to \p arg.
306  */
drm_control(struct drm_device * dev,void * data,struct drm_file * file_priv)307 int drm_control(struct drm_device *dev, void *data,
308 		struct drm_file *file_priv)
309 {
310 	struct drm_control *ctl = data;
311 
312 	/* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */
313 
314 
315 	switch (ctl->func) {
316 	case DRM_INST_HANDLER:
317 		if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
318 			return 0;
319 		if (drm_core_check_feature(dev, DRIVER_MODESET))
320 			return 0;
321 		if (dev->if_version < DRM_IF_VERSION(1, 2) &&
322 		    ctl->irq != dev->pdev->irq)
323 			return -EINVAL;
324 		return drm_irq_install(dev);
325 	case DRM_UNINST_HANDLER:
326 		if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
327 			return 0;
328 		if (drm_core_check_feature(dev, DRIVER_MODESET))
329 			return 0;
330 		return drm_irq_uninstall(dev);
331 	default:
332 		return -EINVAL;
333 	}
334 }
335 
336 /**
337  * drm_vblank_count - retrieve "cooked" vblank counter value
338  * @dev: DRM device
339  * @crtc: which counter to retrieve
340  *
341  * Fetches the "cooked" vblank count value that represents the number of
342  * vblank events since the system was booted, including lost events due to
343  * modesetting activity.
344  */
drm_vblank_count(struct drm_device * dev,int crtc)345 u32 drm_vblank_count(struct drm_device *dev, int crtc)
346 {
347 	return atomic_read(&dev->_vblank_count[crtc]);
348 }
349 EXPORT_SYMBOL(drm_vblank_count);
350 
351 /**
352  * drm_update_vblank_count - update the master vblank counter
353  * @dev: DRM device
354  * @crtc: counter to update
355  *
356  * Call back into the driver to update the appropriate vblank counter
357  * (specified by @crtc).  Deal with wraparound, if it occurred, and
358  * update the last read value so we can deal with wraparound on the next
359  * call if necessary.
360  *
361  * Only necessary when going from off->on, to account for frames we
362  * didn't get an interrupt for.
363  *
364  * Note: caller must hold dev->vbl_lock since this reads & writes
365  * device vblank fields.
366  */
drm_update_vblank_count(struct drm_device * dev,int crtc)367 static void drm_update_vblank_count(struct drm_device *dev, int crtc)
368 {
369 	u32 cur_vblank, diff;
370 
371 	/*
372 	 * Interrupts were disabled prior to this call, so deal with counter
373 	 * wrap if needed.
374 	 * NOTE!  It's possible we lost a full dev->max_vblank_count events
375 	 * here if the register is small or we had vblank interrupts off for
376 	 * a long time.
377 	 */
378 	cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
379 	diff = cur_vblank - dev->last_vblank[crtc];
380 	if (cur_vblank < dev->last_vblank[crtc]) {
381 		diff += dev->max_vblank_count;
382 
383 		DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
384 			  crtc, dev->last_vblank[crtc], cur_vblank, diff);
385 	}
386 
387 	DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
388 		  crtc, diff);
389 
390 	atomic_add(diff, &dev->_vblank_count[crtc]);
391 }
392 
393 /**
394  * drm_vblank_get - get a reference count on vblank events
395  * @dev: DRM device
396  * @crtc: which CRTC to own
397  *
398  * Acquire a reference count on vblank events to avoid having them disabled
399  * while in use.
400  *
401  * RETURNS
402  * Zero on success, nonzero on failure.
403  */
drm_vblank_get(struct drm_device * dev,int crtc)404 int drm_vblank_get(struct drm_device *dev, int crtc)
405 {
406 	unsigned long irqflags;
407 	int ret = 0;
408 
409 	spin_lock_irqsave(&dev->vbl_lock, irqflags);
410 	/* Going from 0->1 means we have to enable interrupts again */
411 	if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
412 	    !dev->vblank_enabled[crtc]) {
413 		ret = dev->driver->enable_vblank(dev, crtc);
414 		DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
415 		if (ret)
416 			atomic_dec(&dev->vblank_refcount[crtc]);
417 		else {
418 			dev->vblank_enabled[crtc] = 1;
419 			drm_update_vblank_count(dev, crtc);
420 		}
421 	}
422 	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
423 
424 	return ret;
425 }
426 EXPORT_SYMBOL(drm_vblank_get);
427 
428 /**
429  * drm_vblank_put - give up ownership of vblank events
430  * @dev: DRM device
431  * @crtc: which counter to give up
432  *
433  * Release ownership of a given vblank counter, turning off interrupts
434  * if possible.
435  */
drm_vblank_put(struct drm_device * dev,int crtc)436 void drm_vblank_put(struct drm_device *dev, int crtc)
437 {
438 	BUG_ON (atomic_read (&dev->vblank_refcount[crtc]) == 0);
439 
440 	/* Last user schedules interrupt disable */
441 	if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
442 		mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
443 }
444 EXPORT_SYMBOL(drm_vblank_put);
445 
446 /**
447  * drm_vblank_pre_modeset - account for vblanks across mode sets
448  * @dev: DRM device
449  * @crtc: CRTC in question
450  * @post: post or pre mode set?
451  *
452  * Account for vblank events across mode setting events, which will likely
453  * reset the hardware frame counter.
454  */
drm_vblank_pre_modeset(struct drm_device * dev,int crtc)455 void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
456 {
457 	/*
458 	 * To avoid all the problems that might happen if interrupts
459 	 * were enabled/disabled around or between these calls, we just
460 	 * have the kernel take a reference on the CRTC (just once though
461 	 * to avoid corrupting the count if multiple, mismatch calls occur),
462 	 * so that interrupts remain enabled in the interim.
463 	 */
464 	if (!dev->vblank_inmodeset[crtc]) {
465 		dev->vblank_inmodeset[crtc] = 0x1;
466 		if (drm_vblank_get(dev, crtc) == 0)
467 			dev->vblank_inmodeset[crtc] |= 0x2;
468 	}
469 }
470 EXPORT_SYMBOL(drm_vblank_pre_modeset);
471 
drm_vblank_post_modeset(struct drm_device * dev,int crtc)472 void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
473 {
474 	unsigned long irqflags;
475 
476 	if (dev->vblank_inmodeset[crtc]) {
477 		spin_lock_irqsave(&dev->vbl_lock, irqflags);
478 		dev->vblank_disable_allowed = 1;
479 		spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
480 
481 		if (dev->vblank_inmodeset[crtc] & 0x2)
482 			drm_vblank_put(dev, crtc);
483 
484 		dev->vblank_inmodeset[crtc] = 0;
485 	}
486 }
487 EXPORT_SYMBOL(drm_vblank_post_modeset);
488 
489 /**
490  * drm_modeset_ctl - handle vblank event counter changes across mode switch
491  * @DRM_IOCTL_ARGS: standard ioctl arguments
492  *
493  * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
494  * ioctls around modesetting so that any lost vblank events are accounted for.
495  *
496  * Generally the counter will reset across mode sets.  If interrupts are
497  * enabled around this call, we don't have to do anything since the counter
498  * will have already been incremented.
499  */
drm_modeset_ctl(struct drm_device * dev,void * data,struct drm_file * file_priv)500 int drm_modeset_ctl(struct drm_device *dev, void *data,
501 		    struct drm_file *file_priv)
502 {
503 	struct drm_modeset_ctl *modeset = data;
504 	int crtc, ret = 0;
505 
506 	/* If drm_vblank_init() hasn't been called yet, just no-op */
507 	if (!dev->num_crtcs)
508 		goto out;
509 
510 	crtc = modeset->crtc;
511 	if (crtc >= dev->num_crtcs) {
512 		ret = -EINVAL;
513 		goto out;
514 	}
515 
516 	switch (modeset->cmd) {
517 	case _DRM_PRE_MODESET:
518 		drm_vblank_pre_modeset(dev, crtc);
519 		break;
520 	case _DRM_POST_MODESET:
521 		drm_vblank_post_modeset(dev, crtc);
522 		break;
523 	default:
524 		ret = -EINVAL;
525 		break;
526 	}
527 
528 out:
529 	return ret;
530 }
531 
532 /**
533  * Wait for VBLANK.
534  *
535  * \param inode device inode.
536  * \param file_priv DRM file private.
537  * \param cmd command.
538  * \param data user argument, pointing to a drm_wait_vblank structure.
539  * \return zero on success or a negative number on failure.
540  *
541  * This function enables the vblank interrupt on the pipe requested, then
542  * sleeps waiting for the requested sequence number to occur, and drops
543  * the vblank interrupt refcount afterwards. (vblank irq disable follows that
544  * after a timeout with no further vblank waits scheduled).
545  */
drm_wait_vblank(struct drm_device * dev,void * data,struct drm_file * file_priv)546 int drm_wait_vblank(struct drm_device *dev, void *data,
547 		    struct drm_file *file_priv)
548 {
549 	union drm_wait_vblank *vblwait = data;
550 	int ret = 0;
551 	unsigned int flags, seq, crtc;
552 
553 	if ((!dev->pdev->irq) || (!dev->irq_enabled))
554 		return -EINVAL;
555 
556 	if (vblwait->request.type & _DRM_VBLANK_SIGNAL)
557 		return -EINVAL;
558 
559 	if (vblwait->request.type &
560 	    ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) {
561 		DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n",
562 			  vblwait->request.type,
563 			  (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK));
564 		return -EINVAL;
565 	}
566 
567 	flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
568 	crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
569 
570 	if (crtc >= dev->num_crtcs)
571 		return -EINVAL;
572 
573 	ret = drm_vblank_get(dev, crtc);
574 	if (ret) {
575 		DRM_ERROR("failed to acquire vblank counter, %d\n", ret);
576 		return ret;
577 	}
578 	seq = drm_vblank_count(dev, crtc);
579 
580 	switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
581 	case _DRM_VBLANK_RELATIVE:
582 		vblwait->request.sequence += seq;
583 		vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
584 	case _DRM_VBLANK_ABSOLUTE:
585 		break;
586 	default:
587 		ret = -EINVAL;
588 		goto done;
589 	}
590 
591 	if ((flags & _DRM_VBLANK_NEXTONMISS) &&
592 	    (seq - vblwait->request.sequence) <= (1<<23)) {
593 		vblwait->request.sequence = seq + 1;
594 	}
595 
596 	DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
597 		  vblwait->request.sequence, crtc);
598 	dev->last_vblank_wait[crtc] = vblwait->request.sequence;
599 	DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
600 		    (((drm_vblank_count(dev, crtc) -
601 		       vblwait->request.sequence) <= (1 << 23)) ||
602 		     !dev->irq_enabled));
603 
604 	if (ret != -EINTR) {
605 		struct timeval now;
606 
607 		do_gettimeofday(&now);
608 
609 		vblwait->reply.tval_sec = now.tv_sec;
610 		vblwait->reply.tval_usec = now.tv_usec;
611 		vblwait->reply.sequence = drm_vblank_count(dev, crtc);
612 		DRM_DEBUG("returning %d to client\n",
613 			  vblwait->reply.sequence);
614 	} else {
615 		DRM_DEBUG("vblank wait interrupted by signal\n");
616 	}
617 
618 done:
619 	drm_vblank_put(dev, crtc);
620 	return ret;
621 }
622 
623 /**
624  * drm_handle_vblank - handle a vblank event
625  * @dev: DRM device
626  * @crtc: where this event occurred
627  *
628  * Drivers should call this routine in their vblank interrupt handlers to
629  * update the vblank counter and send any signals that may be pending.
630  */
drm_handle_vblank(struct drm_device * dev,int crtc)631 void drm_handle_vblank(struct drm_device *dev, int crtc)
632 {
633 	atomic_inc(&dev->_vblank_count[crtc]);
634 	DRM_WAKEUP(&dev->vbl_queue[crtc]);
635 }
636 EXPORT_SYMBOL(drm_handle_vblank);
637