[PATCH] Support for TI1031 PCI -> PCMCIA bridges
Tim Small
tim_small at yahoo.com
Sun May 18 01:16:41 BST 2003
Hi Pavel et al,
I've got my TI1031 working under 2.4.20 now.. This is built on Pavel's
original patch here:
http://lists.insecure.org/lists/linux-kernel/2003/Mar/0012.html
Pavel suggested this different change to pci.c (although I think that if you are presenting a CARDBUS header type then the cardbus vendor and device IDs should be present), but I don't know which is correct:
--- linux.orig/drivers/pci/pci.c
+++ linux/drivers/pci/pci.c
@@ -1405,12 +1405,17 @@ int pci_setup_device(struct pci_dev * de
break;
case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */
- if (class != PCI_CLASS_BRIDGE_CARDBUS)
+ switch (class) {
+ case PCI_CLASS_BRIDGE_CARDBUS:
+ pci_read_bases(dev, 1, 0);
+ pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
+ pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device);
+ /* fallthrough */
+ case PCI_CLASS_BRIDGE_PCMCIA:
+ pci_read_irq(dev);
+ default:
goto bad;
- pci_read_irq(dev);
- pci_read_bases(dev, 1, 0);
- pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
- pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device);
+ }
break;
default: /* unknown header */
The patch below is against a stock 2.4.20 (and so includes Pavel's
original)... I'd be glad of any feedback - particularly if you have a
TI PCI1031 based device (pretty rare, I think). The sypnosis is:
. Change pci.c to allow PCMCIA bridge devices which present CARDBUS PCI
header types (all TI PCI1031s do this, and possibly other similar devices)
. Change the yenta driver to correctly init the 1031, principally
routing interrupts correctly, but also so that PCI <-> PCMCIA bridges
are picked up (this is the only part of the patch that I'm not
particularly sure about)..
Thanks!
Tim.
-------------- next part --------------
--- linux-2.4.20-old/drivers/pcmcia/yenta.c 2003-01-18 22:20:34.000000000 +0000
+++ linux-2.4.20-miniitx/drivers/pcmcia/yenta.c 2003-05-17 23:31:29.000000000 +0100
@@ -798,7 +798,7 @@
struct pci_socket_ops *op;
} cardbus_override[] = {
{ PD(TI,1130), &ti113x_ops },
- { PD(TI,1031), &ti_ops },
+ { PD(TI,1031), &ti113x_ops },
{ PD(TI,1131), &ti113x_ops },
{ PD(TI,1250), &ti1250_ops },
{ PD(TI,1220), &ti_ops },
--- linux-2.4.20-old/drivers/pcmcia/ti113x.h 2003-01-18 22:45:57.000000000 +0000
+++ linux-2.4.20-miniitx/drivers/pcmcia/ti113x.h 2003-05-17 23:30:28.000000000 +0100
@@ -32,6 +32,12 @@
#include <linux/config.h>
+/* Register definitions for TI 103X PCI-to-PCMCIA bridges */
+
+#define TI103X_BRIDGE_CONTROL 0x003e /* 16 bit */
+#define TI103X_BRC_WRITEPOST_ENA 0x0400
+#define TI103X_BRC_PCI_IREQ_ENA 0x0080
+
/* Register definitions for TI 113X PCI-to-CardBus bridges */
/* System Control Register */
@@ -167,6 +173,43 @@
new |= I365_INTR_ENA;
if (new != reg)
exca_writeb(socket, I365_INTCTL, new);
+
+/*
+ * If ISA interrupts don't work, then fall back to routing card
+ * interrupts to the PCI INTA/B interrupt lines (other methods
+ * are the PCI IRQSER pin, or direct connection to the ISA bus
+ * IRQ lines).
+ */
+ if (!socket->cap.irq_mask) {
+ printk (KERN_INFO "ti113x: Routing card interrupts to PCI\n");
+ if (socket->dev->device == PCI_DEVICE_ID_TI_1031) {
+ /* The 1030 may have this interface as well. */
+ int devctl;
+ u16 bridgectl;
+ devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
+ devctl &= ~TI113X_DCR_IMODE_SERIAL;
+
+ /* Route functional interrupts to PCI */
+ bridgectl = config_readw(socket, TI103X_BRIDGE_CONTROL);
+ bridgectl &= ~TI103X_BRC_PCI_IREQ_ENA;
+
+ config_writeb(socket, TI113X_DEVICE_CONTROL, devctl);
+ config_writew(socket, TI103X_BRIDGE_CONTROL, bridgectl);
+ } else {
+ int devctl, irqmux;
+
+ devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
+ devctl &= ~TI113X_DCR_IMODE_MASK;
+
+ /* Is twiddling this register safe on earlier chips? */
+ 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);
+ }
+ }
return 0;
}
--- linux-2.4.20-old/drivers/pci/pci.c 2003-01-18 22:21:11.000000000 +0000
+++ linux-2.4.20-miniitx/drivers/pci/pci.c 2003-05-09 13:12:06.000000000 +0100
@@ -1391,7 +1391,7 @@
break;
case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */
- if (class != PCI_CLASS_BRIDGE_CARDBUS)
+ if ((class != PCI_CLASS_BRIDGE_CARDBUS) && (class != PCI_CLASS_BRIDGE_PCMCIA))
goto bad;
pci_read_irq(dev);
pci_read_bases(dev, 1, 0);
--- linux-2.4.20-old/drivers/pcmcia/pci_socket.c 2001-12-21 17:41:55.000000000 +0000
+++ linux-2.4.20-miniitx/drivers/pcmcia/pci_socket.c 2003-05-17 23:49:14.000000000 +0100
@@ -235,7 +235,7 @@
static struct pci_device_id cardbus_table [] __devinitdata = { {
class: PCI_CLASS_BRIDGE_CARDBUS << 8,
- class_mask: ~0,
+ class_mask: ~(0x02 << 8), /* also allow PCMCIA BRIDGES */
vendor: PCI_ANY_ID,
device: PCI_ANY_ID,
More information about the linux-pcmcia
mailing list