Beispiel #1
0
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;
}
Beispiel #2
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;
}