diff options
Diffstat (limited to 'drivers/pcmcia/yenta_socket.c')
-rw-r--r-- | drivers/pcmcia/yenta_socket.c | 64 |
1 files changed, 31 insertions, 33 deletions
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 967c766f53ba..83ace277426c 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -17,6 +17,7 @@ #include <linux/delay.h> #include <linux/module.h> #include <linux/io.h> +#include <linux/slab.h> #include <pcmcia/cs_types.h> #include <pcmcia/ss.h> @@ -42,6 +43,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 +67,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 +344,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 +355,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 +371,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 +913,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 +926,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 +938,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 +975,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 +989,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 +999,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); @@ -1280,12 +1291,9 @@ static int yenta_dev_suspend_noirq(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct yenta_socket *socket = pci_get_drvdata(pdev); - int ret; - - ret = pcmcia_socket_dev_suspend(dev); if (!socket) - return ret; + return 0; if (socket->type && socket->type->save_state) socket->type->save_state(socket); @@ -1302,7 +1310,7 @@ static int yenta_dev_suspend_noirq(struct device *dev) */ /* pci_set_power_state(dev, 3); */ - return ret; + return 0; } static int yenta_dev_resume_noirq(struct device *dev) @@ -1326,26 +1334,16 @@ static int yenta_dev_resume_noirq(struct device *dev) if (socket->type && socket->type->restore_state) socket->type->restore_state(socket); - pcmcia_socket_dev_early_resume(dev); - return 0; -} - -static int yenta_dev_resume(struct device *dev) -{ - pcmcia_socket_dev_late_resume(dev); return 0; } static const struct dev_pm_ops yenta_pm_ops = { .suspend_noirq = yenta_dev_suspend_noirq, .resume_noirq = yenta_dev_resume_noirq, - .resume = yenta_dev_resume, .freeze_noirq = yenta_dev_suspend_noirq, .thaw_noirq = yenta_dev_resume_noirq, - .thaw = yenta_dev_resume, .poweroff_noirq = yenta_dev_suspend_noirq, .restore_noirq = yenta_dev_resume_noirq, - .restore = yenta_dev_resume, }; #define YENTA_PM_OPS (¥ta_pm_ops) |