diff options
author | Jens Künzer <Jens.Kuenzer@fpga.homeip.net> | 2010-03-06 08:27:22 +0100 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-03-15 14:50:16 +0100 |
commit | 0d3a940de51c47a3d6322537c8dce925db755477 (patch) | |
tree | def17f37fabf348a4de30c99cad065bedc13a726 /drivers/pcmcia/ti113x.h | |
parent | ba8819e991ac507fcbfa080eacdff3e7eea4dc03 (diff) | |
download | linux-stable-0d3a940de51c47a3d6322537c8dce925db755477.tar.gz linux-stable-0d3a940de51c47a3d6322537c8dce925db755477.tar.bz2 linux-stable-0d3a940de51c47a3d6322537c8dce925db755477.zip |
pcmcia: re-route Cardbus IRQ to ISA on ti1130 bridges if necessary
As the PCI irq pin of the ti1130 pcmcia bridge is not connected (at
least on some old IBM Thinkpad 760ED notebooks), the Cardbus IRQ has
to be routed to an ISA irq.
Part 3 of a series to allow the ISA irq to be used for Cardbus devices
if the socket's PCI irq is unusable.
[linux@dominikbrodowski.net: split up the original patch, commit message,
cleanup]
Signed-off-by: Jens Kuenzer <Jens.Kuenzer@fpga.homeip.net>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia/ti113x.h')
-rw-r--r-- | drivers/pcmcia/ti113x.h | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index aaa70227bfb0..9ffa97d0b16c 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h @@ -296,7 +296,7 @@ static int ti_init(struct yenta_socket *socket) u8 new, reg = exca_readb(socket, I365_INTCTL); new = reg & ~I365_INTR_ENA; - if (socket->cb_irq) + if (socket->dev->irq) new |= I365_INTR_ENA; if (new != reg) exca_writeb(socket, I365_INTCTL, new); @@ -316,14 +316,47 @@ static int ti_override(struct yenta_socket *socket) return 0; } +static void ti113x_use_isa_irq(struct yenta_socket *socket) +{ + int isa_irq = -1; + u8 intctl; + u32 isa_irq_mask = 0; + + if (!isa_probe) + return; + + /* get a free isa int */ + isa_irq_mask = yenta_probe_irq(socket, isa_interrupts); + if (!isa_irq_mask) + return; /* no useable isa irq found */ + + /* choose highest available */ + for (; isa_irq_mask; isa_irq++) + isa_irq_mask >>= 1; + socket->cb_irq = isa_irq; + + exca_writeb(socket, I365_CSCINT, (isa_irq << 4)); + + intctl = exca_readb(socket, I365_INTCTL); + intctl &= ~(I365_INTR_ENA | I365_IRQ_MASK); /* CSC Enable */ + exca_writeb(socket, I365_INTCTL, intctl); + + dev_info(&socket->dev->dev, + "Yenta TI113x: using isa irq %d for CardBus\n", isa_irq); +} + + static int ti113x_override(struct yenta_socket *socket) { u8 cardctl; cardctl = config_readb(socket, TI113X_CARD_CONTROL); cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC); - if (socket->cb_irq) + if (socket->dev->irq) cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ; + else + ti113x_use_isa_irq(socket); + config_writeb(socket, TI113X_CARD_CONTROL, cardctl); return ti_override(socket); |