예제 #1
0
static void mfc_firmware_request_complete_handler(const struct firmware *fw,
						  void *context)
{
	if (fw != NULL) {
		mfc_load_firmware(fw->data, fw->size);
		mfc_fw_info = fw;
	} else {
		mfc_err("failed to load MFC F/W, MFC will not working\n");
	}
}
예제 #2
0
static void mfc_firmware_request_complete_handler(const struct firmware *fw,
						  void *context)
{
	if (fw != NULL) {
		mfcdev->fw.state = mfc_load_firmware(fw->data, fw->size);
		printk(KERN_INFO "MFC F/W loaded successfully (size: %d)\n", fw->size);

		mfcdev->fw.info = fw;
	} else {
		printk(KERN_ERR "failed to load MFC F/W, MFC will not working\n");
	}
}
예제 #3
0
static int mfc_open(struct inode *inode, struct file *file)
{
	struct mfc_inst_ctx *mfc_ctx;
	int ret;

	mutex_lock(&mfc_mutex);

	if (!mfc_is_running()) {
		/* Request CMA allocation */
		ret = s5p_alloc_media_memory_bank(S5P_MDEV_MFC, 0);
		if (ret < 0) {
			ret = -ENOMEM;
			goto err_open;
		}

		ret = s5p_alloc_media_memory_bank(S5P_MDEV_MFC, 1);
		if (ret < 0) {
			ret = -ENOMEM;
			goto err_alloc0;
		}

		/* Turn on mfc power domain regulator */
		ret = regulator_enable(mfc_pd_regulator);
		if (ret < 0) {
			mfc_err("MFC_RET_POWER_ENABLE_FAIL\n");
			ret = -EINVAL;
			goto err_alloc1;
		}

#ifdef CONFIG_DVFS_LIMIT
		s5pv210_lock_dvfs_high_level(DVFS_LOCK_TOKEN_1, L2);
#endif
		clk_enable(mfc_sclk);

		mfc_load_firmware(mfc_fw_info->data, mfc_fw_info->size);

		if (mfc_init_hw() != true) {
			clk_disable(mfc_sclk);
			ret =  -ENODEV;
			goto err_regulator;
		}
		clk_disable(mfc_sclk);
	}

	mfc_ctx = (struct mfc_inst_ctx *)kmalloc(sizeof(struct mfc_inst_ctx), GFP_KERNEL);
	if (mfc_ctx == NULL) {
		mfc_err("MFCINST_MEMORY_ALLOC_FAIL\n");
		ret = -ENOMEM;
		goto err_regulator;
	}

	memset(mfc_ctx, 0, sizeof(struct mfc_inst_ctx));

	/* get the inst no allocating some part of memory among reserved memory */
	mfc_ctx->mem_inst_no = mfc_get_mem_inst_no();
	mfc_ctx->InstNo = -1;
	if (mfc_ctx->mem_inst_no < 0) {
		mfc_err("MFCINST_INST_NUM_EXCEEDED\n");
		ret = -EPERM;
		goto err_mem_inst;
	}

	if (mfc_set_state(mfc_ctx, MFCINST_STATE_OPENED) < 0) {
		mfc_err("MFCINST_ERR_STATE_INVALID\n");
		ret = -ENODEV;
		goto err_set_state;
	}

	/* Decoder only */
	mfc_ctx->extraDPB = MFC_MAX_EXTRA_DPB;
	mfc_ctx->FrameType = MFC_RET_FRAME_NOT_SET;

	file->private_data = mfc_ctx;

	mutex_unlock(&mfc_mutex);

	return 0;

err_set_state:
	mfc_return_mem_inst_no(mfc_ctx->mem_inst_no);
err_mem_inst:
	kfree(mfc_ctx);
err_regulator:
	if (!mfc_is_running()) {
#ifdef CONFIG_DVFS_LIMIT
		s5pv210_unlock_dvfs_high_level(DVFS_LOCK_TOKEN_1);
#endif
		/* Turn off mfc power domain regulator */
		ret = regulator_disable(mfc_pd_regulator);
		if (ret < 0)
			mfc_err("MFC_RET_POWER_DISABLE_FAIL\n");
	}
err_alloc1:
	if (!mfc_is_running())
		s5p_release_media_memory_bank(S5P_MDEV_MFC, 1);
err_alloc0:
	if (!mfc_is_running())
		s5p_release_media_memory_bank(S5P_MDEV_MFC, 0);
err_open:
	mutex_unlock(&mfc_mutex);

	return ret;
}
예제 #4
0
static int mfc_open(struct inode *inode, struct file *file)
{
	struct mfc_inst_ctx *mfc_ctx;
	int ret;
	enum mfc_ret_code retcode;
	int inst_id;
#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
	struct mfc_alloc_buffer *alloc;
#endif

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

	mutex_lock(&mfcdev->lock);

#if defined(CONFIG_USE_MFC_CMA) && defined(CONFIG_MACH_MEHMET)
	if (atomic_read(&mfcdev->inst_cnt) == 0) {
		size_t size = 0x02800000;
		mfcdev->cma_vaddr = dma_alloc_coherent(mfcdev->device, size,
						&mfcdev->cma_dma_addr, 0);
		if (!mfcdev->cma_vaddr) {
			printk(KERN_ERR "%s: dma_alloc_coherent returns "
						"-ENOMEM\n", __func__);
			mutex_unlock(&mfcdev->lock);
			return -ENOMEM;
		}
		printk(KERN_INFO "%s[%d] size 0x%x, vaddr 0x%x, base 0x%x\n",
					 __func__, __LINE__, (int)size,
						(int)mfcdev->cma_vaddr,
						(int)mfcdev->cma_dma_addr);
	}
#endif

#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
	if (mfcdev->drm_playback) {
		mfc_err("DRM playback was activated, cannot open no more instance\n");
		ret = -EINVAL;
		goto err_drm_playback;
	}
#endif
	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 existing, 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");
			ret = -ENODEV;
			goto err_fw_state;
		}

		if (soc_is_exynos4212() || soc_is_exynos4412()) {
			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 loaded successfully (size: %d)\n", mfcdev->fw.info->size);
			}
		}
	}

	if (atomic_read(&mfcdev->inst_cnt) == 0) {
#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
		if (check_magic(mfcdev->drm_info.addr)) {
			mfc_dbg("DRM playback starting\n");

			clear_magic(mfcdev->drm_info.addr);

			mfcdev->drm_playback = 1;

			mfc_set_buf_alloc_scheme(MBS_FIRST_FIT);
		} else {
			/* reload F/W for first instance again */
			if (soc_is_exynos4210()) {
				mfcdev->fw.state = mfc_load_firmware(mfcdev->fw.info->data, mfcdev->fw.info->size);
				if (!mfcdev->fw.state) {
					printk(KERN_ERR "failed to reload 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);
				}
			}
		}
#else
		/* reload F/W for first instance again */
		if (soc_is_exynos4210()) {
			mfcdev->fw.state = mfc_load_firmware(mfcdev->fw.info->data, mfcdev->fw.info->size);
			if (!mfcdev->fw.state) {
				printk(KERN_ERR "failed to reload 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);
			}
		}
#endif
		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();

		s5p_sysmmu_enable(mfcdev->device);

#ifdef CONFIG_VIDEO_MFC_VCM_UMP
		vcm_set_pgtable_base(VCM_DEV_MFC);
#else /* CONFIG_S5P_VMEM or kernel virtual memory allocator */
		s5p_sysmmu_set_tablebase_pgd(mfcdev->device,
							__pa(swapper_pg_dir));

		/*
		 * RMVME: the power-gating work really (on <-> off),
		 * all TBL entry was invalidated already when the power off
		 */
		s5p_sysmmu_tlb_invalidate(mfcdev->device, 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;
		}
	}
#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
	else {
		if (check_magic(mfcdev->drm_info.addr)) {
			clear_magic(mfcdev->drm_info.addr);
			mfc_err("MFC instances are not cleared before DRM playback!\n");
			ret = -EINVAL;
			goto err_drm_start;
		}
	}
#endif
	if (atomic_read(&mfcdev->inst_cnt) >= MFC_MAX_INSTANCE_NUM) {
		mfc_err("exceed max instance number, too many instance opened already\n");
		ret = -EINVAL;
		goto err_inst_cnt;
	}

	inst_id = get_free_inst_id(mfcdev);
	if (inst_id < 0) {
		mfc_err("failed to get instance ID\n");
		ret = -EINVAL;
		goto err_inst_id;
	}

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

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

	mfc_ctx->id = inst_id;
	mfc_ctx->dev = mfcdev;

#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
	if (mfcdev->drm_playback) {
		alloc = _mfc_alloc_buf(mfc_ctx, MFC_CTX_SIZE_L, ALIGN_2KB, MBT_CTX | PORT_A);
		if (alloc == NULL) {
			mfc_err("failed to alloc context buffer\n");
			ret = -ENOMEM;
			goto err_drm_ctx;
		}

		mfc_ctx->ctxbufofs = mfc_mem_base_ofs(alloc->real) >> 11;
		mfc_ctx->ctxbufsize = alloc->size;
		memset((void *)alloc->addr, 0, alloc->size);
		mfc_mem_cache_clean((void *)alloc->addr, alloc->size);
	}
예제 #5
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;
}
예제 #6
0
static int mfc_open(struct inode *inode, struct file *file)
{
	struct mfc_inst_ctx *mfc_ctx;
	int ret;
	enum mfc_ret_code retcode;
	int inst_id;
#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
	struct mfc_alloc_buffer *alloc;
#endif

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

	mutex_lock(&mfcdev->lock);
#if SUPPORT_SLICE_ENCODING
	mfcdev->frame_working_flag = 1;
	mfcdev->frame_sys = 0;
#endif

	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 existing, 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");
			ret = -ENODEV;
			goto err_fw_state;
		}

		if (soc_is_exynos4212() || soc_is_exynos4412()) {
			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 loaded successfully (size: %d)\n", mfcdev->fw.info->size);
			}
		}
	}

	if (atomic_read(&mfcdev->inst_cnt) == 0) {
		/* reload F/W for first instance again */
		if (soc_is_exynos4210()) {
			mfcdev->fw.state = mfc_load_firmware(mfcdev->fw.info->data, mfcdev->fw.info->size);
			if (!mfcdev->fw.state) {
				printk(KERN_ERR "failed to reload 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);
			}
		}

#if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER)
		dev_lock(mfcdev->bus_dev, mfcdev->device, 133133);
#endif
#ifdef CONFIG_BUSFREQ
		pm_qos_add_request(&bus_qos_pm_qos_req, PM_QOS_BUS_QOS, 1);
#endif

		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(mfcdev);

		s5p_sysmmu_enable(mfcdev->device);

#ifdef CONFIG_VIDEO_MFC_VCM_UMP
		vcm_set_pgtable_base(VCM_DEV_MFC);
#else /* CONFIG_S5P_VMEM or kernel virtual memory allocator */
		s5p_sysmmu_set_tablebase_pgd(mfcdev->device,
							__pa(swapper_pg_dir));

		/*
		 * RMVME: the power-gating work really (on <-> off),
		 * all TBL entry was invalidated already when the power off
		 */
		s5p_sysmmu_tlb_invalidate(mfcdev->device, SYSMMU_MFC_R);
#endif
		mfc_clock_off(mfcdev);
#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;
		}
	}

	if (atomic_read(&mfcdev->inst_cnt) >= MFC_MAX_INSTANCE_NUM) {
		mfc_err("exceed max instance number, too many instance opened already\n");
		ret = -EINVAL;
		goto err_inst_cnt;
	}

	inst_id = get_free_inst_id(mfcdev);
	if (inst_id < 0) {
		mfc_err("failed to get instance ID\n");
		ret = -EINVAL;
		goto err_inst_id;
	}

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

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

#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
	if (check_magic(mfcdev->drm_info.addr) >= 0) {
		mfc_info("DRM instance starting\n");
		clear_magic(mfcdev->drm_info.addr + check_magic(mfcdev->drm_info.addr));
		mfc_ctx->drm_flag = 1;
		mfc_set_buf_alloc_scheme(MBS_FIRST_FIT);
	} else {
		mfc_ctx->drm_flag = 0;
	}
#endif

	mfc_ctx->id = inst_id;
	mfc_ctx->dev = mfcdev;

#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
	if (mfc_ctx->drm_flag) {
		alloc = _mfc_alloc_buf(mfc_ctx, MFC_CTX_SIZE_L, ALIGN_2KB, MBT_CTX | PORT_A);
		if (alloc == NULL) {
			mfc_err("failed to alloc context buffer\n");
			ret = -ENOMEM;
			goto err_drm_ctx;
		}

		mfc_ctx->ctxbufofs = mfc_mem_base_ofs(alloc->real) >> 11;
		mfc_ctx->ctxbufsize = alloc->size;
		memset((void *)alloc->addr, 0, alloc->size);
		mfc_mem_cache_clean((void *)alloc->addr, alloc->size);
	}
예제 #7
0
static int mfc_open(struct inode *inode, struct file *file)
{
	struct mfc_inst_ctx *mfc_ctx;
	int ret;

	mutex_lock(&mfc_mutex);

	if (!mfc_is_running()) {
		/* Turn on mfc power domain regulator */
		ret = regulator_enable(mfc_pd_regulator);
		if (ret < 0) {
			mfc_err("MFC_RET_POWER_ENABLE_FAIL\n");
			ret = -EINVAL;
			goto err_open;
		}

		clk_enable(mfc_sclk);

		mfc_load_firmware(mfc_fw_info->data, mfc_fw_info->size);

		if (mfc_init_hw() != MFCINST_RET_OK) {
			clk_disable(mfc_sclk);
			ret =  -ENODEV;
			goto err_regulator;
		}
		clk_disable(mfc_sclk);
	}

	mfc_ctx = (struct mfc_inst_ctx *)kmalloc(sizeof(struct mfc_inst_ctx), GFP_KERNEL);
	if (mfc_ctx == NULL) {
		mfc_err("MFCINST_MEMORY_ALLOC_FAIL\n");
		ret = -ENOMEM;
		goto err_regulator;
	}

	memset(mfc_ctx, 0, sizeof(struct mfc_inst_ctx));

	/* get the inst no allocating some part of memory among reserved memory */
	mfc_ctx->mem_inst_no = mfc_get_mem_inst_no();
	mfc_ctx->InstNo = -1;
	if (mfc_ctx->mem_inst_no < 0) {
		mfc_err("MFCINST_INST_NUM_EXCEEDED\n");
		ret = -EPERM;
		goto err_mem_inst;
	}

	if (mfc_set_state(mfc_ctx, MFCINST_STATE_OPENED) < 0) {
		mfc_err("MFCINST_ERR_STATE_INVALID\n");
		ret = -ENODEV;
		goto err_set_state;
	}

	/* Decoder only */
	mfc_ctx->extraDPB = MFC_MAX_EXTRA_DPB;
	mfc_ctx->FrameType = MFC_RET_FRAME_NOT_SET;

	file->private_data = mfc_ctx;

	mutex_unlock(&mfc_mutex);

	return 0;

err_set_state:
	mfc_return_mem_inst_no(mfc_ctx->mem_inst_no);
err_mem_inst:
	kfree(mfc_ctx);
err_regulator:
	if (!mfc_is_running()) {
		/* Turn off mfc power domain regulator */
		ret = regulator_disable(mfc_pd_regulator);
		if (ret < 0)
			mfc_err("MFC_RET_POWER_DISABLE_FAIL\n");
	}
err_open:
	mutex_unlock(&mfc_mutex);

	return ret;
}
예제 #8
0
static int mfc_probe(struct platform_device *pdev)
{
	struct resource *res;
	size_t size;
	int ret;

#if	ENABLE_MONITORING_MFC_DD
	mfc_info("MFC mfc_probe..dev_id(%d)\n",S5P_MDEV_MFC);
#endif

	/* mfc clock enable should be here */

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL)
	{
		dev_err(&pdev->dev, "failed to get memory region resource\n");
		ret = -ENOENT;
		goto probe_out;
	}

	// 60K is required for mfc register (0x0 ~ 0xe008)
	size = (res->end - res->start) + 1;
	mfc_mem = request_mem_region(res->start, size, pdev->name);
	if (mfc_mem == NULL)
	{
		dev_err(&pdev->dev, "failed to get memory region\n");
		ret = -ENOENT;
		goto probe_out;
	}

	mfc_sfr_base_vaddr = ioremap(mfc_mem->start, mfc_mem->end - mfc_mem->start + 1);
	if (mfc_sfr_base_vaddr == NULL)
	{
		dev_err(&pdev->dev, "failed to ioremap address region\n");
		ret = -ENOENT;
		goto probe_out;
	}

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res == NULL)
	{
		dev_err(&pdev->dev, "failed to get irq resource\n");
		ret = -ENOENT;
		goto probe_out;
	}

#if !defined(MFC_POLLING)
	ret = request_irq(res->start, mfc_irq, IRQF_DISABLED, pdev->name, pdev);
	if (ret != 0)
	{
		dev_err(&pdev->dev, "failed to install irq (%d)\n", ret);
		goto probe_out;
	}
#endif

	mutex_init(&mfc_mutex);

	/*
	 * buffer memory secure
	 */
	mfc_port0_base_paddr = s5p_get_media_memory_bank(S5P_MDEV_MFC, 0);
	mfc_port0_base_paddr = ALIGN_TO_128KB(mfc_port0_base_paddr);
	mfc_port0_base_vaddr = phys_to_virt(mfc_port0_base_paddr);

	if (mfc_port0_base_vaddr == NULL)
	{
		mfc_err("fail to mapping port0 buffer\n");
		ret = -EPERM;
		goto probe_out;
	}

	mfc_port1_base_paddr = s5p_get_media_memory_bank(S5P_MDEV_MFC, 1);
	mfc_port1_base_paddr = ALIGN_TO_128KB(mfc_port1_base_paddr);
	mfc_port1_base_vaddr = phys_to_virt(mfc_port1_base_paddr);

	if (mfc_port1_base_vaddr == NULL)
	{
		mfc_err("fail to mapping port1 buffer\n");
		ret = -EPERM;
		goto probe_out;
	}

//	mfc_debug("mfc_port0_base_paddr = 0x%08x, mfc_port1_base_paddr = 0x%08x <<\n",
//		(unsigned int)mfc_port0_base_paddr, (unsigned int)mfc_port1_base_paddr);
//	mfc_debug("mfc_port0_base_vaddr = 0x%08x, mfc_port1_base_vaddr = 0x%08x <<\n",
//		(unsigned int)mfc_port0_base_vaddr, (unsigned int)mfc_port1_base_vaddr);

	/*
	 * MFC FW downloading
	 */
	if (mfc_load_firmware() < 0)
	{
		mfc_err("MFCINST_ERR_FW_INIT_FAIL\n");
		ret = -EPERM;
		goto probe_out;
	}

	mfc_init_mem_inst_no();
	mfc_init_buffer();

	mfc_clk = clk_get(&pdev->dev, "mfc");
	if (mfc_clk == NULL)
	{
		printk(KERN_ERR "failed to find mfc clock source\n");
		return -ENOENT;
	}

	ret = misc_register(&mfc_miscdev);

	return 0;

probe_out:
	dev_err(&pdev->dev, "not found (%d). \n", ret);
	return ret;
}