aboutsummaryrefslogtreecommitdiffstats
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.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index c9f5453f20e7..c8a34476570a 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -276,7 +276,6 @@ static void vblank_disable_fn(unsigned long arg)
276void drm_vblank_cleanup(struct drm_device *dev) 276void drm_vblank_cleanup(struct drm_device *dev)
277{ 277{
278 int crtc; 278 int crtc;
279 unsigned long irqflags;
280 279
281 /* Bail if the driver didn't call drm_vblank_init() */ 280 /* Bail if the driver didn't call drm_vblank_init() */
282 if (dev->num_crtcs == 0) 281 if (dev->num_crtcs == 0)
@@ -285,11 +284,10 @@ void drm_vblank_cleanup(struct drm_device *dev)
285 for (crtc = 0; crtc < dev->num_crtcs; crtc++) { 284 for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
286 struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; 285 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
287 286
288 del_timer_sync(&vblank->disable_timer); 287 WARN_ON(vblank->enabled &&
288 drm_core_check_feature(dev, DRIVER_MODESET));
289 289
290 spin_lock_irqsave(&dev->vbl_lock, irqflags); 290 del_timer_sync(&vblank->disable_timer);
291 vblank_disable_and_save(dev, crtc);
292 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
293 } 291 }
294 292
295 kfree(dev->vblank); 293 kfree(dev->vblank);
@@ -475,17 +473,23 @@ int drm_irq_uninstall(struct drm_device *dev)
475 dev->irq_enabled = false; 473 dev->irq_enabled = false;
476 474
477 /* 475 /*
478 * Wake up any waiters so they don't hang. 476 * Wake up any waiters so they don't hang. This is just to paper over
477 * isssues for UMS drivers which aren't in full control of their
478 * vblank/irq handling. KMS drivers must ensure that vblanks are all
479 * disabled when uninstalling the irq handler.
479 */ 480 */
480 if (dev->num_crtcs) { 481 if (dev->num_crtcs) {
481 spin_lock_irqsave(&dev->vbl_lock, irqflags); 482 spin_lock_irqsave(&dev->vbl_lock, irqflags);
482 for (i = 0; i < dev->num_crtcs; i++) { 483 for (i = 0; i < dev->num_crtcs; i++) {
483 struct drm_vblank_crtc *vblank = &dev->vblank[i]; 484 struct drm_vblank_crtc *vblank = &dev->vblank[i];
484 485
486 if (!vblank->enabled)
487 continue;
488
489 WARN_ON(drm_core_check_feature(dev, DRIVER_MODESET));
490
491 vblank_disable_and_save(dev, i);
485 wake_up(&vblank->queue); 492 wake_up(&vblank->queue);
486 vblank->enabled = false;
487 vblank->last =
488 dev->driver->get_vblank_counter(dev, i);
489 } 493 }
490 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 494 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
491 } 495 }
@@ -1233,6 +1237,38 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
1233EXPORT_SYMBOL(drm_crtc_vblank_off); 1237EXPORT_SYMBOL(drm_crtc_vblank_off);
1234 1238
1235/** 1239/**
1240 * drm_crtc_vblank_reset - reset vblank state to off on a CRTC
1241 * @crtc: CRTC in question
1242 *
1243 * Drivers can use this function to reset the vblank state to off at load time.
1244 * Drivers should use this together with the drm_crtc_vblank_off() and
1245 * drm_crtc_vblank_on() functions. The difference compared to
1246 * drm_crtc_vblank_off() is that this function doesn't save the vblank counter
1247 * and hence doesn't need to call any driver hooks.
1248 */
1249void drm_crtc_vblank_reset(struct drm_crtc *drm_crtc)
1250{
1251 struct drm_device *dev = drm_crtc->dev;
1252 unsigned long irqflags;
1253 int crtc = drm_crtc_index(drm_crtc);
1254 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1255
1256 spin_lock_irqsave(&dev->vbl_lock, irqflags);
1257 /*
1258 * Prevent subsequent drm_vblank_get() from enabling the vblank
1259 * interrupt by bumping the refcount.
1260 */
1261 if (!vblank->inmodeset) {
1262 atomic_inc(&vblank->refcount);
1263 vblank->inmodeset = 1;
1264 }
1265 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
1266
1267 WARN_ON(!list_empty(&dev->vblank_event_list));
1268}
1269EXPORT_SYMBOL(drm_crtc_vblank_reset);
1270
1271/**
1236 * drm_vblank_on - enable vblank events on a CRTC 1272 * drm_vblank_on - enable vblank events on a CRTC
1237 * @dev: DRM device 1273 * @dev: DRM device
1238 * @crtc: CRTC in question 1274 * @crtc: CRTC in question
@@ -1653,7 +1689,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
1653 struct timeval tvblank; 1689 struct timeval tvblank;
1654 unsigned long irqflags; 1690 unsigned long irqflags;
1655 1691
1656 if (!dev->num_crtcs) 1692 if (WARN_ON_ONCE(!dev->num_crtcs))
1657 return false; 1693 return false;
1658 1694
1659 if (WARN_ON(crtc >= dev->num_crtcs)) 1695 if (WARN_ON(crtc >= dev->num_crtcs))