/*========================================================================== FUNCTION uGPIOInt_DeregisterInterrupt DESCRIPTION See uGPIOInt.h ==========================================================================*/ int32 uGPIOInt_DeregisterInterrupt(uint32 gpio) { int nStatus; int nQDIResult; /* * if the GPIO is not configured by UGPIO module then we will * not have any valid index etc. Hence its better to abandon * any invalid accesses from this point. */ if ((!VALID_UGPIO(gpio))||(!VALID_UGPIO_IDX(gpio))) { return UGPIOINT_ERROR; } qurt_mutex_lock(&uGPIOIntData.uGPIOIntLock); /* * Clear out the handler and remove the event. Here the direct connect * interrupt handler is just saved for error checking purposes as it is * largely handled by the Main GPIO interrupt controller. */ uGPIOIntData.state[UGPIOINT_IDX(gpio)].isr = NULL; uGPIOIntData.state[UGPIOINT_IDX(gpio)].isr_param = 0; uGPIOIntData.state[UGPIOINT_IDX(gpio)].intr_trigger = 0; /* * Deregister IST from QURT so it can stop waiting for an interrupt. */ nStatus = qurt_interrupt_deregister(uGPIOIntData.state[UGPIOINT_IDX(gpio)].qurt_intr_id); if (QURT_EOK != nStatus) { qurt_mutex_unlock(&uGPIOIntData.uGPIOIntLock); return UGPIOINT_ERROR; } uGPIOInt_UnConfigureDirectConnectInterrupt(gpio); nQDIResult = qurt_qdi_handle_invoke(uGPIOIntData.ugpioint_qdi, UGPIOINT_QDI_CLEAR_GPIO_CONFIG, (uint32)gpio); /* * Restore interrupts */ qurt_mutex_unlock(&uGPIOIntData.uGPIOIntLock); if (nQDIResult != UGPIOINT_QDI_SUCCESS) { return UGPIOINT_ERROR; } else return UGPIOINT_SUCCESS; } /* END uGPIOInt_DeregisterInterrupt */
/*========================================================================== FUNCTION uInterruptController_IsInterruptPending DESCRIPTION See uInterruptController.h ==========================================================================*/ int32 uInterruptController_IsInterruptPending( uint32 nInterruptID, uint32 * state) { int nStatus; int32 nResult; nResult = UINTERRUPT_SUCCESS; if (!VALID_UINT(nInterruptID)) { return UINTERRUPT_ERROR; } qurt_mutex_lock(&uIntData.uIntLock); if (QURT_EOK != qurt_interrupt_status(nInterruptID, &nStatus)) { *state = 0; nResult = UINTERRUPT_ERROR; } else { if((nStatus == 1)&&(uIntData.state[UINT_IDX(nInterruptID)].intr_flags & UINTF_REGISTERED)) { *state = 1; } else { *state = 0; } } qurt_mutex_unlock(&uIntData.uIntLock); return nResult; } /* END uInterruptController_IsInterruptPending */
/*========================================================================== FUNCTION uInterruptController_TriggerInterrupt DESCRIPTION See uInterruptController.h ==========================================================================*/ int32 uInterruptController_TriggerInterrupt(uint32 nInterruptID) { if (!VALID_UINT(nInterruptID)) { return UINTERRUPT_ERROR; } qurt_mutex_lock(&uIntData.uIntLock); qurt_interrupt_raise((unsigned int) nInterruptID); qurt_mutex_unlock(&uIntData.uIntLock); return UINTERRUPT_SUCCESS; } /* END uInterruptController_TriggerInterrupt */
void halide_mutex_unlock(halide_mutex *mutex) { qurt_mutex_unlock((qurt_mutex_t *)mutex); }
/*============================================================================= FUNCTION uInterruptController_ISTMain DESCRIPTION This is the main Micro Interrupt service thread function that processes incoming L2VIC interrupts from QURT. PARAMETERS void * ISTParam this parameter for now is ignored. DEPENDENCIES None. RETURN VALUE None. SIDE EFFECTS None. ==========================================================================*/ void uInterruptController_ISTMain ( void * ISTParam ) { int nStatus; uint32 nIdx; uint32 nInterruptID; uIRQ ClientIsr; uIRQCtx ClientIsrParam; unsigned int nSignalValue; nInterruptID = UINT_NONE; uIntData.nThreadID = qurt_thread_get_id(); /* * Main loop. Process an interrupt IPC, then wait for another. */ while(1) { while (1) { unsigned int nSignalValue; nSignalValue = qurt_anysignal_wait( &uIntData.ISTSignal, uIntData.nIntRegistrationMask | uIntData.nIntMask | SIG_INT_ABORT | UINT_TASK_STOP); if (SIG_INT_ABORT & nSignalValue) { /* * Clear task stop signal. */ qurt_anysignal_clear(&uIntData.ISTSignal,SIG_INT_ABORT); break; } if (UINT_TASK_STOP & nSignalValue) { /* * Clear task stop signal. */ qurt_anysignal_clear(&uIntData.ISTSignal,UINT_TASK_STOP); break; } qurt_mutex_lock(&uIntData.uIntLock); if (nSignalValue & uIntData.nIntRegistrationMask) { /* * we get the QURT Interrupt and clear the interrupt registration mask that was set. */ nInterruptID = GetInterruptFromSignalMask(nSignalValue & uIntData.nIntRegistrationMask); if (nInterruptID == UINT_NONE) { // Ideally throw an error here . qurt_mutex_unlock(&uIntData.uIntLock); continue; } /* * Register with QURT using the interrupt vector */ nStatus = qurt_interrupt_register(nInterruptID,&uIntData.ISTSignal, uIntData.state[UINT_IDX(nInterruptID)].nInterruptMask); qurt_mutex_unlock(&uIntData.uIntLock); if (nStatus != QURT_EOK) { /* throw an error */ break; } continue; } qurt_mutex_unlock(&uIntData.uIntLock); /* * If its not a task stop due to deregistration or an error due to qdi * we should error fatal if we still do not get the interrupt registration signal. */ if ( !(uIntData.nIntMask & nSignalValue) ) { /* Ideally throw an error in Uimage*/ break; } qurt_mutex_lock(&uIntData.uIntLock); /* * find the interrupt that fired. */ for (nIdx=0;nIdx < MAX_NUMBER_OF_UINTS;nIdx++) { if (uIntData.state[nIdx].nInterruptMask & nSignalValue) { nInterruptID = uIntData.state[nIdx].qurt_intr_id; break; } } ClientIsr = uIntData.state[UINT_IDX(nInterruptID)].isr; ClientIsrParam = uIntData.state[UINT_IDX(nInterruptID)].isr_param; qurt_mutex_unlock(&uIntData.uIntLock); if (ClientIsr == NULL) { uInterruptController_UnRegister(nInterruptID); } else { ClientIsr(ClientIsrParam); } /* * Clear signal and reactivate interrupt. */ qurt_anysignal_clear(&uIntData.ISTSignal,(uIntData.state[UINT_IDX(nInterruptID)].nInterruptMask | SIG_INT_ABORT | UINT_TASK_STOP)); nStatus = qurt_interrupt_acknowledge(uIntData.state[UINT_IDX(nInterruptID)].qurt_intr_id); if (QURT_EOK != nStatus) { /* Ideally throw an error*/ break; } } nSignalValue = qurt_anysignal_wait(&uIntData.ISTSignal, (UINT_TASK_START | SIG_INT_ABORT | UINT_TASK_STOP)); /* * Wait for the next time this interrupt is registered with QURT. */ if (UINT_TASK_START & nSignalValue) { /* * Clear signal and reactivate interrupt. */ qurt_anysignal_clear(&uIntData.ISTSignal,(UINT_TASK_START | SIG_INT_ABORT | UINT_TASK_STOP)); } } } /* END uInterruptController_ISTMain */
/*========================================================================== FUNCTION uGPIOInt_RegisterInterrupt DESCRIPTION See uGPIOInt.h ==========================================================================*/ int32 uGPIOInt_RegisterInterrupt( uint32 gpio,uGPIOIntTriggerType trigger, uGPIOINTISR isr,uGPIOINTISRCtx param, uint32 nFlags) { int nQDIResult; if (!VALID_UGPIO(gpio)) { return UGPIOINT_ERROR; } if (trigger > UGPIOINT_TRIGGER_FALLING) { return UGPIOINT_ERROR; } qurt_mutex_lock(&uGPIOIntData.uGPIOIntLock); if (uGPIOInt_AssignInterruptIndex(gpio) == UGPIOINT_ERROR) { qurt_mutex_unlock(&uGPIOIntData.uGPIOIntLock); return UGPIOINT_ERROR; } if((uGPIOIntData.state[UGPIOINT_IDX(gpio)].isr != NULL) && (uGPIOIntData.state[UGPIOINT_IDX(gpio)].isr != isr)) { /* * Restore interrupts and return an error. */ qurt_mutex_unlock(&uGPIOIntData.uGPIOIntLock); return UGPIOINT_ERROR; } uGPIOIntData.state[UGPIOINT_IDX(gpio)].isr = isr; uGPIOIntData.state[UGPIOINT_IDX(gpio)].isr_param = param; /* * Update static GPIOInt map with Trigger */ uGPIOIntData.state[UGPIOINT_IDX(gpio)].intr_trigger = (uint8)trigger; uGPIOIntData.state[UGPIOINT_IDX(gpio)].gpio_intr_flags |= UGPIOINTF_REGISTERED; uGPIOInt_ConfigureDirectConnectInterrupt(gpio,trigger); /* * An IST thread is already created. * It will only be restarted on a re registration. */ qurt_anysignal_set(&uGPIOIntData.ISTSignal, uGPIOIntData.state[UGPIOINT_IDX(gpio)].nIntRegMask); nQDIResult = qurt_qdi_handle_invoke(uGPIOIntData.ugpioint_qdi, UGPIOINT_QDI_SET_GPIO_CONFIG, (uint32)gpio,(uint32)trigger, (uint32)uGPIOIntData.state[UGPIOINT_IDX(gpio)].qurt_intr_id); qurt_mutex_unlock(&uGPIOIntData.uGPIOIntLock); if (nQDIResult != UGPIOINT_QDI_SUCCESS) { return UGPIOINT_ERROR; } return UGPIOINT_SUCCESS; } /* END uGPIOInt_RegisterInterrupt */