/* Deinitialize hardware */
void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev)
{
	mfc_debug(2, "mfc deinit start\n");

	if (!dev) {
		mfc_err("no mfc device to run\n");
		return;
	}

	if (!IS_MFCv7X(dev) && !IS_MFCV8(dev)) {
		s5p_mfc_clock_on(dev);
		s5p_mfc_reset(dev);
		s5p_mfc_clock_off(dev);
	}

	mfc_debug(2, "mfc deinit completed\n");
}
static int s5p_mfc_wakeup_v6(struct s5p_mfc_dev *dev)
{
	int ret;

	mfc_debug_enter();
	/* 0. MFC reset */
	mfc_debug(2, "MFC reset..\n");
	WARN_ON(dev->risc_on);
	s5p_mfc_clock_on(dev);
	ret = s5p_mfc_ctrl_ops_call(dev, reset, dev);
	if (ret) {
		mfc_err("Failed to reset MFC - timeout\n");
		s5p_mfc_clock_off(dev);
		return ret;
	}
	mfc_debug(2, "Done MFC reset..\n");
	/* 1. Set DRAM base Addr */
	s5p_mfc_init_memctrl_v6(dev);
	/* 2. Initialize registers of channel I/F */
	s5p_mfc_clean_dev_int_flags(dev);
	/* 3. Send MFC wakeup command and wait for completion*/
	if (IS_MFCV8(dev))
		ret = s5p_mfc_wait_wakeup_v8(dev);
	else
		ret = s5p_mfc_wait_wakeup_v6(dev);

	s5p_mfc_clock_off(dev);
	if (ret)
		return ret;

	dev->int_cond = 0;
	if (dev->int_err != 0 || dev->int_type !=
						S5P_MFC_R2H_CMD_WAKEUP_RET) {
		/* Failure. */
		mfc_err("Failed to wakeup - error: %d int: %d\n", dev->int_err,
								dev->int_type);
		return -EIO;
	}
	dev->risc_on = 1;
	mfc_debug_leave();
	return 0;
}
/* Reset the device */
static int s5p_mfc_reset(struct s5p_mfc_dev *dev)
{
	int i;
	unsigned int status;
	unsigned long timeout;

	mfc_debug_enter();

	if (!dev) {
		mfc_err("no mfc device to run\n");
		return -EINVAL;
	}

	/* Stop procedure */
	/* Reset VI */
	/*
	s5p_mfc_write_reg(dev, 0x3f7, S5P_FIMV_SW_RESET);
	*/

	if (IS_MFCV6(dev)) {
		/* Zero Initialization of MFC registers */
		s5p_mfc_write_reg(dev, 0, S5P_FIMV_RISC2HOST_CMD);
		s5p_mfc_write_reg(dev, 0, S5P_FIMV_HOST2RISC_CMD);
		s5p_mfc_write_reg(dev, 0, S5P_FIMV_FW_VERSION);

		for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT; i++)
			s5p_mfc_write_reg(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN + (i*4));

		if (IS_MFCv6X(dev))
			if (s5p_mfc_bus_reset(dev))
				return -EIO;
		if (!IS_MFCV8(dev))
			s5p_mfc_write_reg(dev, 0, S5P_FIMV_RISC_ON);
		s5p_mfc_write_reg(dev, 0x1FFF, S5P_FIMV_MFC_RESET);
		s5p_mfc_write_reg(dev, 0, S5P_FIMV_MFC_RESET);
	} else {
		s5p_mfc_write_reg(dev, 0x3f6, S5P_FIMV_SW_RESET);	/*  reset RISC */
		s5p_mfc_write_reg(dev, 0x3e2, S5P_FIMV_SW_RESET);	/*  All reset except for MC */
		mdelay(10);

		timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);

		/* Check MC status */
		do {
			if (time_after(jiffies, timeout)) {
				mfc_err_dev("Timeout while resetting MFC.\n");
				return -EIO;
			}

			status = s5p_mfc_read_reg(dev, S5P_FIMV_MC_STATUS);

		} while (status & 0x3);

		s5p_mfc_write_reg(dev, 0x0, S5P_FIMV_SW_RESET);
		s5p_mfc_write_reg(dev, 0x3fe, S5P_FIMV_SW_RESET);
	}

	mfc_debug_leave();

	return 0;
}