Skip to content

Commit

Permalink
pcmcia: re-route Cardbus IRQ to ISA on ti1130 bridges if necessary
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jens Künzer authored and Dominik Brodowski committed Mar 15, 2010
1 parent ba8819e commit 0d3a940
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 13 deletions.
37 changes: 35 additions & 2 deletions drivers/pcmcia/ti113x.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
25 changes: 14 additions & 11 deletions drivers/pcmcia/yenta_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ module_param_string(o2_speedup, o2_speedup, sizeof(o2_speedup), 0444);
MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' "
"or 'default' (uses recommended behaviour for the detected bridge)");

/*
* Only probe "regular" interrupts, don't
* touch dangerous spots like the mouse irq,
* because there are mice that apparently
* get really confused if they get fondled
* too intimately.
*
* Default to 11, 10, 9, 7, 6, 5, 4, 3.
*/
static u32 isa_interrupts = 0x0ef8;


#define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args)

/* Don't ask.. */
Expand All @@ -54,6 +66,8 @@ MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' "
*/
#ifdef CONFIG_YENTA_TI
static int yenta_probe_cb_irq(struct yenta_socket *socket);
static unsigned int yenta_probe_irq(struct yenta_socket *socket,
u32 isa_irq_mask);
#endif


Expand Down Expand Up @@ -898,17 +912,6 @@ static struct cardbus_type cardbus_type[] = {
};


/*
* Only probe "regular" interrupts, don't
* touch dangerous spots like the mouse irq,
* because there are mice that apparently
* get really confused if they get fondled
* too intimately.
*
* Default to 11, 10, 9, 7, 6, 5, 4, 3.
*/
static u32 isa_interrupts = 0x0ef8;

static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
{
int i;
Expand Down

0 comments on commit 0d3a940

Please sign in to comment.