aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-12-02 15:55:41 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-01-20 09:57:21 -0500
commit7147573a5ce499dec3979e6b524691d47e1288d5 (patch)
treeb3c414243613b8aeee33921602d6b6363d4f2565
parent80f0b5aff8f49f63eaf08bdae243de3a8ea3f77e (diff)
drm/gma500: move fbcon restore to lastclose
Doing this within the fb->destroy callback leads to a locking nightmare. And all other drm drivers that restore the fbcon do it in lastclose, too. With this adjustments all fb->destroy callbacks optionally drop references to any gem objects used as backing storage, call drm_framebuffer_cleanup and then kfree the struct. Which nicely simplifies the locking for framebuffer unreferencing and freeing, since this doesn't require that we hold the mode_config lock. A slight exception is the vmwgfx surface backed framebuffer, it also calls drm_master_put and removes the object from a device-private framebuffer list. Both seem to have solid locking in place already. Conclusion is that now it is no longer required to hold the mode_config lock while freeing a framebuffer. v2: Drop the corresponding mutex_lock WARN check from drm_framebuffer_unreference. v3: Use just the mode_config lock not modeset_lock_all, due to patch reordering. Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/drm_crtc.c2
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c24
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c10
3 files changed, 10 insertions, 26 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 81545540b2df..8d665fafc15e 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -317,9 +317,7 @@ static void drm_framebuffer_free(struct kref *kref)
317 */ 317 */
318void drm_framebuffer_unreference(struct drm_framebuffer *fb) 318void drm_framebuffer_unreference(struct drm_framebuffer *fb)
319{ 319{
320 struct drm_device *dev = fb->dev;
321 DRM_DEBUG("FB ID: %d\n", fb->base.id); 320 DRM_DEBUG("FB ID: %d\n", fb->base.id);
322 WARN_ON(!drm_modeset_is_locked(dev));
323 kref_put(&fb->refcount, drm_framebuffer_free); 321 kref_put(&fb->refcount, drm_framebuffer_free);
324} 322}
325EXPORT_SYMBOL(drm_framebuffer_unreference); 323EXPORT_SYMBOL(drm_framebuffer_unreference);
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 38e7e7597de2..49800d2b79dd 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -668,30 +668,6 @@ static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
668{ 668{
669 struct psb_framebuffer *psbfb = to_psb_fb(fb); 669 struct psb_framebuffer *psbfb = to_psb_fb(fb);
670 struct gtt_range *r = psbfb->gtt; 670 struct gtt_range *r = psbfb->gtt;
671 struct drm_device *dev = fb->dev;
672 struct drm_psb_private *dev_priv = dev->dev_private;
673 struct psb_fbdev *fbdev = dev_priv->fbdev;
674 struct drm_crtc *crtc;
675 int reset = 0;
676
677 /* Should never get stolen memory for a user fb */
678 WARN_ON(r->stolen);
679
680 /* Check if we are erroneously live */
681 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
682 if (crtc->fb == fb)
683 reset = 1;
684
685 if (reset)
686 /*
687 * Now force a sane response before we permit the DRM CRTC
688 * layer to do stupid things like blank the display. Instead
689 * we reset this framebuffer as if the user had forced a reset.
690 * We must do this before the cleanup so that the DRM layer
691 * doesn't get a chance to stick its oar in where it isn't
692 * wanted.
693 */
694 drm_fb_helper_restore_fbdev_mode(&fbdev->psb_fb_helper);
695 671
696 /* Let DRM do its clean up */ 672 /* Let DRM do its clean up */
697 drm_framebuffer_cleanup(fb); 673 drm_framebuffer_cleanup(fb);
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index dd1fbfa7e467..dbcefe9f78fa 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -149,6 +149,16 @@ static struct drm_ioctl_desc psb_ioctls[] = {
149 149
150static void psb_lastclose(struct drm_device *dev) 150static void psb_lastclose(struct drm_device *dev)
151{ 151{
152 int ret;
153 struct drm_psb_private *dev_priv = dev->dev_private;
154 struct psb_fbdev *fbdev = dev_priv->fbdev;
155
156 mutex_lock(&dev->mode_config.mutex);
157 ret = drm_fb_helper_restore_fbdev_mode(&fbdev->psb_fb_helper);
158 if (ret)
159 DRM_DEBUG("failed to restore crtc mode\n");
160 mutex_unlock(&dev->mode_config.mutex);
161
152 return; 162 return;
153} 163}
154 164