/*==========================================================================

   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 */
Пример #4
0
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 */