Esempio n. 1
0
asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
{
    struct pt_regs *old_regs;
    struct irq_desc *desc = irq_desc + irq;
    unsigned short pending, other_ints;

    old_regs = set_irq_regs(regs);

    /*
     * Some hardware gives randomly wrong interrupts.  Rather
     * than crashing, do something sensible.
     */
    if (irq >= NR_IRQS)
        desc = &bad_irq_desc;

    irq_enter();

    generic_handle_irq(irq);

    /* If we're the only interrupt running (ignoring IRQ15 which is for
       syscalls), lower our priority to IRQ14 so that softirqs run at
       that level.  If there's another, lower-level interrupt, irq_exit
       will defer softirqs to that.  */
    CSYNC();
    pending = bfin_read_IPEND() & ~0x8000;
    other_ints = pending & (pending - 1);
    if (other_ints == 0)
        lower_to_irq14();
    irq_exit();

    set_irq_regs(old_regs);
}
Esempio n. 2
0
asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
{
	struct pt_regs *old_regs;
	struct irq_desc *desc = irq_desc + irq;
#ifndef CONFIG_IPIPE
	unsigned short pending, other_ints;
#endif
	old_regs = set_irq_regs(regs);

	/*
	 * Some hardware gives randomly wrong interrupts.  Rather
	 * than crashing, do something sensible.
	 */
	if (irq >= NR_IRQS)
		desc = &bad_irq_desc;

	irq_enter();
#ifdef CONFIG_DEBUG_STACKOVERFLOW
	/* Debugging check for stack overflow: is there less than STACK_WARN free? */
	{
		long sp;

		sp = __get_SP() & (THREAD_SIZE-1);

		if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
			dump_stack();
			printk(KERN_EMERG "%s: possible stack overflow while handling irq %i "
					" only %ld bytes free\n",
				__func__, irq, sp - sizeof(struct thread_info));
		}
	}
#endif
	generic_handle_irq(irq);

#ifndef CONFIG_IPIPE
	/*
	 * If we're the only interrupt running (ignoring IRQ15 which
	 * is for syscalls), lower our priority to IRQ14 so that
	 * softirqs run at that level.  If there's another,
	 * lower-level interrupt, irq_exit will defer softirqs to
	 * that. If the interrupt pipeline is enabled, we are already
	 * running at IRQ14 priority, so we don't need this code.
	 */
	CSYNC();
	pending = bfin_read_IPEND() & ~0x8000;
	other_ints = pending & (pending - 1);
	if (other_ints == 0)
		lower_to_irq14();
#endif /* !CONFIG_IPIPE */
	irq_exit();

	set_irq_regs(old_regs);
}
Esempio n. 3
0
static void maybe_lower_to_irq14(void)
{
	unsigned short pending, other_ints;

	/*
	 * If we're the only interrupt running (ignoring IRQ15 which
	 * is for syscalls), lower our priority to IRQ14 so that
	 * softirqs run at that level.  If there's another,
	 * lower-level interrupt, irq_exit will defer softirqs to
	 * that. If the interrupt pipeline is enabled, we are already
	 * running at IRQ14 priority, so we don't need this code.
	 */
	CSYNC();
	pending = bfin_read_IPEND() & ~0x8000;
	other_ints = pending & (pending - 1);
	if (other_ints == 0)
		lower_to_irq14();
}