STATUS pciIntDisconnect ( VOIDFUNCPTR *vector, /* interrupt vector to attach to */ VOIDFUNCPTR routine /* routine to be called */ ) { int irq = IVEC_TO_INUM ((int)vector) - INT_NUM_IRQ0; PCI_INT_RTN *pRtn; int oldLevel; for (pRtn = (PCI_INT_RTN *)DLL_FIRST (&pciIntList[irq]); pRtn != NULL; pRtn = (PCI_INT_RTN *)DLL_NEXT (&pRtn->node)) { if (pRtn->routine == routine) { oldLevel = intLock (); /* LOCK INTERRUPT */ dllRemove (&pciIntList[irq], &pRtn->node); intUnlock (oldLevel); /* UNLOCK INTERRUPT */ free ((char *)pRtn); return (OK); } } return (ERROR); }
STATUS pciIntConnect (VOIDFUNCPTR *vector, VOIDFUNCPTR routine, int parameter) { static int alreadyConnected=FALSE; int irq = IVEC_TO_INUM ((int)vector) - sysVectorIRQ0; PCI_INT_RTN *pRtn; int oldLevel; pRtn = (PCI_INT_RTN *)malloc (sizeof (PCI_INT_RTN)); if (pRtn == NULL) { return (ERROR); } pRtn->routine = routine; pRtn->parameter = parameter; oldLevel = intLock (); /* LOCK INTERRUPT */ dllAdd (&pciIntList[irq], &pRtn->node); intUnlock (oldLevel); /* UNLOCK INTERRUPT */ if (!alreadyConnected) { if (intConnect(vector, (VOIDFUNCPTR) pciInt, irq) == ERROR) { return -1; } alreadyConnected=TRUE; } return (OK); }
/******************************************************************************* *This routine is used to check interrupt id and interrupt cpuid * */ LOCAL STATUS armGicLvlVecChk ( int * pLevel, int * pVector, int * pSrcCpuId ) { UINT32 currentLevel, levelBak; g_vicIntCheck = 1; if (NULL != vicIntBreakInPtr) { (void)vicIntBreakInPtr(); /*lint !e534 !e718*/ } /* read pending interrupt register and mask undefined bits */ levelBak = *GIC_CPU_IntAck; currentLevel = levelBak & GIC_INT_SPURIOUS; /* If no interrupt is pending, register will have a value of 0x3ff, * return ERROR */ if (currentLevel == GIC_INT_SPURIOUS) { return ERROR; } /* check if interrupt is IPI */ if(currentLevel < SGI_INT_MAX) { /* * When we find that this is a SGI interrupt, we add armGicLinesNum to * the current SGI level (0 - SGI_INT_MAX), in other words, the SGI * level is redefined by software to declare that this is a specific * interrupt, then we need save the source CPU ID to ack this interrupt. */ *pSrcCpuId = levelBak & GIC_SGI_SRC_CPU_ID_MASK; *pLevel = (int)(currentLevel + armGicLinesNum); *pVector = IVEC_TO_INUM(currentLevel + armGicLinesNum); } else { *pLevel =(int)currentLevel; *pVector = IVEC_TO_INUM(currentLevel); } if(vicIntLvlChgHookPtr != NULL) { (void)vicIntLvlChgHookPtr(0, *pLevel); /*lint !e534 !e119*/ } return OK; }
/***************************************************************************** * 函 数 名 : BSP_INT_DisConnect * * 功能描述 : 取消注册某个中断 * * 输入参数 : VOIDFUNCPTR * vector 中断向量号,取值范围0~40 * VOIDFUNCPTR routine 中断服务程序 * BSP_S32 parameter 中断服务程序参数 * 输出参数 : 无 * * 返 回 值 : OK&ERROR * * 修改记录 : 2009年3月5日 zhanghailun creat *****************************************************************************/ BSP_S32 BSP_INT_DisConnect (VOIDFUNCPTR * vector,VOIDFUNCPTR routine, BSP_S32 parameter) { BSP_S32 s32Result = OK; if(IVEC_TO_INUM(vector) >= (INT_LVL_MAX)) { return ERROR; } if(IVEC_TO_INUM(vector) < INT_LVL_MAX) { free_irq((unsigned int)vector, NULL); s32Result = OK; } return s32Result; }
/***************************************************************************** * 函 数 名 : BSP_INT_Connect * * 功能描述 : 注册某个中断 * * 输入参数 : VOIDFUNCPTR * vector 中断向量号,取值范围0~40 * VOIDFUNCPTR routine 中断服务程序 * BSP_S32 parameter 中断服务程序参数 * 输出参数 : 无 * * 返 回 值 : OK&ERROR * * 修改记录 : 2009年3月5日 zhanghailun creat *****************************************************************************/ BSP_S32 BSP_INT_Connect (VOIDFUNCPTR * vector,VOIDFUNCPTR routine, BSP_S32 parameter) { BSP_S32 s32Result = OK; char *acTmp = g_subvic_irq_name; int iTmp; if(IVEC_TO_INUM(vector) >= (INT_LVL_MAX)) { return ERROR; } if(IVEC_TO_INUM(vector) < INT_LVL_MAX) { iTmp = IVEC_TO_INUM(vector); acTmp[9] = (iTmp%10) + '0'; acTmp[8] = ((iTmp/10)%10) + '0'; acTmp[7] = (iTmp/100) + '0'; s32Result = request_irq((unsigned int)vector, (irq_handler_t)routine, 0, acTmp, NULL); } return s32Result; }
int sysPciIvecToIrq ( int vector /* vector address */ ) { UINT32 irq; UINT32 intNum = IVEC_TO_INUM (vector); /* walk through the sysInumTbl[] to get the match */ for (irq = PCI_INT_BASE; irq < (PCI_INT_BASE + PCI_INT_LINES); irq++) { if (sysInumTbl[irq] == intNum) return (irq); } return (ERROR); }
PUBLIC IX_STATUS ixOsalIrqUnbind (UINT32 irqLevel) { /* * disable interrupts for this vector */ if (intDisable (IVEC_TO_INUM (irqLevel)) != OK) { return IX_FAIL; } /* * register a dummy ISR */ if (intConnect ((IxOsalVoidFnVoidPtr *) irqLevel, (IxOsalVoidFnVoidPtr) ixOsalDummyIsr, 0) != OK) { return IX_FAIL; } return IX_SUCCESS; }