Example #1
0
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;
}
Example #2
0
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;
}