summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r--drivers/gpu/drm/drm_irq.c22
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) &&