arch/mips/bcm63xx/irq.c

Source file repositories/reference/linux-study-clean/arch/mips/bcm63xx/irq.c

File Facts

System
Linux kernel
Corpus path
arch/mips/bcm63xx/irq.c
Extension
.c
Size
14428 bytes
Lines
554
Domain
Architecture Layer
Bucket
arch/mips
Inferred role
Architecture Layer: implementation source
Status
source 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 (pending[to_call / 32] & (1 << (to_call & 0x1f))) {	\
			handle_internal(to_call);			\
			break;						\
		}							\
	}								\
}									\
									\
static void __internal_irq_mask_##width(struct irq_data *d)		\
{									\
	u32 val;							\
	unsigned irq = d->irq - IRQ_INTERNAL_BASE;			\
	unsigned reg = (irq / 32) ^ (width/32 - 1);			\
	unsigned bit = irq & 0x1f;					\
	unsigned long flags;						\
	int cpu;							\
									\
	spin_lock_irqsave(&ipic_lock, flags);				\
	for_each_present_cpu(cpu) {					\
		if (!irq_mask_addr[cpu])				\
			break;						\
									\
		val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\
		val &= ~(1 << bit);					\
		bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\
	}								\
	spin_unlock_irqrestore(&ipic_lock, flags);			\
}									\
									\
static void __internal_irq_unmask_##width(struct irq_data *d,		\
					  const struct cpumask *m)	\
{									\
	u32 val;							\
	unsigned irq = d->irq - IRQ_INTERNAL_BASE;			\
	unsigned reg = (irq / 32) ^ (width/32 - 1);			\
	unsigned bit = irq & 0x1f;					\
	unsigned long flags;						\
	int cpu;							\
									\
	spin_lock_irqsave(&ipic_lock, flags);				\
	for_each_present_cpu(cpu) {					\
		if (!irq_mask_addr[cpu])				\
			break;						\
									\
		val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\
		if (enable_irq_for_cpu(cpu, d, m))			\
			val |= (1 << bit);				\
		else							\
			val &= ~(1 << bit);				\
		bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\
	}								\
	spin_unlock_irqrestore(&ipic_lock, flags);			\
}

BUILD_IPIC_INTERNAL(32);
BUILD_IPIC_INTERNAL(64);

asmlinkage void plat_irq_dispatch(void)
{
	u32 cause;

	do {
		cause = read_c0_cause() & read_c0_status() & ST0_IM;

		if (!cause)
			break;

		if (cause & CAUSEF_IP7)
			do_IRQ(7);
		if (cause & CAUSEF_IP0)
			do_IRQ(0);
		if (cause & CAUSEF_IP1)
			do_IRQ(1);
		if (cause & CAUSEF_IP2)
			dispatch_internal(0);
		if (is_ext_irq_cascaded) {
			if (cause & CAUSEF_IP3)
				dispatch_internal(1);
		} else {
			if (cause & CAUSEF_IP3)
				do_IRQ(IRQ_EXT_0);
			if (cause & CAUSEF_IP4)
				do_IRQ(IRQ_EXT_1);
			if (cause & CAUSEF_IP5)
				do_IRQ(IRQ_EXT_2);
			if (cause & CAUSEF_IP6)
				do_IRQ(IRQ_EXT_3);
		}
	} while (1);
}

Annotation

Implementation Notes