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; }
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++) { if ((acipc->acipc_db.event_db[i].IIR_bit & acipc->IIR_val) && (acipc->acipc_db.event_db[i].mode == ACIPC_CB_NORMAL)) { on_events = (acipc->IIR_val) & (acipc->acipc_db. event_db[i].mask); /* clean the event(s) */ acipc_writel_withdummy(IPC_ICR, on_events); /* * 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); /* * 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; }
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; }