aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-08-26 23:01:23 -0400
committerDave Airlie <airlied@redhat.com>2015-08-26 23:01:23 -0400
commit31607793ee81da3f1024df9560f0dec49abde37f (patch)
tree889573a0db31cb34fb5f322328aac8fa4158e34d
parent40b2dffbcc67e92d5df97785dffc68fe88605bfa (diff)
parent36d4e87b497d9cb3bf8e1bb2f803c7aa41dfb463 (diff)
Merge tag 'vmwgfx-next-15-08-21' of git://people.freedesktop.org/~thomash/linux into drm-next
Pull request of 15-08-21 The third pull request for 4.3. Contains two fixes for regressions introduced with previous pull requests. * tag 'vmwgfx-next-15-08-21' of git://people.freedesktop.org/~thomash/linux: drm/vmwgfx: Remove duplicate ttm_bo_device_release drm/vmwgfx: Fix a circular locking dependency in the fbdev code
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c1
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fb.c29
2 files changed, 17 insertions, 13 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index f97ec5686cbc..03854d606d58 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -965,7 +965,6 @@ static int vmw_driver_unload(struct drm_device *dev)
965 ttm_object_device_release(&dev_priv->tdev); 965 ttm_object_device_release(&dev_priv->tdev);
966 iounmap(dev_priv->mmio_virt); 966 iounmap(dev_priv->mmio_virt);
967 arch_phys_wc_del(dev_priv->mmio_mtrr); 967 arch_phys_wc_del(dev_priv->mmio_mtrr);
968 (void)ttm_bo_device_release(&dev_priv->bdev);
969 if (dev_priv->ctx.staged_bindings) 968 if (dev_priv->ctx.staged_bindings)
970 vmw_binding_state_free(dev_priv->ctx.staged_bindings); 969 vmw_binding_state_free(dev_priv->ctx.staged_bindings);
971 vmw_ttm_global_release(dev_priv); 970 vmw_ttm_global_release(dev_priv);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index 042c5b4c706c..3b1faf7862a5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -68,8 +68,7 @@ struct vmw_fb_par {
68 68
69 struct drm_crtc *crtc; 69 struct drm_crtc *crtc;
70 struct drm_connector *con; 70 struct drm_connector *con;
71 71 struct delayed_work local_work;
72 bool local_mode;
73}; 72};
74 73
75static int vmw_fb_setcolreg(unsigned regno, unsigned red, unsigned green, 74static int vmw_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
@@ -167,8 +166,10 @@ static int vmw_fb_blank(int blank, struct fb_info *info)
167 * Dirty code 166 * Dirty code
168 */ 167 */
169 168
170static void vmw_fb_dirty_flush(struct vmw_fb_par *par) 169static void vmw_fb_dirty_flush(struct work_struct *work)
171{ 170{
171 struct vmw_fb_par *par = container_of(work, struct vmw_fb_par,
172 local_work.work);
172 struct vmw_private *vmw_priv = par->vmw_priv; 173 struct vmw_private *vmw_priv = par->vmw_priv;
173 struct fb_info *info = vmw_priv->fb_info; 174 struct fb_info *info = vmw_priv->fb_info;
174 unsigned long irq_flags; 175 unsigned long irq_flags;
@@ -248,7 +249,6 @@ static void vmw_fb_dirty_mark(struct vmw_fb_par *par,
248 unsigned x1, unsigned y1, 249 unsigned x1, unsigned y1,
249 unsigned width, unsigned height) 250 unsigned width, unsigned height)
250{ 251{
251 struct fb_info *info = par->vmw_priv->fb_info;
252 unsigned long flags; 252 unsigned long flags;
253 unsigned x2 = x1 + width; 253 unsigned x2 = x1 + width;
254 unsigned y2 = y1 + height; 254 unsigned y2 = y1 + height;
@@ -262,7 +262,8 @@ static void vmw_fb_dirty_mark(struct vmw_fb_par *par,
262 /* if we are active start the dirty work 262 /* if we are active start the dirty work
263 * we share the work with the defio system */ 263 * we share the work with the defio system */
264 if (par->dirty.active) 264 if (par->dirty.active)
265 schedule_delayed_work(&info->deferred_work, VMW_DIRTY_DELAY); 265 schedule_delayed_work(&par->local_work,
266 VMW_DIRTY_DELAY);
266 } else { 267 } else {
267 if (x1 < par->dirty.x1) 268 if (x1 < par->dirty.x1)
268 par->dirty.x1 = x1; 269 par->dirty.x1 = x1;
@@ -326,9 +327,14 @@ static void vmw_deferred_io(struct fb_info *info,
326 par->dirty.x2 = info->var.xres; 327 par->dirty.x2 = info->var.xres;
327 par->dirty.y2 = y2; 328 par->dirty.y2 = y2;
328 spin_unlock_irqrestore(&par->dirty.lock, flags); 329 spin_unlock_irqrestore(&par->dirty.lock, flags);
329 }
330 330
331 vmw_fb_dirty_flush(par); 331 /*
332 * Since we've already waited on this work once, try to
333 * execute asap.
334 */
335 cancel_delayed_work(&par->local_work);
336 schedule_delayed_work(&par->local_work, 0);
337 }
332}; 338};
333 339
334static struct fb_deferred_io vmw_defio = { 340static struct fb_deferred_io vmw_defio = {
@@ -601,11 +607,7 @@ static int vmw_fb_set_par(struct fb_info *info)
601 /* If there already was stuff dirty we wont 607 /* If there already was stuff dirty we wont
602 * schedule a new work, so lets do it now */ 608 * schedule a new work, so lets do it now */
603 609
604#if (defined(VMWGFX_STANDALONE) && defined(VMWGFX_FB_DEFERRED)) 610 schedule_delayed_work(&par->local_work, 0);
605 schedule_delayed_work(&par->def_par.deferred_work, 0);
606#else
607 schedule_delayed_work(&info->deferred_work, 0);
608#endif
609 611
610out_unlock: 612out_unlock:
611 if (old_mode) 613 if (old_mode)
@@ -662,6 +664,7 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
662 vmw_priv->fb_info = info; 664 vmw_priv->fb_info = info;
663 par = info->par; 665 par = info->par;
664 memset(par, 0, sizeof(*par)); 666 memset(par, 0, sizeof(*par));
667 INIT_DELAYED_WORK(&par->local_work, &vmw_fb_dirty_flush);
665 par->vmw_priv = vmw_priv; 668 par->vmw_priv = vmw_priv;
666 par->vmalloc = NULL; 669 par->vmalloc = NULL;
667 par->max_width = fb_width; 670 par->max_width = fb_width;
@@ -784,6 +787,7 @@ int vmw_fb_close(struct vmw_private *vmw_priv)
784 787
785 /* ??? order */ 788 /* ??? order */
786 fb_deferred_io_cleanup(info); 789 fb_deferred_io_cleanup(info);
790 cancel_delayed_work_sync(&par->local_work);
787 unregister_framebuffer(info); 791 unregister_framebuffer(info);
788 792
789 (void) vmw_fb_kms_detach(par, true, true); 793 (void) vmw_fb_kms_detach(par, true, true);
@@ -811,6 +815,7 @@ int vmw_fb_off(struct vmw_private *vmw_priv)
811 spin_unlock_irqrestore(&par->dirty.lock, flags); 815 spin_unlock_irqrestore(&par->dirty.lock, flags);
812 816
813 flush_delayed_work(&info->deferred_work); 817 flush_delayed_work(&info->deferred_work);
818 flush_delayed_work(&par->local_work);
814 819
815 mutex_lock(&par->bo_mutex); 820 mutex_lock(&par->bo_mutex);
816 (void) vmw_fb_kms_detach(par, true, false); 821 (void) vmw_fb_kms_detach(par, true, false);