arch/mips/kernel/irq_txx9.c

Source file repositories/reference/linux-study-clean/arch/mips/kernel/irq_txx9.c

File Facts

System
Linux kernel
Corpus path
arch/mips/kernel/irq_txx9.c
Extension
.c
Size
4526 bytes
Lines
179
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

struct txx9_irc_reg {
	u32 cer;
	u32 cr[2];
	u32 unused0;
	u32 ilr[8];
	u32 unused1[4];
	u32 imr;
	u32 unused2[7];
	u32 scr;
	u32 unused3[7];
	u32 ssr;
	u32 unused4[7];
	u32 csr;
};

/* IRCER : Int. Control Enable */
#define TXx9_IRCER_ICE	0x00000001

/* IRCR : Int. Control */
#define TXx9_IRCR_LOW	0x00000000
#define TXx9_IRCR_HIGH	0x00000001
#define TXx9_IRCR_DOWN	0x00000002
#define TXx9_IRCR_UP	0x00000003
#define TXx9_IRCR_EDGE(cr)	((cr) & 0x00000002)

/* IRSCR : Int. Status Control */
#define TXx9_IRSCR_EIClrE	0x00000100
#define TXx9_IRSCR_EIClr_MASK	0x0000000f

/* IRCSR : Int. Current Status */
#define TXx9_IRCSR_IF	0x00010000
#define TXx9_IRCSR_ILV_MASK	0x00000700
#define TXx9_IRCSR_IVL_MASK	0x0000001f

#define irc_dlevel	0
#define irc_elevel	1

static struct txx9_irc_reg __iomem *txx9_ircptr __read_mostly;

static struct {
	unsigned char level;
	unsigned char mode;
} txx9irq[TXx9_MAX_IR] __read_mostly;

static void txx9_irq_unmask(struct irq_data *d)
{
	unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
	u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16 ) / 2];
	int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;

	__raw_writel((__raw_readl(ilrp) & ~(0xff << ofs))
		     | (txx9irq[irq_nr].level << ofs),
		     ilrp);
}

static inline void txx9_irq_mask(struct irq_data *d)
{
	unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
	u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16) / 2];
	int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;

	__raw_writel((__raw_readl(ilrp) & ~(0xff << ofs))
		     | (irc_dlevel << ofs),
		     ilrp);
	mmiowb();
}

static void txx9_irq_mask_ack(struct irq_data *d)
{
	unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;

	txx9_irq_mask(d);
	/* clear edge detection */
	if (unlikely(TXx9_IRCR_EDGE(txx9irq[irq_nr].mode)))
		__raw_writel(TXx9_IRSCR_EIClrE | irq_nr, &txx9_ircptr->scr);
}

static int txx9_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
	unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
	u32 cr;
	u32 __iomem *crp;
	int ofs;
	int mode;

	if (flow_type & IRQF_TRIGGER_PROBE)
		return 0;
	switch (flow_type & IRQF_TRIGGER_MASK) {
	case IRQF_TRIGGER_RISING:	mode = TXx9_IRCR_UP;	break;
	case IRQF_TRIGGER_FALLING:	mode = TXx9_IRCR_DOWN;	break;

Annotation

Implementation Notes