aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_irq.c
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2008-09-30 15:14:26 -0400
committerDave Airlie <airlied@linux.ie>2008-10-17 17:10:11 -0400
commit0a3e67a4caac273a3bfc4ced3da364830b1ab241 (patch)
tree02a2e5e76d9dffcb556d09b0eee4d34ebe5d81cb /drivers/gpu/drm/drm_irq.c
parent2df68b439fcb97a4c55f81516206ef4ee325e28d (diff)
drm: Rework vblank-wait handling to allow interrupt reduction.
Previously, drivers supporting vblank interrupt waits would run the interrupt all the time, or all the time that any 3d client was running, preventing the CPU from sleeping for long when the system was otherwise idle. Now, interrupts are disabled any time that no client is waiting on a vblank event. The new method uses vblank counters on the chipsets when the interrupts are turned off, rather than counting interrupts, so that we can continue to present accurate vblank numbers. Co-author: Michel Dänzer <michel@tungstengraphics.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r--drivers/gpu/drm/drm_irq.c447
1 files changed, 378 insertions, 69 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 61ed5158f783..d0c13d954f52 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -71,19 +71,131 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
71 return 0; 71 return 0;
72} 72}
73 73
74static 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
97static 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->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs,
110 DRM_MEM_DRIVER);
111 drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
112 dev->num_crtcs, DRM_MEM_DRIVER);
113 drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
114 dev->num_crtcs, DRM_MEM_DRIVER);
115 drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) *
116 dev->num_crtcs, DRM_MEM_DRIVER);
117 drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs,
118 DRM_MEM_DRIVER);
119 drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) *
120 dev->num_crtcs, DRM_MEM_DRIVER);
121
122 dev->num_crtcs = 0;
123}
124
125int drm_vblank_init(struct drm_device *dev, int num_crtcs)
126{
127 int i, ret = -ENOMEM;
128
129 setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
130 (unsigned long)dev);
131 spin_lock_init(&dev->vbl_lock);
132 atomic_set(&dev->vbl_signal_pending, 0);
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->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs,
141 DRM_MEM_DRIVER);
142 if (!dev->vbl_sigs)
143 goto err;
144
145 dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
146 DRM_MEM_DRIVER);
147 if (!dev->_vblank_count)
148 goto err;
149
150 dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs,
151 DRM_MEM_DRIVER);
152 if (!dev->vblank_refcount)
153 goto err;
154
155 dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int),
156 DRM_MEM_DRIVER);
157 if (!dev->vblank_enabled)
158 goto err;
159
160 dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
161 if (!dev->last_vblank)
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 INIT_LIST_HEAD(&dev->vbl_sigs[i]);
173 atomic_set(&dev->_vblank_count[i], 0);
174 atomic_set(&dev->vblank_refcount[i], 0);
175 }
176
177 dev->vblank_disable_allowed = 0;
178
179 return 0;
180
181err:
182 drm_vblank_cleanup(dev);
183 return ret;
184}
185EXPORT_SYMBOL(drm_vblank_init);
186
74/** 187/**
75 * Install IRQ handler. 188 * Install IRQ handler.
76 * 189 *
77 * \param dev DRM device. 190 * \param dev DRM device.
78 * \param irq IRQ number.
79 * 191 *
80 * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver 192 * Initializes the IRQ related data. Installs the handler, calling the driver
81 * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions 193 * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
82 * before and after the installation. 194 * before and after the installation.
83 */ 195 */
84static int drm_irq_install(struct drm_device * dev) 196int drm_irq_install(struct drm_device *dev)
85{ 197{
86 int ret; 198 int ret = 0;
87 unsigned long sh_flags = 0; 199 unsigned long sh_flags = 0;
88 200
89 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 201 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
@@ -109,17 +221,6 @@ static int drm_irq_install(struct drm_device * dev)
109 221
110 DRM_DEBUG("irq=%d\n", dev->pdev->irq); 222 DRM_DEBUG("irq=%d\n", dev->pdev->irq);
111 223
112 if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
113 init_waitqueue_head(&dev->vbl_queue);
114
115 spin_lock_init(&dev->vbl_lock);
116
117 INIT_LIST_HEAD(&dev->vbl_sigs);
118 INIT_LIST_HEAD(&dev->vbl_sigs2);
119
120 dev->vbl_pending = 0;
121 }
122
123 /* Before installing handler */ 224 /* Before installing handler */
124 dev->driver->irq_preinstall(dev); 225 dev->driver->irq_preinstall(dev);
125 226
@@ -141,10 +242,16 @@ static int drm_irq_install(struct drm_device * dev)
141 } 242 }
142 243
143 /* After installing handler */ 244 /* After installing handler */
144 dev->driver->irq_postinstall(dev); 245 ret = dev->driver->irq_postinstall(dev);
246 if (ret < 0) {
247 mutex_lock(&dev->struct_mutex);
248 dev->irq_enabled = 0;
249 mutex_unlock(&dev->struct_mutex);
250 }
145 251
146 return 0; 252 return ret;
147} 253}
254EXPORT_SYMBOL(drm_irq_install);
148 255
149/** 256/**
150 * Uninstall the IRQ handler. 257 * Uninstall the IRQ handler.
@@ -174,11 +281,12 @@ int drm_irq_uninstall(struct drm_device * dev)
174 281
175 free_irq(dev->pdev->irq, dev); 282 free_irq(dev->pdev->irq, dev);
176 283
284 drm_vblank_cleanup(dev);
285
177 dev->locked_tasklet_func = NULL; 286 dev->locked_tasklet_func = NULL;
178 287
179 return 0; 288 return 0;
180} 289}
181
182EXPORT_SYMBOL(drm_irq_uninstall); 290EXPORT_SYMBOL(drm_irq_uninstall);
183 291
184/** 292/**
@@ -218,6 +326,174 @@ int drm_control(struct drm_device *dev, void *data,
218} 326}
219 327
220/** 328/**
329 * drm_vblank_count - retrieve "cooked" vblank counter value
330 * @dev: DRM device
331 * @crtc: which counter to retrieve
332 *
333 * Fetches the "cooked" vblank count value that represents the number of
334 * vblank events since the system was booted, including lost events due to
335 * modesetting activity.
336 */
337u32 drm_vblank_count(struct drm_device *dev, int crtc)
338{
339 return atomic_read(&dev->_vblank_count[crtc]);
340}
341EXPORT_SYMBOL(drm_vblank_count);
342
343/**
344 * drm_update_vblank_count - update the master vblank counter
345 * @dev: DRM device
346 * @crtc: counter to update
347 *
348 * Call back into the driver to update the appropriate vblank counter
349 * (specified by @crtc). Deal with wraparound, if it occurred, and
350 * update the last read value so we can deal with wraparound on the next
351 * call if necessary.
352 *
353 * Only necessary when going from off->on, to account for frames we
354 * didn't get an interrupt for.
355 *
356 * Note: caller must hold dev->vbl_lock since this reads & writes
357 * device vblank fields.
358 */
359static void drm_update_vblank_count(struct drm_device *dev, int crtc)
360{
361 u32 cur_vblank, diff;
362
363 /*
364 * Interrupts were disabled prior to this call, so deal with counter
365 * wrap if needed.
366 * NOTE! It's possible we lost a full dev->max_vblank_count events
367 * here if the register is small or we had vblank interrupts off for
368 * a long time.
369 */
370 cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
371 diff = cur_vblank - dev->last_vblank[crtc];
372 if (cur_vblank < dev->last_vblank[crtc]) {
373 diff += dev->max_vblank_count;
374
375 DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
376 crtc, dev->last_vblank[crtc], cur_vblank, diff);
377 }
378
379 DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
380 crtc, diff);
381
382 atomic_add(diff, &dev->_vblank_count[crtc]);
383}
384
385/**
386 * drm_vblank_get - get a reference count on vblank events
387 * @dev: DRM device
388 * @crtc: which CRTC to own
389 *
390 * Acquire a reference count on vblank events to avoid having them disabled
391 * while in use.
392 *
393 * RETURNS
394 * Zero on success, nonzero on failure.
395 */
396int drm_vblank_get(struct drm_device *dev, int crtc)
397{
398 unsigned long irqflags;
399 int ret = 0;
400
401 spin_lock_irqsave(&dev->vbl_lock, irqflags);
402 /* Going from 0->1 means we have to enable interrupts again */
403 if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
404 !dev->vblank_enabled[crtc]) {
405 ret = dev->driver->enable_vblank(dev, crtc);
406 DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
407 if (ret)
408 atomic_dec(&dev->vblank_refcount[crtc]);
409 else {
410 dev->vblank_enabled[crtc] = 1;
411 drm_update_vblank_count(dev, crtc);
412 }
413 }
414 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
415
416 return ret;
417}
418EXPORT_SYMBOL(drm_vblank_get);
419
420/**
421 * drm_vblank_put - give up ownership of vblank events
422 * @dev: DRM device
423 * @crtc: which counter to give up
424 *
425 * Release ownership of a given vblank counter, turning off interrupts
426 * if possible.
427 */
428void drm_vblank_put(struct drm_device *dev, int crtc)
429{
430 /* Last user schedules interrupt disable */
431 if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
432 mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
433}
434EXPORT_SYMBOL(drm_vblank_put);
435
436/**
437 * drm_modeset_ctl - handle vblank event counter changes across mode switch
438 * @DRM_IOCTL_ARGS: standard ioctl arguments
439 *
440 * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
441 * ioctls around modesetting so that any lost vblank events are accounted for.
442 *
443 * Generally the counter will reset across mode sets. If interrupts are
444 * enabled around this call, we don't have to do anything since the counter
445 * will have already been incremented.
446 */
447int drm_modeset_ctl(struct drm_device *dev, void *data,
448 struct drm_file *file_priv)
449{
450 struct drm_modeset_ctl *modeset = data;
451 unsigned long irqflags;
452 int crtc, ret = 0;
453
454 /* If drm_vblank_init() hasn't been called yet, just no-op */
455 if (!dev->num_crtcs)
456 goto out;
457
458 crtc = modeset->crtc;
459 if (crtc >= dev->num_crtcs) {
460 ret = -EINVAL;
461 goto out;
462 }
463
464 /*
465 * To avoid all the problems that might happen if interrupts
466 * were enabled/disabled around or between these calls, we just
467 * have the kernel take a reference on the CRTC (just once though
468 * to avoid corrupting the count if multiple, mismatch calls occur),
469 * so that interrupts remain enabled in the interim.
470 */
471 switch (modeset->cmd) {
472 case _DRM_PRE_MODESET:
473 if (!dev->vblank_inmodeset[crtc]) {
474 dev->vblank_inmodeset[crtc] = 1;
475 drm_vblank_get(dev, crtc);
476 }
477 break;
478 case _DRM_POST_MODESET:
479 if (dev->vblank_inmodeset[crtc]) {
480 spin_lock_irqsave(&dev->vbl_lock, irqflags);
481 dev->vblank_disable_allowed = 1;
482 dev->vblank_inmodeset[crtc] = 0;
483 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
484 drm_vblank_put(dev, crtc);
485 }
486 break;
487 default:
488 ret = -EINVAL;
489 break;
490 }
491
492out:
493 return ret;
494}
495
496/**
221 * Wait for VBLANK. 497 * Wait for VBLANK.
222 * 498 *
223 * \param inode device inode. 499 * \param inode device inode.
@@ -236,12 +512,12 @@ int drm_control(struct drm_device *dev, void *data,
236 * 512 *
237 * If a signal is not requested, then calls vblank_wait(). 513 * If a signal is not requested, then calls vblank_wait().
238 */ 514 */
239int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv) 515int drm_wait_vblank(struct drm_device *dev, void *data,
516 struct drm_file *file_priv)
240{ 517{
241 union drm_wait_vblank *vblwait = data; 518 union drm_wait_vblank *vblwait = data;
242 struct timeval now;
243 int ret = 0; 519 int ret = 0;
244 unsigned int flags, seq; 520 unsigned int flags, seq, crtc;
245 521
246 if ((!dev->pdev->irq) || (!dev->irq_enabled)) 522 if ((!dev->pdev->irq) || (!dev->irq_enabled))
247 return -EINVAL; 523 return -EINVAL;
@@ -255,13 +531,17 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
255 } 531 }
256 532
257 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; 533 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
534 crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
258 535
259 if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ? 536 if (crtc >= dev->num_crtcs)
260 DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
261 return -EINVAL; 537 return -EINVAL;
262 538
263 seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 539 ret = drm_vblank_get(dev, crtc);
264 : &dev->vbl_received); 540 if (ret) {
541 DRM_ERROR("failed to acquire vblank counter, %d\n", ret);
542 return ret;
543 }
544 seq = drm_vblank_count(dev, crtc);
265 545
266 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { 546 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
267 case _DRM_VBLANK_RELATIVE: 547 case _DRM_VBLANK_RELATIVE:
@@ -270,7 +550,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
270 case _DRM_VBLANK_ABSOLUTE: 550 case _DRM_VBLANK_ABSOLUTE:
271 break; 551 break;
272 default: 552 default:
273 return -EINVAL; 553 ret = -EINVAL;
554 goto done;
274 } 555 }
275 556
276 if ((flags & _DRM_VBLANK_NEXTONMISS) && 557 if ((flags & _DRM_VBLANK_NEXTONMISS) &&
@@ -280,8 +561,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
280 561
281 if (flags & _DRM_VBLANK_SIGNAL) { 562 if (flags & _DRM_VBLANK_SIGNAL) {
282 unsigned long irqflags; 563 unsigned long irqflags;
283 struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY) 564 struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
284 ? &dev->vbl_sigs2 : &dev->vbl_sigs;
285 struct drm_vbl_sig *vbl_sig; 565 struct drm_vbl_sig *vbl_sig;
286 566
287 spin_lock_irqsave(&dev->vbl_lock, irqflags); 567 spin_lock_irqsave(&dev->vbl_lock, irqflags);
@@ -302,22 +582,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
302 } 582 }
303 } 583 }
304 584
305 if (dev->vbl_pending >= 100) { 585 if (atomic_read(&dev->vbl_signal_pending) >= 100) {
306 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 586 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
307 return -EBUSY; 587 ret = -EBUSY;
588 goto done;
308 } 589 }
309 590
310 dev->vbl_pending++;
311
312 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 591 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
313 592
314 if (! 593 vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
315 (vbl_sig = 594 DRM_MEM_DRIVER);
316 drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) { 595 if (!vbl_sig) {
317 return -ENOMEM; 596 ret = -ENOMEM;
597 goto done;
598 }
599
600 ret = drm_vblank_get(dev, crtc);
601 if (ret) {
602 drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
603 DRM_MEM_DRIVER);
604 return ret;
318 } 605 }
319 606
320 memset((void *)vbl_sig, 0, sizeof(*vbl_sig)); 607 atomic_inc(&dev->vbl_signal_pending);
321 608
322 vbl_sig->sequence = vblwait->request.sequence; 609 vbl_sig->sequence = vblwait->request.sequence;
323 vbl_sig->info.si_signo = vblwait->request.signal; 610 vbl_sig->info.si_signo = vblwait->request.signal;
@@ -331,20 +618,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
331 618
332 vblwait->reply.sequence = seq; 619 vblwait->reply.sequence = seq;
333 } else { 620 } else {
334 if (flags & _DRM_VBLANK_SECONDARY) { 621 DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
335 if (dev->driver->vblank_wait2) 622 vblwait->request.sequence, crtc);
336 ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence); 623 DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
337 } else if (dev->driver->vblank_wait) 624 ((drm_vblank_count(dev, crtc)
338 ret = 625 - vblwait->request.sequence) <= (1 << 23)));
339 dev->driver->vblank_wait(dev, 626
340 &vblwait->request.sequence); 627 if (ret != -EINTR) {
341 628 struct timeval now;
342 do_gettimeofday(&now); 629
343 vblwait->reply.tval_sec = now.tv_sec; 630 do_gettimeofday(&now);
344 vblwait->reply.tval_usec = now.tv_usec; 631
632 vblwait->reply.tval_sec = now.tv_sec;
633 vblwait->reply.tval_usec = now.tv_usec;
634 vblwait->reply.sequence = drm_vblank_count(dev, crtc);
635 DRM_DEBUG("returning %d to client\n",
636 vblwait->reply.sequence);
637 } else {
638 DRM_DEBUG("vblank wait interrupted by signal\n");
639 }
345 } 640 }
346 641
347 done: 642done:
643 drm_vblank_put(dev, crtc);
348 return ret; 644 return ret;
349} 645}
350 646
@@ -352,44 +648,57 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
352 * Send the VBLANK signals. 648 * Send the VBLANK signals.
353 * 649 *
354 * \param dev DRM device. 650 * \param dev DRM device.
651 * \param crtc CRTC where the vblank event occurred
355 * 652 *
356 * Sends a signal for each task in drm_device::vbl_sigs and empties the list. 653 * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
357 * 654 *
358 * If a signal is not requested, then calls vblank_wait(). 655 * If a signal is not requested, then calls vblank_wait().
359 */ 656 */
360void drm_vbl_send_signals(struct drm_device * dev) 657static void drm_vbl_send_signals(struct drm_device *dev, int crtc)
361{ 658{
659 struct drm_vbl_sig *vbl_sig, *tmp;
660 struct list_head *vbl_sigs;
661 unsigned int vbl_seq;
362 unsigned long flags; 662 unsigned long flags;
363 int i;
364 663
365 spin_lock_irqsave(&dev->vbl_lock, flags); 664 spin_lock_irqsave(&dev->vbl_lock, flags);
366 665
367 for (i = 0; i < 2; i++) { 666 vbl_sigs = &dev->vbl_sigs[crtc];
368 struct drm_vbl_sig *vbl_sig, *tmp; 667 vbl_seq = drm_vblank_count(dev, crtc);
369 struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs;
370 unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 :
371 &dev->vbl_received);
372 668
373 list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { 669 list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
374 if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { 670 if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
375 vbl_sig->info.si_code = vbl_seq; 671 vbl_sig->info.si_code = vbl_seq;
376 send_sig_info(vbl_sig->info.si_signo, 672 send_sig_info(vbl_sig->info.si_signo,
377 &vbl_sig->info, vbl_sig->task); 673 &vbl_sig->info, vbl_sig->task);
378 674
379 list_del(&vbl_sig->head); 675 list_del(&vbl_sig->head);
380
381 drm_free(vbl_sig, sizeof(*vbl_sig),
382 DRM_MEM_DRIVER);
383 676
384 dev->vbl_pending--; 677 drm_free(vbl_sig, sizeof(*vbl_sig),
385 } 678 DRM_MEM_DRIVER);
386 } 679 atomic_dec(&dev->vbl_signal_pending);
680 drm_vblank_put(dev, crtc);
681 }
387 } 682 }
388 683
389 spin_unlock_irqrestore(&dev->vbl_lock, flags); 684 spin_unlock_irqrestore(&dev->vbl_lock, flags);
390} 685}
391 686
392EXPORT_SYMBOL(drm_vbl_send_signals); 687/**
688 * drm_handle_vblank - handle a vblank event
689 * @dev: DRM device
690 * @crtc: where this event occurred
691 *
692 * Drivers should call this routine in their vblank interrupt handlers to
693 * update the vblank counter and send any signals that may be pending.
694 */
695void drm_handle_vblank(struct drm_device *dev, int crtc)
696{
697 atomic_inc(&dev->_vblank_count[crtc]);
698 DRM_WAKEUP(&dev->vbl_queue[crtc]);
699 drm_vbl_send_signals(dev, crtc);
700}
701EXPORT_SYMBOL(drm_handle_vblank);
393 702
394/** 703/**
395 * Tasklet wrapper function. 704 * Tasklet wrapper function.