diff options
Diffstat (limited to 'arch/m68k/mac/oss.c')
| -rw-r--r-- | arch/m68k/mac/oss.c | 106 |
1 files changed, 33 insertions, 73 deletions
diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index 6c4c882c126e..1641607f300d 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Operating System Services (OSS) chip handling * Written by Joshua M. Thompson (funaho@jurai.org) @@ -21,109 +22,74 @@ #include <linux/init.h> #include <linux/irq.h> -#include <asm/bootinfo.h> #include <asm/macintosh.h> #include <asm/macints.h> #include <asm/mac_via.h> #include <asm/mac_oss.h> +#include "mac.h" + int oss_present; volatile struct mac_oss *oss; /* * Initialize the OSS - * - * The OSS "detection" code is actually in via_init() which is always called - * before us. Thus we can count on oss_present being valid on entry. */ void __init oss_init(void) { int i; - if (!oss_present) return; + if (macintosh_config->ident != MAC_MODEL_IIFX) + return; oss = (struct mac_oss *) OSS_BASE; + pr_debug("OSS detected at %p", oss); + oss_present = 1; /* Disable all interrupts. Unlike a VIA it looks like we */ /* do this by setting the source's interrupt level to zero. */ - for (i = 0; i <= OSS_NUM_SOURCES; i++) { + for (i = 0; i < OSS_NUM_SOURCES; i++) oss->irq_level[i] = 0; - } } /* - * Initialize OSS for Nubus access + * Handle OSS interrupts. + * XXX how do you clear a pending IRQ? is it even necessary? */ -void __init oss_nubus_init(void) +static void oss_iopism_irq(struct irq_desc *desc) { + generic_handle_irq(IRQ_MAC_ADB); } -/* - * Handle miscellaneous OSS interrupts. - */ - -static void oss_irq(unsigned int irq, struct irq_desc *desc) +static void oss_scsi_irq(struct irq_desc *desc) { - int events = oss->irq_pending & - (OSS_IP_IOPSCC | OSS_IP_SCSI | OSS_IP_IOPISM); - -#ifdef DEBUG_IRQS - if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) { - printk("oss_irq: irq %u events = 0x%04X\n", irq, - (int) oss->irq_pending); - } -#endif - - if (events & OSS_IP_IOPSCC) { - oss->irq_pending &= ~OSS_IP_IOPSCC; - generic_handle_irq(IRQ_MAC_SCC); - } - - if (events & OSS_IP_SCSI) { - oss->irq_pending &= ~OSS_IP_SCSI; - generic_handle_irq(IRQ_MAC_SCSI); - } - - if (events & OSS_IP_IOPISM) { - oss->irq_pending &= ~OSS_IP_IOPISM; - generic_handle_irq(IRQ_MAC_ADB); - } + generic_handle_irq(IRQ_MAC_SCSI); } -/* - * Nubus IRQ handler, OSS style - * - * Unlike the VIA/RBV this is on its own autovector interrupt level. - */ - -static void oss_nubus_irq(unsigned int irq, struct irq_desc *desc) +static void oss_nubus_irq(struct irq_desc *desc) { - int events, irq_bit, i; + u16 events, irq_bit; + int irq_num; events = oss->irq_pending & OSS_IP_NUBUS; - if (!events) - return; - -#ifdef DEBUG_NUBUS_INT - if (console_loglevel > 7) { - printk("oss_nubus_irq: events = 0x%04X\n", events); - } -#endif - /* There are only six slots on the OSS, not seven */ - - i = 6; - irq_bit = 0x40; + irq_num = NUBUS_SOURCE_BASE + 5; + irq_bit = OSS_IP_NUBUS5; do { - --i; - irq_bit >>= 1; if (events & irq_bit) { - oss->irq_pending &= ~irq_bit; - generic_handle_irq(NUBUS_SOURCE_BASE + i); + events &= ~irq_bit; + generic_handle_irq(irq_num); } - } while(events & (irq_bit - 1)); + --irq_num; + irq_bit >>= 1; + } while (events); +} + +static void oss_iopscc_irq(struct irq_desc *desc) +{ + generic_handle_irq(IRQ_MAC_SCC); } /* @@ -143,14 +109,14 @@ static void oss_nubus_irq(unsigned int irq, struct irq_desc *desc) void __init oss_register_interrupts(void) { - irq_set_chained_handler(OSS_IRQLEV_IOPISM, oss_irq); - irq_set_chained_handler(OSS_IRQLEV_SCSI, oss_irq); + irq_set_chained_handler(OSS_IRQLEV_IOPISM, oss_iopism_irq); + irq_set_chained_handler(OSS_IRQLEV_SCSI, oss_scsi_irq); irq_set_chained_handler(OSS_IRQLEV_NUBUS, oss_nubus_irq); - irq_set_chained_handler(OSS_IRQLEV_IOPSCC, oss_irq); + irq_set_chained_handler(OSS_IRQLEV_IOPSCC, oss_iopscc_irq); irq_set_chained_handler(OSS_IRQLEV_VIA1, via1_irq); /* OSS_VIA1 gets enabled here because it has no machspec interrupt. */ - oss->irq_level[OSS_VIA1] = IRQ_AUTO_6; + oss->irq_level[OSS_VIA1] = OSS_IRQLEV_VIA1; } /* @@ -163,9 +129,6 @@ void __init oss_register_interrupts(void) */ void oss_irq_enable(int irq) { -#ifdef DEBUG_IRQUSE - printk("oss_irq_enable(%d)\n", irq); -#endif switch(irq) { case IRQ_MAC_SCC: oss->irq_level[OSS_IOPSCC] = OSS_IRQLEV_IOPSCC; @@ -199,9 +162,6 @@ void oss_irq_enable(int irq) { */ void oss_irq_disable(int irq) { -#ifdef DEBUG_IRQUSE - printk("oss_irq_disable(%d)\n", irq); -#endif switch(irq) { case IRQ_MAC_SCC: oss->irq_level[OSS_IOPSCC] = 0; |
