/* * Main handler for inter-processor interrupts */ void handle_IPI(int ipinr, struct pt_regs *regs) { unsigned int cpu = smp_processor_id(); struct pt_regs *old_regs = set_irq_regs(regs); if ((unsigned)ipinr < NR_IPI) { trace_ipi_entry(ipi_types[ipinr]); __inc_irq_stat(cpu, ipi_irqs[ipinr]); } switch (ipinr) { case IPI_RESCHEDULE: scheduler_ipi(); break; case IPI_CALL_FUNC: irq_enter(); mt_trace_ISR_start(ipinr); generic_smp_call_function_interrupt(); mt_trace_ISR_end(ipinr); irq_exit(); break; case IPI_CALL_FUNC_SINGLE: irq_enter(); mt_trace_ISR_start(ipinr); generic_smp_call_function_single_interrupt(); mt_trace_ISR_end(ipinr); irq_exit(); break; case IPI_CPU_STOP: irq_enter(); mt_trace_ISR_start(ipinr); ipi_cpu_stop(cpu); mt_trace_ISR_end(ipinr); irq_exit(); break; default: pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); break; } if ((unsigned)ipinr < NR_IPI) trace_ipi_exit(ipi_types[ipinr]); set_irq_regs(old_regs); }
/* * handle_IRQ handles all hardware IRQ's. Decoded IRQs should * not come via this function. Instead, they should provide their * own 'handler'. Used by platform code implementing C-based 1st * level decoding. */ void handle_IRQ(unsigned int irq, struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); #ifdef CONFIG_MTK_SCHED_TRACERS struct irq_desc *desc; #endif mt_trace_ISR_start(irq); irq_enter(); #ifdef CONFIG_MTK_SCHED_TRACERS desc = irq_to_desc(irq); trace_irq_entry(irq, (desc && desc->action && desc->action->name) ? desc->action->name : "-"); #endif /* * Some hardware gives randomly wrong interrupts. Rather * than crashing, do something sensible. */ if (unlikely(irq >= nr_irqs)) { if (printk_ratelimit()) printk(KERN_WARNING "Bad IRQ%u\n", irq); ack_bad_irq(irq); } else { generic_handle_irq(irq); } #ifdef CONFIG_MTK_SCHED_TRACERS trace_irq_exit(irq); #endif mt_trace_ISR_end(irq); irq_exit(); set_irq_regs(old_regs); }