arch/arm/mach-omap1/irq.c

Source file repositories/reference/linux-study-clean/arch/arm/mach-omap1/irq.c

File Facts

System
Linux kernel
Corpus path
arch/arm/mach-omap1/irq.c
Extension
.c
Size
7543 bytes
Lines
259
Domain
Architecture Layer
Bucket
arch/arm
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

struct omap_irq_bank {
	unsigned long base_reg;
	void __iomem *va;
	unsigned long trigger_map;
	unsigned long wake_enable;
};

static u32 omap_l2_irq;
static unsigned int irq_bank_count;
static struct omap_irq_bank *irq_banks;
static struct irq_domain *domain;

static inline unsigned int irq_bank_readl(int bank, int offset)
{
	return readl_relaxed(irq_banks[bank].va + offset);
}
static inline void irq_bank_writel(unsigned long value, int bank, int offset)
{
	writel_relaxed(value, irq_banks[bank].va + offset);
}

static void omap_ack_irq(int irq)
{
	if (irq > 31)
		writel_relaxed(0x1, irq_banks[1].va + IRQ_CONTROL_REG_OFFSET);

	writel_relaxed(0x1, irq_banks[0].va + IRQ_CONTROL_REG_OFFSET);
}

static void omap_mask_ack_irq(struct irq_data *d)
{
	struct irq_chip_type *ct = irq_data_get_chip_type(d);

	ct->chip.irq_mask(d);
	omap_ack_irq(d->irq);
}

/*
 * Allows tuning the IRQ type and priority
 *
 * NOTE: There is currently no OMAP fiq handler for Linux. Read the
 *	 mailing list threads on FIQ handlers if you are planning to
 *	 add a FIQ handler for OMAP.
 */
static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger)
{
	signed int bank;
	unsigned long val, offset;

	bank = IRQ_BANK(irq);
	/* FIQ is only available on bank 0 interrupts */
	fiq = bank ? 0 : (fiq & 0x1);
	val = fiq | ((priority & 0x1f) << 2) | ((trigger & 0x1) << 1);
	offset = IRQ_ILR0_REG_OFFSET + IRQ_BIT(irq) * 0x4;
	irq_bank_writel(val, bank, offset);
}

#ifdef CONFIG_ARCH_OMAP15XX
static struct omap_irq_bank omap1510_irq_banks[] = {
	{ .base_reg = OMAP_IH1_BASE,		.trigger_map = 0xb3febfff },
	{ .base_reg = OMAP_IH2_BASE,		.trigger_map = 0xffbfffed },
};
static struct omap_irq_bank omap310_irq_banks[] = {
	{ .base_reg = OMAP_IH1_BASE,		.trigger_map = 0xb3faefc3 },
	{ .base_reg = OMAP_IH2_BASE,		.trigger_map = 0x65b3c061 },
};
#endif

#if defined(CONFIG_ARCH_OMAP16XX)

static struct omap_irq_bank omap1610_irq_banks[] = {
	{ .base_reg = OMAP_IH1_BASE,		.trigger_map = 0xb3fefe8f },
	{ .base_reg = OMAP_IH2_BASE,		.trigger_map = 0xfdb7c1fd },
	{ .base_reg = OMAP_IH2_BASE + 0x100,	.trigger_map = 0xffffb7ff },
	{ .base_reg = OMAP_IH2_BASE + 0x200,	.trigger_map = 0xffffffff },
};
#endif

asmlinkage void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs)
{
	void __iomem *l1 = irq_banks[0].va;
	void __iomem *l2 = irq_banks[1].va;
	u32 irqnr;

	do {
		irqnr = readl_relaxed(l1 + IRQ_ITR_REG_OFFSET);
		irqnr &= ~(readl_relaxed(l1 + IRQ_MIR_REG_OFFSET) & 0xffffffff);
		if (!irqnr)
			break;

Annotation

Implementation Notes