/*
 * 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);
}
Exemple #2
0
/*
 * 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);
}