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

📄 irq.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
字号:
/* * Code to handle irqs on Orion boards *  -- Cort <cort@fsmlabs.com> */#include <linux/errno.h>#include <linux/init.h>#include <linux/kernel_stat.h>#include <linux/module.h>#include <linux/signal.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/interrupt.h>#include <linux/ioport.h>#include <linux/timex.h>#include <linux/malloc.h>#include <linux/random.h>#include <asm/bitops.h>#include <asm/bootinfo.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/mipsregs.h>#include <asm/system.h>#include <asm/orion.h>void (*board_time_init)(struct irqaction *irq);extern asmlinkage void orionIRQ(void);unsigned long spurious_count = 0;irq_desc_t irq_desc[NR_IRQS];static void galileo_ack(unsigned int irq_nr){	*((unsigned long *) (((unsigned)( 0x14000000  )|0xA0000000)   + 0xC18) ) = (((( 0 )&0xff)<<24)+	((( 0 )&0xff00)<<8)+	((( 0 )&0xff0000)>>8)+	((( 0 )&0xff000000)>>24))  ;}struct hw_interrupt_type galileo_pic = {        " Galileo  ",        NULL,        NULL,        NULL, /* unmask_irq */        NULL, /* mask_irq */        galileo_ack, /* mask_and_ack */        0};/* Function for careful CP0 interrupt mask access */static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask){	unsigned long status = read_32bit_cp0_register(CP0_STATUS);	status &= ~((clr_mask & 0xFF) << 8);	status |=   (set_mask & 0xFF) << 8;	write_32bit_cp0_register(CP0_STATUS, status);}static inline void mask_irq(unsigned int irq_nr){        modify_cp0_intmask(irq_nr, 0);}static inline void unmask_irq(unsigned int irq_nr){	modify_cp0_intmask(0, irq_nr);}void disable_irq(unsigned int irq_nr){	unsigned long flags;	save_and_cli(flags);	mask_irq(irq_nr);	restore_flags(flags);}void enable_irq(unsigned int irq_nr){	unsigned long flags;	save_and_cli(flags);	unmask_irq(irq_nr);	restore_flags(flags);}/*static struct irqaction *irq_action[NR_IRQS] = {	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};*/void __init orion_time_init(struct irqaction *irq){	__u32 timer_count;		irq_desc[2].handler = &galileo_pic;	irq_desc[2].action = irq;		/* This code was provided by the CoSine guys and despite its	 * appearance init's the timer.	 * -- Cort	 */	*((__u32 *) (((unsigned)( 0x14000000  )|0xA0000000)   + 0x864) ) = (((( 0 )&0xff)<<24)+	((( 0 )&0xff00)<<8)+	((( 0 )&0xff0000)>>8)+	((( 0 )&0xff000000)>>24)) ;		*((__u32 *) (((unsigned)( 0x14000000  )|0xA0000000)   + 0x850) ) = (((( 0 )&0xff)<<24)+	((( 0 )&0xff00)<<8)+	((( 0 )&0xff0000)>>8)+	((( 0 )&0xff000000)>>24)) ;        timer_count = 300000000/100;		*((__u32 *) (((unsigned)( 0x14000000  )|0xA0000000)   + 0x850) ) = ((((  timer_count  )&0xff)<<24)+	(((  timer_count  )&0xff00)<<8)+	(((  timer_count  )&0xff0000)>>8)+	(((  timer_count  )&0xff000000)>>24))  ;	*((__u32 *) (((unsigned)( 0x14000000  )|0xA0000000)   + 0xC1C) ) = ((((  0x100   )&0xff)<<24)+	(((  0x100   )&0xff00)<<8)+	(((  0x100   )&0xff0000)>>8)+	(((  0x100   )&0xff000000)>>24))  ;     	*((__u32 *) (((unsigned)( 0x14000000  )|0xA0000000)   + 0x864) ) = ((((  0x03  )&0xff)<<24)+	(((  0x03  )&0xff00)<<8)+	(((  0x03  )&0xff0000)>>8)+	(((  0x03  )&0xff000000)>>24))  ;     	*((__u32 *) (((unsigned)( 0x14000000  )|0xA0000000)   + 0xC18) ) = (((( 0 )&0xff)<<24)+	((( 0 )&0xff00)<<8)+	((( 0 )&0xff0000)>>8)+	((( 0 )&0xff000000)>>24))  ;}int get_irq_list(char *buf){	int i, len = 0, j;	struct irqaction * action;	len += sprintf(buf+len, "           ");	for (j=0; j<smp_num_cpus; j++)		len += sprintf(buf+len, "CPU%d       ",j);	*(char *)(buf+len++) = '\n';	for (i = 0 ; i < NR_IRQS ; i++) {		action = irq_desc[i].action;		if ( !action || !action->handler )			continue;		len += sprintf(buf+len, "%3d: ", i);				len += sprintf(buf+len, "%10u ", kstat_irqs(i));		if ( irq_desc[i].handler )					len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename );		else			len += sprintf(buf+len, "  None      ");		len += sprintf(buf+len, "    %s",action->name);		for (action=action->next; action; action = action->next) {			len += sprintf(buf+len, ", %s", action->name);		}		len += sprintf(buf+len, "\n");	}	len += sprintf(buf+len, "BAD: %10lu\n", spurious_count);	return len;}asmlinkage void do_IRQ(int irq, struct pt_regs * regs){	struct irqaction *action;	int do_random, cpu;	int status;	cpu = smp_processor_id();	irq_enter(cpu);	kstat.irqs[cpu][irq]++;	status = 0;	if (irq_desc[irq].handler->ack)		irq_desc[irq].handler->ack(irq);		action = irq_desc[irq].action;	if (action && action->handler)	{		if (!(action->flags & SA_INTERRUPT))			__sti();		do { 			status |= action->flags;			action->handler(irq, action->dev_id, regs);			action = action->next;		} while ( action );		__cli();		if (irq_desc[irq].handler)		{			if (irq_desc[irq].handler->end)				irq_desc[irq].handler->end(irq);			else if (irq_desc[irq].handler->enable)				irq_desc[irq].handler->enable(irq);		}	}	irq_exit(cpu);	if (softirq_active(cpu)&softirq_mask(cpu))		do_softirq();	/* unmasking and bottom half handling is done magically for us. */}int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),	unsigned long irqflags, const char * devname, void *dev_id){	struct irqaction *old, **p, *action;	unsigned long flags;	if (irq >= NR_IRQS)		return -EINVAL;	if (!handler)	{		/* Free */		for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next)		{			/* Found it - now free it */			save_flags(flags);			cli();			*p = action->next;			restore_flags(flags);			kfree(action);			return 0;		}		return -ENOENT;	}		action = (struct irqaction *)		kmalloc(sizeof(struct irqaction), GFP_KERNEL);	if (!action)		return -ENOMEM;		save_flags(flags);	cli();		action->handler = handler;	action->flags = irqflags;						action->mask = 0;	action->name = devname;	action->dev_id = dev_id;	action->next = NULL;	enable_irq(irq);		p = &irq_desc[irq].action;		if ((old = *p) != NULL) {		/* Can't share interrupts unless both agree to */		if (!(old->flags & action->flags & SA_SHIRQ))			return -EBUSY;		/* add new interrupt at end of irq queue */		do {			p = &old->next;			old = *p;		} while (old);	}	*p = action;	restore_flags(flags);		return 0;}		void free_irq(unsigned int irq, void *dev_id){	request_irq(irq, NULL, 0, NULL, dev_id);}unsigned long probe_irq_on (void){	return 0;}int probe_irq_off (unsigned long irqs){	return 0;}int (*irq_cannonicalize)(int irq);int orion_irq_cannonicalize(int i){	return i;}void __init init_IRQ(void){		irq_cannonicalize = orion_irq_cannonicalize;	set_except_vector(0, orionIRQ);}EXPORT_SYMBOL(irq_cannonicalize);

⌨️ 快捷键说明

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