int M68328_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { if (irq >= INTERNAL_IRQS) { printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname); return -ENXIO; } if (!int_irq_list[irq]) { int_irq_list[irq] = new_irq_node(); int_irq_list[irq]->flags = IRQ_FLG_STD; } if (!(int_irq_list[irq]->flags & IRQ_FLG_STD)) { if (int_irq_list[irq]->flags & IRQ_FLG_LOCK) { printk("%s: IRQ %d from %s is not replaceable\n", __FUNCTION__, irq, int_irq_list[irq]->devname); return -EBUSY; } if (flags & IRQ_FLG_REPLACE) { printk("%s: %s can't replace IRQ %d from %s\n", __FUNCTION__, devname, irq, int_irq_list[irq]->devname); return -EBUSY; } } int_irq_list[irq]->handler = handler; int_irq_list[irq]->flags = flags; int_irq_list[irq]->dev_id = dev_id; int_irq_list[irq]->devname = devname; /* enable in the IMR */ if (!int_irq_ablecount[irq]) *(volatile unsigned long *)0xfffff304 &= ~(1<<irq); return 0; }
int atari_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { int vector; unsigned long oflags = flags; /* * The following is a hack to make some PCI card drivers work, * which set the SA_SHIRQ flag. */ flags &= ~SA_SHIRQ; if (flags == SA_INTERRUPT) { printk ("%s: SA_INTERRUPT changed to IRQ_TYPE_SLOW for %s\n", __FUNCTION__, devname); flags = IRQ_TYPE_SLOW; } if (flags < IRQ_TYPE_SLOW || flags > IRQ_TYPE_PRIO) { printk ("%s: Bad irq type 0x%lx <0x%lx> requested from %s\n", __FUNCTION__, flags, oflags, devname); return -EINVAL; } if (!IS_VALID_INTNO(irq)) { printk ("%s: Unknown irq %d requested from %s\n", __FUNCTION__, irq, devname); return -ENXIO; } vector = IRQ_SOURCE_TO_VECTOR(irq); /* * Check type/source combination: slow ints are (currently) * only possible for MFP-interrupts. */ if (flags == IRQ_TYPE_SLOW && (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE)) { printk ("%s: Slow irq requested for non-MFP source %d from %s\n", __FUNCTION__, irq, devname); return -EINVAL; } if (vectors[vector] == bad_interrupt) { /* int has no handler yet */ irq_handler[irq].handler = handler; irq_handler[irq].dev_id = dev_id; irq_param[irq].flags = flags; irq_param[irq].devname = devname; vectors[vector] = (flags == IRQ_TYPE_SLOW) ? slow_handlers[irq-STMFP_SOURCE_BASE] : (flags == IRQ_TYPE_FAST) ? atari_fast_irq_handler : atari_prio_irq_handler; /* If MFP int, also enable and umask it */ atari_turnon_irq(irq); atari_enable_irq(irq); return 0; } else if (irq_param[irq].flags == flags) { /* old handler is of same type -> handlers can be chained */ irq_node_t *node; unsigned long flags; save_flags(flags); cli(); if (irq_handler[irq].handler != atari_call_irq_list) { /* Only one handler yet, make a node for this first one */ if (!(node = new_irq_node())) return -ENOMEM; node->handler = irq_handler[irq].handler; node->dev_id = irq_handler[irq].dev_id; node->devname = irq_param[irq].devname; node->next = NULL; irq_handler[irq].handler = atari_call_irq_list; irq_handler[irq].dev_id = node; irq_param[irq].devname = "chained"; } if (!(node = new_irq_node())) return -ENOMEM; node->handler = handler; node->dev_id = dev_id; node->devname = devname; /* new handlers are put in front of the queue */ node->next = irq_handler[irq].dev_id; irq_handler[irq].dev_id = node; restore_flags(flags); return 0; } else { printk ("%s: Irq %d allocated by other type int (call from %s)\n", __FUNCTION__, irq, devname); return -EBUSY; } }