diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 5e1994a8ffca33b7808ca2bdca1df05ff3aecf05..e07dcf40a3ba89a609834436bbf3827bdb86f559 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -1085,7 +1085,8 @@ static struct drm_driver driver = { .release = drm_release, .unlocked_ioctl = vmw_unlocked_ioctl, .mmap = vmw_mmap, - .poll = drm_poll, + .poll = vmw_fops_poll, + .read = vmw_fops_read, .fasync = drm_fasync, #if defined(CONFIG_COMPAT) .compat_ioctl = drm_compat_ioctl, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 83b2563e684aefc89540b3f99e5774fcba0f23a8..0e9b2cefaa9d30542c84d56f4a12a9f01a85a826 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -469,6 +469,10 @@ extern int vmw_present_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int vmw_present_readback_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern unsigned int vmw_fops_poll(struct file *filp, + struct poll_table_struct *wait); +extern ssize_t vmw_fops_read(struct file *filp, char __user *buffer, + size_t count, loff_t *offset); /** * Fifo utilities - vmwgfx_fifo.c diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index c0284a4784c9616d0d90d6edd6cd40170ca190b2..97f23abeacda647eab399af9301bf1a719ebf33d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -282,3 +282,46 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data, out_clips: return ret; } + + +/** + * vmw_fops_poll - wrapper around the drm_poll function + * + * @filp: See the linux fops poll documentation. + * @wait: See the linux fops poll documentation. + * + * Wrapper around the drm_poll function that makes sure the device is + * processing the fifo if drm_poll decides to wait. + */ +unsigned int vmw_fops_poll(struct file *filp, struct poll_table_struct *wait) +{ + struct drm_file *file_priv = filp->private_data; + struct vmw_private *dev_priv = + vmw_priv(file_priv->minor->dev); + + vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); + return drm_poll(filp, wait); +} + + +/** + * vmw_fops_read - wrapper around the drm_read function + * + * @filp: See the linux fops read documentation. + * @buffer: See the linux fops read documentation. + * @count: See the linux fops read documentation. + * offset: See the linux fops read documentation. + * + * Wrapper around the drm_read function that makes sure the device is + * processing the fifo if drm_read decides to wait. + */ +ssize_t vmw_fops_read(struct file *filp, char __user *buffer, + size_t count, loff_t *offset) +{ + struct drm_file *file_priv = filp->private_data; + struct vmw_private *dev_priv = + vmw_priv(file_priv->minor->dev); + + vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); + return drm_read(filp, buffer, count, offset); +}