diff options
author | imp <imp@FreeBSD.org> | 2001-08-01 19:41:56 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2001-08-01 19:41:56 +0000 |
commit | 15c0c44955c2d18e4582a561777c0536482d5478 (patch) | |
tree | 13cf87427c226ea014ca373b7c76eea30d1a6252 /sys/pccard/pcic.c | |
parent | 19b910842dfd92ac9592f6c8681e8d1d0f199805 (diff) | |
download | FreeBSD-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.c | 25 |
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); */ } /* |