Example #1
0
/**
 * handle_IRQ_event - irq action chain handler
 * @irq:	the interrupt number
 * @action:	the interrupt action chain for this irq
 *
 * Handles the action chain of an irq event
 */
irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
{
	irqreturn_t ret, retval = IRQ_NONE;
	unsigned int status = 0;

#ifdef __i386__
	if (debug_direct_keyboard && irq == 1)
		lockdep_off();
#endif

	handle_dynamic_tick(action);

	/*
	 * Unconditionally enable interrupts for threaded
	 * IRQ handlers:
	 */
	if (!hardirq_count() || !(action->flags & IRQF_DISABLED))
		local_irq_enable();

	do {
		unsigned int preempt_count = preempt_count();

		ret = action->handler(irq, action->dev_id);
		if (preempt_count() != preempt_count) {
			stop_trace();
			print_symbol("BUG: unbalanced irq-handler preempt count in %s!\n", (unsigned long) action->handler);
			printk("entered with %08x, exited with %08x.\n", preempt_count, preempt_count());
			dump_stack();
			preempt_count() = preempt_count;
		}
		if (ret == IRQ_HANDLED)
			status |= action->flags;
		retval |= ret;
		action = action->next;
	} while (action);

	if (status & IRQF_SAMPLE_RANDOM) {
		local_irq_enable();
		add_interrupt_randomness(irq);
	}
	local_irq_disable();

#ifdef __i386__
	if (debug_direct_keyboard && irq == 1)
		lockdep_on();
#endif
	return retval;
}
Example #2
0
/**
 * handle_IRQ_event - irq action chain handler
 * @irq:	the interrupt number
 * @regs:	pointer to a register structure
 * @action:	the interrupt action chain for this irq
 *
 * Handles the action chain of an irq event
 */
irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
			     struct irqaction *action)
{
	irqreturn_t ret, retval = IRQ_NONE;
	unsigned int status = 0;
  
 	MARK(kernel_irq_entry, "%u %u", irq, (regs)?(!user_mode(regs)):(1));
	handle_dynamic_tick(action);

	/*
	 * Unconditionally enable interrupts for threaded
	 * IRQ handlers:
	 */
	if (!hardirq_count() || !(action->flags & IRQF_DISABLED))
		local_irq_enable();

	do {
		unsigned int preempt_count = preempt_count();

		ret = action->handler(irq, action->dev_id, regs);
		if (preempt_count() != preempt_count) {
			stop_trace();
			print_symbol("BUG: unbalanced irq-handler preempt count in %s!\n", (unsigned long) action->handler);
			printk("entered with %08x, exited with %08x.\n", preempt_count, preempt_count());
			dump_stack();
			preempt_count() = preempt_count;
		}
		if (ret == IRQ_HANDLED)
			status |= action->flags;
		retval |= ret;
		action = action->next;
	} while (action);

	if (status & IRQF_SAMPLE_RANDOM) {
		local_irq_enable();
		add_interrupt_randomness(irq);
	}
	local_irq_disable();

 	MARK(kernel_irq_exit, MARK_NOARGS);

	return retval;
}
Example #3
0
/**
 * handle_IRQ_event - irq action chain handler
 * @irq:	the interrupt number
 * @action:	the interrupt action chain for this irq
 *
 * Handles the action chain of an irq event
 */
irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
{
	irqreturn_t ret, retval = IRQ_NONE;
	unsigned int status = 0;

	handle_dynamic_tick(action);

	if (!(action->flags & IRQF_DISABLED))
		local_irq_enable_in_hardirq();

	do {
		ret = action->handler(irq, action->dev_id);
		if (ret == IRQ_HANDLED)
			status |= action->flags;
		retval |= ret;
		action = action->next;
	} while (action);

	if (status & IRQF_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);
	local_irq_disable();

	return retval;
}