diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_fbdev.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_fbdev.c | 61 |
1 files changed, 12 insertions, 49 deletions
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 6c9351b2e3af..96476d7d7ed2 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c | |||
@@ -55,13 +55,6 @@ static int intel_fbdev_set_par(struct fb_info *info) | |||
55 | ret = drm_fb_helper_set_par(info); | 55 | ret = drm_fb_helper_set_par(info); |
56 | 56 | ||
57 | if (ret == 0) { | 57 | if (ret == 0) { |
58 | /* | ||
59 | * FIXME: fbdev presumes that all callbacks also work from | ||
60 | * atomic contexts and relies on that for emergency oops | ||
61 | * printing. KMS totally doesn't do that and the locking here is | ||
62 | * by far not the only place this goes wrong. Ignore this for | ||
63 | * now until we solve this for real. | ||
64 | */ | ||
65 | mutex_lock(&fb_helper->dev->struct_mutex); | 58 | mutex_lock(&fb_helper->dev->struct_mutex); |
66 | intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT); | 59 | intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT); |
67 | mutex_unlock(&fb_helper->dev->struct_mutex); | 60 | mutex_unlock(&fb_helper->dev->struct_mutex); |
@@ -80,13 +73,6 @@ static int intel_fbdev_blank(int blank, struct fb_info *info) | |||
80 | ret = drm_fb_helper_blank(blank, info); | 73 | ret = drm_fb_helper_blank(blank, info); |
81 | 74 | ||
82 | if (ret == 0) { | 75 | if (ret == 0) { |
83 | /* | ||
84 | * FIXME: fbdev presumes that all callbacks also work from | ||
85 | * atomic contexts and relies on that for emergency oops | ||
86 | * printing. KMS totally doesn't do that and the locking here is | ||
87 | * by far not the only place this goes wrong. Ignore this for | ||
88 | * now until we solve this for real. | ||
89 | */ | ||
90 | mutex_lock(&fb_helper->dev->struct_mutex); | 76 | mutex_lock(&fb_helper->dev->struct_mutex); |
91 | intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT); | 77 | intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT); |
92 | mutex_unlock(&fb_helper->dev->struct_mutex); | 78 | mutex_unlock(&fb_helper->dev->struct_mutex); |
@@ -106,13 +92,6 @@ static int intel_fbdev_pan_display(struct fb_var_screeninfo *var, | |||
106 | ret = drm_fb_helper_pan_display(var, info); | 92 | ret = drm_fb_helper_pan_display(var, info); |
107 | 93 | ||
108 | if (ret == 0) { | 94 | if (ret == 0) { |
109 | /* | ||
110 | * FIXME: fbdev presumes that all callbacks also work from | ||
111 | * atomic contexts and relies on that for emergency oops | ||
112 | * printing. KMS totally doesn't do that and the locking here is | ||
113 | * by far not the only place this goes wrong. Ignore this for | ||
114 | * now until we solve this for real. | ||
115 | */ | ||
116 | mutex_lock(&fb_helper->dev->struct_mutex); | 95 | mutex_lock(&fb_helper->dev->struct_mutex); |
117 | intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT); | 96 | intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT); |
118 | mutex_unlock(&fb_helper->dev->struct_mutex); | 97 | mutex_unlock(&fb_helper->dev->struct_mutex); |
@@ -125,9 +104,9 @@ static struct fb_ops intelfb_ops = { | |||
125 | .owner = THIS_MODULE, | 104 | .owner = THIS_MODULE, |
126 | .fb_check_var = drm_fb_helper_check_var, | 105 | .fb_check_var = drm_fb_helper_check_var, |
127 | .fb_set_par = intel_fbdev_set_par, | 106 | .fb_set_par = intel_fbdev_set_par, |
128 | .fb_fillrect = cfb_fillrect, | 107 | .fb_fillrect = drm_fb_helper_cfb_fillrect, |
129 | .fb_copyarea = cfb_copyarea, | 108 | .fb_copyarea = drm_fb_helper_cfb_copyarea, |
130 | .fb_imageblit = cfb_imageblit, | 109 | .fb_imageblit = drm_fb_helper_cfb_imageblit, |
131 | .fb_pan_display = intel_fbdev_pan_display, | 110 | .fb_pan_display = intel_fbdev_pan_display, |
132 | .fb_blank = intel_fbdev_blank, | 111 | .fb_blank = intel_fbdev_blank, |
133 | .fb_setcmap = drm_fb_helper_setcmap, | 112 | .fb_setcmap = drm_fb_helper_setcmap, |
@@ -236,9 +215,9 @@ static int intelfb_create(struct drm_fb_helper *helper, | |||
236 | obj = intel_fb->obj; | 215 | obj = intel_fb->obj; |
237 | size = obj->base.size; | 216 | size = obj->base.size; |
238 | 217 | ||
239 | info = framebuffer_alloc(0, &dev->pdev->dev); | 218 | info = drm_fb_helper_alloc_fbi(helper); |
240 | if (!info) { | 219 | if (IS_ERR(info)) { |
241 | ret = -ENOMEM; | 220 | ret = PTR_ERR(info); |
242 | goto out_unpin; | 221 | goto out_unpin; |
243 | } | 222 | } |
244 | 223 | ||
@@ -247,24 +226,13 @@ static int intelfb_create(struct drm_fb_helper *helper, | |||
247 | fb = &ifbdev->fb->base; | 226 | fb = &ifbdev->fb->base; |
248 | 227 | ||
249 | ifbdev->helper.fb = fb; | 228 | ifbdev->helper.fb = fb; |
250 | ifbdev->helper.fbdev = info; | ||
251 | 229 | ||
252 | strcpy(info->fix.id, "inteldrmfb"); | 230 | strcpy(info->fix.id, "inteldrmfb"); |
253 | 231 | ||
254 | info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; | 232 | info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; |
255 | info->fbops = &intelfb_ops; | 233 | info->fbops = &intelfb_ops; |
256 | 234 | ||
257 | ret = fb_alloc_cmap(&info->cmap, 256, 0); | ||
258 | if (ret) { | ||
259 | ret = -ENOMEM; | ||
260 | goto out_unpin; | ||
261 | } | ||
262 | /* setup aperture base/size for vesafb takeover */ | 235 | /* setup aperture base/size for vesafb takeover */ |
263 | info->apertures = alloc_apertures(1); | ||
264 | if (!info->apertures) { | ||
265 | ret = -ENOMEM; | ||
266 | goto out_unpin; | ||
267 | } | ||
268 | info->apertures->ranges[0].base = dev->mode_config.fb_base; | 236 | info->apertures->ranges[0].base = dev->mode_config.fb_base; |
269 | info->apertures->ranges[0].size = dev_priv->gtt.mappable_end; | 237 | info->apertures->ranges[0].size = dev_priv->gtt.mappable_end; |
270 | 238 | ||
@@ -276,7 +244,7 @@ static int intelfb_create(struct drm_fb_helper *helper, | |||
276 | size); | 244 | size); |
277 | if (!info->screen_base) { | 245 | if (!info->screen_base) { |
278 | ret = -ENOSPC; | 246 | ret = -ENOSPC; |
279 | goto out_unpin; | 247 | goto out_destroy_fbi; |
280 | } | 248 | } |
281 | info->screen_size = size; | 249 | info->screen_size = size; |
282 | 250 | ||
@@ -303,6 +271,8 @@ static int intelfb_create(struct drm_fb_helper *helper, | |||
303 | vga_switcheroo_client_fb_set(dev->pdev, info); | 271 | vga_switcheroo_client_fb_set(dev->pdev, info); |
304 | return 0; | 272 | return 0; |
305 | 273 | ||
274 | out_destroy_fbi: | ||
275 | drm_fb_helper_release_fbi(helper); | ||
306 | out_unpin: | 276 | out_unpin: |
307 | i915_gem_object_ggtt_unpin(obj); | 277 | i915_gem_object_ggtt_unpin(obj); |
308 | drm_gem_object_unreference(&obj->base); | 278 | drm_gem_object_unreference(&obj->base); |
@@ -544,16 +514,9 @@ static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { | |||
544 | static void intel_fbdev_destroy(struct drm_device *dev, | 514 | static void intel_fbdev_destroy(struct drm_device *dev, |
545 | struct intel_fbdev *ifbdev) | 515 | struct intel_fbdev *ifbdev) |
546 | { | 516 | { |
547 | if (ifbdev->helper.fbdev) { | ||
548 | struct fb_info *info = ifbdev->helper.fbdev; | ||
549 | 517 | ||
550 | unregister_framebuffer(info); | 518 | drm_fb_helper_unregister_fbi(&ifbdev->helper); |
551 | iounmap(info->screen_base); | 519 | drm_fb_helper_release_fbi(&ifbdev->helper); |
552 | if (info->cmap.len) | ||
553 | fb_dealloc_cmap(&info->cmap); | ||
554 | |||
555 | framebuffer_release(info); | ||
556 | } | ||
557 | 520 | ||
558 | drm_fb_helper_fini(&ifbdev->helper); | 521 | drm_fb_helper_fini(&ifbdev->helper); |
559 | 522 | ||
@@ -802,7 +765,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous | |||
802 | if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen) | 765 | if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen) |
803 | memset_io(info->screen_base, 0, info->screen_size); | 766 | memset_io(info->screen_base, 0, info->screen_size); |
804 | 767 | ||
805 | fb_set_suspend(info, state); | 768 | drm_fb_helper_set_suspend(&ifbdev->helper, state); |
806 | console_unlock(); | 769 | console_unlock(); |
807 | } | 770 | } |
808 | 771 | ||