drm: fix up fb resize again
authorDave Airlie <airlied@linux.ie>
Fri, 6 Jun 2008 06:24:27 +0000 (16:24 +1000)
committerDave Airlie <airlied@linux.ie>
Fri, 6 Jun 2008 06:24:27 +0000 (16:24 +1000)
linux-core/drm_crtc.c
linux-core/drm_crtc.h
linux-core/drm_crtc_helper.c
linux-core/intel_display.c

index d49834b957e5ced21d2c5ce60a43459f595d490d..e1b371cc2d3522ee5720a64209117947dada6fba 100644 (file)
@@ -2055,25 +2055,10 @@ int drm_mode_replacefb(struct drm_device *dev,
                goto out;
        }
 
-       fb->width = r->width;
-       fb->height = r->height;
-       fb->pitch = r->pitch;
-       fb->bits_per_pixel = r->bpp;
-       fb->depth = r->depth;
-       fb->mm_handle = r->handle;
-
        if (dev->mode_config.funcs->resize_fb)
-         dev->mode_config.funcs->resize_fb(dev, fb);
+               ret = dev->mode_config.funcs->resize_fb(dev, file_priv, fb, r);
        else
-         ret = -EINVAL;
-#if 0
-       /* find all crtcs connected to this fb */
-       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-               if (crtc->fb->base.id == r->buffer_id) {
-                       crtc->funcs->mode_set_base(crtc, crtc->x, crtc->y);
-               }
-       }
-#endif
+               ret = -EINVAL;
 out:
        mutex_unlock(&dev->mode_config.mutex);
        return ret;
index 043b4a57263d17194808a75fd123d3d9cc8b1dcd..5f5f195a534a51cd4f89b8cd1bcdec6efa19fbb5 100644 (file)
@@ -522,9 +522,9 @@ struct drm_mode_set {
  * the CRTC<->connector mappings as needed and update its view of the screen.
  */
 struct drm_mode_config_funcs {
-       bool (*resize_fb)(struct drm_device *dev, struct drm_framebuffer *fb);
+       int (*resize_fb)(struct drm_device *dev, struct drm_file *file_priv, struct drm_framebuffer *fb, struct drm_mode_fb_cmd *mode_cmd);
        struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd);
-       void (*fb_changed)(struct drm_device *dev);
+       int (*fb_changed)(struct drm_device *dev);
 };
 
 struct drm_mode_group {
index 777820d7eeeffba67a9cd6b35cf56f88c5b89963..bfddab99f3475df67e872844b3b1c5339c15ad2a 100644 (file)
@@ -758,3 +758,4 @@ out_err:
        return ret;
 }
 EXPORT_SYMBOL(drm_get_buffer_object);
+
index 0081b5be559e8ea1d6ddb181a197ca157a2260e8..0a2854a23314a964f0d318fe19d86fc43626c0d2 100644 (file)
@@ -1517,8 +1517,38 @@ struct drm_framebuffer *intel_user_framebuffer_create(struct drm_device *dev,
        return &intel_fb->base;
 }
 
+static int intel_insert_new_fb(struct drm_device *dev, struct drm_file *file_priv,
+                               struct drm_framebuffer *fb, struct drm_mode_fb_cmd *mode_cmd)
+{
+       struct intel_framebuffer *intel_fb;
+       struct drm_buffer_object *bo;
+       struct drm_crtc *crtc;
+
+       intel_fb = to_intel_framebuffer(fb);
+
+       mutex_lock(&dev->struct_mutex);
+       bo = drm_lookup_buffer_object(file_priv, mode_cmd->handle, 0);
+       mutex_unlock(&dev->struct_mutex);
+       
+       if (!bo)
+               return -EINVAL;
+       drm_helper_mode_fill_fb_struct(fb, mode_cmd);
+       
+       drm_bo_usage_deref_unlocked(&intel_fb->bo);
+
+       intel_fb->bo = bo;
+
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               if (crtc->fb == fb) {
+                       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+                       crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y);
+               }
+       }
+       return 0;
+}
+
 static const struct drm_mode_config_funcs intel_mode_funcs = {
-       .resize_fb = NULL,
+       .resize_fb = intel_insert_new_fb,
        .fb_create = intel_user_framebuffer_create,
        .fb_changed = intelfb_probe,
 };