Skip to contentSkip to conversation

yenta: irq-routing for TI bridges

PATCH In review Daniel Ritz 5 participants 15 messages Feb 23, 2004 – Feb 25, 2004

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 yenta: irq-routing for TI bridges

hi

this patch should fix up wrongly initialized TI bridges. in a safe way (hopefully).

people with a TI bridge please test.
andrew, any chance for this in -mm?
thanx to Guylhem Aznar for testing it.

rgds
-daniel

---patch---

another TI irq routing patch. this one is not blidly guessing what's right. it changes the routing depending on the device control registers. and it only changes the device control register when interrupts are not working at all. this has the following advantages over the old (and disabled in 2.6, but not in 2.4) routing code:
- it shouldn't change working setups
- it's in the right place (the old code is wrong: checks irq_mask before it is set)
- it doens't disable working parallel ISA interrupts
- irqmux is 32bit, the old code operates on a 8bit variable, chaning the routing on 5 of 7 MFUNCs.
- the routing of INTB depends on the chip and the INTRTIE flag in the device control register (may be unsafe, don't know)

against 2.6.3-bk

drivers/pcmcia/ti113x.h +59 -37
@@ -273,6 +273,8 @@
 
 static int ti_override(struct yenta_socket *socket)
 {
+	u32 irqmux, irqmux_old, devctl;
+	unsigned probe_mask;
 	u8 new, reg = exca_readb(socket, I365_INTCTL);
 
 	new = reg & ~I365_INTR_ENA;
@@ -281,33 +283,73 @@
 
 	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
+	 * a more reliable way of changing the IRQMUX. don't blindly guess
+	 * what's right, look up the device control register, change the
+	 * routing depending on that data. only fall back to PCI interrupts
+	 * when it's not working at all. there should be no change to the
+	 * IRQMUX when it's programmed right.
 	 */
-	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 */
+	/* check IRQ routing to see if 16bit cards would work */
+	irqmux = irqmux_old = config_readl(socket, TI122X_IRQMUX);
+	devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
+	printk(KERN_INFO "Yenta TI: irqmux %08x, devctl %02x\n", irqmux, devctl);
+
+#if 1
+	/* serialized interrupts: MFUNC3 must be IRQSER */
+	if (devctl & TI113X_DCR_IMODE_SERIAL)
+		irqmux = (irqmux & ~0xf000) | 0x1000;
+#endif
 
+#if 1
+	/* if we have all serial: probe, fall back to parallel PCI */
+	if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) {
+		/* write down if changed, probe */
+		if (irqmux_old != irqmux) {
+			printk(KERN_INFO "Yenta TI: changing to %08x", irqmux);
 			config_writel(socket, TI122X_IRQMUX, irqmux);
+		}
+	
+		probe_mask = yenta_probe_irq(socket, isa_interrupts);
+		if (!probe_mask) {
+			/* no chance to have all serial working -> PCI */
+			printk(KERN_INFO "Yenta TI: serial interrupts not working -> PCI\n");
+			devctl &= ~TI113X_DCR_IMODE_MASK;
 			config_writeb(socket, TI113X_DEVICE_CONTROL, devctl);
 		}
 	}
 #endif
 
+	/* parallel PCI interrupts: MFUNC0 must be INTA */
+	if ((devctl & TI113X_DCR_IMODE_MASK) != TI12XX_DCR_IMODE_ALL_SERIAL) {
+		u32 sysctl;
+		irqmux = (irqmux & ~0x0f) | 0x02;
+
+		/* route INTB depending on INTRTIE */
+		switch (socket->dev->device) {
+			/* there are more... */
+			case PCI_DEVICE_ID_TI_1220:
+			case PCI_DEVICE_ID_TI_1221:
+			case PCI_DEVICE_ID_TI_1225:
+			case PCI_DEVICE_ID_TI_1420:
+			case PCI_DEVICE_ID_TI_1450:
+			//case PCI_DEVICE_ID_TI_1451:
+			case PCI_DEVICE_ID_TI_1520:
+				sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
+				if (!(sysctl & TI122X_SCR_INTRTIE))
+					irqmux = (irqmux & ~0xf0) | 0x20;
+
+			default:
+				break;
+		}
+	}
+
+	if (irqmux_old != irqmux) {
+		printk(KERN_INFO "Yenta TI: changing to %08x", irqmux);
+		config_writel(socket, TI122X_IRQMUX, irqmux);
+	}
+
 	return 0;
 }
 
@@ -365,26 +407,6 @@
 			old, diag);
 		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);
 }

===== drivers/pcmcia/yenta_socket.c 1.51 vs edited =====

drivers/pcmcia/yenta_socket.c +55 -52

125 lines not on this page · raw message

#1 lore raw
Quoted 2 lines · Daniel Ritz

this patch should fix up wrongly initialized TI bridges. in a safe way (hopefully).

Unfortunately not.

This is a working setup:

DCR = 6162
MUX = fba97543

Changing MUX from those values _breaks_. Let's see what the code does.

drivers/pcmcia/ti113x.h line 303

Quoted 10 lines
drivers/pcmcia/ti113x.h +10 -0
+	/* check IRQ routing to see if 16bit cards would work */
+	irqmux = irqmux_old = config_readl(socket, TI122X_IRQMUX);
+	devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
+	printk(KERN_INFO "Yenta TI: irqmux %08x, devctl %02x\n", irqmux, devctl);
+
+#if 1
+	/* serialized interrupts: MFUNC3 must be IRQSER */
+	if (devctl & TI113X_DCR_IMODE_SERIAL)
+		irqmux = (irqmux & ~0xf000) | 0x1000;
+#endif

DCR doesn't have bit 2 set, so we don't change this (which is fine.)

drivers/pcmcia/ti113x.h line 307

Quoted 4 lines
drivers/pcmcia/ti113x.h +3 -0
+#if 1
+	/* if we have all serial: probe, fall back to parallel PCI */
+	if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) {

Not true, so this is skipped (which again is fine.)

Quoted 8 lines
drivers/pcmcia/ti113x.h +7 -0
+		/* write down if changed, probe */
+		if (irqmux_old != irqmux) {
+			printk(KERN_INFO "Yenta TI: changing to %08x", irqmux);
 			config_writel(socket, TI122X_IRQMUX, irqmux);
+		}
+	
+		probe_mask = yenta_probe_irq(socket, isa_interrupts);
+		if (!probe_mask) {

drivers/pcmcia/ti113x.h line 325

Quoted 10 lines
drivers/pcmcia/ti113x.h +5 -0
+			/* no chance to have all serial working -> PCI */
+			printk(KERN_INFO "Yenta TI: serial interrupts not working -> PCI\n");
+			devctl &= ~TI113X_DCR_IMODE_MASK;
 			config_writeb(socket, TI113X_DEVICE_CONTROL, devctl);
 		}
 	}
 #endif
 
+	/* parallel PCI interrupts: MFUNC0 must be INTA */
+	if ((devctl & TI113X_DCR_IMODE_MASK) != TI12XX_DCR_IMODE_ALL_SERIAL) {

Ok, this is true.

drivers/pcmcia/ti113x.h line 327

Quoted 2 lines
drivers/pcmcia/ti113x.h +2 -0
+		u32 sysctl;
+		irqmux = (irqmux & ~0x0f) | 0x02;

Whoops, we've just taken out IRQ3 as a routed ISA IRQ.

Quoted 4 lines
drivers/pcmcia/ti113x.h +4 -0
+
+		/* route INTB depending on INTRTIE */
+		switch (socket->dev->device) {
+			/* there are more... */

drivers/pcmcia/ti113x.h line 341

Quoted 10 lines
drivers/pcmcia/ti113x.h +10 -0
+			case PCI_DEVICE_ID_TI_1220:
+			case PCI_DEVICE_ID_TI_1221:
+			case PCI_DEVICE_ID_TI_1225:
+			case PCI_DEVICE_ID_TI_1420:
+			case PCI_DEVICE_ID_TI_1450:
+			//case PCI_DEVICE_ID_TI_1451:
+			case PCI_DEVICE_ID_TI_1520:
+				sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
+				if (!(sysctl & TI122X_SCR_INTRTIE))
+					irqmux = (irqmux & ~0xf0) | 0x20;

Whoops, just taken out IRQ4 as a routed ISA IRQ.

drivers/pcmcia/ti113x.h line 351

Quoted 10 lines
drivers/pcmcia/ti113x.h +10 -0
+
+			default:
+				break;
+		}
+	}
+
+	if (irqmux_old != irqmux) {
+		printk(KERN_INFO "Yenta TI: changing to %08x", irqmux);
+		config_writel(socket, TI122X_IRQMUX, irqmux);
+	}

Net result - not good and probably not acceptable.

Signature · 4 lines
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core
#2 lore raw
Quoted 54 lines · Russell King
Quoted 2 lines · Daniel Ritz

this patch should fix up wrongly initialized TI bridges. in a safe way (hopefully).

Unfortunately not.

This is a working setup:

DCR = 6162
MUX = fba97543

Changing MUX from those values _breaks_. Let's see what the code does.

drivers/pcmcia/ti113x.h line 303

Quoted 10 lines
drivers/pcmcia/ti113x.h +10 -0
+	/* check IRQ routing to see if 16bit cards would work */
+	irqmux = irqmux_old = config_readl(socket, TI122X_IRQMUX);
+	devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
+	printk(KERN_INFO "Yenta TI: irqmux %08x, devctl %02x\n", irqmux, devctl);
+
+#if 1
+	/* serialized interrupts: MFUNC3 must be IRQSER */
+	if (devctl & TI113X_DCR_IMODE_SERIAL)
+		irqmux = (irqmux & ~0xf000) | 0x1000;
+#endif

DCR doesn't have bit 2 set, so we don't change this (which is fine.)

drivers/pcmcia/ti113x.h line 307

Quoted 4 lines
drivers/pcmcia/ti113x.h +3 -0
+#if 1
+	/* if we have all serial: probe, fall back to parallel PCI */
+	if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) {

Not true, so this is skipped (which again is fine.)

Quoted 8 lines
drivers/pcmcia/ti113x.h +7 -0
+		/* write down if changed, probe */
+		if (irqmux_old != irqmux) {
+			printk(KERN_INFO "Yenta TI: changing to %08x", irqmux);
 			config_writel(socket, TI122X_IRQMUX, irqmux);
+		}
+	
+		probe_mask = yenta_probe_irq(socket, isa_interrupts);
+		if (!probe_mask) {

drivers/pcmcia/ti113x.h line 325

Quoted 10 lines
drivers/pcmcia/ti113x.h +5 -0
+			/* no chance to have all serial working -> PCI */
+			printk(KERN_INFO "Yenta TI: serial interrupts not working -> PCI\n");
+			devctl &= ~TI113X_DCR_IMODE_MASK;
 			config_writeb(socket, TI113X_DEVICE_CONTROL, devctl);
 		}
 	}
 #endif
 
+	/* parallel PCI interrupts: MFUNC0 must be INTA */
+	if ((devctl & TI113X_DCR_IMODE_MASK) != TI12XX_DCR_IMODE_ALL_SERIAL) {

Ok, this is true.

Quoted 4 lines

drivers/pcmcia/ti113x.h line 327

Quoted 2 lines
drivers/pcmcia/ti113x.h +2 -0
+		u32 sysctl;
+		irqmux = (irqmux & ~0x0f) | 0x02;

Whoops, we've just taken out IRQ3 as a routed ISA IRQ.

ok, not good. what about: read the routing in MFUNC0, test if it works, only set to PCI if it doesn't work. the problem is we can't test if another device already sits on that irq. we shouldn't do anything then.

Quoted 17 lines
Quoted 5 lines
drivers/pcmcia/ti113x.h +4 -0
+
+		/* route INTB depending on INTRTIE */
+		switch (socket->dev->device) {
+			/* there are more... */

drivers/pcmcia/ti113x.h line 341

Quoted 10 lines
drivers/pcmcia/ti113x.h +10 -0
+			case PCI_DEVICE_ID_TI_1220:
+			case PCI_DEVICE_ID_TI_1221:
+			case PCI_DEVICE_ID_TI_1225:
+			case PCI_DEVICE_ID_TI_1420:
+			case PCI_DEVICE_ID_TI_1450:
+			//case PCI_DEVICE_ID_TI_1451:
+			case PCI_DEVICE_ID_TI_1520:
+				sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
+				if (!(sysctl & TI122X_SCR_INTRTIE))
+					irqmux = (irqmux & ~0xf0) | 0x20;

Whoops, just taken out IRQ4 as a routed ISA IRQ.

same as for MFUNC0: test first. or delete that part. and even set IRQTIE on these chips if we have to use PCI fallback?

Quoted 13 lines

drivers/pcmcia/ti113x.h line 351

Quoted 11 lines
drivers/pcmcia/ti113x.h +10 -0
+
+			default:
+				break;
+		}
+	}
+
+	if (irqmux_old != irqmux) {
+		printk(KERN_INFO "Yenta TI: changing to %08x", irqmux);
+		config_writel(socket, TI122X_IRQMUX, irqmux);
+	}

Net result - not good and probably not acceptable.

yeah, not as it is now. more checks are needed, PCI fallback only if nothing else works. may be we should just make it a module param like in pcmcia-cs i82365.c?

new patch later today (first some sleep and work)

Quoted 8 lines
Signature · 5 lines
-- 
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core
#3 lore raw
Quoted 3 lines · Daniel Ritz

ok, not good. what about: read the routing in MFUNC0, test if it works, only set to PCI if it doesn't work. the problem is we can't test if another device already sits on that irq. we shouldn't do anything then.

What if we just check if irqmux is 0. Is it 0 on your card? I believe the only problem is the the cards that don't have irqmux initialized from EEPROM.

I think that your fix is too intrusive. I'm not sure it's worth it. After all, we are not going to support every possible piece of broken hardware, only those that are relatively widespread. I have one, you have one (presumably), let's see what we have.

Could you please give more information about your hardware? My hardware is a card based on TI PCI1410 with broken EEPROM. It has one slot. irqmux is 0 on startup. Attempts to write to EEPROM damage the card permanently. It stops working as a valid PCI device and prevents booting Linux with PCI support.

I'm concerned that you are reading irqmux in ti_override(), which is also used in bridges without irqmux. Those bridges only need changes in devctl if any. The fix should be in ti12xx_override() or even ti1250_override().

Quoted 3 lines

yeah, not as it is now. more checks are needed, PCI fallback only if nothing else works. may be we should just make it a module param like in pcmcia-cs i82365.c?

The parameter would be the last resort. Shifting the problem to the users is more like a surrender than a victory. Not to mention that such approach won't work well with multiple card and/or solid kernel.

Signature · 2 lines
Regards,
Pavel Roskin
#4 lore raw
Quoted 8 lines · Pavel Roskin
Quoted 3 lines · Daniel Ritz

ok, not good. what about: read the routing in MFUNC0, test if it works, only set to PCI if it doesn't work. the problem is we can't test if another device already sits on that irq. we shouldn't do anything then.

What if we just check if irqmux is 0. Is it 0 on your card? I believe the only problem is the the cards that don't have irqmux initialized from EEPROM.

not good. newer chips (eg 1520) have a default value != 0. when a manufacter forgets the serial ROM and does nothing in the BIOS you end up with default values (eg. the 1520 has all serial interrupts). for the 1410 irqmux defaults to 0.

Quoted 2 lines

I think that your fix is too intrusive. I'm not sure it's worth it.

currently yes, i try to do better in the next version.

Quoted 4 lines

After all, we are not going to support every possible piece of broken hardware, only those that are relatively widespread. I have one, you have one (presumably), let's see what we have.

not broken hardware. uninitialized hardware. hardware that doesn't work with yenta_socket but works with some redmond os...bad...

Quoted 5 lines

Could you please give more information about your hardware? My hardware is a card based on TI PCI1410 with broken EEPROM. It has one slot. irqmux is 0 on startup. Attempts to write to EEPROM damage the card permanently. It stops working as a valid PCI device and prevents booting Linux with PCI support.

it's a 1410. and it's working. almost. with the redmond os it works, with linux it works too and with freebsd the laptop dies as soon as inserting a card.

it's programmed for serial interrputs and PCI, INTA is routed. so not really a problem there. (and my patch does _nothing_ there :)

Quoted 4 lines

I'm concerned that you are reading irqmux in ti_override(), which is also used in bridges without irqmux. Those bridges only need changes in devctl if any. The fix should be in ti12xx_override() or even ti1250_override().

good catch...ti113x is one w/o irqmux...so yes ti12xx_override is the right place. another bug in the disabled code...and i think in 2.4 too)

Quoted 8 lines
Quoted 4 lines

yeah, not as it is now. more checks are needed, PCI fallback only if nothing else works. may be we should just make it a module param like in pcmcia-cs i82365.c?

The parameter would be the last resort. Shifting the problem to the users is more like a surrender than a victory. Not to mention that such approach won't work well with multiple card and/or solid kernel.

of course a module param would suck. that's why i didn't write code.

there's another bug btw. one that is probably never hit and harmless too:
rmk's notbook has parellel isa interrupts, INTA is _not_ routed. if it happens that all the interrupts are taken by other devices the resource manager falls back to routing the card to PCI which we know is not working...however it is not happening on a notebook.

#5 lore raw
Quoted 2 lines · Daniel Ritz

there's another bug btw. one that is probably never hit and harmless too:
rmk's notbook has parellel isa interrupts, INTA is _not_ routed.

Not true. It has parallel ISA interrupts _and_ parallel PCI interrupts. It's a TI 1250. Unfortunately, the 1250 data sheet isn't available, however there seems to be some consistency in the device codes to features offered.

The 1450 and 1251A (both of which seem similar to 1250) has separate pins for PCI parallel interrupts which are outside the control of the "IRQMUX" register. When these pins are not used for parallel PCI interrupts, they function as "GPIO3" and "IRQSER" (for PCI serial interrupts) respectively. The function of these pins is controlled by the device control register.

Please note that "IRQMUX" is a misleading definition of the register in question. The register programs various multifunction pins on the device which _may_ be IRQ outputs, LED outputs, ZV switching outputs, audio, or even GPIO.

Signature · 4 lines
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core
#6 lore raw

[removing akpm from cc as it is pcmcia centric]

Quoted 8 lines · Russell King
Quoted 2 lines · Daniel Ritz

there's another bug btw. one that is probably never hit and harmless too:
rmk's notbook has parellel isa interrupts, INTA is _not_ routed.

Not true. It has parallel ISA interrupts _and_ parallel PCI interrupts. It's a TI 1250. Unfortunately, the 1250 data sheet isn't available, however there seems to be some consistency in the device codes to features offered.

ok, i see the 1250, 1450 are different. the 1410/1520 doc says nothing about it. did i miss something about the 1410/1520/etc ?

Quoted 8 lines

The 1450 and 1251A (both of which seem similar to 1250) has separate pins for PCI parallel interrupts which are outside the control of the "IRQMUX" register. When these pins are not used for parallel PCI interrupts, they function as "GPIO3" and "IRQSER" (for PCI serial interrupts) respectively. The function of these pins is controlled by the device control register.

Quoted 4 lines

Please note that "IRQMUX" is a misleading definition of the register in question. The register programs various multifunction pins on the device which _may_ be IRQ outputs, LED outputs, ZV switching outputs, audio, or even GPIO.

TI calls it Multifunction Routing Register for a reason :)

so i think the safe way would be:
- move routing code to 12xx_override()
- first test interrupts, do nothing if working correct
- try to reflect the settings in device control register, test again
- fall back to pci if nothing works
- handle the 125x/1450 by not touching MFUNC0
- don't do INTB routing, set INTRTIE instead (on 2 slot chips) (- remove the bad code from 2.4 and do the same)

#7 lore raw

PATCH 1/1 yenta: irq-routing for TI bridges - take 2

hi

the last patch was bad...chaning stuff it shouldn't on TI125x, 145x...

another try...comments?
couldn't find datasheets for 1210, 1220, 1250 so i'm not quite sure about them.... compile tested (my TI works, so no difference there)

against 2.6.3-bk

rgds
-daniel

include/linux/pci_ids.h +2 -0
@@ -704,6 +704,7 @@
 #define PCI_VENDOR_ID_TI		0x104c
 #define PCI_DEVICE_ID_TI_TVP4010	0x3d04
 #define PCI_DEVICE_ID_TI_TVP4020	0x3d07
+#define PCI_DEVICE_ID_TI_4450		0x8011
 #define PCI_DEVICE_ID_TI_1130		0xac12
 #define PCI_DEVICE_ID_TI_1031		0xac13
 #define PCI_DEVICE_ID_TI_1131		0xac15
@@ -720,6 +721,7 @@
 #define PCI_DEVICE_ID_TI_4451		0xac42
 #define PCI_DEVICE_ID_TI_1410		0xac50
 #define PCI_DEVICE_ID_TI_1420		0xac51
+#define PCI_DEVICE_ID_TI_1451A		0xac52
 #define PCI_DEVICE_ID_TI_1520		0xac55
 #define PCI_DEVICE_ID_TI_1510		0xac56
 
drivers/pcmcia/yenta_socket.c +56 -54

138 lines not on this page · raw message

drivers/pcmcia/ti113x.h +103 -50

183 lines not on this page · raw message

#8 lore raw

Re: [PATCH] yenta: irq-routing for TI bridges - take 2

Quoted 6 lines · Daniel Ritz

hi

the last patch was bad...chaning stuff it shouldn't on TI125x, 145x...

another try...comments?
couldn't find datasheets for 1210, 1220, 1250 so i'm not quite sure about them....

http://www.mit.edu/afs/sipb/contrib/doc/specs/ic/bridge/

Quoted 1 line

compile tested (my TI works, so no difference there)

Works for me. yenta_socket is compiled into the kernel. Two cards: TI 1221 with 2 slots (no fixup needed) and TI 1410 that needs it.

Yenta: CardBus bridge found at 0000:00:08.0 [133f:1233]
Yenta: Enabling burst memory read transactions
Yenta: Using CSCINT to route CSC interrupts to PCI
Yenta: Routing CardBus interrupts to PCI
Yenta TI: mfunc 0cc07d92, devctl 60
Yenta: ISA IRQ mask 0x0000, PCI irq 5
Socket status: 30000006
Yenta: CardBus bridge found at 0000:00:08.1 [133f:1233]
Yenta: Using CSCINT to route CSC interrupts to PCI
Yenta: Routing CardBus interrupts to PCI
Yenta TI: mfunc 0cc07d92, devctl 60
Yenta: ISA IRQ mask 0x0000, PCI irq 5
Socket status: 30000006
Yenta: CardBus bridge found at 0000:00:0a.0 [0000:0000]
Yenta: Enabling burst memory read transactions
Yenta: Using CSCINT to route CSC interrupts to PCI
Yenta: Routing CardBus interrupts to PCI
Yenta TI: mfunc 00000000, devctl 66
Yenta TI: changing mfunc to 00001000
Yenta TI: falling back to PCI interrupts
Yenta TI: changing mfunc to 00001002
Yenta: ISA IRQ mask 0x0000, PCI irq 12

$ cat /proc/interrupts
           CPU0
  0:     664717          XT-PIC  timer
  1:       1530          XT-PIC  i8042
  2:          0          XT-PIC  cascade
  5:          3          XT-PIC  yenta, yenta, orinoco_cs
  7:          0          XT-PIC  acpi
  8:          4          XT-PIC  rtc
 10:       1502          XT-PIC  uhci_hcd, uhci_hcd
 11:         46          XT-PIC  eth0
 12:          3          XT-PIC  yenta, VIA686A, orinoco_cs
 14:      36354          XT-PIC  ide0
 15:         21          XT-PIC  ide1
NMI:          0
ERR:          0
Signature · 2 lines
Regards,
Pavel Roskin
#9 lore raw

Re: [PATCH] yenta: irq-routing for TI bridges - take 2

Quoted 10 lines · Pavel Roskin
Quoted 6 lines · Daniel Ritz

hi

the last patch was bad...chaning stuff it shouldn't on TI125x, 145x...

another try...comments?
couldn't find datasheets for 1210, 1220, 1250 so i'm not quite sure about them....

http://www.mit.edu/afs/sipb/contrib/doc/specs/ic/bridge/

thanks...i looked at the 1220 datasheet and it seems the chip is sane enough so no special case like the 1250 is needed. the 1210 should be just the same but with only one slot.

Quoted 6 lines
Quoted 2 lines

compile tested (my TI works, so no difference there)

Works for me. yenta_socket is compiled into the kernel. Two cards: TI 1221 with 2 slots (no fixup needed) and TI 1410 that needs it.

nice to hear it works.

Quoted 6 lines

Yenta: CardBus bridge found at 0000:00:08.0 [133f:1233]
Yenta: Enabling burst memory read transactions
Yenta: Using CSCINT to route CSC interrupts to PCI
Yenta: Routing CardBus interrupts to PCI
Yenta TI: mfunc 0cc07d92, devctl 60

mfunc0 is inta, mfunc1 is irq9, mfunc2 is activity led, mfunc3 is irq7, mfunc4 GPI3, mfunc5 is the other led, mfunc6 is irq12...

this would give you irq7,9,12 but device control says parallel PCI only..

Quoted 5 lines

Yenta: ISA IRQ mask 0x0000, PCI irq 5
Socket status: 30000006
Yenta: CardBus bridge found at 0000:00:08.1 [133f:1233]
Yenta: Using CSCINT to route CSC interrupts to PCI
Yenta: Routing CardBus interrupts to PCI

Quoted 8 lines

Yenta TI: mfunc 0cc07d92, devctl 60
Yenta: ISA IRQ mask 0x0000, PCI irq 5
Socket status: 30000006
Yenta: CardBus bridge found at 0000:00:0a.0 [0000:0000]
Yenta: Enabling burst memory read transactions
Yenta: Using CSCINT to route CSC interrupts to PCI
Yenta: Routing CardBus interrupts to PCI
Yenta TI: mfunc 00000000, devctl 66

that's just an uninitialized ti1410. so we're using PCI

Quoted 5 lines

Yenta TI: changing mfunc to 00001000
Yenta TI: falling back to PCI interrupts
Yenta TI: changing mfunc to 00001002
Yenta: ISA IRQ mask 0x0000, PCI irq 12

Quoted 20 lines
$ cat /proc/interrupts
           CPU0
  0:     664717          XT-PIC  timer
  1:       1530          XT-PIC  i8042
  2:          0          XT-PIC  cascade
  5:          3          XT-PIC  yenta, yenta, orinoco_cs
  7:          0          XT-PIC  acpi
  8:          4          XT-PIC  rtc
 10:       1502          XT-PIC  uhci_hcd, uhci_hcd
 11:         46          XT-PIC  eth0
 12:          3          XT-PIC  yenta, VIA686A, orinoco_cs
 14:      36354          XT-PIC  ide0
 15:         21          XT-PIC  ide1
NMI:          0
ERR:          0
Signature · 2 lines
Regards,
Pavel Roskin

rgds
-daniel

#10 lore raw

Re: [PATCH] yenta: irq-routing for TI bridges - take 2

Quoted 10 lines · Daniel Ritz
Quoted 5 lines

Yenta: CardBus bridge found at 0000:00:08.0 [133f:1233]
Yenta: Enabling burst memory read transactions
Yenta: Using CSCINT to route CSC interrupts to PCI
Yenta: Routing CardBus interrupts to PCI
Yenta TI: mfunc 0cc07d92, devctl 60

mfunc0 is inta, mfunc1 is irq9, mfunc2 is activity led, mfunc3 is irq7, mfunc4 GPI3, mfunc5 is the other led, mfunc6 is irq12...

this would give you irq7,9,12 but device control says parallel PCI only..

That's not surprising. The card is a PCI device, it's not connected to the ISA bus.

[snip]

Quoted 5 lines

that's just an uninitialized ti1410. so we're using PCI

Quoted 2 lines

Yenta TI: changing mfunc to 00001000
Yenta TI: falling back to PCI interrupts

By the way, I looked through your mails an I still don't quite understand what the above is for. I understand you are trying serial ISA interrupts first. What's the reason for that? Do you know any device that needs this? I would prefer not to add any code unless it's known to be needed. Any probe is potentially dangerous. The known problems are with PCI cards, which have PCI interrupts and don't need anything else. I believe laptops are engineered better and don't need any fixes.

Quoted 2 lines
Quoted 2 lines

Yenta TI: changing mfunc to 00001002
Yenta: ISA IRQ mask 0x0000, PCI irq 12

Apparently you are enabling INTA. Shouldn't you disable serial ISA interrupts if they didn't work?

I also think you are using mfunc_old incorrectly. Either it should be the current value of irqmux, in which case you should change it when testing serial ISA interrupts, or it's the initial value of irqmux, in which case you shouldn't compare it to mfunc the second time. You cannot have it both ways. Please create one more variable, e.g. mfunc_current.

Signature · 2 lines
Regards,
Pavel Roskin
#11 lore raw

Re: [PATCH] yenta: irq-routing for TI bridges - take 2

Quoted 8 lines · Pavel Roskin
Quoted 6 lines · Daniel Ritz
Quoted 5 lines

Yenta: CardBus bridge found at 0000:00:08.0 [133f:1233]
Yenta: Enabling burst memory read transactions
Yenta: Using CSCINT to route CSC interrupts to PCI
Yenta: Routing CardBus interrupts to PCI
Yenta TI: mfunc 0cc07d92, devctl 60

Quoted 7 lines
Quoted 4 lines

mfunc0 is inta, mfunc1 is irq9, mfunc2 is activity led, mfunc3 is irq7, mfunc4 GPI3, mfunc5 is the other led, mfunc6 is irq12...

this would give you irq7,9,12 but device control says parallel PCI only..

That's not surprising. The card is a PCI device, it's not connected to the ISA bus.

that explains it...

Quoted 8 lines

[snip]

Quoted 5 lines

that's just an uninitialized ti1410. so we're using PCI

Quoted 2 lines

Yenta TI: changing mfunc to 00001000
Yenta TI: falling back to PCI interrupts

Quoted 8 lines

By the way, I looked through your mails an I still don't quite understand what the above is for. I understand you are trying serial ISA interrupts first. What's the reason for that? Do you know any device that needs this? I would prefer not to add any code unless it's known to be needed. Any probe is potentially dangerous. The known problems are with PCI cards, which have PCI interrupts and don't need anything else. I believe laptops are engineered better and don't need any fixes.

it's looking at the device control register first. if it's configured for serial interutps then test it...my laptop for example uses serial interrupts (plus the parallel PCI)

may be there are cards out there that need an exclusive interrupt. i don't know.

the reason why i did it is the comment in the old code:

/*
* 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
*/

the comment is there for a reason. so make sure DEVCTL is wrong, not MFUNC. if we do check for all serial and don't fall back to PCI, the code wouldn't fixup most of the non-working setups.

Quoted 5 lines
Quoted 2 lines
Quoted 2 lines

Yenta TI: changing mfunc to 00001002
Yenta: ISA IRQ mask 0x0000, PCI irq 12

Apparently you are enabling INTA. Shouldn't you disable serial ISA interrupts if they didn't work?

it does so by masking out the routing bits in the device control register, it set it to PCI only...but read on

Quoted 7 lines

I also think you are using mfunc_old incorrectly. Either it should be the current value of irqmux, in which case you should change it when testing serial ISA interrupts, or it's the initial value of irqmux, in which case you shouldn't compare it to mfunc the second time. You cannot have it both ways. Please create one more variable, e.g. mfunc_current.

no, it's the way it should be. but it should really go back to the old value if serial interrupts probing failed. then it would be correct.

Quoted 5 lines
Signature · 2 lines
Regards,
Pavel Roskin

rgds,
-daniel

#12 lore raw
In reply to Russell King
Quoted 5 lines · Russell King

Not true. It has parallel ISA interrupts _and_ parallel PCI interrupts. It's a TI 1250. Unfortunately, the 1250 data sheet isn't available, however there seems to be some consistency in the device codes to features offered.

I have a TI 1250 data sheet (well 1250A, which is what I think you actually have).

Quoted 6 lines

The 1450 and 1251A (both of which seem similar to 1250) has separate pins for PCI parallel interrupts which are outside the control of the "IRQMUX" register. When these pins are not used for parallel PCI interrupts, they function as "GPIO3" and "IRQSER" (for PCI serial interrupts) respectively. The function of these pins is controlled by the device control register.

The 1250A is the same.

-- Dave

#13 lore raw
In reply to Russell King
Quoted 5 lines · Russell King
Quoted 2 lines · Daniel Ritz

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.

Signature · 2 lines
Regards,
Pavel Roskin
drivers/pcmcia/ti113x.h +27 -47
@@ -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);
 }
 
#14 lore raw
Quoted 8 lines · Pavel Roskin
Quoted 5 lines · Russell King
Quoted 2 lines · Daniel Ritz

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.

Only because I've hit this problem before. With the original IRQMUX patches, they managed to probe the available IRQs (finding IRQ3 and IRQ4 available) and then changed IRQMUX preventing these signals working.

The net result was that an inserted card was allocated IRQ3 or IRQ4 and no surprises that it was unable to signal its interrupt.

Signature · 4 lines
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core