diff options
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r-- | drivers/gpu/drm/drm_irq.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 4d79dad9d44f..10574a0c3a55 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -185,8 +185,15 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) return; } - dev->driver->disable_vblank(dev, crtc); - vblank->enabled = false; + /* + * Only disable vblank interrupts if they're enabled. This avoids + * calling the ->disable_vblank() operation in atomic context with the + * hardware potentially runtime suspended. + */ + if (vblank->enabled) { + dev->driver->disable_vblank(dev, crtc); + vblank->enabled = false; + } /* No further vblank irq's will be processed after * this point. Get current hardware vblank count and @@ -778,7 +785,7 @@ static struct timeval get_drm_timestamp(void) /** * drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent - * vblank interval + * vblank interval * @dev: DRM device * @crtc: which CRTC's vblank timestamp to retrieve * @tvblank: Pointer to target struct timeval which should receive the timestamp @@ -933,6 +940,7 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc, { struct timeval now; unsigned int seq; + if (crtc >= 0) { seq = drm_vblank_count_and_time(dev, crtc, &now); } else { @@ -1422,7 +1430,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, unsigned int seq; int ret; - e = kzalloc(sizeof *e, GFP_KERNEL); + e = kzalloc(sizeof(*e), GFP_KERNEL); if (e == NULL) { ret = -ENOMEM; goto err_put; @@ -1431,7 +1439,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, e->pipe = pipe; e->base.pid = current->pid; e->event.base.type = DRM_EVENT_VBLANK; - e->event.base.length = sizeof e->event; + e->event.base.length = sizeof(e->event); e->event.user_data = vblwait->request.signal; e->base.event = &e->event.base; e->base.file_priv = file_priv; @@ -1451,12 +1459,12 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, goto err_unlock; } - if (file_priv->event_space < sizeof e->event) { + if (file_priv->event_space < sizeof(e->event)) { ret = -EBUSY; goto err_unlock; } - file_priv->event_space -= sizeof e->event; + file_priv->event_space -= sizeof(e->event); seq = drm_vblank_count_and_time(dev, pipe, &now); if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) && |