drivers/irqchip/irq-clps711x.c

Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-clps711x.c

File Facts

System
Linux kernel
Corpus path
drivers/irqchip/irq-clps711x.c
Extension
.c
Size
5957 bytes
Lines
228
Domain
Driver Families
Bucket
drivers/irqchip
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  CLPS711X IRQ driver
 *
 *  Copyright (C) 2013 Alexander Shiyan <shc_work@mail.ru>
 */

#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/slab.h>

#include <asm/exception.h>
#include <asm/mach/irq.h>

#define CLPS711X_INTSR1	(0x0240)
#define CLPS711X_INTMR1	(0x0280)
#define CLPS711X_BLEOI	(0x0600)
#define CLPS711X_MCEOI	(0x0640)
#define CLPS711X_TEOI	(0x0680)
#define CLPS711X_TC1EOI	(0x06c0)
#define CLPS711X_TC2EOI	(0x0700)
#define CLPS711X_RTCEOI	(0x0740)
#define CLPS711X_UMSEOI	(0x0780)
#define CLPS711X_COEOI	(0x07c0)
#define CLPS711X_INTSR2	(0x1240)
#define CLPS711X_INTMR2	(0x1280)
#define CLPS711X_SRXEOF	(0x1600)
#define CLPS711X_KBDEOI	(0x1700)
#define CLPS711X_INTSR3	(0x2240)
#define CLPS711X_INTMR3	(0x2280)

static const struct {
#define CLPS711X_FLAG_EN	(1 << 0)
#define CLPS711X_FLAG_FIQ	(1 << 1)
	unsigned int	flags;
	phys_addr_t	eoi;
} clps711x_irqs[] = {
	[1]	= { CLPS711X_FLAG_FIQ, CLPS711X_BLEOI, },
	[3]	= { CLPS711X_FLAG_FIQ, CLPS711X_MCEOI, },
	[4]	= { CLPS711X_FLAG_EN, CLPS711X_COEOI, },
	[5]	= { CLPS711X_FLAG_EN, },
	[6]	= { CLPS711X_FLAG_EN, },
	[7]	= { CLPS711X_FLAG_EN, },
	[8]	= { CLPS711X_FLAG_EN, CLPS711X_TC1EOI, },
	[9]	= { CLPS711X_FLAG_EN, CLPS711X_TC2EOI, },
	[10]	= { CLPS711X_FLAG_EN, CLPS711X_RTCEOI, },
	[11]	= { CLPS711X_FLAG_EN, CLPS711X_TEOI, },
	[12]	= { CLPS711X_FLAG_EN, },
	[13]	= { CLPS711X_FLAG_EN, },
	[14]	= { CLPS711X_FLAG_EN, CLPS711X_UMSEOI, },
	[15]	= { CLPS711X_FLAG_EN, CLPS711X_SRXEOF, },
	[16]	= { CLPS711X_FLAG_EN, CLPS711X_KBDEOI, },
	[17]	= { CLPS711X_FLAG_EN, },
	[18]	= { CLPS711X_FLAG_EN, },
	[28]	= { CLPS711X_FLAG_EN, },
	[29]	= { CLPS711X_FLAG_EN, },
	[32]	= { CLPS711X_FLAG_FIQ, },
};

static struct {
	void __iomem		*base;
	void __iomem		*intmr[3];
	void __iomem		*intsr[3];
	struct irq_domain	*domain;
	struct irq_domain_ops	ops;
} *clps711x_intc;

static void __exception_irq_entry clps711x_irqh(struct pt_regs *regs)
{
	u32 irqstat;

	do {
		irqstat = readw_relaxed(clps711x_intc->intmr[0]) &
			  readw_relaxed(clps711x_intc->intsr[0]);
		if (irqstat)
			generic_handle_domain_irq(clps711x_intc->domain,
						  fls(irqstat) - 1);

		irqstat = readw_relaxed(clps711x_intc->intmr[1]) &
			  readw_relaxed(clps711x_intc->intsr[1]);
		if (irqstat)
			generic_handle_domain_irq(clps711x_intc->domain,
						  fls(irqstat) - 1 + 16);
	} while (irqstat);
}

Annotation

Implementation Notes