diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c index 68b171af237b..8b0eeeed4d78 100644 --- a/drivers/gpu/drm/drm_debugfs_crc.c +++ b/drivers/gpu/drm/drm_debugfs_crc.c @@ -125,6 +125,12 @@ static const struct file_operations drm_crtc_crc_control_fops = { .write = crc_control_write }; +static int crtc_crc_data_count(struct drm_crtc_crc *crc) +{ + assert_spin_locked(&crc->lock); + return CIRC_CNT(crc->head, crc->tail, DRM_CRC_ENTRIES_NR); +} + static int crtc_crc_open(struct inode *inode, struct file *filep) { struct drm_crtc *crtc = inode->i_private; @@ -160,8 +166,19 @@ static int crtc_crc_open(struct inode *inode, struct file *filep) crc->entries = entries; crc->values_cnt = values_cnt; crc->opened = true; + + /* + * Only return once we got a first frame, so userspace doesn't have to + * guess when this particular piece of HW will be ready to start + * generating CRCs. + */ + ret = wait_event_interruptible_lock_irq(crc->wq, + crtc_crc_data_count(crc), + crc->lock); spin_unlock_irq(&crc->lock); + WARN_ON(ret); + return 0; err_disable: @@ -189,12 +206,6 @@ static int crtc_crc_release(struct inode *inode, struct file *filep) return 0; } -static int crtc_crc_data_count(struct drm_crtc_crc *crc) -{ - assert_spin_locked(&crc->lock); - return CIRC_CNT(crc->head, crc->tail, DRM_CRC_ENTRIES_NR); -} - /* * 1 frame field of 10 chars plus a number of CRC fields of 10 chars each, space * separated, with a newline at the end and null-terminated.