diff options
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); | ||