Loading arch/m68k/mac/baboon.c +1 −1 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ irqreturn_t baboon_irq(int irq, void *dev_id, struct pt_regs *regs) for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) { if (events & irq_bit/* & baboon_active*/) { baboon_active &= ~irq_bit; mac_do_irq_list(IRQ_BABOON_0 + i, regs); m68k_handle_int(IRQ_BABOON_0 + i, regs); baboon_active |= irq_bit; baboon->mb_ifr &= ~irq_bit; } Loading arch/m68k/mac/config.c +0 −5 Original line number Diff line number Diff line Loading @@ -169,12 +169,7 @@ void __init config_mac(void) mach_sched_init = mac_sched_init; mach_init_IRQ = mac_init_IRQ; mach_request_irq = mac_request_irq; mach_free_irq = mac_free_irq; enable_irq = mac_enable_irq; disable_irq = mac_disable_irq; mach_get_model = mac_get_model; mach_get_irq_list = show_mac_interrupts; mach_gettimeoffset = mac_gettimeoffset; #warning move to adb/via init #if 0 Loading arch/m68k/mac/iop.c +1 −1 Original line number Diff line number Diff line Loading @@ -317,7 +317,7 @@ void __init iop_register_interrupts(void) { if (iop_ism_present) { if (oss_present) { cpu_request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, IRQ_FLG_LOCK, "ISM IOP", (void *) IOP_NUM_ISM); oss_irq_enable(IRQ_MAC_ADB); Loading arch/m68k/mac/macints.c +127 −369 Original line number Diff line number Diff line Loading @@ -137,14 +137,6 @@ #define DEBUG_SPURIOUS #define SHUTUP_SONIC /* * The mac_irq_list array is an array of linked lists of irq_node_t nodes. * Each node contains one handler to be called whenever the interrupt * occurs, with fast handlers listed before slow handlers. */ irq_node_t *mac_irq_list[NUM_MAC_SOURCES]; /* SCC interrupt mask */ static int scc_mask; Loading Loading @@ -209,8 +201,8 @@ extern int baboon_irq_pending(int); * SCC interrupt routines */ static void scc_irq_enable(int); static void scc_irq_disable(int); static void scc_irq_enable(unsigned int); static void scc_irq_disable(unsigned int); /* * console_loglevel determines NMI handler function Loading @@ -221,21 +213,25 @@ irqreturn_t mac_debug_handler(int, void *, struct pt_regs *); /* #define DEBUG_MACINTS */ static void mac_enable_irq(unsigned int irq); static void mac_disable_irq(unsigned int irq); static struct irq_controller mac_irq_controller = { .name = "mac", .lock = SPIN_LOCK_UNLOCKED, .enable = mac_enable_irq, .disable = mac_disable_irq, }; void mac_init_IRQ(void) { int i; #ifdef DEBUG_MACINTS printk("mac_init_IRQ(): Setting things up...\n"); #endif /* Initialize the IRQ handler lists. Initially each list is empty, */ for (i = 0; i < NUM_MAC_SOURCES; i++) { mac_irq_list[i] = NULL; } scc_mask = 0; m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER, NUM_MAC_SOURCES - IRQ_USER); /* Make sure the SONIC interrupt is cleared or things get ugly */ #ifdef SHUTUP_SONIC printk("Killing onboard sonic... "); Loading @@ -252,119 +248,22 @@ void mac_init_IRQ(void) * at levels 1-7. Most of the work is done elsewhere. */ if (oss_present) { if (oss_present) oss_register_interrupts(); } else { else via_register_interrupts(); } if (psc_present) psc_register_interrupts(); if (baboon_present) baboon_register_interrupts(); if (psc_present) psc_register_interrupts(); if (baboon_present) baboon_register_interrupts(); iop_register_interrupts(); cpu_request_irq(7, mac_nmi_handler, IRQ_FLG_LOCK, "NMI", request_irq(IRQ_AUTO_7, mac_nmi_handler, 0, "NMI", mac_nmi_handler); #ifdef DEBUG_MACINTS printk("mac_init_IRQ(): Done!\n"); #endif } /* * Routines to work with irq_node_t's on linked lists lifted from * the Amiga code written by Roman Zippel. */ static inline void mac_insert_irq(irq_node_t **list, irq_node_t *node) { unsigned long flags; irq_node_t *cur; if (!node->dev_id) printk("%s: Warning: dev_id of %s is zero\n", __FUNCTION__, node->devname); local_irq_save(flags); cur = *list; if (node->flags & IRQ_FLG_FAST) { node->flags &= ~IRQ_FLG_SLOW; while (cur && cur->flags & IRQ_FLG_FAST) { list = &cur->next; cur = cur->next; } } else if (node->flags & IRQ_FLG_SLOW) { while (cur) { list = &cur->next; cur = cur->next; } } else { while (cur && !(cur->flags & IRQ_FLG_SLOW)) { list = &cur->next; cur = cur->next; } } node->next = cur; *list = node; local_irq_restore(flags); } static inline void mac_delete_irq(irq_node_t **list, void *dev_id) { unsigned long flags; irq_node_t *node; local_irq_save(flags); for (node = *list; node; list = &node->next, node = *list) { if (node->dev_id == dev_id) { *list = node->next; /* Mark it as free. */ node->handler = NULL; local_irq_restore(flags); return; } } local_irq_restore(flags); printk ("%s: tried to remove invalid irq\n", __FUNCTION__); } /* * Call all the handlers for a given interrupt. Fast handlers are called * first followed by slow handlers. * * This code taken from the original Amiga code written by Roman Zippel. */ void mac_do_irq_list(int irq, struct pt_regs *fp) { irq_node_t *node, *slow_nodes; unsigned long flags; kstat_cpu(0).irqs[irq]++; #ifdef DEBUG_SPURIOUS if (!mac_irq_list[irq] && (console_loglevel > 7)) { printk("mac_do_irq_list: spurious interrupt %d!\n", irq); return; } #endif /* serve first fast and normal handlers */ for (node = mac_irq_list[irq]; node && (!(node->flags & IRQ_FLG_SLOW)); node = node->next) node->handler(irq, node->dev_id, fp); if (!node) return; local_save_flags(flags); local_irq_restore((flags & ~0x0700) | (fp->sr & 0x0700)); /* if slow handlers exists, serve them now */ slow_nodes = node; for (; node; node = node->next) { node->handler(irq, node->dev_id, fp); } } /* * mac_enable_irq - enable an interrupt source * mac_disable_irq - disable an interrupt source Loading @@ -374,66 +273,68 @@ void mac_do_irq_list(int irq, struct pt_regs *fp) * These routines are just dispatchers to the VIA/OSS/PSC routines. */ void mac_enable_irq (unsigned int irq) static void mac_enable_irq(unsigned int irq) { int irq_src = IRQ_SRC(irq); switch(irq_src) { case 1: via_irq_enable(irq); case 1: via_irq_enable(irq); break; case 2: case 7: if (oss_present) { case 7: if (oss_present) oss_irq_enable(irq); } else { else via_irq_enable(irq); } break; case 3: case 4: case 5: case 6: if (psc_present) { case 6: if (psc_present) psc_irq_enable(irq); } else if (oss_present) { else if (oss_present) oss_irq_enable(irq); } else if (irq_src == 4) { else if (irq_src == 4) scc_irq_enable(irq); } break; case 8: if (baboon_present) { case 8: if (baboon_present) baboon_irq_enable(irq); } break; } } void mac_disable_irq (unsigned int irq) static void mac_disable_irq(unsigned int irq) { int irq_src = IRQ_SRC(irq); switch(irq_src) { case 1: via_irq_disable(irq); case 1: via_irq_disable(irq); break; case 2: case 7: if (oss_present) { case 7: if (oss_present) oss_irq_disable(irq); } else { else via_irq_disable(irq); } break; case 3: case 4: case 5: case 6: if (psc_present) { case 6: if (psc_present) psc_irq_disable(irq); } else if (oss_present) { else if (oss_present) oss_irq_disable(irq); } else if (irq_src == 4) { else if (irq_src == 4) scc_irq_disable(irq); } break; case 8: if (baboon_present) { case 8: if (baboon_present) baboon_irq_disable(irq); } break; } } Loading @@ -441,27 +342,28 @@ void mac_disable_irq (unsigned int irq) void mac_clear_irq(unsigned int irq) { switch(IRQ_SRC(irq)) { case 1: via_irq_clear(irq); case 1: via_irq_clear(irq); break; case 2: case 7: if (oss_present) { case 7: if (oss_present) oss_irq_clear(irq); } else { else via_irq_clear(irq); } break; case 3: case 4: case 5: case 6: if (psc_present) { case 6: if (psc_present) psc_irq_clear(irq); } else if (oss_present) { else if (oss_present) oss_irq_clear(irq); } break; case 8: if (baboon_present) { case 8: if (baboon_present) baboon_irq_clear(irq); } break; } } Loading @@ -469,171 +371,23 @@ void mac_clear_irq( unsigned int irq ) int mac_irq_pending(unsigned int irq) { switch(IRQ_SRC(irq)) { case 1: return via_irq_pending(irq); case 1: return via_irq_pending(irq); case 2: case 7: if (oss_present) { case 7: if (oss_present) return oss_irq_pending(irq); } else { else return via_irq_pending(irq); } case 3: case 4: case 5: case 6: if (psc_present) { case 6: if (psc_present) return psc_irq_pending(irq); } else if (oss_present) { else if (oss_present) return oss_irq_pending(irq); } } return 0; } /* * Add an interrupt service routine to an interrupt source. * Returns 0 on success. * * FIXME: You can register interrupts on nonexistent source (ie PSC4 on a * non-PSC machine). We should return -EINVAL in those cases. */ int mac_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { irq_node_t *node; #ifdef DEBUG_MACINTS printk ("%s: irq %d requested for %s\n", __FUNCTION__, irq, devname); #endif if (irq < VIA1_SOURCE_BASE) { return cpu_request_irq(irq, handler, flags, devname, dev_id); } if (irq >= NUM_MAC_SOURCES) { printk ("%s: unknown irq %d requested by %s\n", __FUNCTION__, irq, devname); } /* Get a node and stick it onto the right list */ if (!(node = new_irq_node())) return -ENOMEM; node->handler = handler; node->flags = flags; node->dev_id = dev_id; node->devname = devname; node->next = NULL; mac_insert_irq(&mac_irq_list[irq], node); /* Now enable the IRQ source */ mac_enable_irq(irq); return 0; } /* * Removes an interrupt service routine from an interrupt source. */ void mac_free_irq(unsigned int irq, void *dev_id) { #ifdef DEBUG_MACINTS printk ("%s: irq %d freed by %p\n", __FUNCTION__, irq, dev_id); #endif if (irq < VIA1_SOURCE_BASE) { cpu_free_irq(irq, dev_id); return; } if (irq >= NUM_MAC_SOURCES) { printk ("%s: unknown irq %d freed\n", __FUNCTION__, irq); return; } mac_delete_irq(&mac_irq_list[irq], dev_id); /* If the list for this interrupt is */ /* empty then disable the source. */ if (!mac_irq_list[irq]) { mac_disable_irq(irq); } } /* * Generate a pretty listing for /proc/interrupts * * By the time we're called the autovector interrupt list has already been * generated, so we just need to do the machspec interrupts. * * 990506 (jmt) - rewritten to handle chained machspec interrupt handlers. * Also removed display of num_spurious it is already * displayed for us as autovector irq 0. */ int show_mac_interrupts(struct seq_file *p, void *v) { int i; irq_node_t *node; char *base; /* Don't do Nubus interrupts in this loop; we do them separately */ /* below so that we can print slot numbers instead of IRQ numbers */ for (i = VIA1_SOURCE_BASE ; i < NUM_MAC_SOURCES ; ++i) { /* Nonexistant interrupt or nothing registered; skip it. */ if ((node = mac_irq_list[i]) == NULL) continue; if (node->flags & IRQ_FLG_STD) continue; base = ""; switch(IRQ_SRC(i)) { case 1: base = "via1"; break; case 2: if (oss_present) { base = "oss"; } else { base = "via2"; } break; case 3: case 4: case 5: case 6: if (psc_present) { base = "psc"; } else if (oss_present) { base = "oss"; } else { if (IRQ_SRC(i) == 4) base = "scc"; } break; case 7: base = "nbus"; break; case 8: base = "bbn"; break; } seq_printf(p, "%4s %2d: %10u ", base, i, kstat_cpu(0).irqs[i]); do { if (node->flags & IRQ_FLG_FAST) { seq_puts(p, "F "); } else if (node->flags & IRQ_FLG_SLOW) { seq_puts(p, "S "); } else { seq_puts(p, " "); } seq_printf(p, "%s\n", node->devname); if ((node = node->next)) { seq_puts(p, " "); } } while(node); } return 0; } Loading Loading @@ -705,13 +459,15 @@ irqreturn_t mac_nmi_handler(int irq, void *dev_id, struct pt_regs *fp) * done in hardware (only the PSC can do that.) */ static void scc_irq_enable(int irq) { static void scc_irq_enable(unsigned int irq) { int irq_idx = IRQ_IDX(irq); scc_mask |= (1 << irq_idx); } static void scc_irq_disable(int irq) { static void scc_irq_disable(unsigned int irq) { int irq_idx = IRQ_IDX(irq); scc_mask &= ~(1 << irq_idx); Loading Loading @@ -747,6 +503,8 @@ void mac_scc_dispatch(int irq, void *dev_id, struct pt_regs *regs) /* and since they're autovector interrupts they */ /* pretty much kill the system. */ if (reg & 0x38) mac_do_irq_list(IRQ_SCCA, regs); if (reg & 0x07) mac_do_irq_list(IRQ_SCCB, regs); if (reg & 0x38) m68k_handle_int(IRQ_SCCA, regs); if (reg & 0x07) m68k_handle_int(IRQ_SCCB, regs); } arch/m68k/mac/oss.c +7 −7 Original line number Diff line number Diff line Loading @@ -67,15 +67,15 @@ void __init oss_init(void) void __init oss_register_interrupts(void) { cpu_request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, "scsi", (void *) oss); cpu_request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK, request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK, "scc", mac_scc_dispatch); cpu_request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, "nubus", (void *) oss); cpu_request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, "sound", (void *) oss); cpu_request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, "via1", (void *) via1); } Loading Loading @@ -113,7 +113,7 @@ irqreturn_t oss_irq(int irq, void *dev_id, struct pt_regs *regs) oss->irq_pending &= ~OSS_IP_SOUND; } else if (events & OSS_IP_SCSI) { oss->irq_level[OSS_SCSI] = OSS_IRQLEV_DISABLED; mac_do_irq_list(IRQ_MAC_SCSI, regs); m68k_handle_int(IRQ_MAC_SCSI, regs); oss->irq_pending &= ~OSS_IP_SCSI; oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI; } else { Loading Loading @@ -146,7 +146,7 @@ irqreturn_t oss_nubus_irq(int irq, void *dev_id, struct pt_regs *regs) for (i = 0, irq_bit = 1 ; i < 6 ; i++, irq_bit <<= 1) { if (events & irq_bit) { oss->irq_level[i] = OSS_IRQLEV_DISABLED; mac_do_irq_list(NUBUS_SOURCE_BASE + i, regs); m68k_handle_int(NUBUS_SOURCE_BASE + i, regs); oss->irq_pending &= ~irq_bit; oss->irq_level[i] = OSS_IRQLEV_NUBUS; } Loading Loading
arch/m68k/mac/baboon.c +1 −1 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ irqreturn_t baboon_irq(int irq, void *dev_id, struct pt_regs *regs) for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) { if (events & irq_bit/* & baboon_active*/) { baboon_active &= ~irq_bit; mac_do_irq_list(IRQ_BABOON_0 + i, regs); m68k_handle_int(IRQ_BABOON_0 + i, regs); baboon_active |= irq_bit; baboon->mb_ifr &= ~irq_bit; } Loading
arch/m68k/mac/config.c +0 −5 Original line number Diff line number Diff line Loading @@ -169,12 +169,7 @@ void __init config_mac(void) mach_sched_init = mac_sched_init; mach_init_IRQ = mac_init_IRQ; mach_request_irq = mac_request_irq; mach_free_irq = mac_free_irq; enable_irq = mac_enable_irq; disable_irq = mac_disable_irq; mach_get_model = mac_get_model; mach_get_irq_list = show_mac_interrupts; mach_gettimeoffset = mac_gettimeoffset; #warning move to adb/via init #if 0 Loading
arch/m68k/mac/iop.c +1 −1 Original line number Diff line number Diff line Loading @@ -317,7 +317,7 @@ void __init iop_register_interrupts(void) { if (iop_ism_present) { if (oss_present) { cpu_request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, IRQ_FLG_LOCK, "ISM IOP", (void *) IOP_NUM_ISM); oss_irq_enable(IRQ_MAC_ADB); Loading
arch/m68k/mac/macints.c +127 −369 Original line number Diff line number Diff line Loading @@ -137,14 +137,6 @@ #define DEBUG_SPURIOUS #define SHUTUP_SONIC /* * The mac_irq_list array is an array of linked lists of irq_node_t nodes. * Each node contains one handler to be called whenever the interrupt * occurs, with fast handlers listed before slow handlers. */ irq_node_t *mac_irq_list[NUM_MAC_SOURCES]; /* SCC interrupt mask */ static int scc_mask; Loading Loading @@ -209,8 +201,8 @@ extern int baboon_irq_pending(int); * SCC interrupt routines */ static void scc_irq_enable(int); static void scc_irq_disable(int); static void scc_irq_enable(unsigned int); static void scc_irq_disable(unsigned int); /* * console_loglevel determines NMI handler function Loading @@ -221,21 +213,25 @@ irqreturn_t mac_debug_handler(int, void *, struct pt_regs *); /* #define DEBUG_MACINTS */ static void mac_enable_irq(unsigned int irq); static void mac_disable_irq(unsigned int irq); static struct irq_controller mac_irq_controller = { .name = "mac", .lock = SPIN_LOCK_UNLOCKED, .enable = mac_enable_irq, .disable = mac_disable_irq, }; void mac_init_IRQ(void) { int i; #ifdef DEBUG_MACINTS printk("mac_init_IRQ(): Setting things up...\n"); #endif /* Initialize the IRQ handler lists. Initially each list is empty, */ for (i = 0; i < NUM_MAC_SOURCES; i++) { mac_irq_list[i] = NULL; } scc_mask = 0; m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER, NUM_MAC_SOURCES - IRQ_USER); /* Make sure the SONIC interrupt is cleared or things get ugly */ #ifdef SHUTUP_SONIC printk("Killing onboard sonic... "); Loading @@ -252,119 +248,22 @@ void mac_init_IRQ(void) * at levels 1-7. Most of the work is done elsewhere. */ if (oss_present) { if (oss_present) oss_register_interrupts(); } else { else via_register_interrupts(); } if (psc_present) psc_register_interrupts(); if (baboon_present) baboon_register_interrupts(); if (psc_present) psc_register_interrupts(); if (baboon_present) baboon_register_interrupts(); iop_register_interrupts(); cpu_request_irq(7, mac_nmi_handler, IRQ_FLG_LOCK, "NMI", request_irq(IRQ_AUTO_7, mac_nmi_handler, 0, "NMI", mac_nmi_handler); #ifdef DEBUG_MACINTS printk("mac_init_IRQ(): Done!\n"); #endif } /* * Routines to work with irq_node_t's on linked lists lifted from * the Amiga code written by Roman Zippel. */ static inline void mac_insert_irq(irq_node_t **list, irq_node_t *node) { unsigned long flags; irq_node_t *cur; if (!node->dev_id) printk("%s: Warning: dev_id of %s is zero\n", __FUNCTION__, node->devname); local_irq_save(flags); cur = *list; if (node->flags & IRQ_FLG_FAST) { node->flags &= ~IRQ_FLG_SLOW; while (cur && cur->flags & IRQ_FLG_FAST) { list = &cur->next; cur = cur->next; } } else if (node->flags & IRQ_FLG_SLOW) { while (cur) { list = &cur->next; cur = cur->next; } } else { while (cur && !(cur->flags & IRQ_FLG_SLOW)) { list = &cur->next; cur = cur->next; } } node->next = cur; *list = node; local_irq_restore(flags); } static inline void mac_delete_irq(irq_node_t **list, void *dev_id) { unsigned long flags; irq_node_t *node; local_irq_save(flags); for (node = *list; node; list = &node->next, node = *list) { if (node->dev_id == dev_id) { *list = node->next; /* Mark it as free. */ node->handler = NULL; local_irq_restore(flags); return; } } local_irq_restore(flags); printk ("%s: tried to remove invalid irq\n", __FUNCTION__); } /* * Call all the handlers for a given interrupt. Fast handlers are called * first followed by slow handlers. * * This code taken from the original Amiga code written by Roman Zippel. */ void mac_do_irq_list(int irq, struct pt_regs *fp) { irq_node_t *node, *slow_nodes; unsigned long flags; kstat_cpu(0).irqs[irq]++; #ifdef DEBUG_SPURIOUS if (!mac_irq_list[irq] && (console_loglevel > 7)) { printk("mac_do_irq_list: spurious interrupt %d!\n", irq); return; } #endif /* serve first fast and normal handlers */ for (node = mac_irq_list[irq]; node && (!(node->flags & IRQ_FLG_SLOW)); node = node->next) node->handler(irq, node->dev_id, fp); if (!node) return; local_save_flags(flags); local_irq_restore((flags & ~0x0700) | (fp->sr & 0x0700)); /* if slow handlers exists, serve them now */ slow_nodes = node; for (; node; node = node->next) { node->handler(irq, node->dev_id, fp); } } /* * mac_enable_irq - enable an interrupt source * mac_disable_irq - disable an interrupt source Loading @@ -374,66 +273,68 @@ void mac_do_irq_list(int irq, struct pt_regs *fp) * These routines are just dispatchers to the VIA/OSS/PSC routines. */ void mac_enable_irq (unsigned int irq) static void mac_enable_irq(unsigned int irq) { int irq_src = IRQ_SRC(irq); switch(irq_src) { case 1: via_irq_enable(irq); case 1: via_irq_enable(irq); break; case 2: case 7: if (oss_present) { case 7: if (oss_present) oss_irq_enable(irq); } else { else via_irq_enable(irq); } break; case 3: case 4: case 5: case 6: if (psc_present) { case 6: if (psc_present) psc_irq_enable(irq); } else if (oss_present) { else if (oss_present) oss_irq_enable(irq); } else if (irq_src == 4) { else if (irq_src == 4) scc_irq_enable(irq); } break; case 8: if (baboon_present) { case 8: if (baboon_present) baboon_irq_enable(irq); } break; } } void mac_disable_irq (unsigned int irq) static void mac_disable_irq(unsigned int irq) { int irq_src = IRQ_SRC(irq); switch(irq_src) { case 1: via_irq_disable(irq); case 1: via_irq_disable(irq); break; case 2: case 7: if (oss_present) { case 7: if (oss_present) oss_irq_disable(irq); } else { else via_irq_disable(irq); } break; case 3: case 4: case 5: case 6: if (psc_present) { case 6: if (psc_present) psc_irq_disable(irq); } else if (oss_present) { else if (oss_present) oss_irq_disable(irq); } else if (irq_src == 4) { else if (irq_src == 4) scc_irq_disable(irq); } break; case 8: if (baboon_present) { case 8: if (baboon_present) baboon_irq_disable(irq); } break; } } Loading @@ -441,27 +342,28 @@ void mac_disable_irq (unsigned int irq) void mac_clear_irq(unsigned int irq) { switch(IRQ_SRC(irq)) { case 1: via_irq_clear(irq); case 1: via_irq_clear(irq); break; case 2: case 7: if (oss_present) { case 7: if (oss_present) oss_irq_clear(irq); } else { else via_irq_clear(irq); } break; case 3: case 4: case 5: case 6: if (psc_present) { case 6: if (psc_present) psc_irq_clear(irq); } else if (oss_present) { else if (oss_present) oss_irq_clear(irq); } break; case 8: if (baboon_present) { case 8: if (baboon_present) baboon_irq_clear(irq); } break; } } Loading @@ -469,171 +371,23 @@ void mac_clear_irq( unsigned int irq ) int mac_irq_pending(unsigned int irq) { switch(IRQ_SRC(irq)) { case 1: return via_irq_pending(irq); case 1: return via_irq_pending(irq); case 2: case 7: if (oss_present) { case 7: if (oss_present) return oss_irq_pending(irq); } else { else return via_irq_pending(irq); } case 3: case 4: case 5: case 6: if (psc_present) { case 6: if (psc_present) return psc_irq_pending(irq); } else if (oss_present) { else if (oss_present) return oss_irq_pending(irq); } } return 0; } /* * Add an interrupt service routine to an interrupt source. * Returns 0 on success. * * FIXME: You can register interrupts on nonexistent source (ie PSC4 on a * non-PSC machine). We should return -EINVAL in those cases. */ int mac_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { irq_node_t *node; #ifdef DEBUG_MACINTS printk ("%s: irq %d requested for %s\n", __FUNCTION__, irq, devname); #endif if (irq < VIA1_SOURCE_BASE) { return cpu_request_irq(irq, handler, flags, devname, dev_id); } if (irq >= NUM_MAC_SOURCES) { printk ("%s: unknown irq %d requested by %s\n", __FUNCTION__, irq, devname); } /* Get a node and stick it onto the right list */ if (!(node = new_irq_node())) return -ENOMEM; node->handler = handler; node->flags = flags; node->dev_id = dev_id; node->devname = devname; node->next = NULL; mac_insert_irq(&mac_irq_list[irq], node); /* Now enable the IRQ source */ mac_enable_irq(irq); return 0; } /* * Removes an interrupt service routine from an interrupt source. */ void mac_free_irq(unsigned int irq, void *dev_id) { #ifdef DEBUG_MACINTS printk ("%s: irq %d freed by %p\n", __FUNCTION__, irq, dev_id); #endif if (irq < VIA1_SOURCE_BASE) { cpu_free_irq(irq, dev_id); return; } if (irq >= NUM_MAC_SOURCES) { printk ("%s: unknown irq %d freed\n", __FUNCTION__, irq); return; } mac_delete_irq(&mac_irq_list[irq], dev_id); /* If the list for this interrupt is */ /* empty then disable the source. */ if (!mac_irq_list[irq]) { mac_disable_irq(irq); } } /* * Generate a pretty listing for /proc/interrupts * * By the time we're called the autovector interrupt list has already been * generated, so we just need to do the machspec interrupts. * * 990506 (jmt) - rewritten to handle chained machspec interrupt handlers. * Also removed display of num_spurious it is already * displayed for us as autovector irq 0. */ int show_mac_interrupts(struct seq_file *p, void *v) { int i; irq_node_t *node; char *base; /* Don't do Nubus interrupts in this loop; we do them separately */ /* below so that we can print slot numbers instead of IRQ numbers */ for (i = VIA1_SOURCE_BASE ; i < NUM_MAC_SOURCES ; ++i) { /* Nonexistant interrupt or nothing registered; skip it. */ if ((node = mac_irq_list[i]) == NULL) continue; if (node->flags & IRQ_FLG_STD) continue; base = ""; switch(IRQ_SRC(i)) { case 1: base = "via1"; break; case 2: if (oss_present) { base = "oss"; } else { base = "via2"; } break; case 3: case 4: case 5: case 6: if (psc_present) { base = "psc"; } else if (oss_present) { base = "oss"; } else { if (IRQ_SRC(i) == 4) base = "scc"; } break; case 7: base = "nbus"; break; case 8: base = "bbn"; break; } seq_printf(p, "%4s %2d: %10u ", base, i, kstat_cpu(0).irqs[i]); do { if (node->flags & IRQ_FLG_FAST) { seq_puts(p, "F "); } else if (node->flags & IRQ_FLG_SLOW) { seq_puts(p, "S "); } else { seq_puts(p, " "); } seq_printf(p, "%s\n", node->devname); if ((node = node->next)) { seq_puts(p, " "); } } while(node); } return 0; } Loading Loading @@ -705,13 +459,15 @@ irqreturn_t mac_nmi_handler(int irq, void *dev_id, struct pt_regs *fp) * done in hardware (only the PSC can do that.) */ static void scc_irq_enable(int irq) { static void scc_irq_enable(unsigned int irq) { int irq_idx = IRQ_IDX(irq); scc_mask |= (1 << irq_idx); } static void scc_irq_disable(int irq) { static void scc_irq_disable(unsigned int irq) { int irq_idx = IRQ_IDX(irq); scc_mask &= ~(1 << irq_idx); Loading Loading @@ -747,6 +503,8 @@ void mac_scc_dispatch(int irq, void *dev_id, struct pt_regs *regs) /* and since they're autovector interrupts they */ /* pretty much kill the system. */ if (reg & 0x38) mac_do_irq_list(IRQ_SCCA, regs); if (reg & 0x07) mac_do_irq_list(IRQ_SCCB, regs); if (reg & 0x38) m68k_handle_int(IRQ_SCCA, regs); if (reg & 0x07) m68k_handle_int(IRQ_SCCB, regs); }
arch/m68k/mac/oss.c +7 −7 Original line number Diff line number Diff line Loading @@ -67,15 +67,15 @@ void __init oss_init(void) void __init oss_register_interrupts(void) { cpu_request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, "scsi", (void *) oss); cpu_request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK, request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK, "scc", mac_scc_dispatch); cpu_request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, "nubus", (void *) oss); cpu_request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, "sound", (void *) oss); cpu_request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, "via1", (void *) via1); } Loading Loading @@ -113,7 +113,7 @@ irqreturn_t oss_irq(int irq, void *dev_id, struct pt_regs *regs) oss->irq_pending &= ~OSS_IP_SOUND; } else if (events & OSS_IP_SCSI) { oss->irq_level[OSS_SCSI] = OSS_IRQLEV_DISABLED; mac_do_irq_list(IRQ_MAC_SCSI, regs); m68k_handle_int(IRQ_MAC_SCSI, regs); oss->irq_pending &= ~OSS_IP_SCSI; oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI; } else { Loading Loading @@ -146,7 +146,7 @@ irqreturn_t oss_nubus_irq(int irq, void *dev_id, struct pt_regs *regs) for (i = 0, irq_bit = 1 ; i < 6 ; i++, irq_bit <<= 1) { if (events & irq_bit) { oss->irq_level[i] = OSS_IRQLEV_DISABLED; mac_do_irq_list(NUBUS_SOURCE_BASE + i, regs); m68k_handle_int(NUBUS_SOURCE_BASE + i, regs); oss->irq_pending &= ~irq_bit; oss->irq_level[i] = OSS_IRQLEV_NUBUS; } Loading