int irq_connect_dynamic(unsigned int irq, unsigned int priority, void (*routine)(void *parameter), void *parameter, uint32_t flags) { int vector; int stub_idx; /* * Invoke the interrupt controller routine _SysIntVecAlloc() which will: * a) allocate a vector satisfying the requested priority, * b) create a new entry in the dynamic stub array * c) program the underlying interrupt controller device such that * when <irq> is asserted, the allocated interrupt vector will be * presented to the CPU. * * The _SysIntVecAlloc() routine will use the "utility" routine * _IntVecAlloc() provided in this module to scan the * _interrupt_vectors_allocated[] array for a suitable vector. */ vector = _SysIntVecAlloc(irq, priority, flags); __ASSERT(vector != -1, "Unable to request a vector for irq %d with priority %d", irq, priority); stub_idx = _stub_alloc(&next_irq_stub, ALL_DYN_IRQ_STUBS); __ASSERT(stub_idx != -1, "No available interrupt stubs found"); dyn_irq_list[stub_idx].handler = routine; dyn_irq_list[stub_idx].param = parameter; _IntVecSet(vector, _get_dynamic_stub(stub_idx, &_DynIntStubsBegin), 0); return vector; }
int irq_connect_dynamic(unsigned int irq, unsigned int priority, void (*routine)(void *parameter), void *parameter, uint32_t flags) { int vector; int stub_idx; /* * Check if the same IRQ was already connected before, in such as case, * simply re-connect the existing stub. */ int i; for (i=0; i<next_irq_stub; ++i) { if (dyn_irq_list[i].irq == irq) { __ASSERT(dyn_irq_list[i].priority == priority, "Non consistent priority"); dyn_irq_list[i].handler = routine; dyn_irq_list[i].param = parameter; _SysIntVecProgram(dyn_irq_list[i].vector, irq, flags); _IntVecSet(dyn_irq_list[i].vector, _get_dynamic_stub(i, &_DynIntStubsBegin), 0); return dyn_irq_list[i].vector; } } /* * Invoke the interrupt controller routine _SysIntVecAlloc() which will: * a) allocate a vector satisfying the requested priority, * b) create a new entry in the dynamic stub array * c) program the underlying interrupt controller device such that * when <irq> is asserted, the allocated interrupt vector will be * presented to the CPU. * * The _SysIntVecAlloc() routine will use the "utility" routine * _IntVecAlloc() provided in this module to scan the * _interrupt_vectors_allocated[] array for a suitable vector. */ vector = _SysIntVecAlloc(irq, priority, flags); #if defined(DEBUG) /* * The return value from _SysIntVecAlloc() will be -1 if an invalid * <irq> or <priority> was specified, or if a vector could not be * allocated to honour the requested priority (for the boards that can * support programming the interrupt vector for each IRQ). */ if (vector == -1) return (-1); #endif /* DEBUG */ stub_idx = _stub_alloc(&next_irq_stub, ALL_DYN_IRQ_STUBS); __ASSERT(stub_idx != -1, "No available interrupt stubs found"); dyn_irq_list[stub_idx].handler = routine; dyn_irq_list[stub_idx].param = parameter; dyn_irq_list[stub_idx].vector = vector; dyn_irq_list[stub_idx].irq = irq; dyn_irq_list[stub_idx].priority = priority; _IntVecSet(vector, _get_dynamic_stub(stub_idx, &_DynIntStubsBegin), 0); return vector; }