diff options
| author | David Vrabel <david.vrabel@csr.com> | 2008-11-19 09:48:07 -0500 |
|---|---|---|
| committer | David Vrabel <david.vrabel@csr.com> | 2008-11-19 09:48:07 -0500 |
| commit | dba0a918722ee0f0ba3442575e4448c3ab622be4 (patch) | |
| tree | fdb466cf09e7916135098d651b18924b2fe9ba5f /drivers/gpu/drm/drm_irq.c | |
| parent | 0996e6382482ce9014787693d3884e9468153a5c (diff) | |
| parent | 7f0f598a0069d1ab072375965a4b69137233169c (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-upstream
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
| -rw-r--r-- | drivers/gpu/drm/drm_irq.c | 80 |
1 files changed, 0 insertions, 80 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 212a94f715b2..15c8dabc3e97 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -280,8 +280,6 @@ int drm_irq_uninstall(struct drm_device * dev) | |||
| 280 | 280 | ||
| 281 | drm_vblank_cleanup(dev); | 281 | drm_vblank_cleanup(dev); |
| 282 | 282 | ||
| 283 | dev->locked_tasklet_func = NULL; | ||
| 284 | |||
| 285 | return 0; | 283 | return 0; |
| 286 | } | 284 | } |
| 287 | EXPORT_SYMBOL(drm_irq_uninstall); | 285 | EXPORT_SYMBOL(drm_irq_uninstall); |
| @@ -699,81 +697,3 @@ void drm_handle_vblank(struct drm_device *dev, int crtc) | |||
| 699 | drm_vbl_send_signals(dev, crtc); | 697 | drm_vbl_send_signals(dev, crtc); |
| 700 | } | 698 | } |
| 701 | EXPORT_SYMBOL(drm_handle_vblank); | 699 | EXPORT_SYMBOL(drm_handle_vblank); |
| 702 | |||
| 703 | /** | ||
| 704 | * Tasklet wrapper function. | ||
| 705 | * | ||
| 706 | * \param data DRM device in disguise. | ||
| 707 | * | ||
| 708 | * Attempts to grab the HW lock and calls the driver callback on success. On | ||
| 709 | * failure, leave the lock marked as contended so the callback can be called | ||
| 710 | * from drm_unlock(). | ||
| 711 | */ | ||
| 712 | static void drm_locked_tasklet_func(unsigned long data) | ||
| 713 | { | ||
| 714 | struct drm_device *dev = (struct drm_device *)data; | ||
| 715 | unsigned long irqflags; | ||
| 716 | void (*tasklet_func)(struct drm_device *); | ||
| 717 | |||
| 718 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
| 719 | tasklet_func = dev->locked_tasklet_func; | ||
| 720 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
| 721 | |||
| 722 | if (!tasklet_func || | ||
| 723 | !drm_lock_take(&dev->lock, | ||
| 724 | DRM_KERNEL_CONTEXT)) { | ||
| 725 | return; | ||
| 726 | } | ||
| 727 | |||
| 728 | dev->lock.lock_time = jiffies; | ||
| 729 | atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); | ||
| 730 | |||
| 731 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
| 732 | tasklet_func = dev->locked_tasklet_func; | ||
| 733 | dev->locked_tasklet_func = NULL; | ||
| 734 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
| 735 | |||
| 736 | if (tasklet_func != NULL) | ||
| 737 | tasklet_func(dev); | ||
| 738 | |||
| 739 | drm_lock_free(&dev->lock, | ||
| 740 | DRM_KERNEL_CONTEXT); | ||
| 741 | } | ||
| 742 | |||
| 743 | /** | ||
| 744 | * Schedule a tasklet to call back a driver hook with the HW lock held. | ||
| 745 | * | ||
| 746 | * \param dev DRM device. | ||
| 747 | * \param func Driver callback. | ||
| 748 | * | ||
| 749 | * This is intended for triggering actions that require the HW lock from an | ||
| 750 | * interrupt handler. The lock will be grabbed ASAP after the interrupt handler | ||
| 751 | * completes. Note that the callback may be called from interrupt or process | ||
| 752 | * context, it must not make any assumptions about this. Also, the HW lock will | ||
| 753 | * be held with the kernel context or any client context. | ||
| 754 | */ | ||
| 755 | void drm_locked_tasklet(struct drm_device *dev, void (*func)(struct drm_device *)) | ||
| 756 | { | ||
| 757 | unsigned long irqflags; | ||
| 758 | static DECLARE_TASKLET(drm_tasklet, drm_locked_tasklet_func, 0); | ||
| 759 | |||
| 760 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ) || | ||
| 761 | test_bit(TASKLET_STATE_SCHED, &drm_tasklet.state)) | ||
| 762 | return; | ||
| 763 | |||
| 764 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
| 765 | |||
| 766 | if (dev->locked_tasklet_func) { | ||
| 767 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
| 768 | return; | ||
| 769 | } | ||
| 770 | |||
| 771 | dev->locked_tasklet_func = func; | ||
| 772 | |||
| 773 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
| 774 | |||
| 775 | drm_tasklet.data = (unsigned long)dev; | ||
| 776 | |||
| 777 | tasklet_hi_schedule(&drm_tasklet); | ||
| 778 | } | ||
| 779 | EXPORT_SYMBOL(drm_locked_tasklet); | ||
