summaryrefslogtreecommitdiffstats
path: root/sys/pccard/pcic.c
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2001-08-01 19:41:56 +0000
committerimp <imp@FreeBSD.org>2001-08-01 19:41:56 +0000
commit15c0c44955c2d18e4582a561777c0536482d5478 (patch)
tree13cf87427c226ea014ca373b7c76eea30d1a6252 /sys/pccard/pcic.c
parent19b910842dfd92ac9592f6c8681e8d1d0f199805 (diff)
downloadFreeBSD-src-15c0c44955c2d18e4582a561777c0536482d5478.zip
FreeBSD-src-15c0c44955c2d18e4582a561777c0536482d5478.tar.gz
TI cardbus bridges, 12xx and newer, have an interesting register. It
is the diagnostics register at offset 0x93. When bit 5 is set in this register, bits 4-7 in ExCA register 0x5 being 0000 are required for pci interrupt routing. When it is clear, then bit 4 of ExCA register 0x3 is used to enable it. The only other issue is that when you route interrupts this way, you must read ExCA register 0x4 in order to clear the interrupt, else you get an interrupt storm. Deal with this requirement by setting things up. It is believed that this won't hurt other chipsets, but other chipsets may require their own work arounds.
Diffstat (limited to 'sys/pccard/pcic.c')
-rw-r--r--sys/pccard/pcic.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/sys/pccard/pcic.c b/sys/pccard/pcic.c
index 2b2b4da..a716e0a 100644
--- a/sys/pccard/pcic.c
+++ b/sys/pccard/pcic.c
@@ -308,13 +308,34 @@ pcic_do_mgt_irq(struct pcic_slot *sp, int irq)
u_int32_t reg;
if (sp->sc->csc_route == pci_parallel) {
+ /* Do the PCI side of things: Enable the Card Change int */
reg = CB_SM_CD;
bus_space_write_4(sp->bst, sp->bsh, CB_SOCKET_MASK, reg);
+ /*
+ * TI Chips need us to set the following. We tell the
+ * controller to route things via PCI interrupts. Also
+ * we clear the interrupt number in the STAT_INT register
+ * as well. The TI-12xx and newer chips require one or the
+ * other of these to happen, depending on what is set in the
+ * diagnostic register. I do both on the theory that other
+ * chips might need one or the other and that no harm will
+ * come from it. If there is harm, then I'll make it a bit
+ * in the tables.
+ */
+ pcic_setb(sp, PCIC_INT_GEN, PCIC_INTR_ENA);
+ pcic_clrb(sp, PCIC_STAT_INT, PCIC_CSCSELECT);
} else {
/* Management IRQ changes */
+ /*
+ * The PCIC_INTR_ENA bit means either "tie the function
+ * and csc interrupts together" or "Route csc interrupts
+ * via PCI" or "Reserved". In any case, we want to clear
+ * it since we're using ISA interrupts.
+ */
pcic_clrb(sp, PCIC_INT_GEN, PCIC_INTR_ENA);
irq = host_irq_to_pcic(irq);
- sp->putb(sp, PCIC_STAT_INT, (irq << 4) | 0x8);
+ sp->putb(sp, PCIC_STAT_INT, (irq << PCIC_SI_IRQ_SHIFT) |
+ PCIC_CDEN);
}
}
@@ -629,7 +650,7 @@ pcic_disable(struct slot *slt)
struct pcic_slot *sp = slt->cdata;
sp->putb(sp, PCIC_INT_GEN, 0);
- sp->putb(sp, PCIC_POWER, 0);
+/* sp->putb(sp, PCIC_POWER, 0); */
}
/*
OpenPOWER on IntegriCloud