⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irq_txx9.c

📁 linux 内核源代码
💻 C
字号:
/* * linux/arch/mips/kernel/irq_txx9.c * * Based on linux/arch/mips/jmr3927/rbhma3100/irq.c, *          linux/arch/mips/tx4927/common/tx4927_irq.c, *          linux/arch/mips/tx4938/common/irq.c * * Copyright 2001, 2003-2005 MontaVista Software Inc. * Author: MontaVista Software, Inc. *         ahennessy@mvista.com *         source@mvista.com * Copyright (C) 2000-2001 Toshiba Corporation * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. */#include <linux/init.h>#include <linux/interrupt.h>#include <linux/types.h>#include <asm/txx9irq.h>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	1static 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(unsigned int irq){	unsigned int irq_nr = 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);#ifdef CONFIG_CPU_TX39XX	/* update IRCSR */	__raw_writel(0, &txx9_ircptr->imr);	__raw_writel(irc_elevel, &txx9_ircptr->imr);#endif}static inline void txx9_irq_mask(unsigned int irq){	unsigned int irq_nr = 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);#ifdef CONFIG_CPU_TX39XX	/* update IRCSR */	__raw_writel(0, &txx9_ircptr->imr);	__raw_writel(irc_elevel, &txx9_ircptr->imr);	/* flush write buffer */	__raw_readl(&txx9_ircptr->ssr);#else	mmiowb();#endif}static void txx9_irq_mask_ack(unsigned int irq){	unsigned int irq_nr = irq - TXX9_IRQ_BASE;	txx9_irq_mask(irq);	/* 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(unsigned int irq, unsigned int flow_type){	unsigned int irq_nr = 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;	case IRQF_TRIGGER_HIGH:	mode = TXx9_IRCR_HIGH;	break;	case IRQF_TRIGGER_LOW:	mode = TXx9_IRCR_LOW;	break;	default:		return -EINVAL;	}	crp = &txx9_ircptr->cr[(unsigned int)irq_nr / 8];	cr = __raw_readl(crp);	ofs = (irq_nr & (8 - 1)) * 2;	cr &= ~(0x3 << ofs);	cr |= (mode & 0x3) << ofs;	__raw_writel(cr, crp);	txx9irq[irq_nr].mode = mode;	return 0;}static struct irq_chip txx9_irq_chip = {	.name		= "TXX9",	.ack		= txx9_irq_mask_ack,	.mask		= txx9_irq_mask,	.mask_ack	= txx9_irq_mask_ack,	.unmask		= txx9_irq_unmask,	.set_type	= txx9_irq_set_type,};void __init txx9_irq_init(unsigned long baseaddr){	int i;	txx9_ircptr = ioremap(baseaddr, sizeof(struct txx9_irc_reg));	for (i = 0; i < TXx9_MAX_IR; i++) {		txx9irq[i].level = 4; /* middle level */		txx9irq[i].mode = TXx9_IRCR_LOW;		set_irq_chip_and_handler(TXX9_IRQ_BASE + i,					 &txx9_irq_chip, handle_level_irq);	}	/* mask all IRC interrupts */	__raw_writel(0, &txx9_ircptr->imr);	for (i = 0; i < 8; i++)		__raw_writel(0, &txx9_ircptr->ilr[i]);	/* setup IRC interrupt mode (Low Active) */	for (i = 0; i < 2; i++)		__raw_writel(0, &txx9_ircptr->cr[i]);	/* enable interrupt control */	__raw_writel(TXx9_IRCER_ICE, &txx9_ircptr->cer);	__raw_writel(irc_elevel, &txx9_ircptr->imr);}int __init txx9_irq_set_pri(int irc_irq, int new_pri){	int old_pri;	if ((unsigned int)irc_irq >= TXx9_MAX_IR)		return 0;	old_pri = txx9irq[irc_irq].level;	txx9irq[irc_irq].level = new_pri;	return old_pri;}int txx9_irq(void){	u32 csr = __raw_readl(&txx9_ircptr->csr);	if (likely(!(csr & TXx9_IRCSR_IF)))		return TXX9_IRQ_BASE + (csr & (TXx9_MAX_IR - 1));	return -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -