aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/ti113x.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/ti113x.h')
-rw-r--r--drivers/pcmcia/ti113x.h40
1 files changed, 30 insertions, 10 deletions
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index 52c073a9d7e4..a8a1d104524a 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -442,6 +442,25 @@ out:
442} 442}
443 443
444 444
445/* changes the irq of func1 to match that of func0 */
446static int ti12xx_align_irqs(struct yenta_socket *socket, int *old_irq)
447{
448 struct pci_dev *func0;
449
450 /* find func0 device */
451 func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07);
452 if (!func0)
453 return 0;
454
455 if (old_irq)
456 *old_irq = socket->cb_irq;
457 socket->cb_irq = socket->dev->irq = func0->irq;
458
459 pci_dev_put(func0);
460
461 return 1;
462}
463
445/* 464/*
446 * ties INTA and INTB together. also changes the devices irq to that of 465 * ties INTA and INTB together. also changes the devices irq to that of
447 * the function 0 device. call from func1 only. 466 * the function 0 device. call from func1 only.
@@ -449,26 +468,22 @@ out:
449 */ 468 */
450static int ti12xx_tie_interrupts(struct yenta_socket *socket, int *old_irq) 469static int ti12xx_tie_interrupts(struct yenta_socket *socket, int *old_irq)
451{ 470{
452 struct pci_dev *func0;
453 u32 sysctl; 471 u32 sysctl;
472 int ret;
454 473
455 sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); 474 sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
456 if (sysctl & TI122X_SCR_INTRTIE) 475 if (sysctl & TI122X_SCR_INTRTIE)
457 return 0; 476 return 0;
458 477
459 /* find func0 device */ 478 /* align */
460 func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07); 479 ret = ti12xx_align_irqs(socket, old_irq);
461 if (!func0) 480 if (!ret)
462 return 0; 481 return 0;
463 482
464 /* change the interrupt to match func0, tie 'em up */ 483 /* tie */
465 *old_irq = socket->cb_irq;
466 socket->cb_irq = socket->dev->irq = func0->irq;
467 sysctl |= TI122X_SCR_INTRTIE; 484 sysctl |= TI122X_SCR_INTRTIE;
468 config_writel(socket, TI113X_SYSTEM_CONTROL, sysctl); 485 config_writel(socket, TI113X_SYSTEM_CONTROL, sysctl);
469 486
470 pci_dev_put(func0);
471
472 return 1; 487 return 1;
473} 488}
474 489
@@ -489,7 +504,7 @@ static void ti12xx_untie_interrupts(struct yenta_socket *socket, int old_irq)
489 */ 504 */
490static void ti12xx_irqroute_func1(struct yenta_socket *socket) 505static void ti12xx_irqroute_func1(struct yenta_socket *socket)
491{ 506{
492 u32 mfunc, mfunc_old, devctl; 507 u32 mfunc, mfunc_old, devctl, sysctl;
493 int pci_irq_status; 508 int pci_irq_status;
494 509
495 mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC); 510 mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
@@ -497,6 +512,11 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
497 printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n", 512 printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
498 pci_name(socket->dev), mfunc, devctl); 513 pci_name(socket->dev), mfunc, devctl);
499 514
515 /* if IRQs are configured as tied, align irq of func1 with func0 */
516 sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
517 if (sysctl & TI122X_SCR_INTRTIE)
518 ti12xx_align_irqs(socket, NULL);
519
500 /* make sure PCI interrupts are enabled before probing */ 520 /* make sure PCI interrupts are enabled before probing */
501 ti_init(socket); 521 ti_init(socket);
502 522