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

📄 irq.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
		handle = do_bad_IRQ;	desc = irq_desc + irq;	if (is_chained && desc->chip == &bad_chip)		printk(KERN_WARNING "Trying to install chained handler for IRQ%d\n", irq);	spin_lock_irqsave(&irq_controller_lock, flags);	if (handle == do_bad_IRQ) {		desc->chip->mask(irq);		desc->chip->ack(irq);		desc->depth = 1;		desc->enabled = 0;	}	desc->handle = handle;	if (handle != do_bad_IRQ && is_chained) {		desc->valid = 0;		desc->probe_ok = 0;		desc->depth = 0;		desc->chip->unmask(irq);	}	spin_unlock_irqrestore(&irq_controller_lock, flags);}void set_irq_chip(unsigned int irq, struct irqchip *chip){	struct irqdesc *desc;	unsigned long flags;	if (irq >= NR_IRQS) {		printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);		return;	}	if (chip == NULL)		chip = &bad_chip;	desc = irq_desc + irq;	spin_lock_irqsave(&irq_controller_lock, flags);	desc->chip = chip;	spin_unlock_irqrestore(&irq_controller_lock, flags);}int set_irq_type(unsigned int irq, unsigned int type){	struct irqdesc *desc;	unsigned long flags;	int ret = -ENXIO;	if (irq >= NR_IRQS) {		printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);		return -ENODEV;	}	desc = irq_desc + irq;	if (desc->chip->type) {		spin_lock_irqsave(&irq_controller_lock, flags);		ret = desc->chip->type(irq, type);		spin_unlock_irqrestore(&irq_controller_lock, flags);	}	return ret;}void set_irq_flags(unsigned int irq, unsigned int iflags){	struct irqdesc *desc;	unsigned long flags;	if (irq >= NR_IRQS) {		printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq);		return;	}	desc = irq_desc + irq;	spin_lock_irqsave(&irq_controller_lock, flags);	desc->valid = (iflags & IRQF_VALID) != 0;	desc->probe_ok = (iflags & IRQF_PROBE) != 0;	desc->noautoenable = (iflags & IRQF_NOAUTOEN) != 0;	spin_unlock_irqrestore(&irq_controller_lock, flags);}int setup_irq(unsigned 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->depth = 1;		if (!desc->noautoenable) {			desc->depth = 0;			desc->enabled = 1;			desc->chip->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 * *///FIXME - handler used to return void - whats the significance of the change?int request_irq(unsigned int irq, irqreturn_t (*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;	cpus_clear(action->mask);	action->name = devname;	action->next = NULL;	action->dev_id = dev_id;	retval = setup_irq(irq, action);	if (retval)		kfree(action);	return retval;}EXPORT_SYMBOL(request_irq);/** *	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 may 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);}EXPORT_SYMBOL(free_irq);/* 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;	/*	 * 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;		if (irq_desc[i].chip->type)			irq_desc[i].chip->type(i, IRQT_PROBE);		irq_desc[i].chip->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;}EXPORT_SYMBOL(probe_irq_on);/* * 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);	return irq_found;}EXPORT_SYMBOL(probe_irq_off);void __init init_irq_proc(void){}void __init init_IRQ(void){	struct irqdesc *desc;	extern void init_dma(void);	int irq;	for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++)		*desc = bad_irq_desc;	arc_init_irq();	init_dma();}

⌨️ 快捷键说明

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