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;
}
static int shm_param_init(void)
{
	struct cp_load_table_head *ptable = get_cp_load_table();
	if (!ptable)
		return -1;

	/* main ring buffer */
	shm_rbctl[shm_rb_main].skctl_pa = ptable->dp.ACIPCOtherPortKeySectionBegin;

	shm_rbctl[shm_rb_main].tx_skbuf_size = SHM_SKBUF_SIZE;
	shm_rbctl[shm_rb_main].rx_skbuf_size = SHM_SKBUF_SIZE;

	shm_rbctl[shm_rb_main].tx_pa = ptable->dp.ACIPCOtherPortDlBegin;
	shm_rbctl[shm_rb_main].rx_pa = ptable->dp.ACIPCOtherPortUlBegin;

	shm_rbctl[shm_rb_main].tx_total_size =
	    ptable->dp.ACIPCOtherPortDlEnd - ptable->dp.ACIPCOtherPortDlBegin + 4;
	shm_rbctl[shm_rb_main].rx_total_size =
	    ptable->dp.ACIPCOtherPortUlEnd - ptable->dp.ACIPCOtherPortUlBegin + 4;

	shm_rbctl[shm_rb_main].tx_skbuf_num =
	    shm_rbctl[shm_rb_main].tx_total_size /
	    shm_rbctl[shm_rb_main].tx_skbuf_size;
	shm_rbctl[shm_rb_main].rx_skbuf_num =
	    shm_rbctl[shm_rb_main].rx_total_size /
	    shm_rbctl[shm_rb_main].rx_skbuf_size;

	shm_rbctl[shm_rb_main].tx_skbuf_low_wm =
	    (shm_rbctl[shm_rb_main].tx_skbuf_num + 1) / 4;
	shm_rbctl[shm_rb_main].rx_skbuf_low_wm =
	    (shm_rbctl[shm_rb_main].rx_skbuf_num + 1) / 4;

	/* psd dedicated ring buffer */
	shm_rbctl[shm_rb_psd].skctl_pa = ptable->dp.ACIPCPSKeySectionBegin;

	shm_rbctl[shm_rb_psd].tx_skbuf_size = SHM_PSD_TX_SKBUF_SIZE;
	shm_rbctl[shm_rb_psd].rx_skbuf_size = SHM_PSD_RX_SKBUF_SIZE;


	shm_rbctl[shm_rb_psd].tx_pa = ptable->dp.ACIPCPSDownlinkBegin;
	shm_rbctl[shm_rb_psd].rx_pa = ptable->dp.ACIPCPSUplinkBegin;

	shm_rbctl[shm_rb_psd].tx_total_size =
	    ptable->dp.ACIPCPSDownlinkEnd - ptable->dp.ACIPCPSDownlinkBegin + 4;
	shm_rbctl[shm_rb_psd].rx_total_size =
	    ptable->dp.ACIPCPSUplinkEnd - ptable->dp.ACIPCPSUplinkBegin + 4;

	shm_rbctl[shm_rb_psd].tx_skbuf_num =
	    shm_rbctl[shm_rb_psd].tx_total_size /
	    shm_rbctl[shm_rb_psd].tx_skbuf_size;
	shm_rbctl[shm_rb_psd].rx_skbuf_num =
	    shm_rbctl[shm_rb_psd].rx_total_size /
	    shm_rbctl[shm_rb_psd].rx_skbuf_size;

	shm_rbctl[shm_rb_psd].tx_skbuf_low_wm =
	    (shm_rbctl[shm_rb_psd].tx_skbuf_num + 1) / 4;
	shm_rbctl[shm_rb_psd].rx_skbuf_low_wm =
	    (shm_rbctl[shm_rb_psd].rx_skbuf_num + 1) / 4;


	/* diag ring buffer */
	shm_rbctl[shm_rb_diag].skctl_pa = ptable->dp.ACIPCDIAGKeySectionBegin;

	shm_rbctl[shm_rb_diag].tx_skbuf_size = SHM_SKBUF_SIZE;
	shm_rbctl[shm_rb_diag].rx_skbuf_size = SHM_SKBUF_SIZE;

	shm_rbctl[shm_rb_diag].tx_pa = ptable->dp.ACIPCDIAGPortUlBegin;
	shm_rbctl[shm_rb_diag].rx_pa = ptable->dp.ACIPCDIAGPortDlBegin;

	shm_rbctl[shm_rb_diag].tx_total_size =
	    ptable->dp.ACIPCDIAGPortUlEnd - ptable->dp.ACIPCDIAGPortUlBegin + 4;
	shm_rbctl[shm_rb_diag].rx_total_size =
	    ptable->dp.ACIPCDIAGPortDlEnd - ptable->dp.ACIPCDIAGPortDlBegin + 4;

	shm_rbctl[shm_rb_diag].tx_skbuf_num =
	    shm_rbctl[shm_rb_diag].tx_total_size /
	    shm_rbctl[shm_rb_diag].tx_skbuf_size;
	shm_rbctl[shm_rb_diag].rx_skbuf_num =
	    shm_rbctl[shm_rb_diag].rx_total_size /
	    shm_rbctl[shm_rb_diag].rx_skbuf_size;

	shm_rbctl[shm_rb_diag].tx_skbuf_low_wm =
	    (shm_rbctl[shm_rb_diag].tx_skbuf_num + 1) / 4;
	shm_rbctl[shm_rb_diag].rx_skbuf_low_wm =
	    (shm_rbctl[shm_rb_diag].rx_skbuf_num + 1) / 4;

	printk("ACIPCPSDownlinkBegin: 0x%08x, ACIPCPSDownlinkEnd: 0x%08x\n",
	       ptable->dp.ACIPCPSDownlinkBegin,
	       ptable->dp.ACIPCPSDownlinkEnd);
	printk("ACIPCPSUplinkBegin: 0x%08x, ACIPCPSUplinkEnd: 0x%08x\n",
	       ptable->dp.ACIPCPSUplinkBegin,
	       ptable->dp.ACIPCPSUplinkEnd);
	printk
	    ("ACIPCOtherPortDlBegin: 0x%08x, ACIPCOtherPortDlEnd: 0x%08x\n",
	     ptable->dp.ACIPCOtherPortDlBegin,
	     ptable->dp.ACIPCOtherPortDlEnd);
	printk
	    ("ACIPCOtherPortUlBegin: 0x%08x, ACIPCOtherPortUlEnd: 0x%08x\n",
	     ptable->dp.ACIPCOtherPortUlBegin,
	     ptable->dp.ACIPCOtherPortUlEnd);
	printk
	    ("ACIPCDIAGPortDlBegin: 0x%08x, ACIPCDIAGPortDlEnd: 0x%08x\n",
	     ptable->dp.ACIPCDIAGPortDlBegin,
	     ptable->dp.ACIPCDIAGPortDlEnd);
	printk
	    ("ACIPCDIAGPortUlBegin: 0x%08x, ACIPCDIAGPortUlEnd: 0x%08x\n",
	     ptable->dp.ACIPCDIAGPortUlBegin,
	     ptable->dp.ACIPCDIAGPortUlEnd);
	printk
	    ("ACIPCOtherPortKeySectionBegin: 0x%08x, ACIPCPSKeySectionBegin: 0x%08x \
	      ACIPCDIAGPortKeySectionBegin: 0x%08x \n",
	     ptable->dp.ACIPCOtherPortKeySectionBegin,
	     ptable->dp.ACIPCPSKeySectionBegin,
	     ptable->dp.ACIPCDIAGKeySectionBegin);

	return 0;
}