Skip to content

Commit

Permalink
simplefb: fix unmapping fb during destruction
Browse files Browse the repository at this point in the history
Unfortunately, fbdev does not create its own "struct device" for
framebuffers. Instead, it attaches to the device of the parent layer. This
has the side-effect that devm_* managed resources are not cleaned up on
framebuffer-destruction but rather during destruction of the
parent-device. In case of fbdev this might be too late, though.
remove_conflicting_framebuffer() may remove fbdev devices but keep the
parent device as it is.

Therefore, we now use plain ioremap() and unmap the framebuffer in the
fb_destroy() callback. Note that we must not free the device here as this
might race with the parent-device removal. Instead, we rely on
unregister_framebuffer() as barrier and we're safe.

Reported-by: Tom Gundersen <teg@jklm.no>
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Acked-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
  • Loading branch information
David Herrmann authored and Tomi Valkeinen committed Oct 30, 2013
1 parent cc9fd77 commit 498f6d3
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions drivers/video/simplefb.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,15 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
return 0;
}

static void simplefb_destroy(struct fb_info *info)
{
if (info->screen_base)
iounmap(info->screen_base);
}

static struct fb_ops simplefb_ops = {
.owner = THIS_MODULE,
.fb_destroy = simplefb_destroy,
.fb_setcolreg = simplefb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
Expand Down Expand Up @@ -212,8 +219,8 @@ static int simplefb_probe(struct platform_device *pdev)

info->fbops = &simplefb_ops;
info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE;
info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start,
info->fix.smem_len);
info->screen_base = ioremap(info->fix.smem_start,
info->fix.smem_len);
if (!info->screen_base) {
framebuffer_release(info);
return -ENODEV;
Expand All @@ -231,6 +238,7 @@ static int simplefb_probe(struct platform_device *pdev)
ret = register_framebuffer(info);
if (ret < 0) {
dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret);
iounmap(info->screen_base);
framebuffer_release(info);
return ret;
}
Expand Down

0 comments on commit 498f6d3

Please sign in to comment.