drivers/pcmcia/ti113x.h | 126 +++++++++++++++++++++++------------------- drivers/pcmcia/yenta_socket.c | 6 +- 2 files changed, 73 insertions(+), 59 deletions(-) diff -puN drivers/pcmcia/ti113x.h~yenta-20030817-5-pm2 drivers/pcmcia/ti113x.h --- 25/drivers/pcmcia/ti113x.h~yenta-20030817-5-pm2 2003-08-17 14:20:45.000000000 -0700 +++ 25-akpm/drivers/pcmcia/ti113x.h 2003-08-17 14:20:45.000000000 -0700 @@ -166,18 +166,6 @@ static void ti_restore_state(struct yent config_writeb(socket, TI1250_DIAGNOSTIC, ti_diag(socket)); } -static int ti_intctl(struct yenta_socket *socket) -{ - u8 new, reg = exca_readb(socket, I365_INTCTL); - - new = reg & ~I365_INTR_ENA; - if (socket->cb_irq) - new |= I365_INTR_ENA; - if (new != reg) - exca_writeb(socket, I365_INTCTL, new); - return 0; -} - /* * Zoom video control for TI122x/113x chips */ @@ -257,11 +245,6 @@ static void ti_set_zv(struct yenta_socke } } } -static int ti_init(struct yenta_socket *socket) -{ - ti_intctl(socket); - return 0; -} /* @@ -276,6 +259,18 @@ static int ti_init(struct yenta_socket * * This makes us correctly get PCI CSC interrupt * events. */ +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) + new |= I365_INTR_ENA; + if (new != reg) + exca_writeb(socket, I365_INTCTL, new); + return 0; +} + static int ti_override(struct yenta_socket *socket) { u8 new, reg = exca_readb(socket, I365_INTCTL); @@ -316,63 +311,82 @@ static int ti_override(struct yenta_sock return 0; } -static int ti113x_init(struct yenta_socket *socket) -{ - config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket)); - config_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket)); - config_writeb(socket, TI113X_DEVICE_CONTROL, ti_devctl(socket)); - ti_intctl(socket); - return 0; -} - static int ti113x_override(struct yenta_socket *socket) { - ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL); - ti_cardctl(socket) = config_readb(socket, TI113X_CARD_CONTROL); - ti_devctl(socket) = config_readb(socket, TI113X_DEVICE_CONTROL); + u8 cardctl; - ti_cardctl(socket) &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC); + 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) - ti_cardctl(socket) |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ; + cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ; + config_writeb(socket, TI113X_CARD_CONTROL, cardctl); + return ti_override(socket); } -static int ti1250_init(struct yenta_socket *socket) +static int ti12xx_override(struct yenta_socket *socket) { - ti113x_init(socket); - ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX); -#if 0 - ti_irqmux(socket) = (ti_irqmux(socket) & ~0x0f) | 0x02; /* route INTA */ - if (!(ti_sysctl(socket) & TI122X_SCR_INTRTIE)) - ti_irqmux(socket) |= 0x20; /* route INTB */ -#endif - - config_writel(socket, TI122X_IRQMUX, ti_irqmux(socket)); - - config_writeb(socket, TI1250_DIAGNOSTIC, ti_diag(socket)); - return 0; + u32 val; + + /* make sure that memory burst is active */ + val = config_readl(socket, TI113X_SYSTEM_CONTROL); + if (!(val & TI122X_SCR_MRBURSTUP)) { + printk(KERN_INFO "Yenta: Enabling burst memory read transactions\n"); + val |= TI122X_SCR_MRBURSTUP; + config_writel(socket, TI113X_SYSTEM_CONTROL, val); + } + + /* + * Yenta expects controllers to use CSCINT to route + * CSC interrupts to PCI rather than INTVAL. + */ + val = config_readb(socket, TI1250_DIAGNOSTIC); + printk(KERN_INFO "Yenta: Using %s to route CSC interrupts to PCI\n", + (val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL"); + printk(KERN_INFO "Yenta: Routing CardBus interrupts to %s\n", + (val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA"); + + return ti_override(socket); } + static int ti1250_override(struct yenta_socket *socket) { - ti_diag(socket) = config_readb(socket, TI1250_DIAGNOSTIC); + u8 old, diag; - ti_diag(socket) &= ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ); + old = config_readb(socket, TI1250_DIAGNOSTIC); + diag = old & ~(TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ); if (socket->cb_irq) - ti_diag(socket) |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ; - return ti113x_override(socket); -} + diag |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ; + if (diag != old) { + printk(KERN_INFO "Yenta: adjusting diagnostic: %02x -> %02x\n", + old, diag); + config_writeb(socket, TI1250_DIAGNOSTIC, diag); + } -static int ti12xx_override(struct yenta_socket *socket) -{ - /* make sure that memory burst is active */ - ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL); - ti_sysctl(socket) |= TI122X_SCR_MRBURSTUP; - config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket)); +#if 0 + /* + * This is highly machine specific, and we should NOT touch + * this register - we have no knowledge how the hardware + * is actually wired. + * + * If we're going to do this, we should probably look into + * using the subsystem IDs. + * + * On ThinkPad 380XD, this changes MFUNC0 from the ISA IRQ3 + * output (which it is) to IRQ2. We also change MFUNC1 + * from ISA IRQ4 to IRQ6. + */ + irqmux = config_readl(socket, TI122X_IRQMUX); + irqmux = (irqmux & ~0x0f) | 0x02; /* route INTA */ + if (!(ti_sysctl(socket) & TI122X_SCR_INTRTIE)) + irqmux = (irqmux & ~0xf0) | 0x20; /* route INTB */ + config_writel(socket, TI122X_IRQMUX, irqmux); +#endif - return ti113x_override(socket); + return ti12xx_override(socket); } #endif /* CONFIG_CARDBUS */ diff -puN drivers/pcmcia/yenta_socket.c~yenta-20030817-5-pm2 drivers/pcmcia/yenta_socket.c --- 25/drivers/pcmcia/yenta_socket.c~yenta-20030817-5-pm2 2003-08-17 14:20:45.000000000 -0700 +++ 25-akpm/drivers/pcmcia/yenta_socket.c 2003-08-17 14:20:45.000000000 -0700 @@ -788,19 +788,19 @@ struct cardbus_type cardbus_type[] = { .override = ti113x_override, .save_state = ti_save_state, .restore_state = ti_restore_state, - .sock_init = ti113x_init, + .sock_init = ti_init, }, [CARDBUS_TYPE_TI12XX] = { .override = ti12xx_override, .save_state = ti_save_state, .restore_state = ti_restore_state, - .sock_init = ti113x_init, + .sock_init = ti_init, }, [CARDBUS_TYPE_TI1250] = { .override = ti1250_override, .save_state = ti_save_state, .restore_state = ti_restore_state, - .sock_init = ti1250_init, + .sock_init = ti_init, }, [CARDBUS_TYPE_RICOH] = { .override = ricoh_override, _