Пример #1
0
void free_irq(unsigned int irq, void *dev_id)
{
	struct irqaction * action, **p;
	unsigned long flags;

	if (irq >= NR_IRQS) {
		printk("Trying to free IRQ%d\n",irq);
		return;
	}
	if (IS_RESERVED_IRQ(irq)) {
		printk("Trying to free reserved IRQ %d\n", irq);
		return;
	}
	for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
		if (action->dev_id != dev_id)
			continue;

		/* Found it - now free it */
		save_flags(flags);
		cli();
		*p = action->next;
		if (!irq[irq_action])
			mask_irq(irq);
		restore_flags(flags);
		kfree(action);
		return;
	}
	printk("Trying to free free IRQ%d\n",irq);
}
Пример #2
0
int request_irq(unsigned int irq, 
		void (*handler)(int, void *, struct pt_regs *),
		unsigned long irqflags, 
		const char * devname,
		void *dev_id)
{
	int shared = 0;
	struct irqaction * action, **p;
	unsigned long flags;

	if (irq >= NR_IRQS)
		return -EINVAL;
	if (IS_RESERVED_IRQ(irq))
		return -EINVAL;
	if (!handler)
		return -EINVAL;
	p = irq_action + irq;
	action = *p;
	if (action) {
		/* Can't share interrupts unless both agree to */
		if (!(action->flags & irqflags & SA_SHIRQ))
			return -EBUSY;

		/* Can't share interrupts unless both are same type */
		if ((action->flags ^ irqflags) & SA_INTERRUPT)
			return -EBUSY;

		/* add new interrupt at end of irq queue */
		do {
			p = &action->next;
			action = *p;
		} while (action);
		shared = 1;
	}

	action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
					     GFP_KERNEL);
	if (!action)
		return -ENOMEM;

	if (irqflags & SA_SAMPLE_RANDOM)
		rand_initialize_irq(irq);

	action->handler = handler;
	action->flags = irqflags;
	action->mask = 0;
	action->name = devname;
	action->next = NULL;
	action->dev_id = dev_id;

	save_flags(flags);
	cli();
	*p = action;

	if (!shared)
		unmask_irq(irq);

	restore_flags(flags);
	return 0;
}
Пример #3
0
/*
 * Routine to check and install requested interrupt. Just sets up logical
 * structures, doesn't alter interrupts at all.
 */
int uHALr_RequestInterrupt(unsigned int intNum,
                           PrHandler handler, const unsigned char *devname)
{
    struct uHALis_IRQ *action;

    if (intNum >= NR_IRQS)
        return -1;
    if (IS_RESERVED_IRQ(intNum))
        return -1;
    if (!handler)
        return -1;

    action = &uHALv_IRQVector[intNum];

    /* Can't share interrupts (yet) */
    if (action->handler)
        return -1;

    action->handler = handler;
    action->name = devname;
    action->flags = 0;
    action->mask = 0;
    action->next = 0;

    return 0;
}
Пример #4
0
/* Call this routine before trying to change the routine attached to an IRQ */
int uHALr_FreeInterrupt(unsigned int intNum)
{
    if (intNum >= NR_IRQS)
    {
        uHALr_printf("Can't free Interrupt %d\n", intNum);
        return -1;
    }

    if (IS_RESERVED_IRQ(intNum))
    {
        uHALr_printf("Can't free reserved Interrupt %d\n", intNum);
        return -1;
    }

    // Disable the interrupt & then remove the handler
    uHALr_DisableInterrupt(intNum);
    uHALv_IRQVector[intNum].handler = (PrHandler) 0;

#ifdef DEBUG
    uHALr_printf("free'd Interrupt %d\n", intNum);
#endif

    return 0;
}