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 #include <linux/vgaarb.h> 41 /** 42 * Get interrupt from bus id. 43 * 44 * \param inode device inode. 45 * \param file_priv DRM file private. 46 * \param cmd command. 47 * \param arg user argument, pointing to a drm_irq_busid structure. 48 * \return zero on success or a negative number on failure. 49 * 50 * Finds the PCI device with the specified bus id and gets its IRQ number. 51 * This IOCTL is deprecated, and will now return EINVAL for any busid not equal 52 * to that of the device that this DRM instance attached to. 53 */ 54 int drm_irq_by_busid(struct drm_device *dev, void *data, 55 struct drm_file *file_priv) 56 { 57 struct drm_irq_busid *p = data; 58 59 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 60 return -EINVAL; 61 62 if ((p->busnum >> 8) != drm_get_pci_domain(dev) || 63 (p->busnum & 0xff) != dev->pdev->bus->number || 64 p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn)) 65 return -EINVAL; 66 67 p->irq = dev->pdev->irq; 68 69 DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum, 70 p->irq); 71 72 return 0; 73 } 74 75 static void vblank_disable_fn(unsigned long arg) 76 { 77 struct drm_device *dev = (struct drm_device *)arg; 78 unsigned long irqflags; 79 int i; 80 81 if (!dev->vblank_disable_allowed) 82 return; 83 84 for (i = 0; i < dev->num_crtcs; i++) { 85 spin_lock_irqsave(&dev->vbl_lock, irqflags); 86 if (atomic_read(&dev->vblank_refcount[i]) == 0 && 87 dev->vblank_enabled[i]) { 88 DRM_DEBUG("disabling vblank on crtc %d\n", i); 89 dev->last_vblank[i] = 90 dev->driver->get_vblank_counter(dev, i); 91 dev->driver->disable_vblank(dev, i); 92 dev->vblank_enabled[i] = 0; 93 } 94 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 95 } 96 } 97 98 void drm_vblank_cleanup(struct drm_device *dev) 99 { 100 /* Bail if the driver didn't call drm_vblank_init() */ 101 if (dev->num_crtcs == 0) 102 return; 103 104 del_timer(&dev->vblank_disable_timer); 105 106 vblank_disable_fn((unsigned long)dev); 107 108 kfree(dev->vbl_queue); 109 kfree(dev->_vblank_count); 110 kfree(dev->vblank_refcount); 111 kfree(dev->vblank_enabled); 112 kfree(dev->last_vblank); 113 kfree(dev->last_vblank_wait); 114 kfree(dev->vblank_inmodeset); 115 116 dev->num_crtcs = 0; 117 } 118 119 int drm_vblank_init(struct drm_device *dev, int num_crtcs) 120 { 121 int i, ret = -ENOMEM; 122 123 setup_timer(&dev->vblank_disable_timer, vblank_disable_fn, 124 (unsigned long)dev); 125 spin_lock_init(&dev->vbl_lock); 126 dev->num_crtcs = num_crtcs; 127 128 dev->vbl_queue = kmalloc(sizeof(wait_queue_head_t) * num_crtcs, 129 GFP_KERNEL); 130 if (!dev->vbl_queue) 131 goto err; 132 133 dev->_vblank_count = kmalloc(sizeof(atomic_t) * num_crtcs, GFP_KERNEL); 134 if (!dev->_vblank_count) 135 goto err; 136 137 dev->vblank_refcount = kmalloc(sizeof(atomic_t) * num_crtcs, 138 GFP_KERNEL); 139 if (!dev->vblank_refcount) 140 goto err; 141 142 dev->vblank_enabled = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL); 143 if (!dev->vblank_enabled) 144 goto err; 145 146 dev->last_vblank = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL); 147 if (!dev->last_vblank) 148 goto err; 149 150 dev->last_vblank_wait = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL); 151 if (!dev->last_vblank_wait) 152 goto err; 153 154 dev->vblank_inmodeset = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL); 155 if (!dev->vblank_inmodeset) 156 goto err; 157 158 /* Zero per-crtc vblank stuff */ 159 for (i = 0; i < num_crtcs; i++) { 160 init_waitqueue_head(&dev->vbl_queue[i]); 161 atomic_set(&dev->_vblank_count[i], 0); 162 atomic_set(&dev->vblank_refcount[i], 0); 163 } 164 165 dev->vblank_disable_allowed = 0; 166 167 return 0; 168 169 err: 170 drm_vblank_cleanup(dev); 171 return ret; 172 } 173 EXPORT_SYMBOL(drm_vblank_init); 174 175 static void drm_irq_vgaarb_nokms(void *cookie, bool state) 176 { 177 struct drm_device *dev = cookie; 178 179 if (dev->driver->vgaarb_irq) { 180 dev->driver->vgaarb_irq(dev, state); 181 return; 182 } 183 184 if (!dev->irq_enabled) 185 return; 186 187 if (state) 188 dev->driver->irq_uninstall(dev); 189 else { 190 dev->driver->irq_preinstall(dev); 191 dev->driver->irq_postinstall(dev); 192 } 193 } 194 195 /** 196 * Install IRQ handler. 197 * 198 * \param dev DRM device. 199 * 200 * Initializes the IRQ related data. Installs the handler, calling the driver 201 * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions 202 * before and after the installation. 203 */ 204 int drm_irq_install(struct drm_device *dev) 205 { 206 int ret = 0; 207 unsigned long sh_flags = 0; 208 char *irqname; 209 210 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 211 return -EINVAL; 212 213 if (dev->pdev->irq == 0) 214 return -EINVAL; 215 216 mutex_lock(&dev->struct_mutex); 217 218 /* Driver must have been initialized */ 219 if (!dev->dev_private) { 220 mutex_unlock(&dev->struct_mutex); 221 return -EINVAL; 222 } 223 224 if (dev->irq_enabled) { 225 mutex_unlock(&dev->struct_mutex); 226 return -EBUSY; 227 } 228 dev->irq_enabled = 1; 229 mutex_unlock(&dev->struct_mutex); 230 231 DRM_DEBUG("irq=%d\n", dev->pdev->irq); 232 233 /* Before installing handler */ 234 dev->driver->irq_preinstall(dev); 235 236 /* Install handler */ 237 if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) 238 sh_flags = IRQF_SHARED; 239 240 if (dev->devname) 241 irqname = dev->devname; 242 else 243 irqname = dev->driver->name; 244 245 ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler, 246 sh_flags, irqname, dev); 247 248 if (ret < 0) { 249 mutex_lock(&dev->struct_mutex); 250 dev->irq_enabled = 0; 251 mutex_unlock(&dev->struct_mutex); 252 return ret; 253 } 254 255 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 256 vga_client_register(dev->pdev, (void *)dev, drm_irq_vgaarb_nokms, NULL); 257 258 /* After installing handler */ 259 ret = dev->driver->irq_postinstall(dev); 260 if (ret < 0) { 261 mutex_lock(&dev->struct_mutex); 262 dev->irq_enabled = 0; 263 mutex_unlock(&dev->struct_mutex); 264 } 265 266 return ret; 267 } 268 EXPORT_SYMBOL(drm_irq_install); 269 270 /** 271 * Uninstall the IRQ handler. 272 * 273 * \param dev DRM device. 274 * 275 * Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq. 276 */ 277 int drm_irq_uninstall(struct drm_device * dev) 278 { 279 unsigned long irqflags; 280 int irq_enabled, i; 281 282 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 283 return -EINVAL; 284 285 mutex_lock(&dev->struct_mutex); 286 irq_enabled = dev->irq_enabled; 287 dev->irq_enabled = 0; 288 mutex_unlock(&dev->struct_mutex); 289 290 /* 291 * Wake up any waiters so they don't hang. 292 */ 293 spin_lock_irqsave(&dev->vbl_lock, irqflags); 294 for (i = 0; i < dev->num_crtcs; i++) { 295 DRM_WAKEUP(&dev->vbl_queue[i]); 296 dev->vblank_enabled[i] = 0; 297 dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i); 298 } 299 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 300 301 if (!irq_enabled) 302 return -EINVAL; 303 304 DRM_DEBUG("irq=%d\n", dev->pdev->irq); 305 306 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 307 vga_client_register(dev->pdev, NULL, NULL, NULL); 308 309 dev->driver->irq_uninstall(dev); 310 311 free_irq(dev->pdev->irq, dev); 312 313 return 0; 314 } 315 EXPORT_SYMBOL(drm_irq_uninstall); 316 317 /** 318 * IRQ control ioctl. 319 * 320 * \param inode device inode. 321 * \param file_priv DRM file private. 322 * \param cmd command. 323 * \param arg user argument, pointing to a drm_control structure. 324 * \return zero on success or a negative number on failure. 325 * 326 * Calls irq_install() or irq_uninstall() according to \p arg. 327 */ 328 int drm_control(struct drm_device *dev, void *data, 329 struct drm_file *file_priv) 330 { 331 struct drm_control *ctl = data; 332 333 /* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */ 334 335 336 switch (ctl->func) { 337 case DRM_INST_HANDLER: 338 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 339 return 0; 340 if (drm_core_check_feature(dev, DRIVER_MODESET)) 341 return 0; 342 if (dev->if_version < DRM_IF_VERSION(1, 2) && 343 ctl->irq != dev->pdev->irq) 344 return -EINVAL; 345 return drm_irq_install(dev); 346 case DRM_UNINST_HANDLER: 347 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 348 return 0; 349 if (drm_core_check_feature(dev, DRIVER_MODESET)) 350 return 0; 351 return drm_irq_uninstall(dev); 352 default: 353 return -EINVAL; 354 } 355 } 356 357 /** 358 * drm_vblank_count - retrieve "cooked" vblank counter value 359 * @dev: DRM device 360 * @crtc: which counter to retrieve 361 * 362 * Fetches the "cooked" vblank count value that represents the number of 363 * vblank events since the system was booted, including lost events due to 364 * modesetting activity. 365 */ 366 u32 drm_vblank_count(struct drm_device *dev, int crtc) 367 { 368 return atomic_read(&dev->_vblank_count[crtc]); 369 } 370 EXPORT_SYMBOL(drm_vblank_count); 371 372 /** 373 * drm_update_vblank_count - update the master vblank counter 374 * @dev: DRM device 375 * @crtc: counter to update 376 * 377 * Call back into the driver to update the appropriate vblank counter 378 * (specified by @crtc). Deal with wraparound, if it occurred, and 379 * update the last read value so we can deal with wraparound on the next 380 * call if necessary. 381 * 382 * Only necessary when going from off->on, to account for frames we 383 * didn't get an interrupt for. 384 * 385 * Note: caller must hold dev->vbl_lock since this reads & writes 386 * device vblank fields. 387 */ 388 static void drm_update_vblank_count(struct drm_device *dev, int crtc) 389 { 390 u32 cur_vblank, diff; 391 392 /* 393 * Interrupts were disabled prior to this call, so deal with counter 394 * wrap if needed. 395 * NOTE! It's possible we lost a full dev->max_vblank_count events 396 * here if the register is small or we had vblank interrupts off for 397 * a long time. 398 */ 399 cur_vblank = dev->driver->get_vblank_counter(dev, crtc); 400 diff = cur_vblank - dev->last_vblank[crtc]; 401 if (cur_vblank < dev->last_vblank[crtc]) { 402 diff += dev->max_vblank_count; 403 404 DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n", 405 crtc, dev->last_vblank[crtc], cur_vblank, diff); 406 } 407 408 DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", 409 crtc, diff); 410 411 atomic_add(diff, &dev->_vblank_count[crtc]); 412 } 413 414 /** 415 * drm_vblank_get - get a reference count on vblank events 416 * @dev: DRM device 417 * @crtc: which CRTC to own 418 * 419 * Acquire a reference count on vblank events to avoid having them disabled 420 * while in use. 421 * 422 * RETURNS 423 * Zero on success, nonzero on failure. 424 */ 425 int drm_vblank_get(struct drm_device *dev, int crtc) 426 { 427 unsigned long irqflags; 428 int ret = 0; 429 430 spin_lock_irqsave(&dev->vbl_lock, irqflags); 431 /* Going from 0->1 means we have to enable interrupts again */ 432 if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { 433 if (!dev->vblank_enabled[crtc]) { 434 ret = dev->driver->enable_vblank(dev, crtc); 435 DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); 436 if (ret) 437 atomic_dec(&dev->vblank_refcount[crtc]); 438 else { 439 dev->vblank_enabled[crtc] = 1; 440 drm_update_vblank_count(dev, crtc); 441 } 442 } 443 } else { 444 if (!dev->vblank_enabled[crtc]) { 445 atomic_dec(&dev->vblank_refcount[crtc]); 446 ret = -EINVAL; 447 } 448 } 449 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 450 451 return ret; 452 } 453 EXPORT_SYMBOL(drm_vblank_get); 454 455 /** 456 * drm_vblank_put - give up ownership of vblank events 457 * @dev: DRM device 458 * @crtc: which counter to give up 459 * 460 * Release ownership of a given vblank counter, turning off interrupts 461 * if possible. 462 */ 463 void drm_vblank_put(struct drm_device *dev, int crtc) 464 { 465 BUG_ON (atomic_read (&dev->vblank_refcount[crtc]) == 0); 466 467 /* Last user schedules interrupt disable */ 468 if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) 469 mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ); 470 } 471 EXPORT_SYMBOL(drm_vblank_put); 472 473 void drm_vblank_off(struct drm_device *dev, int crtc) 474 { 475 unsigned long irqflags; 476 477 spin_lock_irqsave(&dev->vbl_lock, irqflags); 478 DRM_WAKEUP(&dev->vbl_queue[crtc]); 479 dev->vblank_enabled[crtc] = 0; 480 dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); 481 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 482 } 483 EXPORT_SYMBOL(drm_vblank_off); 484 485 /** 486 * drm_vblank_pre_modeset - account for vblanks across mode sets 487 * @dev: DRM device 488 * @crtc: CRTC in question 489 * @post: post or pre mode set? 490 * 491 * Account for vblank events across mode setting events, which will likely 492 * reset the hardware frame counter. 493 */ 494 void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) 495 { 496 /* 497 * To avoid all the problems that might happen if interrupts 498 * were enabled/disabled around or between these calls, we just 499 * have the kernel take a reference on the CRTC (just once though 500 * to avoid corrupting the count if multiple, mismatch calls occur), 501 * so that interrupts remain enabled in the interim. 502 */ 503 if (!dev->vblank_inmodeset[crtc]) { 504 dev->vblank_inmodeset[crtc] = 0x1; 505 if (drm_vblank_get(dev, crtc) == 0) 506 dev->vblank_inmodeset[crtc] |= 0x2; 507 } 508 } 509 EXPORT_SYMBOL(drm_vblank_pre_modeset); 510 511 void drm_vblank_post_modeset(struct drm_device *dev, int crtc) 512 { 513 unsigned long irqflags; 514 515 if (dev->vblank_inmodeset[crtc]) { 516 spin_lock_irqsave(&dev->vbl_lock, irqflags); 517 dev->vblank_disable_allowed = 1; 518 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 519 520 if (dev->vblank_inmodeset[crtc] & 0x2) 521 drm_vblank_put(dev, crtc); 522 523 dev->vblank_inmodeset[crtc] = 0; 524 } 525 } 526 EXPORT_SYMBOL(drm_vblank_post_modeset); 527 528 /** 529 * drm_modeset_ctl - handle vblank event counter changes across mode switch 530 * @DRM_IOCTL_ARGS: standard ioctl arguments 531 * 532 * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET 533 * ioctls around modesetting so that any lost vblank events are accounted for. 534 * 535 * Generally the counter will reset across mode sets. If interrupts are 536 * enabled around this call, we don't have to do anything since the counter 537 * will have already been incremented. 538 */ 539 int drm_modeset_ctl(struct drm_device *dev, void *data, 540 struct drm_file *file_priv) 541 { 542 struct drm_modeset_ctl *modeset = data; 543 int crtc, ret = 0; 544 545 /* If drm_vblank_init() hasn't been called yet, just no-op */ 546 if (!dev->num_crtcs) 547 goto out; 548 549 crtc = modeset->crtc; 550 if (crtc >= dev->num_crtcs) { 551 ret = -EINVAL; 552 goto out; 553 } 554 555 switch (modeset->cmd) { 556 case _DRM_PRE_MODESET: 557 drm_vblank_pre_modeset(dev, crtc); 558 break; 559 case _DRM_POST_MODESET: 560 drm_vblank_post_modeset(dev, crtc); 561 break; 562 default: 563 ret = -EINVAL; 564 break; 565 } 566 567 out: 568 return ret; 569 } 570 571 static int drm_queue_vblank_event(struct drm_device *dev, int pipe, 572 union drm_wait_vblank *vblwait, 573 struct drm_file *file_priv) 574 { 575 struct drm_pending_vblank_event *e; 576 struct timeval now; 577 unsigned long flags; 578 unsigned int seq; 579 580 e = kzalloc(sizeof *e, GFP_KERNEL); 581 if (e == NULL) 582 return -ENOMEM; 583 584 e->pipe = pipe; 585 e->event.base.type = DRM_EVENT_VBLANK; 586 e->event.base.length = sizeof e->event; 587 e->event.user_data = vblwait->request.signal; 588 e->base.event = &e->event.base; 589 e->base.file_priv = file_priv; 590 e->base.destroy = (void (*) (struct drm_pending_event *)) kfree; 591 592 do_gettimeofday(&now); 593 spin_lock_irqsave(&dev->event_lock, flags); 594 595 if (file_priv->event_space < sizeof e->event) { 596 spin_unlock_irqrestore(&dev->event_lock, flags); 597 kfree(e); 598 return -ENOMEM; 599 } 600 601 file_priv->event_space -= sizeof e->event; 602 seq = drm_vblank_count(dev, pipe); 603 if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) && 604 (seq - vblwait->request.sequence) <= (1 << 23)) { 605 vblwait->request.sequence = seq + 1; 606 vblwait->reply.sequence = vblwait->request.sequence; 607 } 608 609 DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n", 610 vblwait->request.sequence, seq, pipe); 611 612 e->event.sequence = vblwait->request.sequence; 613 if ((seq - vblwait->request.sequence) <= (1 << 23)) { 614 e->event.tv_sec = now.tv_sec; 615 e->event.tv_usec = now.tv_usec; 616 drm_vblank_put(dev, e->pipe); 617 list_add_tail(&e->base.link, &e->base.file_priv->event_list); 618 wake_up_interruptible(&e->base.file_priv->event_wait); 619 } else { 620 list_add_tail(&e->base.link, &dev->vblank_event_list); 621 } 622 623 spin_unlock_irqrestore(&dev->event_lock, flags); 624 625 return 0; 626 } 627 628 /** 629 * Wait for VBLANK. 630 * 631 * \param inode device inode. 632 * \param file_priv DRM file private. 633 * \param cmd command. 634 * \param data user argument, pointing to a drm_wait_vblank structure. 635 * \return zero on success or a negative number on failure. 636 * 637 * This function enables the vblank interrupt on the pipe requested, then 638 * sleeps waiting for the requested sequence number to occur, and drops 639 * the vblank interrupt refcount afterwards. (vblank irq disable follows that 640 * after a timeout with no further vblank waits scheduled). 641 */ 642 int drm_wait_vblank(struct drm_device *dev, void *data, 643 struct drm_file *file_priv) 644 { 645 union drm_wait_vblank *vblwait = data; 646 int ret = 0; 647 unsigned int flags, seq, crtc; 648 649 if ((!dev->pdev->irq) || (!dev->irq_enabled)) 650 return -EINVAL; 651 652 if (vblwait->request.type & _DRM_VBLANK_SIGNAL) 653 return -EINVAL; 654 655 if (vblwait->request.type & 656 ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) { 657 DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n", 658 vblwait->request.type, 659 (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)); 660 return -EINVAL; 661 } 662 663 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; 664 crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; 665 666 if (crtc >= dev->num_crtcs) 667 return -EINVAL; 668 669 ret = drm_vblank_get(dev, crtc); 670 if (ret) { 671 DRM_DEBUG("failed to acquire vblank counter, %d\n", ret); 672 return ret; 673 } 674 seq = drm_vblank_count(dev, crtc); 675 676 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { 677 case _DRM_VBLANK_RELATIVE: 678 vblwait->request.sequence += seq; 679 vblwait->request.type &= ~_DRM_VBLANK_RELATIVE; 680 case _DRM_VBLANK_ABSOLUTE: 681 break; 682 default: 683 ret = -EINVAL; 684 goto done; 685 } 686 687 if (flags & _DRM_VBLANK_EVENT) 688 return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); 689 690 if ((flags & _DRM_VBLANK_NEXTONMISS) && 691 (seq - vblwait->request.sequence) <= (1<<23)) { 692 vblwait->request.sequence = seq + 1; 693 } 694 695 DRM_DEBUG("waiting on vblank count %d, crtc %d\n", 696 vblwait->request.sequence, crtc); 697 dev->last_vblank_wait[crtc] = vblwait->request.sequence; 698 DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, 699 (((drm_vblank_count(dev, crtc) - 700 vblwait->request.sequence) <= (1 << 23)) || 701 !dev->irq_enabled)); 702 703 if (ret != -EINTR) { 704 struct timeval now; 705 706 do_gettimeofday(&now); 707 708 vblwait->reply.tval_sec = now.tv_sec; 709 vblwait->reply.tval_usec = now.tv_usec; 710 vblwait->reply.sequence = drm_vblank_count(dev, crtc); 711 DRM_DEBUG("returning %d to client\n", 712 vblwait->reply.sequence); 713 } else { 714 DRM_DEBUG("vblank wait interrupted by signal\n"); 715 } 716 717 done: 718 drm_vblank_put(dev, crtc); 719 return ret; 720 } 721 722 void drm_handle_vblank_events(struct drm_device *dev, int crtc) 723 { 724 struct drm_pending_vblank_event *e, *t; 725 struct timeval now; 726 unsigned long flags; 727 unsigned int seq; 728 729 do_gettimeofday(&now); 730 seq = drm_vblank_count(dev, crtc); 731 732 spin_lock_irqsave(&dev->event_lock, flags); 733 734 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { 735 if (e->pipe != crtc) 736 continue; 737 if ((seq - e->event.sequence) > (1<<23)) 738 continue; 739 740 DRM_DEBUG("vblank event on %d, current %d\n", 741 e->event.sequence, seq); 742 743 e->event.sequence = seq; 744 e->event.tv_sec = now.tv_sec; 745 e->event.tv_usec = now.tv_usec; 746 drm_vblank_put(dev, e->pipe); 747 list_move_tail(&e->base.link, &e->base.file_priv->event_list); 748 wake_up_interruptible(&e->base.file_priv->event_wait); 749 } 750 751 spin_unlock_irqrestore(&dev->event_lock, flags); 752 } 753 754 /** 755 * drm_handle_vblank - handle a vblank event 756 * @dev: DRM device 757 * @crtc: where this event occurred 758 * 759 * Drivers should call this routine in their vblank interrupt handlers to 760 * update the vblank counter and send any signals that may be pending. 761 */ 762 void drm_handle_vblank(struct drm_device *dev, int crtc) 763 { 764 if (!dev->num_crtcs) 765 return; 766 767 atomic_inc(&dev->_vblank_count[crtc]); 768 DRM_WAKEUP(&dev->vbl_queue[crtc]); 769 drm_handle_vblank_events(dev, crtc); 770 } 771 EXPORT_SYMBOL(drm_handle_vblank); 772