static void gfb_free_framebuffer_work(struct work_struct *work) { struct gfb_data *data = container_of(work, struct gfb_data, free_framebuffer_work.work); struct fb_info *info = data->fb_info; /* int node = info->node; */ unregister_framebuffer(info); if (info->cmap.len != 0) fb_dealloc_cmap(&info->cmap); if (info->monspecs.modedb) fb_destroy_modedb(info->monspecs.modedb); if (info->screen_base) vfree(info->screen_base); fb_destroy_modelist(&info->modelist); fb_deferred_io_cleanup(info); usb_free_urb(data->fb_urb); vfree(data->fb_bitmap); kfree(data->fb_vbitmap); framebuffer_release(info); kfree(data); }
static int memlcd_spi_remove(struct spi_device *spi) { memlcd_priv *priv = dev_get_drvdata(&spi->dev); /* cleanup defio */ fb_deferred_io_cleanup(priv->info); /* remove spi_buf memory */ if(priv->spi_buf) { dev_info(&spi->dev,"Free spi_buf memory"); kfree(priv->spi_buf); } /* remove framebuffer */ if(priv->info) { dev_info(&spi->dev,"Free framebuffer data"); unregister_framebuffer(priv->info); framebuffer_release(priv->info); } /* remove video memory */ if(priv->video_memory) { dev_info(&spi->dev,"Free videomemory"); kfree(priv->video_memory); } /* remove private data */ dev_info(&spi->dev,"Free private data"); kfree(priv); return 0; }
static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) { struct sh_mobile_lcdc_chan *ch; struct sh_mobile_lcdc_board_cfg *board_cfg; int k; /* clean up deferred io and ask board code to disable panel */ for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { ch = &priv->ch[k]; if (!ch->enabled) continue; /* deferred io mode: * flush frame, and wait for frame end interrupt * clean up deferred io and enable clock */ if (ch->info && ch->info->fbdefio) { ch->frame_end = 0; schedule_delayed_work(&ch->info->deferred_work, 0); wait_event(ch->frame_end_wait, ch->frame_end); fb_deferred_io_cleanup(ch->info); ch->info->fbdefio = NULL; sh_mobile_lcdc_clk_on(priv); } if (ch->bl) { ch->bl->props.power = FB_BLANK_POWERDOWN; backlight_update_status(ch->bl); } board_cfg = &ch->cfg.board_cfg; if (board_cfg->display_off && try_module_get(board_cfg->owner)) { board_cfg->display_off(board_cfg->board_data); module_put(board_cfg->owner); } /* disable the meram */ if (ch->meram_enabled) { struct sh_mobile_meram_cfg *cfg; struct sh_mobile_meram_info *mdev; cfg = ch->cfg.meram_cfg; mdev = priv->meram_dev; mdev->ops->meram_unregister(mdev, cfg); ch->meram_enabled = 0; } } /* stop the lcdc */ if (priv->started) { sh_mobile_lcdc_start_stop(priv, 0); priv->started = 0; } /* stop clocks */ for (k = 0; k < ARRAY_SIZE(priv->ch); k++) if (priv->ch[k].enabled) sh_mobile_lcdc_clk_off(priv); }
static int ws_eink_spi_remove(struct spi_device *spi) { struct fb_info *p = spi_get_drvdata(spi); struct ws_eink_fb_par *par = p->par; fb_deferred_io_cleanup(p); unregister_framebuffer(p); vfree(p->screen_base); vfree(par->ssbuf); framebuffer_release(p); return 0; }
static int hecubafb_remove(struct platform_device *dev) { struct fb_info *info = platform_get_drvdata(dev); if (info) { struct hecubafb_par *par = info->par; fb_deferred_io_cleanup(info); unregister_framebuffer(info); vfree((void __force *)info->screen_base); if (par->board->remove) par->board->remove(par); module_put(par->board->owner); framebuffer_release(info); } return 0; }
static int __devexit st7585_remove(struct spi_device *spi) { struct st7585_data *drvdata = spi_get_drvdata(spi); spin_lock_irq(&drvdata->lock); drvdata->spi = NULL; spi_set_drvdata(spi, NULL); if (drvdata->info) { unregister_framebuffer(drvdata->info); fb_deferred_io_cleanup(drvdata->info); framebuffer_release(drvdata->info); } spin_unlock_irq(&drvdata->lock); return 0; }
static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) { struct sh_mobile_lcdc_chan *ch; struct sh_mobile_lcdc_board_cfg *board_cfg; int k; /* clean up deferred io and ask board code to disable panel */ for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { ch = &priv->ch[k]; if (!ch->enabled) continue; /* deferred io mode: * flush frame, and wait for frame end interrupt * clean up deferred io and enable clock */ if (ch->info && ch->info->fbdefio) { ch->frame_end = 0; schedule_delayed_work(&ch->info->deferred_work, 0); wait_event(ch->frame_end_wait, ch->frame_end); fb_deferred_io_cleanup(ch->info); ch->info->fbdefio = NULL; sh_mobile_lcdc_clk_on(priv); } board_cfg = &ch->cfg.board_cfg; if (try_module_get(board_cfg->owner) && board_cfg->display_off) { board_cfg->display_off(board_cfg->board_data); module_put(board_cfg->owner); } } /* stop the lcdc */ if (priv->started) { sh_mobile_lcdc_start_stop(priv, 0); priv->started = 0; } /* stop clocks */ for (k = 0; k < ARRAY_SIZE(priv->ch); k++) if (priv->ch[k].enabled) sh_mobile_lcdc_clk_off(priv); }
/* * Assumes caller is holding info->lock mutex (for open and release at least) */ static int udl_fb_release(struct fb_info *info, int user) { struct udl_fbdev *ufbdev = info->par; ufbdev->fb_count--; #ifdef CONFIG_DRM_FBDEV_EMULATION if ((ufbdev->fb_count == 0) && (info->fbdefio)) { fb_deferred_io_cleanup(info); kfree(info->fbdefio); info->fbdefio = NULL; info->fbops->fb_mmap = udl_fb_mmap; } #endif pr_warn("released /dev/fb%d user=%d count=%d\n", info->node, user, ufbdev->fb_count); return 0; }
static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) { struct sh_mobile_lcdc_chan *ch; struct sh_mobile_lcdc_board_cfg *board_cfg; int k; for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { ch = &priv->ch[k]; if (!ch->enabled) continue; if (ch->info->fbdefio) { ch->frame_end = 0; schedule_delayed_work(&ch->info->deferred_work, 0); wait_event(ch->frame_end_wait, ch->frame_end); fb_deferred_io_cleanup(ch->info); ch->info->fbdefio = NULL; sh_mobile_lcdc_clk_on(priv); } board_cfg = &ch->cfg.board_cfg; if (board_cfg->display_off) board_cfg->display_off(board_cfg->board_data); } if (priv->started) { sh_mobile_lcdc_start_stop(priv, 0); priv->started = 0; } for (k = 0; k < ARRAY_SIZE(priv->ch); k++) if (priv->ch[k].enabled) sh_mobile_lcdc_clk_off(priv); }