aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/ti113x.h
diff options
context:
space:
mode:
authorDaniel Ritz <daniel.ritz@gmx.ch>2005-06-23 03:10:12 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-23 12:45:31 -0400
commitfa912bcb06d5dc9525d8912a145db2bf4b7668c5 (patch)
tree5c62d9a1ef416c83d3e149ca94c4e646eb29daf2 /drivers/pcmcia/ti113x.h
parent7007cab53176dc906e67b4efa62f20ff1432805a (diff)
[PATCH] yenta TI: turn off interrupts during card power-on #2
- make boot-up card recognition more reliable (ie. redo interrogation always if there is no valid 'card inserted' state) (and yes, i saw it happening on an o2micro controller that both CB_CBARD and CB_16BITCARD bits were set at the same time) - also redo interrogation before probing the ISA interrupts. it's safer to do the probing with the socket in a clean state. - make card insert detect more reliable. yenta_get_status() now returns SS_PENDING as long as the card is not completley inserted and one of the voltage bits is set. also !CB_CBARD doesn't mean CB_16BITCARD. there is CB_NOTACARD as well, so make an explicit check for CB_16BITCARD. - for TI bridges: disable IRQs during power-on. in all-serial and tied interrupt mode the interrupts are always disabled for single-slot controllers. for two-slot contollers the disabling is only done when the other slot is empty. to force disabling there is a new module parameter now: pwr_irqs_off=Y (which is a regression for working setups. that's why it's an option, only use when required) - modparm to disable ISA interrupt probing (isa_probe, defaults to on) - remove unneeded code/cleanups (ie. merge yenta_events() into yenta_interrupts()) Signed-off-by: Daniel Ritz <daniel.ritz@gmx.ch> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/pcmcia/ti113x.h')
-rw-r--r--drivers/pcmcia/ti113x.h167
1 files changed, 167 insertions, 0 deletions
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index a8a1d104524a..c7ba99871aca 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -611,6 +611,170 @@ out:
611 } 611 }
612} 612}
613 613
614
615/* Returns true value if the second slot of a two-slot controller is empty */
616static int ti12xx_2nd_slot_empty(struct yenta_socket *socket)
617{
618 struct pci_dev *func;
619 struct yenta_socket *slot2;
620 int devfn;
621 unsigned int state;
622 int ret = 1;
623
624 /* catch the two-slot controllers */
625 switch (socket->dev->device) {
626 case PCI_DEVICE_ID_TI_1220:
627 case PCI_DEVICE_ID_TI_1221:
628 case PCI_DEVICE_ID_TI_1225:
629 case PCI_DEVICE_ID_TI_1251A:
630 case PCI_DEVICE_ID_TI_1251B:
631 case PCI_DEVICE_ID_TI_1420:
632 case PCI_DEVICE_ID_TI_1450:
633 case PCI_DEVICE_ID_TI_1451A:
634 case PCI_DEVICE_ID_TI_1520:
635 case PCI_DEVICE_ID_TI_1620:
636 case PCI_DEVICE_ID_TI_4520:
637 case PCI_DEVICE_ID_TI_4450:
638 case PCI_DEVICE_ID_TI_4451:
639 /*
640 * there are way more, but they need to be added in yenta_socket.c
641 * and pci_ids.h first anyway.
642 */
643 break;
644
645 /* single-slot controllers have the 2nd slot empty always :) */
646 default:
647 return 1;
648 }
649
650 /* get other slot */
651 devfn = socket->dev->devfn & ~0x07;
652 func = pci_get_slot(socket->dev->bus,
653 (socket->dev->devfn & 0x07) ? devfn : devfn | 0x01);
654 if (!func)
655 return 1;
656
657 slot2 = pci_get_drvdata(func);
658 if (!slot2)
659 goto out;
660
661 /* check state */
662 yenta_get_status(&socket->socket, &state);
663 if (state & SS_DETECT) {
664 ret = 0;
665 goto out;
666 }
667
668out:
669 pci_dev_put(func);
670 return ret;
671}
672
673/*
674 * TI specifiy parts for the power hook.
675 *
676 * some TI's with some CB's produces interrupt storm on power on. it has been
677 * seen with atheros wlan cards on TI1225 and TI1410. solution is simply to
678 * disable any CB interrupts during this time.
679 */
680static int ti12xx_power_hook(struct pcmcia_socket *sock, int operation)
681{
682 struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
683 u32 mfunc, devctl, sysctl;
684 u8 gpio3;
685
686 /* only POWER_PRE and POWER_POST are interesting */
687 if ((operation != HOOK_POWER_PRE) && (operation != HOOK_POWER_POST))
688 return 0;
689
690 devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
691 sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
692 mfunc = config_readl(socket, TI122X_MFUNC);
693
694 /*
695 * all serial/tied: only disable when modparm set. always doing it
696 * would mean a regression for working setups 'cos it disables the
697 * interrupts for both both slots on 2-slot controllers
698 * (and users of single slot controllers where it's save have to
699 * live with setting the modparm, most don't have to anyway)
700 */
701 if (((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) &&
702 (pwr_irqs_off || ti12xx_2nd_slot_empty(socket))) {
703 switch (socket->dev->device) {
704 case PCI_DEVICE_ID_TI_1250:
705 case PCI_DEVICE_ID_TI_1251A:
706 case PCI_DEVICE_ID_TI_1251B:
707 case PCI_DEVICE_ID_TI_1450:
708 case PCI_DEVICE_ID_TI_1451A:
709 case PCI_DEVICE_ID_TI_4450:
710 case PCI_DEVICE_ID_TI_4451:
711 /* these chips have no IRQSER setting in MFUNC3 */
712 break;
713
714 default:
715 if (operation == HOOK_POWER_PRE)
716 mfunc = (mfunc & ~TI122X_MFUNC3_MASK);
717 else
718 mfunc = (mfunc & ~TI122X_MFUNC3_MASK) | TI122X_MFUNC3_IRQSER;
719 }
720
721 return 0;
722 }
723
724 /* do the job differently for func0/1 */
725 if ((PCI_FUNC(socket->dev->devfn) == 0) ||
726 ((sysctl & TI122X_SCR_INTRTIE) &&
727 (pwr_irqs_off || ti12xx_2nd_slot_empty(socket)))) {
728 /* some bridges are different */
729 switch (socket->dev->device) {
730 case PCI_DEVICE_ID_TI_1250:
731 case PCI_DEVICE_ID_TI_1251A:
732 case PCI_DEVICE_ID_TI_1251B:
733 case PCI_DEVICE_ID_TI_1450:
734 /* those oldies use gpio3 for INTA */
735 gpio3 = config_readb(socket, TI1250_GPIO3_CONTROL);
736 if (operation == HOOK_POWER_PRE)
737 gpio3 = (gpio3 & ~TI1250_GPIO_MODE_MASK) | 0x40;
738 else
739 gpio3 &= ~TI1250_GPIO_MODE_MASK;
740 config_writeb(socket, TI1250_GPIO3_CONTROL, gpio3);
741 break;
742
743 default:
744 /* all new bridges are the same */
745 if (operation == HOOK_POWER_PRE)
746 mfunc &= ~TI122X_MFUNC0_MASK;
747 else
748 mfunc |= TI122X_MFUNC0_INTA;
749 config_writel(socket, TI122X_MFUNC, mfunc);
750 }
751 } else {
752 switch (socket->dev->device) {
753 case PCI_DEVICE_ID_TI_1251A:
754 case PCI_DEVICE_ID_TI_1251B:
755 case PCI_DEVICE_ID_TI_1450:
756 /* those have INTA elsewhere and INTB in MFUNC0 */
757 if (operation == HOOK_POWER_PRE)
758 mfunc &= ~TI122X_MFUNC0_MASK;
759 else
760 mfunc |= TI125X_MFUNC0_INTB;
761 config_writel(socket, TI122X_MFUNC, mfunc);
762
763 break;
764
765 default:
766 /* all new bridges are the same */
767 if (operation == HOOK_POWER_PRE)
768 mfunc &= ~TI122X_MFUNC1_MASK;
769 else
770 mfunc |= TI122X_MFUNC1_INTB;
771 config_writel(socket, TI122X_MFUNC, mfunc);
772 }
773 }
774
775 return 0;
776}
777
614static int ti12xx_override(struct yenta_socket *socket) 778static int ti12xx_override(struct yenta_socket *socket)
615{ 779{
616 u32 val, val_orig; 780 u32 val, val_orig;
@@ -654,6 +818,9 @@ static int ti12xx_override(struct yenta_socket *socket)
654 else 818 else
655 ti12xx_irqroute_func1(socket); 819 ti12xx_irqroute_func1(socket);
656 820
821 /* install power hook */
822 socket->socket.power_hook = ti12xx_power_hook;
823
657 return ti_override(socket); 824 return ti_override(socket);
658} 825}
659 826