Re: [PATCH] yenta: irq-routing for TI bridges
From: Pavel Roskin
Date: Mon Feb 23 2004 - 19:52:26 EST
On Tue, 24 Feb 2004, Russell King wrote:
> On Tue, Feb 24, 2004 at 12:33:31AM +0100, Daniel Ritz wrote:
> > this patch should fix up wrongly initialized TI bridges. in a safe way
> > (hopefully).
>
> Unfortunately not.
I admire your ability to see problems so fast.
Could you please look at my patch that I posted many times (attached
again)? It's much simpler than the one by Daniel.
First of all, it removes the old attempts to fix the TI issue. You can
always leave them intact if you want.
The fixup is applied is following conditions are met:
1) The card is a ti12xx or newer. If older cards need any fixups, they
are going to be different. Such cards don't have irqmux.
2) No ISA interrupts were detected. That is, we are not breaking working
systems with ISA or serial ISA interrupts.
3) irqmux (the 32 bit value) is 0. This value is not compatible with
working PCI interrupts. Also, being 0 is a sign that irqmux wasn't
initialized from EEPROM.
Those conditions, if implemented properly (I hope so) mean that we are not
breaking existing functionality.
My testing shows that this patch fixes interrupts on certain TI PCI1410
cards with one slot. I believe they have EEPROM but cannot be programmed.
I actually tried that and I can describe my attempts in more details in a
separate thread.
I also have a two-slot TI PCI1221 card, but it has proper irqmux and
doesn't need any fixups.
If any two-slot TI card needs to be supported, it can be done. Most
likely this patch will set up interrupts at least for one of the slots,
which is good already. I don't trust my skills to code from specs without
testing, so it's quite deliberate that the code makes no attempts to
support the second slot. I can do it using the pcmcia-cs i82365 driver as
the starting point.
Please let me know what I can do make the kernel support TI PCI1410
bridges. I have a lot of them on many systems, and it's quite an
annoyance to patch the kernel every time for each of those systems. I'm
ready to put efforts into fixing this problem permanently.
--
Regards,
Pavel Roskin--- linux.orig/drivers/pcmcia/ti113x.h
+++ linux/drivers/pcmcia/ti113x.h
@@ -281,33 +281,6 @@ static int ti_override(struct yenta_sock
ti_set_zv(socket);
-#if 0
- /*
- * If ISA interrupts don't work, then fall back to routing card
- * interrupts to the PCI interrupt of the socket.
- *
- * Tweaking this when we are using serial PCI IRQs causes hangs
- * --rmk
- */
- if (!socket->socket.irq_mask) {
- u8 irqmux, devctl;
-
- devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
- if ((devctl & TI113X_DCR_IMODE_MASK) != TI12XX_DCR_IMODE_ALL_SERIAL) {
- printk (KERN_INFO "ti113x: Routing card interrupts to PCI\n");
-
- devctl &= ~TI113X_DCR_IMODE_MASK;
-
- irqmux = config_readl(socket, TI122X_IRQMUX);
- irqmux = (irqmux & ~0x0f) | 0x02; /* route INTA */
- irqmux = (irqmux & ~0xf0) | 0x20; /* route INTB */
-
- config_writel(socket, TI122X_IRQMUX, irqmux);
- config_writeb(socket, TI113X_DEVICE_CONTROL, devctl);
- }
- }
-#endif
-
return 0;
}
@@ -347,6 +320,33 @@ static int ti12xx_override(struct yenta_
printk(KERN_INFO "Yenta: Routing CardBus interrupts to %s\n",
(val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA");
+ /*
+ * If ISA interrupts don't work, fall back to routing card
+ * interrupts to the PCI bus. Only do it if multifunction
+ * routing register (irqmux) is in the default state, i.e.
+ * the card wasn't initialized.
+ */
+ if (!socket->socket.irq_mask) {
+ u32 irqmux;
+
+ irqmux = config_readl(socket, TI122X_IRQMUX);
+
+ if (irqmux == 0) {
+ u8 devctl;
+
+ printk (KERN_INFO "ti113x: Uninitialized IRQ routing "
+ "detected, enabling PCI interrupts\n");
+
+ /* Route INTA to MFUNC0 */
+ config_writel(socket, TI122X_IRQMUX, 0x02);
+
+ /* Enable parallel PCI interrupts */
+ devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
+ devctl &= ~TI113X_DCR_IMODE_MASK;
+ config_writeb(socket, TI113X_DEVICE_CONTROL, devctl);
+ }
+ }
+
return ti_override(socket);
}
@@ -366,26 +366,6 @@ static int ti1250_override(struct yenta_
config_writeb(socket, TI1250_DIAGNOSTIC, diag);
}
-#if 0
- /*
- * This is highly machine specific, and we should NOT touch
- * this register - we have no knowledge how the hardware
- * is actually wired.
- *
- * If we're going to do this, we should probably look into
- * using the subsystem IDs.
- *
- * On ThinkPad 380XD, this changes MFUNC0 from the ISA IRQ3
- * output (which it is) to IRQ2. We also change MFUNC1
- * from ISA IRQ4 to IRQ6.
- */
- irqmux = config_readl(socket, TI122X_IRQMUX);
- irqmux = (irqmux & ~0x0f) | 0x02; /* route INTA */
- if (!(ti_sysctl(socket) & TI122X_SCR_INTRTIE))
- irqmux = (irqmux & ~0xf0) | 0x20; /* route INTB */
- config_writel(socket, TI122X_IRQMUX, irqmux);
-#endif
-
return ti12xx_override(socket);
}