summaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/yenta_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/yenta_socket.c')
-rw-r--r--drivers/pcmcia/yenta_socket.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 967c766f53b..418988ab6ed 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -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.. */
@@ -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
@@ -329,8 +343,8 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
/* ISA interrupt control? */
intr = exca_readb(socket, I365_INTCTL);
intr = (intr & ~0xf);
- if (!socket->cb_irq) {
- intr |= state->io_irq;
+ if (!socket->dev->irq) {
+ intr |= socket->cb_irq ? socket->cb_irq : state->io_irq;
bridge |= CB_BRIDGE_INTR;
}
exca_writeb(socket, I365_INTCTL, intr);
@@ -340,7 +354,7 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA);
reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
- if (state->io_irq != socket->cb_irq) {
+ if (state->io_irq != socket->dev->irq) {
reg |= state->io_irq;
bridge |= CB_BRIDGE_INTR;
}
@@ -356,7 +370,9 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
exca_writeb(socket, I365_POWER, reg);
/* CSC interrupt: no ISA irq for CSC */
- reg = I365_CSC_DETECT;
+ reg = exca_readb(socket, I365_CSCINT);
+ reg &= I365_CSC_IRQ_MASK;
+ reg |= I365_CSC_DETECT;
if (state->flags & SS_IOCARD) {
if (state->csc_mask & SS_STSCHG)
reg |= I365_CSC_STSCHG;
@@ -896,22 +912,12 @@ 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;
unsigned long val;
u32 mask;
+ u8 reg;
/*
* Probe for usable interrupts using the force
@@ -919,6 +925,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
*/
cb_writel(socket, CB_SOCKET_EVENT, -1);
cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
+ reg = exca_readb(socket, I365_CSCINT);
exca_writeb(socket, I365_CSCINT, 0);
val = probe_irq_on() & isa_irq_mask;
for (i = 1; i < 16; i++) {
@@ -930,7 +937,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
cb_writel(socket, CB_SOCKET_EVENT, -1);
}
cb_writel(socket, CB_SOCKET_MASK, 0);
- exca_writeb(socket, I365_CSCINT, 0);
+ exca_writeb(socket, I365_CSCINT, reg);
mask = probe_irq_mask(val) & 0xffff;
@@ -967,6 +974,8 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id)
/* probes the PCI interrupt, use only on override functions */
static int yenta_probe_cb_irq(struct yenta_socket *socket)
{
+ u8 reg;
+
if (!socket->cb_irq)
return -1;
@@ -979,7 +988,8 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
}
/* generate interrupt, wait */
- exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG);
+ reg = exca_readb(socket, I365_CSCINT);
+ exca_writeb(socket, I365_CSCINT, reg | I365_CSC_STSCHG);
cb_writel(socket, CB_SOCKET_EVENT, -1);
cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
@@ -988,7 +998,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
/* disable interrupts */
cb_writel(socket, CB_SOCKET_MASK, 0);
- exca_writeb(socket, I365_CSCINT, 0);
+ exca_writeb(socket, I365_CSCINT, reg);
cb_writel(socket, CB_SOCKET_EVENT, -1);
exca_readb(socket, I365_CSC);