Пример #1
0
static int mfc_release(struct inode *inode, struct file *file)
{
	struct mfc_inst_ctx *mfc_ctx;
	struct mfc_dev *dev;
	int ret;

	mfc_ctx = (struct mfc_inst_ctx *)file->private_data;
	if (!mfc_ctx)
		return -EINVAL;

	dev = mfc_ctx->dev;

	mutex_lock(&dev->lock);

#ifdef CONFIG_CPU_FREQ
	/* Release MFC & Bus Frequency lock for High resolution */
	if (mfc_ctx->busfreq_flag == true){
		atomic_dec(&dev->busfreq_lock_cnt);
		mfc_ctx->busfreq_flag = false;
		if (atomic_read(&dev->busfreq_lock_cnt) == 0){
			/* release Freq lock back to normal */
			s5pv310_busfreq_lock_free(DVFS_LOCK_ID_MFC);
			mfc_dbg("[%s] Bus Freq lock Released Normal !!\n",__func__);
		}
	}
#endif

	file->private_data = NULL;

	printk(KERN_INFO"[%s]Released Instance id %d \n",__func__,mfc_ctx->id);
	dev->inst_ctx[mfc_ctx->id] = NULL;
	atomic_dec(&dev->inst_cnt);

	mfc_destroy_inst(mfc_ctx);

	if (atomic_read(&dev->inst_cnt) == 0) {
		ret = mfc_power_off();
		if (ret < 0) {
			mfc_err("power disable failed.\n");
			goto err_pwr_disable;
		}
	} else {
#if defined(SYSMMU_MFC_ON) && !defined(CONFIG_VIDEO_MFC_VCM_UMP)
	mfc_clock_on();

	sysmmu_tlb_invalidate(SYSMMU_MFC_L);
	sysmmu_tlb_invalidate(SYSMMU_MFC_R);

	mfc_clock_off();
#endif
	}

	ret = 0;

err_pwr_disable:
	mutex_unlock(&dev->lock);

	return ret;
}
Пример #2
0
static int mfc_open(struct inode *inode, struct file *file)
{
	struct mfc_inst_ctx *mfc_ctx;
	int ret;
	enum mfc_ret_code retcode;

	/* prevent invalid reference */
	file->private_data = NULL;

	mutex_lock(&mfcdev->lock);

	if (!mfcdev->fw.state) {
		if (mfcdev->fw.requesting) {
			printk(KERN_INFO "MFC F/W request is on-going, try again\n");
			ret = -ENODEV;
			goto err_fw_state;
		}

		printk(KERN_INFO "MFC F/W is not exist, requesting...\n");
		ret = request_firmware(&mfcdev->fw.info, MFC_FW_NAME, mfcdev->device);

		if (ret < 0) {
			printk(KERN_INFO "failed to copy MFC F/W during open\n");
			goto err_fw_state;
		}
	}

	if (atomic_read(&mfcdev->inst_cnt) == 0) {
		/* reload F/W for first instance again */
		mfcdev->fw.state = mfc_load_firmware(mfcdev->fw.info->data, mfcdev->fw.info->size);
		if (!mfcdev->fw.state) {
			printk(KERN_ERR "failed to load MFC F/W, MFC will not working\n");
			ret = -ENODEV;
			goto err_fw_state;
		} else {
			printk(KERN_INFO "MFC F/W reloaded successfully (size: %d)\n", mfcdev->fw.info->size);
		}

		ret = mfc_power_on();
		if (ret < 0) {
			mfc_err("power enable failed\n");
			goto err_pwr_enable;
		}

#ifndef CONFIG_PM_RUNTIME
#ifdef SYSMMU_MFC_ON
		mfc_clock_on();

		sysmmu_on(SYSMMU_MFC_L);
		sysmmu_on(SYSMMU_MFC_R);

#ifdef CONFIG_VIDEO_MFC_VCM_UMP
		vcm_set_pgtable_base(VCM_DEV_MFC);
#else /* CONFIG_S5P_VMEM or kernel virtual memory allocator */
		sysmmu_set_tablebase_pgd(SYSMMU_MFC_L, __pa(swapper_pg_dir));
		sysmmu_set_tablebase_pgd(SYSMMU_MFC_R, __pa(swapper_pg_dir));

		/*
		 * RMVME: the power-gating work really (on <-> off),
		 * all TBL entry was invalidated already when the power off
		 */
		sysmmu_tlb_invalidate(SYSMMU_MFC_L);
		sysmmu_tlb_invalidate(SYSMMU_MFC_R);
#endif
		mfc_clock_off();
#endif
#endif
		/* MFC hardware initialization */
		retcode = mfc_start(mfcdev);
		if (retcode != MFC_OK) {
			mfc_err("MFC H/W init failed: %d\n", retcode);
			ret = -ENODEV;
			goto err_start_hw;
		}
		
		/*
		 * Indicate that MFC is running
		 */
		mfc_is_running = 1;
	}

	mfc_ctx = mfc_create_inst();
	if (!mfc_ctx) {
		mfc_err("failed to create instance context\n");
		ret = -ENOMEM;
		goto err_inst_ctx;
	}

	mfc_ctx->id = get_free_inst_id(mfcdev);
	if (mfc_ctx->id < 0) {
		mfc_destroy_inst(mfc_ctx);
		ret = -EINVAL;
		goto err_inst_ctx;
	}

	printk(KERN_INFO "MFC instance [%d] opened", mfc_ctx->id);
	mfc_ctx->dev = mfcdev;

	atomic_inc(&mfcdev->inst_cnt);
	mfcdev->inst_ctx[mfc_ctx->id] = mfc_ctx;

	file->private_data = (struct mfc_inst_ctx *)mfc_ctx;

	mutex_unlock(&mfcdev->lock);

	return 0;

err_inst_ctx:
err_start_hw:
	if (atomic_read(&mfcdev->inst_cnt) == 0) {
		if (mfc_power_off() < 0)
			mfc_err("power disable failed\n");
	}

err_pwr_enable:
err_fw_state:
	mutex_unlock(&mfcdev->lock);

	return ret;
}