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; }
/* * Implementation */ void HookIrqs() { if(HookIrqNo(options.irq) == -1) Error("Attach to %d failed: [%d] %s\n", options.irq, ERR(errno)); if(!rand_initialize_irq(options.irq)) { Error("Attach to %d failed: [%d] %s\n", options.irq, ERR(ENOMEM)); } }
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { irq_handler_t *irq_handle; int bitmask; if (irq < 0 || irq >= NR_IRQS) { printk("Incorrect IRQ %d from %s\n", irq, devname); return -EINVAL; } if (irq_list[irq]) return -EBUSY; /* already used */ /* initialize IRQ pin */ bitmask = 1 << (irq - EXT_IRQ0); switch(irq) { case EXT_IRQ0: case EXT_IRQ1: case EXT_IRQ2: case EXT_IRQ3: if (H8300_GPIO_RESERVE(H8300_GPIO_P8, bitmask) == 0) return -EBUSY; H8300_GPIO_DDR(H8300_GPIO_P8, bitmask, H8300_GPIO_INPUT); break; case EXT_IRQ4: case EXT_IRQ5: if (H8300_GPIO_RESERVE(H8300_GPIO_P9, bitmask) == 0) return -EBUSY; H8300_GPIO_DDR(H8300_GPIO_P9, bitmask, H8300_GPIO_INPUT); break; } if(use_kmalloc) irq_handle = (irq_handler_t *)kmalloc(sizeof(irq_handler_t), GFP_ATOMIC); else { irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t)); (unsigned long)irq_handle |= 0x80000000UL; } if (irq_handle == NULL) return -ENOMEM; irq_handle->handler = handler; irq_handle->flags = flags; irq_handle->count = 0; irq_handle->dev_id = dev_id; irq_handle->devname = devname; irq_list[irq] = irq_handle; if (irq_handle->flags & SA_SAMPLE_RANDOM) rand_initialize_irq(irq); /* enable interrupt */ /* compatible i386 */ if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5) *(volatile unsigned char *)IER |= bitmask; return 0; }
int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { unsigned short ptn = 1 << (irq - EXT_IRQ0); irq_handler_t *irq_handle; if (irq < 0 || irq >= NR_IRQS) { printk("Incorrect IRQ %d from %s\n", irq, devname); return -EINVAL; } if (irq_list[irq]) return -EBUSY; /* already used */ if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) { /* initialize IRQ pin */ unsigned int port_no,bit_no; if (*(volatile unsigned short *)ITSR & ptn) { port_no = irq_assign_table1[irq - EXT_IRQ0].port_no; bit_no = irq_assign_table1[irq - EXT_IRQ0].bit_no; } else { port_no = irq_assign_table0[irq - EXT_IRQ0].port_no; bit_no = irq_assign_table0[irq - EXT_IRQ0].bit_no; } if (H8300_GPIO_RESERVE(port_no, bit_no) == 0) return -EBUSY; /* pin already use */ H8300_GPIO_DDR(port_no, bit_no, H8300_GPIO_INPUT); *(volatile unsigned short *)ISR &= ~ptn; /* ISR clear */ } if (use_kmalloc) irq_handle = (irq_handler_t *)kmalloc(sizeof(irq_handler_t), GFP_ATOMIC); else { /* use bootmem allocater */ irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t)); irq_handle = (irq_handler_t *)((unsigned long)irq_handle | 0x80000000); } if (irq_handle == NULL) return -ENOMEM; irq_handle->handler = handler; irq_handle->flags = flags; irq_handle->count = 0; irq_handle->dev_id = dev_id; irq_handle->devname = devname; irq_list[irq] = irq_handle; if (irq_handle->flags & SA_SAMPLE_RANDOM) rand_initialize_irq(irq); /* enable interrupt */ /* compatible i386 */ if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) *(volatile unsigned short *)IER |= ptn; return 0; }
int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { irq_handler_t *irq_handle; if (irq < 0 || irq >= NR_IRQS) { printk(KERN_ERR "Incorrect IRQ %d from %s\n", irq, devname); return -EINVAL; } if (irq_list[irq] || (h8300_enable_irq_pin(irq) == -EBUSY)) return -EBUSY; if (use_kmalloc) irq_handle = kmalloc(sizeof(irq_handler_t), GFP_ATOMIC); else { /* use bootmem allocater */ irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t)); irq_handle = (irq_handler_t *)((unsigned long)irq_handle | 0x80000000); } if (irq_handle == NULL) return -ENOMEM; irq_handle->handler = handler; irq_handle->flags = flags; irq_handle->count = 0; irq_handle->dev_id = dev_id; irq_handle->devname = devname; irq_list[irq] = irq_handle; if (irq_handle->flags & IRQF_SAMPLE_RANDOM) rand_initialize_irq(irq); enable_irq(irq); return 0; }