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; }