]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm: Add drm_vblank_work_flush_all().
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Wed, 22 May 2024 05:33:39 +0000 (07:33 +0200)
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Mon, 24 Jun 2024 16:03:18 +0000 (18:03 +0200)
In some cases we want to flush all vblank work, right before vblank_off
for example. Add a simple function to make this possible.

Check that both pending_work and running work are empty when flushing.

Co-Developed-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240522053341.137592-2-maarten.lankhorst@linux.intel.com
drivers/gpu/drm/drm_vblank_work.c
include/drm/drm_vblank_work.h

index 4fe9b1d3b00fe01371b292329eea2183e78e5bc6..1752ffb44e1db7d8fd21e6f1e2c68123461747a9 100644 (file)
@@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work)
 }
 EXPORT_SYMBOL(drm_vblank_work_flush);
 
+/**
+ * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc.
+ * @crtc: crtc for which vblank work to flush
+ *
+ * Wait until all currently queued vblank work on @crtc
+ * has finished executing once.
+ */
+void drm_vblank_work_flush_all(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_vblank_crtc *vblank = &dev->vblank[drm_crtc_index(crtc)];
+
+       spin_lock_irq(&dev->event_lock);
+       wait_event_lock_irq(vblank->work_wait_queue,
+                           list_empty(&vblank->pending_work),
+                           dev->event_lock);
+       spin_unlock_irq(&dev->event_lock);
+
+       kthread_flush_worker(vblank->worker);
+}
+EXPORT_SYMBOL(drm_vblank_work_flush_all);
+
 /**
  * drm_vblank_work_init - initialize a vblank work item
  * @work: vblank work item
index eb41d0810c4ff89f0a03bc62c3f9c4d294f40f25..e04d436b72973f64075e83f39862d2bd6bf6851a 100644 (file)
@@ -17,6 +17,7 @@ struct drm_crtc;
  * drm_vblank_work_init()
  * drm_vblank_work_cancel_sync()
  * drm_vblank_work_flush()
+ * drm_vblank_work_flush_all()
  */
 struct drm_vblank_work {
        /**
@@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc,
                          void (*func)(struct kthread_work *work));
 bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work);
 void drm_vblank_work_flush(struct drm_vblank_work *work);
+void drm_vblank_work_flush_all(struct drm_crtc *crtc);
 
 #endif /* !_DRM_VBLANK_WORK_H_ */