[patch for 2.6.12? 2/2] pcmcia: yenta TI: align irq of func1 to func0 if INTRTIE is set

Dominik Brodowski linux at dominikbrodowski.net
Tue May 3 16:18:40 EDT 2005


From: Daniel Ritz <daniel.ritz at gmx.ch>

Make sure that if the INTRTIE bit is set both functions of the
cardbus bridge use the same IRQ before doing any probing...
[ yes i hate the TI bridges for the fact that they are very flexible
  so that so many BIOS vendors get it wrong. ]

Signed-off-by: Daniel Ritz <daniel.ritz at gmx.ch>
Signed-off-by: Dominik Brodowski <linux at dominikbrodowski.net>

---

 drivers/pcmcia/ti113x.h |   40 ++++++++++++++++++++++++++++++----------
 1 files changed, 30 insertions(+), 10 deletions(-)

Index: 2.6.12-rc2/drivers/pcmcia/ti113x.h
===================================================================
--- 2.6.12-rc2.orig/drivers/pcmcia/ti113x.h	2005-04-09 20:57:48.000000000 +0200
+++ 2.6.12-rc2/drivers/pcmcia/ti113x.h	2005-04-09 21:19:03.000000000 +0200
@@ -442,6 +442,25 @@
 }
 
 
+/* changes the irq of func1 to match that of func0 */
+static int ti12xx_align_irqs(struct yenta_socket *socket, int *old_irq)
+{
+	struct pci_dev *func0;
+
+	/* find func0 device */
+	func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07);
+	if (!func0)
+		return 0;
+
+	if (old_irq)
+		*old_irq = socket->cb_irq;
+	socket->cb_irq = socket->dev->irq = func0->irq;
+
+	pci_dev_put(func0);
+
+	return 1;
+}
+
 /*
  * ties INTA and INTB together. also changes the devices irq to that of
  * the function 0 device. call from func1 only.
@@ -449,26 +468,22 @@
  */
 static int ti12xx_tie_interrupts(struct yenta_socket *socket, int *old_irq)
 {
-	struct pci_dev *func0;
 	u32 sysctl;
+	int ret;
 
 	sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
 	if (sysctl & TI122X_SCR_INTRTIE)
 		return 0;
 
-	/* find func0 device */
-	func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07);
-	if (!func0)
+	/* align */
+	ret = ti12xx_align_irqs(socket, old_irq);
+	if (!ret)
 		return 0;
 
-	/* change the interrupt to match func0, tie 'em up */
-	*old_irq = socket->cb_irq;
-	socket->cb_irq = socket->dev->irq = func0->irq;
+	/* tie */
 	sysctl |= TI122X_SCR_INTRTIE;
 	config_writel(socket, TI113X_SYSTEM_CONTROL, sysctl);
 
-	pci_dev_put(func0);
-
 	return 1;
 }
 
@@ -489,7 +504,7 @@
  */
 static void ti12xx_irqroute_func1(struct yenta_socket *socket)
 {
-	u32 mfunc, mfunc_old, devctl;
+	u32 mfunc, mfunc_old, devctl, sysctl;
 	int pci_irq_status;
 
 	mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
@@ -497,6 +512,11 @@
 	printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
 	       pci_name(socket->dev), mfunc, devctl);
 
+	/* if IRQs are configured as tied, align irq of func1 with func0 */
+	sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
+	if (sysctl & TI122X_SCR_INTRTIE)
+		ti12xx_align_irqs(socket, NULL);
+	
 	/* make sure PCI interrupts are enabled before probing */
 	ti_init(socket);
 



More information about the linux-pcmcia mailing list