Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 53294
b: refs/heads/master
c: cd713dd
h: refs/heads/master
v: v3
  • Loading branch information
Finn Thain authored and Linus Torvalds committed May 5, 2007
1 parent 616079e commit 4db6280
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 62 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 67dfb153a352e57e71404d550be7eb60d15d7f2d
refs/heads/master: cd713ddc93bf2f612783aea8eff6d0df6107765e
141 changes: 80 additions & 61 deletions trunk/arch/m68k/mac/via.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down Expand Up @@ -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) &&
Expand All @@ -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;
}
}

Expand Down Expand Up @@ -489,7 +505,8 @@ irqreturn_t via2_irq(int irq, void *dev_id)
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;
Expand All @@ -511,7 +528,7 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id)
if (rbv_present)
events &= via2[rSIER];
else
events &= nubus_active;
events &= ~via2[vDirA];
if (!events)
return IRQ_NONE;

Expand All @@ -533,76 +550,78 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id)
if (rbv_present)
events &= via2[rSIER];
else
events &= nubus_active;
events &= ~via2[vDirA];
} while (events);
return IRQ_HANDLED;
}

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;
}
}
}

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;
}
}

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 4db6280

Please sign in to comment.