acipc_return_code acipc_data_send(acipc_events user_event, acipc_data data)
{
	IPC_ENTER();
	IPCTRACE("acipc_data_send userEvent 0x%x, data 0x%x\n", user_event, data);
	/* writing the data to WDR*/
	acipc_writel(IPC_WDR, data);
	
	/* fire the event to the other subsystem 
	 * to indicate the data is ready for read
	 */ 
	acipc_writel(IPC_ISRW, user_event);

	IPC_LEAVE();
	return ACIPC_RC_OK;
}
u32 set_DDR_avail_flag(void)
{
	unsigned long flags;
	/*
	 * If there's no CP acipc request should return without
	 * HW handling. SW returns expected value in order to avoid
	 * warnings
	 */
	if (!internal_acipc_pm_cp)
		return 1;

	local_irq_save(flags);

	if (ddr_avail_flag)
		pr_warning("******EDDR ***WARNING*** shared flag=1 "\
			   "althoght it already on\n");
	/*
	 * TODO - need to create a shadow for WDR
	 * register and implement clear and set Marcos
	 */
	acipc_writel(IPC_WDR, ACIPC_DDR_AVAIL);
	ddr_avail_flag = 1;

	local_irq_restore(flags);

	return 1;
}
static irqreturn_t acipc_interrupt_handler(int irq, void *dev_id)
{
	u32 i, on_events;

	IPC_ENTER();
	ACIPC_IIR_READ(acipc->IIR_val); /* read the IIR*/

	/*using ACIPCEventStatusGet might cause getting here with IIR=0*/
	if (acipc->IIR_val) 
	{	
		for (i = 0; i < ACIPC_NUMBER_OF_EVENTS; i++)
		{
			/* NOTE: if the driver state is 'NO_DDR' the following 
			 * condition will ignore events that configure to be 
			 * called only when DDR availble. currently this will 
			 * leave the event bit on meaning the LISR will be called
			 * upon release interrupts.thus the driver state must be restore 
			 * ( to NORMAL) before release the interrupts
			 */
#if 0
			if ((acipc->acipc_db.event_db[i].IIR_bit & acipc->IIR_val)&&
			   (!((acipc->acipc_db.driver_mode == ACIPC_CB_ALWAYS_NO_DDR)&&
			   (acipc->acipc_db.event_db[i].mode == ACIPC_CB_NORMAL)))){
#else
			if ((acipc->acipc_db.event_db[i].IIR_bit & acipc->IIR_val) &&
				(acipc->acipc_db.event_db[i].mode == ACIPC_CB_NORMAL)) {
#endif
				on_events = (acipc->IIR_val)&(acipc->acipc_db.event_db[i].mask);
				/* call the user callback with the status of other 
				 * events as define when the user called ACIPCEventBind
				 */
				acipc->acipc_db.event_db[i].cb(on_events);
				/* clean the event(s)*/
				acipc_writel(IPC_ICR, on_events);
				/* if more then one event exist we clear 
				 * the rest of the bits from the global 
				 * IIR_val so user callback will be called only once.
				 */ 
				
				acipc->IIR_val &= (~on_events);
			}
		}
	}

	IPC_LEAVE();

	return IRQ_HANDLED;
}

u32 user_callback(u32 events_status)
{
	acipc->bind_event_arg = events_status;
	acipc->poll_status = 1;
	wake_up_interruptible(&acipc->acipc_wait_q);

	return 0;
}
acipc_return_code acipc_event_set(acipc_events user_event)
{
	IPC_ENTER();
	acipc_writel(IPC_ISRW, user_event);
	IPCTRACE("acipc_event_set userEvent 0x%x\n", user_event);
	
	IPC_LEAVE();
	return(ACIPC_RC_OK);
}
acipc_return_code acipc_event_status_get(u32 user_event, u32 *status)
{
	u32 IIR_local_val;

	IPC_ENTER();
	/* reading the status from IIR*/
	ACIPC_IIR_READ(IIR_local_val);

	/* clear the events hw status*/
	acipc_writel(IPC_ICR, user_event);

	/* verify that this event will be cleared from the global IIR variable. 
	 * for cases this API is called from user callback
	 */
	acipc->IIR_val &= ~(user_event);

	*status = IIR_local_val & user_event;

	IPC_LEAVE();
	return ACIPC_RC_OK;
}