arch/mips/loongson2ef/lemote-2f/irq.c

Source file repositories/reference/linux-study-clean/arch/mips/loongson2ef/lemote-2f/irq.c

File Facts

System
Linux kernel
Corpus path
arch/mips/loongson2ef/lemote-2f/irq.c
Extension
.c
Size
3071 bytes
Lines
118
Domain
Architecture Layer
Bucket
arch/mips
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (unlikely(irq == 7)) {
			/*
			 * This may be a spurious interrupt.
			 *
			 * Read the interrupt status register (ISR). If the most
			 * significant bit is not set then there is no valid
			 * interrupt.
			 */
			outb(0x0B, PIC_MASTER_ISR);	/* ISR register */
			if (~inb(PIC_MASTER_ISR) & 0x80)
				irq = -1;
		}
		raw_spin_unlock(&i8259A_lock);
	}

	return irq;
}
EXPORT_SYMBOL(mach_i8259_irq);

static void i8259_irqdispatch(void)
{
	int irq;

	irq = mach_i8259_irq();
	if (irq >= 0)
		do_IRQ(irq);
	else
		spurious_interrupt();
}

void mach_irq_dispatch(unsigned int pending)
{
	if (pending & CAUSEF_IP7)
		do_IRQ(LOONGSON_TIMER_IRQ);
	else if (pending & CAUSEF_IP6) {	/* North Bridge, Perf counter */
		bonito_irqdispatch();
	} else if (pending & CAUSEF_IP3)	/* CPU UART */
		do_IRQ(LOONGSON_UART_IRQ);
	else if (pending & CAUSEF_IP2)	/* South Bridge */
		i8259_irqdispatch();
	else
		spurious_interrupt();
}

static irqreturn_t ip6_action(int cpl, void *dev_id)
{
	return IRQ_HANDLED;
}

void __init mach_init_irq(void)
{
	/* init all controller
	 *   0-15	  ------> i8259 interrupt
	 *   16-23	  ------> mips cpu interrupt
	 *   32-63	  ------> bonito irq
	 */

	/* setup cs5536 as high level trigger */
	LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1;
	LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1);

	/* Sets the first-level interrupt dispatcher. */
	mips_cpu_irq_init();
	init_i8259_irqs();
	bonito_irq_init();

	/* setup north bridge irq (bonito) */
	if (request_irq(LOONGSON_NORTH_BRIDGE_IRQ, ip6_action,
			IRQF_SHARED | IRQF_NO_THREAD, "cascade", ip6_action))
		pr_err("Failed to register north bridge cascade interrupt\n");
	/* setup source bridge irq (i8259) */
	if (request_irq(LOONGSON_SOUTH_BRIDGE_IRQ, no_action,
			IRQF_NO_THREAD | IRQF_NO_SUSPEND, "cascade", NULL))
		pr_err("Failed to register south bridge cascade interrupt\n");
}

Annotation

Implementation Notes