diff options
author | Dave Airlie <airlied@redhat.com> | 2015-08-26 23:01:23 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-08-26 23:01:23 -0400 |
commit | 31607793ee81da3f1024df9560f0dec49abde37f (patch) | |
tree | 889573a0db31cb34fb5f322328aac8fa4158e34d | |
parent | 40b2dffbcc67e92d5df97785dffc68fe88605bfa (diff) | |
parent | 36d4e87b497d9cb3bf8e1bb2f803c7aa41dfb463 (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.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 29 |
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 | ||
75 | static int vmw_fb_setcolreg(unsigned regno, unsigned red, unsigned green, | 74 | static 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 | ||
170 | static void vmw_fb_dirty_flush(struct vmw_fb_par *par) | 169 | static 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 | ||
334 | static struct fb_deferred_io vmw_defio = { | 340 | static 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 | ||
610 | out_unlock: | 612 | out_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); |