📄 irq.c
字号:
//if (!(action->flags & SA_INTERRUPT)) __sti(); /* reenable ints */ do { action->handler(irq, action->dev_id, regs); action = action->next; } while ( action ); //__cli(); /* disable ints */ if (irq_desc[irq].handler) { } //unmask_irq(1<<irq); enable_it8172_irq(irq); } else { spurious_count++; printk("Unhandled interrupt %d, cause %x, disabled\n", (unsigned)irq, (unsigned)regs->cp0_cause); disable_it8172_irq(irq); } irq_exit(cpu, irq);}int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id){ struct irqaction *old, **p, *action; unsigned long flags; /* * IP0 and IP1 are software interrupts. IP7 is typically the timer interrupt. * * The ITE QED-4N-S01B board has one single interrupt line going from * the system controller to the CPU. It's connected to the CPU external * irq pin 1, which is IP2. The interrupt numbers are listed in it8172_int.h; * the ISA interrupts are numbered from 0 to 15, and the rest go from * there. */ //printk("request_irq: %d handler %x\n", irq, handler); if (irq >= NR_IRQS) return -EINVAL; if (!handler) { /* Free */ for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) { /* Found it - now free it */ save_flags(flags); cli(); *p = action->next; disable_it8172_irq(irq); restore_flags(flags); kfree(action); return 0; } return -ENOENT; } action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL); if (!action) return -ENOMEM; memset(action, 0, sizeof(struct irqaction)); save_flags(flags); cli(); action->handler = handler; action->flags = irqflags; action->mask = 0; action->name = devname; action->dev_id = dev_id; action->next = NULL; p = &irq_desc[irq].action; if ((old = *p) != NULL) { /* Can't share interrupts unless both agree to */ if (!(old->flags & action->flags & SA_SHIRQ)) return -EBUSY; /* add new interrupt at end of irq queue */ do { p = &old->next; old = *p; } while (old); } *p = action; enable_it8172_irq(irq); restore_flags(flags); #if 0 printk("request_irq: status %x cause %x\n", read_32bit_cp0_register(CP0_STATUS), read_32bit_cp0_register(CP0_CAUSE));#endif return 0;} void free_irq(unsigned int irq, void *dev_id){ request_irq(irq, NULL, 0, NULL, dev_id);}void enable_cpu_timer(void){ unsigned long flags; save_and_cli(flags); unmask_irq(1<<EXT_IRQ5_TO_IP); /* timer interrupt */ restore_flags(flags);}unsigned long probe_irq_on (void){ return 0;}int probe_irq_off (unsigned long irqs){ return 0;}void __init init_IRQ(void){ int i; unsigned long flags; memset(irq_desc, 0, sizeof(irq_desc)); set_except_vector(0, it8172_IRQ); /* mask all interrupts */ it8172_hw0_icregs->lb_mask = 0xffff; it8172_hw0_icregs->lpc_mask = 0xffff; it8172_hw0_icregs->pci_mask = 0xffff; it8172_hw0_icregs->nmi_mask = 0xffff; /* make all interrupts level triggered */ it8172_hw0_icregs->lb_trigger = 0; it8172_hw0_icregs->lpc_trigger = 0; it8172_hw0_icregs->pci_trigger = 0; it8172_hw0_icregs->nmi_trigger = 0; /* active level setting */ /* uart, keyboard, and mouse are active high */ it8172_hw0_icregs->lpc_level = (0x10 | 0x2 | 0x1000); it8172_hw0_icregs->lb_level |= 0x20; /* keyboard and mouse are edge triggered */ it8172_hw0_icregs->lpc_trigger |= (0x2 | 0x1000); #if 0 // Enable this piece of code to make internal USB interrupt // edge triggered. it8172_hw0_icregs->pci_trigger |= (1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE)); it8172_hw0_icregs->pci_level &= ~(1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE));#endif for (i = 0; i <= IT8172_INT_END; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; irq_desc[i].handler = &it8172_irq_type; } /* * Enable external int line 2 * All ITE interrupts are masked for now. */ save_and_cli(flags); unmask_irq(1<<EXT_IRQ0_TO_IP); restore_flags(flags);#ifdef CONFIG_REMOTE_DEBUG /* If local serial I/O used for debug port, enter kgdb at once */ puts("Waiting for kgdb to connect..."); set_debug_traps(); breakpoint(); #endif}void mips_spurious_interrupt(struct pt_regs *regs){#if 1 return;#else unsigned long status, cause; printk("got spurious interrupt\n"); status = read_32bit_cp0_register(CP0_STATUS); cause = read_32bit_cp0_register(CP0_CAUSE); printk("status %x cause %x\n", status, cause); printk("epc %x badvaddr %x \n", regs->cp0_epc, regs->cp0_badvaddr);// while(1);#endif}void it8172_hw0_irqdispatch(struct pt_regs *regs){ int irq; unsigned short intstatus, status; intstatus = it8172_hw0_icregs->intstatus; if (intstatus & 0x8) { panic("Got NMI interrupt\n"); } else if (intstatus & 0x4) { /* PCI interrupt */ irq = 0; status = it8172_hw0_icregs->pci_req; while (!(status & 0x1)) { irq++; status >>= 1; } irq += IT8172_PCI_DEV_IRQ_BASE; //printk("pci int %d\n", irq); } else if (intstatus & 0x1) { /* Local Bus interrupt */ irq = 0; status = it8172_hw0_icregs->lb_req; while (!(status & 0x1)) { irq++; status >>= 1; } irq += IT8172_LB_IRQ_BASE; //printk("lb int %d\n", irq); } else if (intstatus & 0x2) { /* LPC interrupt */ /* Since some lpc interrupts are edge triggered, * we could lose an interrupt this way because * we acknowledge all ints at onces. Revisit. */ status = it8172_hw0_icregs->lpc_req; it8172_hw0_icregs->lpc_req = 0; /* acknowledge ints */ irq = 0; while (!(status & 0x1)) { irq++; status >>= 1; } irq += IT8172_LPC_IRQ_BASE; //printk("LPC int %d\n", irq); } else { return; } do_IRQ(irq, regs);}void show_pending_irqs(void){ fputs("intstatus: "); put32(it8172_hw0_icregs->intstatus); puts(""); fputs("pci_req: "); put32(it8172_hw0_icregs->pci_req); puts(""); fputs("lb_req: "); put32(it8172_hw0_icregs->lb_req); puts(""); fputs("lpc_req: "); put32(it8172_hw0_icregs->lpc_req); puts("");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -