static int fimc_release(struct file *filp) { struct fimc_control *ctrl = filp->private_data; struct s3c_platform_fimc *pdata; struct fimc_overlay_buf *buf; struct mm_struct *mm = current->mm; int ret = 0, i; ctrl->mem.curr = ctrl->mem.base; atomic_dec(&ctrl->in_use); filp->private_data = NULL; pdata = to_fimc_plat(ctrl->dev); /* FIXME: turning off actual working camera */ if (ctrl->cam) { /* shutdown the MCLK */ clk_disable(ctrl->cam->clk); /* shutdown */ if (ctrl->cam->cam_power) ctrl->cam->cam_power(0); /* should be initialized at the next open */ ctrl->cam->initialized = 0; } if (ctrl->cap) { for (i = 0; i < FIMC_CAPBUFS; i++) { fimc_dma_free(ctrl, &ctrl->cap->bufs[i], 0); fimc_dma_free(ctrl, &ctrl->cap->bufs[i], 1); } kfree(ctrl->cap); ctrl->cap = NULL; } if (ctrl->out) { if (ctrl->status != FIMC_STREAMOFF) { ret = fimc_outdev_stop_streaming(ctrl); if (ret < 0) fimc_err("Fail: fimc_stop_streaming\n"); ctrl->status = FIMC_STREAMOFF; } buf = &ctrl->out->overlay.buf; for (i = 0; i < FIMC_OUTBUFS; i++) { if (buf->vir_addr[i]) { ret = do_munmap(mm, buf->vir_addr[i], buf->size[i]); if (ret < 0) fimc_err("%s: do_munmap fail\n", __func__); } } kfree(ctrl->out); ctrl->out = NULL; } if (pdata->clk_off) pdata->clk_off(to_platform_device(ctrl->dev), ctrl->clk); fimc_info1("%s: successfully released\n", __func__); return 0; }
static int fimc_release(struct file *filp) { struct fimc_control *ctrl = filp->private_data; struct s3c_platform_fimc *pdata; unsigned long flags; int ret = 0, i; #ifdef VIEW_FUNCTION_CALL printk("[FIMC_DEV] %s(%d)\n", __func__, __LINE__); #endif pdata = to_fimc_plat(ctrl->dev); atomic_dec(&ctrl->in_use); filp->private_data = NULL; /* FIXME: turning off actual working camera */ if (ctrl->cam) { /* shutdown the MCLK */ clk_disable(ctrl->cam->clk); /* shutdown */ if (ctrl->cam->cam_power) ctrl->cam->cam_power(0); /* should be initialized at the next open */ ctrl->cam->initialized = 0; } if (ctrl->cap) { for (i = 0; i < FIMC_CAPBUFS; i++) { fimc_dma_free(ctrl, &ctrl->cap->bufs[i], 0); fimc_dma_free(ctrl, &ctrl->cap->bufs[i], 1); } kfree(ctrl->cap); ctrl->cap = NULL; } if (ctrl->out) { if (ctrl->status != FIMC_STREAMOFF) { ret = fimc_outdev_stop_streaming(ctrl); if (ret < 0) dev_err(ctrl->dev, "Fail: fimc_stop_streaming\n"); ctrl->status = FIMC_STREAMOFF; } kfree(ctrl->out); ctrl->out = NULL; } if (pdata->clk_off) pdata->clk_off(to_platform_device(ctrl->dev), ctrl->clk); #ifdef S5P6442_POWER_GATING_CAM // gFIMC_CNT--; if(ctrl->id == CAM_ID){ spin_lock_irqsave(&fimc_domain_lock, flags); s5p6442_idle_pm_gpiocfg(S5P6442_CAM_ID, S5P6442_LP_MODE); gFIMC_CNT[ctrl->id]--; if((gFIMC_CNT[0] <= 0) && (gFIMC_CNT[1] <= 0) && (gFIMC_CNT[2] <= 0)){ s5p6442_pwrgate_config(S5P6442_CAM_ID, S5P6442_LP_MODE); } spin_unlock_irqrestore(&fimc_domain_lock, flags); } #endif #ifdef CONFIG_CPU_FREQ if(ctrl->id == CAM_ID){ set_dvfs_level(1); } #endif /* CONFIG_CPU_FREQ */ dev_info(ctrl->dev, "%s: successfully released\n", __func__); return 0; }