From: Geert Uytterhoeven <geert@linux-m68k.org>
To: Linus Torvalds <torvalds@linux-foundation.org>,
Andrew Morton <akpm@linux-foundation.org>
Cc: linux-m68k@vger.kernel.org, linux-kernel@vger.kernel.org,
Finn Thain <fthain@telegraphics.com.au>
Subject: [patch 23/33] m68k: Mac nubus IRQ fixes (plan E)
Date: Tue, 01 May 2007 22:32:57 +0200 [thread overview]
Message-ID: <20070501203336.010764675@mail.of.borg> (raw)
In-Reply-To: 20070501203234.252205858@mail.of.borg
[-- Attachment #1: mac68k-irq-plan-e.diff --]
[-- Type: text/plain, Size: 9160 bytes --]
From: Finn Thain <fthain@telegraphics.com.au>
Some Macs lack a slot interrupt enable register. So the existing code makes
disabled and unregistered slot IRQ lines outputs set high. This seems to work
on quadras, but does not work on genuine VIAs (perhaps the card still succeeds
in pulling the line low, or perhaps because this increases the settle time on
the port A input, meaning that the CA1 IRQ could fire before the slot line
reads active).
Because of this, the nubus_active flags were used to mask IRQs, which is
actually worse than the problem it tries to solve. Any interrupt masked by
nubus_active will remain asserted and prevent further transitions on CA1. And
so the nubus gets wedged regardless of hardware (emulated VIA ASIC, real VIA
chip or RBV).
The best solution to this hardware limitation of genuine VIAs is to disable the
umbrella SLOTS IRQ when disabling a slot on those machines. Unfortunately, this
means all slot IRQs get disabled when any slot IRQ is disabled. But it is only
a problem when there's more than 1 device using nubus interrupts.
Another potential problem for genuine VIAs is an unregistered nubus IRQ.
Eventually it will be possible to enable the CA1 interrupt by installing its
handler only _after_ all nubus drivers have loaded but _before_ the kernel
needs them, at which time this last problem can be fixed. For now it can be
worked around:
- disable MacOS extensions
- don't boot MacOS (use the Emile bootloader instead)
- get the bootloaders to disable ROM drivers (Penguin does this for video
cards already, don't know about Emile)
- physically remove unsupported cards
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
arch/m68k/mac/via.c | 141 +++++++++++++++++++++++++++++-----------------------
1 file changed, 80 insertions(+), 61 deletions(-)
--- linux-m68k-2.6.21.orig/arch/m68k/mac/via.c
+++ linux-m68k-2.6.21/arch/m68k/mac/via.c
@@ -64,7 +64,19 @@ static int gIER,gIFR,gBufA,gBufB;
#define MAC_CLOCK_LOW (MAC_CLOCK_TICK&0xFF)
#define MAC_CLOCK_HIGH (MAC_CLOCK_TICK>>8)
-static int nubus_active;
+/* To disable a NuBus slot on Quadras we make the slot IRQ lines outputs, set
+ * high. On RBV we just use the slot interrupt enable register. On Macs with
+ * genuine VIA chips we must use nubus_disabled to keep track of disabled slot
+ * interrupts. When any slot IRQ is disabled we mask the (edge triggered) CA1
+ * or "SLOTS" interrupt. When no slot is disabled, we unmask the CA1 interrupt.
+ * So, on genuine VIAs, having more than one NuBus IRQ can mean trouble,
+ * because closing one of those drivers can mask all of the NuBus interrupts.
+ * Also, since we can't mask the unregistered slot IRQs on genuine VIAs, it's
+ * possible to get interrupts from cards that MacOS or the ROM has configured
+ * but we have not. FWIW, "Designing Cards and Drivers for Macintosh II and
+ * Macintosh SE", page 9-8, says, a slot IRQ with no driver would crash MacOS.
+ */
+static u8 nubus_disabled;
void via_debug_dump(void);
irqreturn_t via1_irq(int, void *);
@@ -383,9 +395,6 @@ int via_get_cache_disable(void)
void __init via_nubus_init(void)
{
- /* don't set nubus_active = 0 here, it kills the Baboon */
- /* interrupt that we've already registered. */
-
/* unlock nubus transactions */
if ((macintosh_config->adb_type != MAC_ADB_PB1) &&
@@ -399,28 +408,35 @@ void __init via_nubus_init(void)
via2[gBufB] |= 0x02;
}
- /* disable nubus slot interrupts. */
- if (rbv_present) {
+ /* Disable all the slot interrupts (where possible). */
+
+ switch (macintosh_config->via_type) {
+ case MAC_VIA_II:
+ /* Just make the port A lines inputs. */
+ switch(macintosh_config->ident) {
+ case MAC_MODEL_II:
+ case MAC_MODEL_IIX:
+ case MAC_MODEL_IICX:
+ case MAC_MODEL_SE30:
+ /* The top two bits are RAM size outputs. */
+ via2[vDirA] &= 0xC0;
+ break;
+ default:
+ via2[vDirA] &= 0x80;
+ }
+ break;
+ case MAC_VIA_IIci:
+ /* RBV. Disable all the slot interrupts. SIER works like IER. */
via2[rSIER] = 0x7F;
- via2[rSIER] = nubus_active | 0x80;
- } else {
- /* These are ADB bits on PMU */
+ break;
+ case MAC_VIA_QUADRA:
+ /* Disable the inactive slot interrupts by making those lines outputs. */
if ((macintosh_config->adb_type != MAC_ADB_PB1) &&
- (macintosh_config->adb_type != MAC_ADB_PB2)) {
- switch(macintosh_config->ident)
- {
- case MAC_MODEL_II:
- case MAC_MODEL_IIX:
- case MAC_MODEL_IICX:
- case MAC_MODEL_SE30:
- via2[vBufA] |= 0x3F;
- via2[vDirA] = ~nubus_active | 0xc0;
- break;
- default:
- via2[vBufA] = 0xFF;
- via2[vDirA] = ~nubus_active;
- }
+ (macintosh_config->adb_type != MAC_ADB_PB2)) {
+ via2[vBufA] |= 0x7F;
+ via2[vDirA] |= 0x7F;
}
+ break;
}
}
@@ -489,7 +505,8 @@ irqreturn_t via2_irq(int irq, void *dev_
via2[gIER] = irq_bit;
via2[gIFR] = irq_bit | rbv_clear;
m68k_handle_int(irq_num);
- via2[gIER] = irq_bit | 0x80;
+ if (irq_num != IRQ_MAC_NUBUS || nubus_disabled == 0)
+ via2[gIER] = irq_bit | 0x80;
}
++irq_num;
irq_bit <<= 1;
@@ -511,7 +528,7 @@ irqreturn_t via_nubus_irq(int irq, void
if (rbv_present)
events &= via2[rSIER];
else
- events &= nubus_active;
+ events &= ~via2[vDirA];
if (!events)
return IRQ_NONE;
@@ -533,7 +550,7 @@ irqreturn_t via_nubus_irq(int irq, void
if (rbv_present)
events &= via2[rSIER];
else
- events &= nubus_active;
+ events &= ~via2[vDirA];
} while (events);
return IRQ_HANDLED;
}
@@ -541,38 +558,38 @@ irqreturn_t via_nubus_irq(int irq, void
void via_irq_enable(int irq) {
int irq_src = IRQ_SRC(irq);
int irq_idx = IRQ_IDX(irq);
- int irq_bit = 1 << irq_idx;
#ifdef DEBUG_IRQUSE
printk(KERN_DEBUG "via_irq_enable(%d)\n", irq);
#endif
if (irq_src == 1) {
- via1[vIER] = irq_bit | 0x80;
+ via1[vIER] = IER_SET_BIT(irq_idx);
} else if (irq_src == 2) {
- via2[gIER] = irq_bit | 0x80;
+ if (irq != IRQ_MAC_NUBUS || nubus_disabled == 0)
+ via2[gIER] = IER_SET_BIT(irq_idx);
} else if (irq_src == 7) {
- nubus_active |= irq_bit;
- if (rbv_present) {
- /* enable the slot interrupt. SIER works like IER. */
+ switch (macintosh_config->via_type) {
+ case MAC_VIA_II:
+ nubus_disabled &= ~(1 << irq_idx);
+ /* Enable the CA1 interrupt when no slot is disabled. */
+ if (!nubus_disabled)
+ via2[gIER] = IER_SET_BIT(1);
+ break;
+ case MAC_VIA_IIci:
+ /* On RBV, enable the slot interrupt.
+ * SIER works like IER.
+ */
via2[rSIER] = IER_SET_BIT(irq_idx);
- } else {
- /* Make sure the bit is an input, to enable the irq */
- /* But not on PowerBooks, that's ADB... */
+ break;
+ case MAC_VIA_QUADRA:
+ /* Make the port A line an input to enable the slot irq.
+ * But not on PowerBooks, that's ADB.
+ */
if ((macintosh_config->adb_type != MAC_ADB_PB1) &&
- (macintosh_config->adb_type != MAC_ADB_PB2)) {
- switch(macintosh_config->ident)
- {
- case MAC_MODEL_II:
- case MAC_MODEL_IIX:
- case MAC_MODEL_IICX:
- case MAC_MODEL_SE30:
- via2[vDirA] &= (~irq_bit | 0xc0);
- break;
- default:
- via2[vDirA] &= ~irq_bit;
- }
- }
+ (macintosh_config->adb_type != MAC_ADB_PB2))
+ via2[vDirA] &= ~(1 << irq_idx);
+ break;
}
}
}
@@ -580,29 +597,31 @@ void via_irq_enable(int irq) {
void via_irq_disable(int irq) {
int irq_src = IRQ_SRC(irq);
int irq_idx = IRQ_IDX(irq);
- int irq_bit = 1 << irq_idx;
#ifdef DEBUG_IRQUSE
printk(KERN_DEBUG "via_irq_disable(%d)\n", irq);
#endif
if (irq_src == 1) {
- via1[vIER] = irq_bit & 0x7F;
+ via1[vIER] = IER_CLR_BIT(irq_idx);
} else if (irq_src == 2) {
- via2[gIER] = irq_bit & 0x7F;
+ via2[gIER] = IER_CLR_BIT(irq_idx);
} else if (irq_src == 7) {
- if (rbv_present) {
- /* disable the slot interrupt. SIER works like IER. */
+ switch (macintosh_config->via_type) {
+ case MAC_VIA_II:
+ nubus_disabled |= 1 << irq_idx;
+ if (nubus_disabled)
+ via2[gIER] = IER_CLR_BIT(1);
+ break;
+ case MAC_VIA_IIci:
via2[rSIER] = IER_CLR_BIT(irq_idx);
- } else {
- /* disable the nubus irq by changing dir to output */
- /* except on PMU */
+ break;
+ case MAC_VIA_QUADRA:
if ((macintosh_config->adb_type != MAC_ADB_PB1) &&
- (macintosh_config->adb_type != MAC_ADB_PB2)) {
- via2[vDirA] |= irq_bit;
- }
+ (macintosh_config->adb_type != MAC_ADB_PB2))
+ via2[vDirA] |= 1 << irq_idx;
+ break;
}
- nubus_active &= ~irq_bit;
}
}
@@ -638,7 +657,7 @@ int via_irq_pending(int irq)
} else if (irq_src == 2) {
return via2[gIFR] & irq_bit;
} else if (irq_src == 7) {
- /* FIXME: this can't work while a slot irq is disabled! */
+ /* Always 0 for MAC_VIA_QUADRA if the slot irq is disabled. */
return ~via2[gBufA] & irq_bit;
}
return 0;
--
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
next prev parent reply other threads:[~2007-05-01 20:51 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-01 20:32 [patch 00/33] m68k patches for 2.6.22 Geert Uytterhoeven
2007-05-01 20:32 ` [patch 01/33] m68k: Atari SCSI revival Geert Uytterhoeven
2007-05-01 20:46 ` Christoph Hellwig
2007-05-01 20:32 ` [patch 02/33] m68k: Reformat the Atari SCSI driver Geert Uytterhoeven
2007-05-01 20:32 ` [patch 03/33] m68k: Atari SCSI driver compile fixes Geert Uytterhoeven
2007-05-01 20:32 ` [patch 04/33] m68k: Atari keyboard and mouse support Geert Uytterhoeven
2007-05-01 20:57 ` Christoph Hellwig
2007-05-01 21:09 ` Dmitry Torokhov
2007-05-03 10:34 ` Michael Schmitz
2007-05-03 10:47 ` Michael Schmitz
2007-05-03 10:50 ` Christoph Hellwig
2007-05-03 10:54 ` Michael Schmitz
2007-05-01 20:32 ` [patch 05/33] m68k: Atari fb revival Geert Uytterhoeven
2007-05-01 21:50 ` Antonino A. Daplas
2007-05-02 20:01 ` James Simmons
2007-05-03 10:33 ` Michael Schmitz
2007-05-01 20:32 ` [patch 06/33] m68k: CROSS_COMPILE = m68k-linux-gnu- Geert Uytterhoeven
2007-05-01 22:56 ` Ville Syrjälä
2007-05-06 11:26 ` Geert Uytterhoeven
2007-05-06 12:55 ` Ville Syrjälä
2007-05-01 20:32 ` [patch 07/33] m68k: Mac89x0 Ethernet netif updates Geert Uytterhoeven
2007-05-01 20:57 ` Jeff Garzik
2007-05-01 20:32 ` [patch 08/33] lockdep: Add missing disable/enable irq variant Geert Uytterhoeven
2007-05-01 20:32 ` [patch 09/33] m68k: reformat various m68k files Geert Uytterhoeven
2007-05-01 20:32 ` [patch 10/33] hilkbd: Kill compiler warning and fix comment dyslexia Geert Uytterhoeven
2007-05-01 20:32 ` [patch 11/33] m68k: early parameter support Geert Uytterhoeven
2007-05-01 20:32 ` [patch 12/33] m68k: make Atari IDE lock reentrant Geert Uytterhoeven
2007-05-01 20:32 ` [patch 13/33] m68k: Correct number of interrupts for Sun3 Geert Uytterhoeven
2007-05-01 20:32 ` [patch 14/33] m68k: Atari SCSI workqueue updates Geert Uytterhoeven
2007-05-01 20:32 ` [patch 15/33] m68k: pmu_queue_request() declaration conflict Geert Uytterhoeven
2007-05-01 20:32 ` [patch 16/33] m68k: Amiga A2065 and Ariadne TX statistics Geert Uytterhoeven
2007-05-01 20:32 ` [patch 17/33] m68k: remove unused adb.h Geert Uytterhoeven
2007-05-01 20:32 ` [patch 18/33] m68k: Mac interrupt priorities Geert Uytterhoeven
2007-05-01 20:32 ` [patch 19/33] NuBus header update Geert Uytterhoeven
2007-05-02 19:47 ` James Simmons
2007-05-03 2:14 ` Brad Boyer
2007-05-01 20:32 ` [patch 20/33] m68k: Mac DP8390 update Geert Uytterhoeven
2007-05-01 20:32 ` [patch 21/33] m68k: reverse Mac IRQ damage Geert Uytterhoeven
2007-05-01 20:32 ` [patch 22/33] m68k: Mac IRQ prep Geert Uytterhoeven
2007-05-01 20:32 ` Geert Uytterhoeven [this message]
2007-05-01 20:32 ` [patch 24/33] m68k: Mac IRQ cleanup Geert Uytterhoeven
2007-05-01 20:32 ` [patch 25/33] m68k: Mac II ADB fixes Geert Uytterhoeven
2007-05-01 20:33 ` [patch 26/33] CUDA " Geert Uytterhoeven
2007-05-01 20:33 ` [patch 27/33] m68k: macmace fixes Geert Uytterhoeven
2007-05-01 20:33 ` [patch 28/33] SONIC: small fix and cleanup Geert Uytterhoeven
2007-05-01 20:33 ` [patch 29/33] SONIC interrupt handling Geert Uytterhoeven
2007-05-01 21:12 ` Christoph Hellwig
2007-05-02 2:55 ` [patch 29/33] SONIC interrupt handling, v4 Finn Thain
2007-05-01 20:33 ` [patch 30/33] Amiga Zorro bus: kill resource_size_t warnings Geert Uytterhoeven
2007-05-01 20:33 ` [patch 31/33] m68k: kill skb_copy_from_linear_data compiler warnings Geert Uytterhoeven
2007-05-01 20:33 ` [patch 32/33] m68k: export csum_partial_copy_from_user Geert Uytterhoeven
2007-05-01 20:33 ` [patch 33/33] Convert non-highmem kmap_atomic() to static inline function Geert Uytterhoeven
2007-05-01 20:49 ` [patch 00/33] m68k patches for 2.6.22 Christoph Hellwig
2007-05-03 1:27 ` Roman Zippel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070501203336.010764675@mail.of.borg \
--to=geert@linux-m68k.org \
--cc=akpm@linux-foundation.org \
--cc=fthain@telegraphics.com.au \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-m68k@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox