static void tegra_fbdev_exit(struct tegra_fbdev *fbdev) { struct fb_info *info = fbdev->base.fbdev; if (info) { int err; err = unregister_framebuffer(info); if (err < 0) DRM_DEBUG_KMS("failed to unregister framebuffer\n"); if (info->cmap.len) fb_dealloc_cmap(&info->cmap); framebuffer_release(info); } if (fbdev->fb) { drm_framebuffer_unregister_private(&fbdev->fb->base); drm_framebuffer_remove(&fbdev->fb->base); } drm_fb_helper_fini(&fbdev->base); tegra_fbdev_free(fbdev); }
static void tegra_fbdev_exit(struct tegra_fbdev *fbdev) { drm_fb_helper_unregister_fbi(&fbdev->base); if (fbdev->fb) drm_framebuffer_remove(&fbdev->fb->base); drm_fb_helper_fini(&fbdev->base); tegra_fbdev_free(fbdev); }
static void tegra_fbdev_exit(struct tegra_fbdev *fbdev) { drm_fb_helper_unregister_fbi(&fbdev->base); if (fbdev->fb) { struct tegra_bo *bo = tegra_fb_get_plane(fbdev->fb, 0); /* Undo the special mapping we made in fbdev probe. */ if (bo && bo->pages) { vunmap(bo->vaddr); bo->vaddr = NULL; } drm_framebuffer_remove(fbdev->fb); } drm_fb_helper_fini(&fbdev->base); tegra_fbdev_free(fbdev); }
static void intel_fbdev_destroy(struct drm_device *dev, struct intel_fbdev *ifbdev) { if (ifbdev->helper.fbdev) { struct fb_info *info = ifbdev->helper.fbdev; unregister_framebuffer(info); iounmap(info->screen_base); if (info->cmap.len) fb_dealloc_cmap(&info->cmap); framebuffer_release(info); } drm_fb_helper_fini(&ifbdev->helper); drm_framebuffer_unregister_private(&ifbdev->fb->base); drm_framebuffer_remove(&ifbdev->fb->base); }
static int tegra_fbdev_probe(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { struct tegra_fbdev *fbdev = to_tegra_fbdev(helper); struct tegra_drm *tegra = helper->dev->dev_private; struct drm_device *drm = helper->dev; struct drm_mode_fb_cmd2 cmd = { 0 }; unsigned int bytes_per_pixel; struct drm_framebuffer *fb; unsigned long offset; struct fb_info *info; struct tegra_bo *bo; size_t size; int err; bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8); cmd.width = sizes->surface_width; cmd.height = sizes->surface_height; cmd.pitches[0] = round_up(sizes->surface_width * bytes_per_pixel, tegra->pitch_align); cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); size = cmd.pitches[0] * cmd.height; bo = tegra_bo_create(drm, size, 0); if (IS_ERR(bo)) return PTR_ERR(bo); info = drm_fb_helper_alloc_fbi(helper); if (IS_ERR(info)) { dev_err(drm->dev, "failed to allocate framebuffer info\n"); drm_gem_object_put_unlocked(&bo->gem); return PTR_ERR(info); } fbdev->fb = tegra_fb_alloc(drm, &cmd, &bo, 1); if (IS_ERR(fbdev->fb)) { err = PTR_ERR(fbdev->fb); dev_err(drm->dev, "failed to allocate DRM framebuffer: %d\n", err); drm_gem_object_put_unlocked(&bo->gem); return PTR_ERR(fbdev->fb); } fb = &fbdev->fb->base; helper->fb = fb; helper->fbdev = info; info->par = helper; info->flags = FBINFO_FLAG_DEFAULT; info->fbops = &tegra_fb_ops; drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth); drm_fb_helper_fill_var(info, helper, fb->width, fb->height); offset = info->var.xoffset * bytes_per_pixel + info->var.yoffset * fb->pitches[0]; if (bo->pages) { bo->vaddr = vmap(bo->pages, bo->num_pages, VM_MAP, pgprot_writecombine(PAGE_KERNEL)); if (!bo->vaddr) { dev_err(drm->dev, "failed to vmap() framebuffer\n"); err = -ENOMEM; goto destroy; } } drm->mode_config.fb_base = (resource_size_t)bo->paddr; info->screen_base = (void __iomem *)bo->vaddr + offset; info->screen_size = size; info->fix.smem_start = (unsigned long)(bo->paddr + offset); info->fix.smem_len = size; return 0; destroy: drm_framebuffer_remove(fb); return err; }