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); }
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); }
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(); }