void mfp_config(unsigned long *mfp_cfgs, int num)
{
	unsigned long flags;
	int i, drv_b11 = 0, no_lpm = 0;

#ifdef CONFIG_ARCH_MMP
	if (cpu_is_pxa910() || cpu_is_pxa988() || cpu_is_pxa986() ||
		cpu_is_mmp2() || cpu_is_mmp3() || cpu_is_pxa1088())
		drv_b11 = 1;
	if (cpu_is_pxa168() || cpu_is_pxa910())
		no_lpm = 1;
#elif defined(CONFIG_ARCH_PXA)
	if (cpu_is_pxa95x())
		drv_b11 = 1;
#endif
	spin_lock_irqsave(&mfp_spin_lock, flags);

	for (i = 0; i < num; i++, mfp_cfgs++) {
		unsigned long tmp, c = *mfp_cfgs;
		struct mfp_pin *p;
		int pin, af, drv, lpm, edge, pull;

		pin = MFP_PIN(c);
		BUG_ON(pin >= MFP_PIN_MAX);
		p = &mfp_table[pin];

		af  = MFP_AF(c);
		drv = MFP_DS(c);
		lpm = MFP_LPM_STATE(c);
		edge = MFP_LPM_EDGE(c);
		pull = MFP_PULL(c);
		if (drv_b11)
			drv = drv << 1;
		if (no_lpm)
			lpm = 0;

		tmp = MFPR_AF_SEL(af) | MFPR_DRIVE(drv);
		tmp |= mfpr_pull[pull] | mfpr_lpm[lpm] | mfpr_edge[edge];
		p->mfpr_run = tmp;
		p->mfpr_lpm = p->mfpr_run;

		p->config = c; __mfp_config_run(p);
	}

	mfpr_sync();
	spin_unlock_irqrestore(&mfp_spin_lock, flags);
}
void mmp_arch_reset(char mode, const char *cmd)
{
	int count = 10;
	static unsigned char data;

	if ((!cpu_is_pxa910()) && (!cpu_is_pxa168()) &&
	    (!cpu_is_pxa988()) && (!cpu_is_pxa986()) &&
	    (!cpu_is_pxa1088()))
		return;

	printk("%s (%c)\n", __func__, mode);

	switch (mode) {
	case 's':
		/* Jump into ROM at address 0 */
		cpu_reset(0);
		break;
	case 'w':
	default:
#if defined(CONFIG_MFD_D2199)
		if (is_panic) {
			/* dump buck1 voltage */
			d2199_extern_reg_read(D2199_BUCK2PH_BUCK1_REG, &data);
			pr_info("buck1 voltage: 0x%x\n", data);

			d2199_extern_reg_write(D2199_BUCK2PH_BUCK1_REG, 0xd8);

			/* double check */
			d2199_extern_reg_read(D2199_BUCK2PH_BUCK1_REG, &data);
			pr_info("buck1 voltage: 0x%x\n", data);
		}
#endif
		while(count--) {
			flush_cache_all();
			outer_flush_all();
			do_wdt_reset(cmd);
			mdelay(1000);
			printk("Watchdog fail...retry\n");
		}
		break;
	}
}
/* Using watchdog reset */
static void do_wdt_reset(const char *cmd)
{
	u32 reg, backup;
	void __iomem *watchdog_virt_base;
	int i;
	int match = 0, count = 0;

	if (cpu_is_pxa910() || cpu_is_pxa988() || cpu_is_pxa986() ||
			cpu_is_pxa1088())
		watchdog_virt_base = CP_TIMERS2_VIRT_BASE;
	else if (cpu_is_pxa168())
		watchdog_virt_base = TIMERS1_VIRT_BASE;
	else
		return;

	/*Hold cp to avoid reset watchdog*/
	if (cpu_is_pxa910() || cpu_is_pxa988() || cpu_is_pxa986() ||
			cpu_is_pxa1088()) {
		/*hold CP first */
		reg = readl(MPMU_APRR) | MPMU_APRR_CPR;
		writel(reg, MPMU_APRR);
		udelay(10);
		/*CP reset MSA */
		reg = readl(MPMU_CPRR) | MPMU_CPRR_DSPR | MPMU_CPRR_BBR;
		writel(reg, MPMU_CPRR);
		udelay(10);
	}

	/*If reboot by recovery, store info for uboot*/
	if (cpu_is_pxa910() || cpu_is_pxa988() || cpu_is_pxa986() ||
			cpu_is_pxa1088()) {
		if (cmd && !strcmp(cmd, "recovery")) {
			for (i = 0, backup = 0; i < 4; i++) {
				backup <<= 8;
				backup |= *(cmd + i);
			}
			do {
				writel(backup, REG_RTC_BR0);
			} while (readl(REG_RTC_BR0) != backup);
		}
	}

	/* reset/enable WDT clock */
	writel(0x7, MPMU_WDTPCR);
	readl(MPMU_WDTPCR);
	writel(0x3, MPMU_WDTPCR);
	readl(MPMU_WDTPCR);

	/* enable WDT reset */
	writel(0xbaba, watchdog_virt_base + TMR_WFAR);
	writel(0xeb10, watchdog_virt_base + TMR_WSAR);
	writel(0x3, watchdog_virt_base + TMR_WMER);

	/* negate hardware reset to the WDT after system reset */
	reg = readl(MPMU_APRR) | MPMU_APRR_WDTR;
	writel(reg, MPMU_APRR);

	/* clear previous WDT status */
	writel(0xbaba, watchdog_virt_base + TMR_WFAR);
	writel(0xeb10, watchdog_virt_base + TMR_WSAR);
	writel(0, watchdog_virt_base + TMR_WSR);

	match = readl(watchdog_virt_base + TMR_WMR);
	count = readl(watchdog_virt_base + TMR_WVR);

	/* set match counter */
	writel(0xbaba, watchdog_virt_base + TMR_WFAR);
	writel(0xeb10, watchdog_virt_base + TMR_WSAR);
	writel((0x20 + count) & 0xFFFF, watchdog_virt_base + TMR_WMR);
}
int seh_api_ioctl_handler(unsigned long arg)
{
	EehApiParams params;
	EEH_STATUS status = EEH_SUCCESS;

	if (copy_from_user(&params, (EehApiParams*)arg, sizeof(EehApiParams)))
		return -EFAULT;

	DPRINT("seh_api_ioctl_handler %d\n ", params.eehApiId);

	switch (params.eehApiId) // specific EEH API handler
	{

	case _EehInit:


		DBGMSG("Kernel Space EehInit Params:No params\n");

		enable_irq(IRQ_COMM_WDT_ID);
		if (copy_to_user(&( (EehApiParams*)arg)->status, &status, sizeof(unsigned int)))
			return -EFAULT;


		break;

	case _EehDeInit:

		DBGMSG("Kernel Space EehDeInit Params:No params\n");

		if (copy_to_user(&( (EehApiParams*)arg)->status, &status, sizeof(unsigned int)))
			return -EFAULT;

		break;

	case _EehInsertComm2Reset:
	{
    	EehInsertComm2ResetParam resetParams;

		DBGMSG("Kernel Space EehInsertComm2Reset Params: %x \n",params.params);
		if(params.params != NULL)
		{
			if (copy_from_user(&resetParams, params.params,sizeof(EehInsertComm2ResetParam)))
				return -EFAULT;

			if(resetParams.AssertType == EEH_AP_ASSERT)
			{
				disable_irq(IRQ_COMM_WDT_ID);
			}
		}
		cp_holdcp();

		if (copy_to_user(&( (EehApiParams*)arg)->status, &status, sizeof(unsigned int)))
			return -EFAULT;

		break;
	}
	case _EehReleaseCommFromReset:

		DBGMSG("Kernel Space EehReleaseCommFromReset Params:No params\n");

		cp_releasecp();

		enable_irq(IRQ_COMM_WDT_ID);
		if (copy_to_user(&( (EehApiParams*)arg)->status, &status, sizeof(unsigned int)))
			return -EFAULT;

		break;

	case _EehDisableCPUFreq:
	{
		DBGMSG("Kernel Space _EehDisableCPUFreq Params: No params\n");

		if (copy_to_user(&( (EehApiParams*)arg)->status, &status, sizeof(unsigned int)))
			return -EFAULT;
	}

	break;

	case _EehEnableCPUFreq:
	{
		DBGMSG("Kernel Space _EehEnableCPUFreq Params: No params\n");

		if (copy_to_user(&( (EehApiParams*)arg)->status, &status, sizeof(unsigned int)))
			return -EFAULT;
	}

	break;

	case _EehGetCPLoadAddr:
	{
		const struct cp_load_table_head *hdr = get_cp_load_table();
		EehGetCPLoadAddrParam param;

		DBGMSG("Kernel Space _EehGetCPLoadAddr\n");

		if(hdr)
		{
			param.arbel_load_addr = hdr->imageBegin - OFFSET_IN_ARBEL_IMAGE;
			if (copy_to_user(((EehApiParams*)arg)->params, &param, sizeof(param)))
				return -EFAULT;
		}
		else
		{
			status = EEH_ERROR;
		}

		if (copy_to_user(&( (EehApiParams*)arg)->status, &status, sizeof(unsigned int)))
			return -EFAULT;
	}

	break;
	case _EehGetModemChipType:
	{
		EehGetModemChipTypeParam param;

		DBGMSG("Kernel Space _EehGetModemChipType\n");

		if(cpu_is_pxa988())
			param.modemChipType = EEH_MODEM_CHIP_TYPE_PXA988;
		else if(cpu_is_pxa986())
			param.modemChipType = EEH_MODEM_CHIP_TYPE_PXA986;
		else if(cpu_is_pxa1088()) /* FIXME: add 1088 support */
			param.modemChipType = EEH_MODEM_CHIP_TYPE_PXA1T88;
		else
			param.modemChipType = EEH_MODEM_CHIP_TYPE_UNKNOWN;

		if (copy_to_user(((EehApiParams*)arg)->params, &param, sizeof(param)))
			return -EFAULT;

		if (copy_to_user(&( (EehApiParams*)arg)->status, &status, sizeof(unsigned int)))
			return -EFAULT;
	}

	break;

	default:
		ERRMSG("WRONG Api = %d (params.eehApiId)\n", params.eehApiId);
		return -EFAULT;
	}
	return 0;
}