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

📄 irq.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	return;}static void irqlck_timeout(unsigned long _data){	struct irqdesc *desc = (struct irqdesc *)_data;	spin_lock(&irq_controller_lock);	del_timer(&desc->lck_timer);	desc->lck_cnt = 0;	desc->lck_pc  = 0;	desc->lck_jif = 0;	desc->lck_warned = -10;	if (desc->disable_depth == 0)		desc->unmask(desc - irq_desc);	spin_unlock(&irq_controller_lock);}#ifdef CONFIG_ARCH_ACORNvoid do_ecard_IRQ(int irq, struct pt_regs *regs){	struct irqdesc * desc;	struct irqaction * action;	int cpu;	desc = irq_desc + irq;	cpu = smp_processor_id();	kstat.irqs[cpu][irq]++;	desc->triggered = 1;	action = desc->action;	if (action) {		do {			action->handler(irq, action->dev_id, regs);			action = action->next;		} while (action);	} else {		spin_lock(&irq_controller_lock);		desc->mask(irq);		spin_unlock(&irq_controller_lock);	}}#endifint setup_arm_irq(int irq, struct irqaction * new){	int shared = 0;	struct irqaction *old, **p;	unsigned long flags;	struct irqdesc *desc;	/*	 * Some drivers like serial.c use request_irq() heavily,	 * so we have to be careful not to interfere with a	 * running system.	 */	if (new->flags & SA_SAMPLE_RANDOM) {		/*		 * This function might sleep, we want to call it first,		 * outside of the atomic block.		 * Yes, this might clear the entropy pool if the wrong		 * driver is attempted to be loaded, without actually		 * installing a new handler, but is this really a problem,		 * only the sysadmin is able to do this.		 */	        rand_initialize_irq(irq);	}	/*	 * The following block of code has to be executed atomically	 */	desc = irq_desc + irq;	spin_lock_irqsave(&irq_controller_lock, flags);	p = &desc->action;	if ((old = *p) != NULL) {		/* Can't share interrupts unless both agree to */		if (!(old->flags & new->flags & SA_SHIRQ)) {			spin_unlock_irqrestore(&irq_controller_lock, flags);			return -EBUSY;		}		/* add new interrupt at end of irq queue */		do {			p = &old->next;			old = *p;		} while (old);		shared = 1;	}	*p = new;	if (!shared) {		desc->probing = 0;		desc->running = 0;		desc->pending = 0;		desc->disable_depth = 1;		if (!desc->noautoenable) {			desc->disable_depth = 0;			desc->unmask(irq);		}	}	spin_unlock_irqrestore(&irq_controller_lock, flags);	return 0;}/** *	request_irq - allocate an interrupt line *	@irq: Interrupt line to allocate *	@handler: Function to be called when the IRQ occurs *	@irqflags: Interrupt type flags *	@devname: An ascii name for the claiming device *	@dev_id: A cookie passed back to the handler function * *	This call allocates interrupt resources and enables the *	interrupt line and IRQ handling. From the point this *	call is made your handler function may be invoked. Since *	your handler function must clear any interrupt the board *	raises, you must take care both to initialise your hardware *	and to set up the interrupt handler in the right order. * *	Dev_id must be globally unique. Normally the address of the *	device data structure is used as the cookie. Since the handler *	receives this value it makes sense to use it. * *	If your interrupt is shared you must pass a non NULL dev_id *	as this is required when freeing the interrupt. * *	Flags: * *	SA_SHIRQ		Interrupt is shared * *	SA_INTERRUPT		Disable local interrupts while processing * *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy * */int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),		 unsigned long irq_flags, const char * devname, void *dev_id){	unsigned long retval;	struct irqaction *action;	if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||	    (irq_flags & SA_SHIRQ && !dev_id))		return -EINVAL;	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);	if (!action)		return -ENOMEM;	action->handler = handler;	action->flags = irq_flags;	action->mask = 0;	action->name = devname;	action->next = NULL;	action->dev_id = dev_id;	retval = setup_arm_irq(irq, action);	if (retval)		kfree(action);	return retval;}/** *	free_irq - free an interrupt *	@irq: Interrupt line to free *	@dev_id: Device identity to free * *	Remove an interrupt handler. The handler is removed and if the *	interrupt line is no longer in use by any driver it is disabled. *	On a shared IRQ the caller must ensure the interrupt is disabled *	on the card it drives before calling this function. * *	This function must not be called from interrupt context. */void free_irq(unsigned int irq, void *dev_id){	struct irqaction * action, **p;	unsigned long flags;	if (irq >= NR_IRQS || !irq_desc[irq].valid) {		printk(KERN_ERR "Trying to free IRQ%d\n",irq);#ifdef CONFIG_DEBUG_ERRORS		__backtrace();#endif		return;	}	spin_lock_irqsave(&irq_controller_lock, flags);	for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) {		if (action->dev_id != dev_id)			continue;	    	/* Found it - now free it */		*p = action->next;		kfree(action);		goto out;	}	printk(KERN_ERR "Trying to free free IRQ%d\n",irq);#ifdef CONFIG_DEBUG_ERRORS	__backtrace();#endifout:	spin_unlock_irqrestore(&irq_controller_lock, flags);}static DECLARE_MUTEX(probe_sem);/* Start the interrupt probing.  Unlike other architectures, * we don't return a mask of interrupts from probe_irq_on, * but return the number of interrupts enabled for the probe. * The interrupts which have been enabled for probing is * instead recorded in the irq_desc structure. */unsigned long probe_irq_on(void){	unsigned int i, irqs = 0;	unsigned long delay;	down(&probe_sem);	/*	 * first snaffle up any unassigned but	 * probe-able interrupts	 */	spin_lock_irq(&irq_controller_lock);	for (i = 0; i < NR_IRQS; i++) {		if (!irq_desc[i].probe_ok || irq_desc[i].action)			continue;		irq_desc[i].probing = 1;		irq_desc[i].triggered = 0;		irq_desc[i].unmask(i);		irqs += 1;	}	spin_unlock_irq(&irq_controller_lock);	/*	 * wait for spurious interrupts to mask themselves out again	 */	for (delay = jiffies + HZ/10; time_before(jiffies, delay); )		/* min 100ms delay */;	/*	 * now filter out any obviously spurious interrupts	 */	spin_lock_irq(&irq_controller_lock);	for (i = 0; i < NR_IRQS; i++) {		if (irq_desc[i].probing && irq_desc[i].triggered) {			irq_desc[i].probing = 0;			irqs -= 1;		}	}	spin_unlock_irq(&irq_controller_lock);	return irqs;}unsigned int probe_irq_mask(unsigned long irqs){	unsigned int mask = 0, i;	spin_lock_irq(&irq_controller_lock);	for (i = 0; i < 16 && i < NR_IRQS; i++)		if (irq_desc[i].probing && irq_desc[i].triggered)			mask |= 1 << i;	spin_unlock_irq(&irq_controller_lock);	up(&probe_sem);	return mask;}/* * Possible return values: *  >= 0 - interrupt number *    -1 - no interrupt/many interrupts */int probe_irq_off(unsigned long irqs){	unsigned int i;	int irq_found = NO_IRQ;	/*	 * look at the interrupts, and find exactly one	 * that we were probing has been triggered	 */	spin_lock_irq(&irq_controller_lock);	for (i = 0; i < NR_IRQS; i++) {		if (irq_desc[i].probing &&		    irq_desc[i].triggered) {			if (irq_found != NO_IRQ) {				irq_found = NO_IRQ;				goto out;			}			irq_found = i;		}	}	if (irq_found == -1)		irq_found = NO_IRQ;out:	spin_unlock_irq(&irq_controller_lock);	up(&probe_sem);	return irq_found;}void __init init_irq_proc(void){}void __init init_IRQ(void){	extern void init_dma(void);	int irq;	for (irq = 0; irq < NR_IRQS; irq++) {		irq_desc[irq].disable_depth = 1;		irq_desc[irq].probe_ok = 0;		irq_desc[irq].valid    = 0;		irq_desc[irq].noautoenable = 0;		irq_desc[irq].mask_ack = dummy_mask_unmask_irq;		irq_desc[irq].mask     = dummy_mask_unmask_irq;		irq_desc[irq].unmask   = dummy_mask_unmask_irq;		INIT_LIST_HEAD(&irq_desc[irq].pend);		init_timer(&irq_desc[irq].lck_timer);		irq_desc[irq].lck_timer.data = (unsigned long)&irq_desc[irq];		irq_desc[irq].lck_timer.function = irqlck_timeout;	}	init_arch_irq();	init_dma();}

⌨️ 快捷键说明

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