11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Regular cardbus driver ("yenta_socket") 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * (C) Copyright 1999, 2000 Linus Torvalds 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Changelog: 71da177e4SLinus Torvalds * Aug 2002: Manfred Spraul <manfred@colorfullife.com> 81da177e4SLinus Torvalds * Dynamically adjust the size of the bridge resource 91da177e4SLinus Torvalds * 101da177e4SLinus Torvalds * May 2003: Dominik Brodowski <linux@brodo.de> 111da177e4SLinus Torvalds * Merge pci_socket.c and yenta.c into one file 121da177e4SLinus Torvalds */ 131da177e4SLinus Torvalds #include <linux/init.h> 141da177e4SLinus Torvalds #include <linux/pci.h> 151da177e4SLinus Torvalds #include <linux/sched.h> 161da177e4SLinus Torvalds #include <linux/workqueue.h> 171da177e4SLinus Torvalds #include <linux/interrupt.h> 181da177e4SLinus Torvalds #include <linux/delay.h> 191da177e4SLinus Torvalds #include <linux/module.h> 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds #include <pcmcia/cs_types.h> 221da177e4SLinus Torvalds #include <pcmcia/ss.h> 231da177e4SLinus Torvalds #include <pcmcia/cs.h> 241da177e4SLinus Torvalds 251da177e4SLinus Torvalds #include <asm/io.h> 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds #include "yenta_socket.h" 281da177e4SLinus Torvalds #include "i82365.h" 291da177e4SLinus Torvalds 301da177e4SLinus Torvalds static int disable_clkrun; 311da177e4SLinus Torvalds module_param(disable_clkrun, bool, 0444); 321da177e4SLinus Torvalds MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option"); 331da177e4SLinus Torvalds 34fa912bcbSDaniel Ritz static int isa_probe = 1; 35fa912bcbSDaniel Ritz module_param(isa_probe, bool, 0444); 36fa912bcbSDaniel Ritz MODULE_PARM_DESC(isa_probe, "If set ISA interrupts are probed (default). Set to N to disable probing"); 37fa912bcbSDaniel Ritz 38fa912bcbSDaniel Ritz static int pwr_irqs_off; 39fa912bcbSDaniel Ritz module_param(pwr_irqs_off, bool, 0644); 40fa912bcbSDaniel Ritz MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!"); 41fa912bcbSDaniel Ritz 421da177e4SLinus Torvalds #if 0 431da177e4SLinus Torvalds #define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args) 441da177e4SLinus Torvalds #else 451da177e4SLinus Torvalds #define debug(x,args...) 461da177e4SLinus Torvalds #endif 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds /* Don't ask.. */ 491da177e4SLinus Torvalds #define to_cycles(ns) ((ns)/120) 501da177e4SLinus Torvalds #define to_ns(cycles) ((cycles)*120) 511da177e4SLinus Torvalds 5263e7ebd0SDaniel Ritz /** 5363e7ebd0SDaniel Ritz * yenta PCI irq probing. 5463e7ebd0SDaniel Ritz * currently only used in the TI/EnE initialization code 5563e7ebd0SDaniel Ritz */ 5663e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_TI 571da177e4SLinus Torvalds static int yenta_probe_cb_irq(struct yenta_socket *socket); 5863e7ebd0SDaniel Ritz #endif 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds static unsigned int override_bios; 621da177e4SLinus Torvalds module_param(override_bios, uint, 0000); 631da177e4SLinus Torvalds MODULE_PARM_DESC (override_bios, "yenta ignore bios resource allocation"); 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds /* 661da177e4SLinus Torvalds * Generate easy-to-use ways of reading a cardbus sockets 671da177e4SLinus Torvalds * regular memory space ("cb_xxx"), configuration space 681da177e4SLinus Torvalds * ("config_xxx") and compatibility space ("exca_xxxx") 691da177e4SLinus Torvalds */ 701da177e4SLinus Torvalds static inline u32 cb_readl(struct yenta_socket *socket, unsigned reg) 711da177e4SLinus Torvalds { 721da177e4SLinus Torvalds u32 val = readl(socket->base + reg); 731da177e4SLinus Torvalds debug("%p %04x %08x\n", socket, reg, val); 741da177e4SLinus Torvalds return val; 751da177e4SLinus Torvalds } 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val) 781da177e4SLinus Torvalds { 791da177e4SLinus Torvalds debug("%p %04x %08x\n", socket, reg, val); 801da177e4SLinus Torvalds writel(val, socket->base + reg); 81c8751e4cSDaniel Ritz readl(socket->base + reg); /* avoid problems with PCI write posting */ 821da177e4SLinus Torvalds } 831da177e4SLinus Torvalds 841da177e4SLinus Torvalds static inline u8 config_readb(struct yenta_socket *socket, unsigned offset) 851da177e4SLinus Torvalds { 861da177e4SLinus Torvalds u8 val; 871da177e4SLinus Torvalds pci_read_config_byte(socket->dev, offset, &val); 881da177e4SLinus Torvalds debug("%p %04x %02x\n", socket, offset, val); 891da177e4SLinus Torvalds return val; 901da177e4SLinus Torvalds } 911da177e4SLinus Torvalds 921da177e4SLinus Torvalds static inline u16 config_readw(struct yenta_socket *socket, unsigned offset) 931da177e4SLinus Torvalds { 941da177e4SLinus Torvalds u16 val; 951da177e4SLinus Torvalds pci_read_config_word(socket->dev, offset, &val); 961da177e4SLinus Torvalds debug("%p %04x %04x\n", socket, offset, val); 971da177e4SLinus Torvalds return val; 981da177e4SLinus Torvalds } 991da177e4SLinus Torvalds 1001da177e4SLinus Torvalds static inline u32 config_readl(struct yenta_socket *socket, unsigned offset) 1011da177e4SLinus Torvalds { 1021da177e4SLinus Torvalds u32 val; 1031da177e4SLinus Torvalds pci_read_config_dword(socket->dev, offset, &val); 1041da177e4SLinus Torvalds debug("%p %04x %08x\n", socket, offset, val); 1051da177e4SLinus Torvalds return val; 1061da177e4SLinus Torvalds } 1071da177e4SLinus Torvalds 1081da177e4SLinus Torvalds static inline void config_writeb(struct yenta_socket *socket, unsigned offset, u8 val) 1091da177e4SLinus Torvalds { 1101da177e4SLinus Torvalds debug("%p %04x %02x\n", socket, offset, val); 1111da177e4SLinus Torvalds pci_write_config_byte(socket->dev, offset, val); 1121da177e4SLinus Torvalds } 1131da177e4SLinus Torvalds 1141da177e4SLinus Torvalds static inline void config_writew(struct yenta_socket *socket, unsigned offset, u16 val) 1151da177e4SLinus Torvalds { 1161da177e4SLinus Torvalds debug("%p %04x %04x\n", socket, offset, val); 1171da177e4SLinus Torvalds pci_write_config_word(socket->dev, offset, val); 1181da177e4SLinus Torvalds } 1191da177e4SLinus Torvalds 1201da177e4SLinus Torvalds static inline void config_writel(struct yenta_socket *socket, unsigned offset, u32 val) 1211da177e4SLinus Torvalds { 1221da177e4SLinus Torvalds debug("%p %04x %08x\n", socket, offset, val); 1231da177e4SLinus Torvalds pci_write_config_dword(socket->dev, offset, val); 1241da177e4SLinus Torvalds } 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds static inline u8 exca_readb(struct yenta_socket *socket, unsigned reg) 1271da177e4SLinus Torvalds { 1281da177e4SLinus Torvalds u8 val = readb(socket->base + 0x800 + reg); 1291da177e4SLinus Torvalds debug("%p %04x %02x\n", socket, reg, val); 1301da177e4SLinus Torvalds return val; 1311da177e4SLinus Torvalds } 1321da177e4SLinus Torvalds 1331da177e4SLinus Torvalds static inline u8 exca_readw(struct yenta_socket *socket, unsigned reg) 1341da177e4SLinus Torvalds { 1351da177e4SLinus Torvalds u16 val; 1361da177e4SLinus Torvalds val = readb(socket->base + 0x800 + reg); 1371da177e4SLinus Torvalds val |= readb(socket->base + 0x800 + reg + 1) << 8; 1381da177e4SLinus Torvalds debug("%p %04x %04x\n", socket, reg, val); 1391da177e4SLinus Torvalds return val; 1401da177e4SLinus Torvalds } 1411da177e4SLinus Torvalds 1421da177e4SLinus Torvalds static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val) 1431da177e4SLinus Torvalds { 1441da177e4SLinus Torvalds debug("%p %04x %02x\n", socket, reg, val); 1451da177e4SLinus Torvalds writeb(val, socket->base + 0x800 + reg); 146c8751e4cSDaniel Ritz readb(socket->base + 0x800 + reg); /* PCI write posting... */ 1471da177e4SLinus Torvalds } 1481da177e4SLinus Torvalds 1491da177e4SLinus Torvalds static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val) 1501da177e4SLinus Torvalds { 1511da177e4SLinus Torvalds debug("%p %04x %04x\n", socket, reg, val); 1521da177e4SLinus Torvalds writeb(val, socket->base + 0x800 + reg); 1531da177e4SLinus Torvalds writeb(val >> 8, socket->base + 0x800 + reg + 1); 154c8751e4cSDaniel Ritz 155c8751e4cSDaniel Ritz /* PCI write posting... */ 156c8751e4cSDaniel Ritz readb(socket->base + 0x800 + reg); 157c8751e4cSDaniel Ritz readb(socket->base + 0x800 + reg + 1); 1581da177e4SLinus Torvalds } 1591da177e4SLinus Torvalds 160030ee39cSLinus Torvalds static ssize_t show_yenta_registers(struct device *yentadev, struct device_attribute *attr, char *buf) 161030ee39cSLinus Torvalds { 162030ee39cSLinus Torvalds struct pci_dev *dev = to_pci_dev(yentadev); 163030ee39cSLinus Torvalds struct yenta_socket *socket = pci_get_drvdata(dev); 164030ee39cSLinus Torvalds int offset = 0, i; 165030ee39cSLinus Torvalds 166030ee39cSLinus Torvalds offset = snprintf(buf, PAGE_SIZE, "CB registers:"); 167030ee39cSLinus Torvalds for (i = 0; i < 0x24; i += 4) { 168030ee39cSLinus Torvalds unsigned val; 169030ee39cSLinus Torvalds if (!(i & 15)) 170030ee39cSLinus Torvalds offset += snprintf(buf + offset, PAGE_SIZE - offset, "\n%02x:", i); 171030ee39cSLinus Torvalds val = cb_readl(socket, i); 172030ee39cSLinus Torvalds offset += snprintf(buf + offset, PAGE_SIZE - offset, " %08x", val); 173030ee39cSLinus Torvalds } 174030ee39cSLinus Torvalds 175030ee39cSLinus Torvalds offset += snprintf(buf + offset, PAGE_SIZE - offset, "\n\nExCA registers:"); 176030ee39cSLinus Torvalds for (i = 0; i < 0x45; i++) { 177030ee39cSLinus Torvalds unsigned char val; 178030ee39cSLinus Torvalds if (!(i & 7)) { 179030ee39cSLinus Torvalds if (i & 8) { 180030ee39cSLinus Torvalds memcpy(buf + offset, " -", 2); 181030ee39cSLinus Torvalds offset += 2; 182030ee39cSLinus Torvalds } else 183030ee39cSLinus Torvalds offset += snprintf(buf + offset, PAGE_SIZE - offset, "\n%02x:", i); 184030ee39cSLinus Torvalds } 185030ee39cSLinus Torvalds val = exca_readb(socket, i); 186030ee39cSLinus Torvalds offset += snprintf(buf + offset, PAGE_SIZE - offset, " %02x", val); 187030ee39cSLinus Torvalds } 188030ee39cSLinus Torvalds buf[offset++] = '\n'; 189030ee39cSLinus Torvalds return offset; 190030ee39cSLinus Torvalds } 191030ee39cSLinus Torvalds 192030ee39cSLinus Torvalds static DEVICE_ATTR(yenta_registers, S_IRUSR, show_yenta_registers, NULL); 193030ee39cSLinus Torvalds 1941da177e4SLinus Torvalds /* 1951da177e4SLinus Torvalds * Ugh, mixed-mode cardbus and 16-bit pccard state: things depend 1961da177e4SLinus Torvalds * on what kind of card is inserted.. 1971da177e4SLinus Torvalds */ 1981da177e4SLinus Torvalds static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value) 1991da177e4SLinus Torvalds { 2001da177e4SLinus Torvalds struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); 2011da177e4SLinus Torvalds unsigned int val; 2021da177e4SLinus Torvalds u32 state = cb_readl(socket, CB_SOCKET_STATE); 2031da177e4SLinus Torvalds 2041da177e4SLinus Torvalds val = (state & CB_3VCARD) ? SS_3VCARD : 0; 2051da177e4SLinus Torvalds val |= (state & CB_XVCARD) ? SS_XVCARD : 0; 206fa912bcbSDaniel Ritz val |= (state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING; 207fa912bcbSDaniel Ritz val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? SS_PENDING : 0; 208fa912bcbSDaniel Ritz 2091da177e4SLinus Torvalds 2101da177e4SLinus Torvalds if (state & CB_CBCARD) { 2111da177e4SLinus Torvalds val |= SS_CARDBUS; 2121da177e4SLinus Torvalds val |= (state & CB_CARDSTS) ? SS_STSCHG : 0; 2131da177e4SLinus Torvalds val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT; 2141da177e4SLinus Torvalds val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0; 215fa912bcbSDaniel Ritz } else if (state & CB_16BITCARD) { 2161da177e4SLinus Torvalds u8 status = exca_readb(socket, I365_STATUS); 2171da177e4SLinus Torvalds val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0; 2181da177e4SLinus Torvalds if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) { 2191da177e4SLinus Torvalds val |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG; 2201da177e4SLinus Torvalds } else { 2211da177e4SLinus Torvalds val |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD; 2221da177e4SLinus Torvalds val |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN; 2231da177e4SLinus Torvalds } 2241da177e4SLinus Torvalds val |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0; 2251da177e4SLinus Torvalds val |= (status & I365_CS_READY) ? SS_READY : 0; 2261da177e4SLinus Torvalds val |= (status & I365_CS_POWERON) ? SS_POWERON : 0; 2271da177e4SLinus Torvalds } 2281da177e4SLinus Torvalds 2291da177e4SLinus Torvalds *value = val; 2301da177e4SLinus Torvalds return 0; 2311da177e4SLinus Torvalds } 2321da177e4SLinus Torvalds 2331da177e4SLinus Torvalds static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state) 2341da177e4SLinus Torvalds { 235ea2f1590SDaniel Ritz /* some birdges require to use the ExCA registers to power 16bit cards */ 236ea2f1590SDaniel Ritz if (!(cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) && 237ea2f1590SDaniel Ritz (socket->flags & YENTA_16BIT_POWER_EXCA)) { 238ea2f1590SDaniel Ritz u8 reg, old; 239ea2f1590SDaniel Ritz reg = old = exca_readb(socket, I365_POWER); 240ea2f1590SDaniel Ritz reg &= ~(I365_VCC_MASK | I365_VPP1_MASK | I365_VPP2_MASK); 241ea2f1590SDaniel Ritz 242ea2f1590SDaniel Ritz /* i82365SL-DF style */ 243ea2f1590SDaniel Ritz if (socket->flags & YENTA_16BIT_POWER_DF) { 244ea2f1590SDaniel Ritz switch (state->Vcc) { 245ea2f1590SDaniel Ritz case 33: reg |= I365_VCC_3V; break; 246ea2f1590SDaniel Ritz case 50: reg |= I365_VCC_5V; break; 247ea2f1590SDaniel Ritz default: reg = 0; break; 248ea2f1590SDaniel Ritz } 249ea2f1590SDaniel Ritz switch (state->Vpp) { 250ea2f1590SDaniel Ritz case 33: 251ea2f1590SDaniel Ritz case 50: reg |= I365_VPP1_5V; break; 252ea2f1590SDaniel Ritz case 120: reg |= I365_VPP1_12V; break; 253ea2f1590SDaniel Ritz } 254ea2f1590SDaniel Ritz } else { 255ea2f1590SDaniel Ritz /* i82365SL-B style */ 256ea2f1590SDaniel Ritz switch (state->Vcc) { 257ea2f1590SDaniel Ritz case 50: reg |= I365_VCC_5V; break; 258ea2f1590SDaniel Ritz default: reg = 0; break; 259ea2f1590SDaniel Ritz } 260ea2f1590SDaniel Ritz switch (state->Vpp) { 261ea2f1590SDaniel Ritz case 50: reg |= I365_VPP1_5V | I365_VPP2_5V; break; 262ea2f1590SDaniel Ritz case 120: reg |= I365_VPP1_12V | I365_VPP2_12V; break; 263ea2f1590SDaniel Ritz } 264ea2f1590SDaniel Ritz } 265ea2f1590SDaniel Ritz 266ea2f1590SDaniel Ritz if (reg != old) 267ea2f1590SDaniel Ritz exca_writeb(socket, I365_POWER, reg); 268ea2f1590SDaniel Ritz } else { 2691da177e4SLinus Torvalds u32 reg = 0; /* CB_SC_STPCLK? */ 2701da177e4SLinus Torvalds switch (state->Vcc) { 2711da177e4SLinus Torvalds case 33: reg = CB_SC_VCC_3V; break; 2721da177e4SLinus Torvalds case 50: reg = CB_SC_VCC_5V; break; 2731da177e4SLinus Torvalds default: reg = 0; break; 2741da177e4SLinus Torvalds } 2751da177e4SLinus Torvalds switch (state->Vpp) { 2761da177e4SLinus Torvalds case 33: reg |= CB_SC_VPP_3V; break; 2771da177e4SLinus Torvalds case 50: reg |= CB_SC_VPP_5V; break; 2781da177e4SLinus Torvalds case 120: reg |= CB_SC_VPP_12V; break; 2791da177e4SLinus Torvalds } 2801da177e4SLinus Torvalds if (reg != cb_readl(socket, CB_SOCKET_CONTROL)) 2811da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_CONTROL, reg); 2821da177e4SLinus Torvalds } 283ea2f1590SDaniel Ritz } 2841da177e4SLinus Torvalds 2851da177e4SLinus Torvalds static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) 2861da177e4SLinus Torvalds { 2871da177e4SLinus Torvalds struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); 2881da177e4SLinus Torvalds u16 bridge; 2891da177e4SLinus Torvalds 290d250a481SDaniel Ritz /* if powering down: do it immediately */ 291d250a481SDaniel Ritz if (state->Vcc == 0) 2921da177e4SLinus Torvalds yenta_set_power(socket, state); 293d250a481SDaniel Ritz 2941da177e4SLinus Torvalds socket->io_irq = state->io_irq; 2951da177e4SLinus Torvalds bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR); 2961da177e4SLinus Torvalds if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) { 2971da177e4SLinus Torvalds u8 intr; 2981da177e4SLinus Torvalds bridge |= (state->flags & SS_RESET) ? CB_BRIDGE_CRST : 0; 2991da177e4SLinus Torvalds 3001da177e4SLinus Torvalds /* ISA interrupt control? */ 3011da177e4SLinus Torvalds intr = exca_readb(socket, I365_INTCTL); 3021da177e4SLinus Torvalds intr = (intr & ~0xf); 3031da177e4SLinus Torvalds if (!socket->cb_irq) { 3041da177e4SLinus Torvalds intr |= state->io_irq; 3051da177e4SLinus Torvalds bridge |= CB_BRIDGE_INTR; 3061da177e4SLinus Torvalds } 3071da177e4SLinus Torvalds exca_writeb(socket, I365_INTCTL, intr); 3081da177e4SLinus Torvalds } else { 3091da177e4SLinus Torvalds u8 reg; 3101da177e4SLinus Torvalds 3111da177e4SLinus Torvalds reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA); 3121da177e4SLinus Torvalds reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET; 3131da177e4SLinus Torvalds reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0; 3141da177e4SLinus Torvalds if (state->io_irq != socket->cb_irq) { 3151da177e4SLinus Torvalds reg |= state->io_irq; 3161da177e4SLinus Torvalds bridge |= CB_BRIDGE_INTR; 3171da177e4SLinus Torvalds } 3181da177e4SLinus Torvalds exca_writeb(socket, I365_INTCTL, reg); 3191da177e4SLinus Torvalds 3201da177e4SLinus Torvalds reg = exca_readb(socket, I365_POWER) & (I365_VCC_MASK|I365_VPP1_MASK); 3211da177e4SLinus Torvalds reg |= I365_PWR_NORESET; 3221da177e4SLinus Torvalds if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO; 3231da177e4SLinus Torvalds if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT; 3241da177e4SLinus Torvalds if (exca_readb(socket, I365_POWER) != reg) 3251da177e4SLinus Torvalds exca_writeb(socket, I365_POWER, reg); 3261da177e4SLinus Torvalds 3271da177e4SLinus Torvalds /* CSC interrupt: no ISA irq for CSC */ 3281da177e4SLinus Torvalds reg = I365_CSC_DETECT; 3291da177e4SLinus Torvalds if (state->flags & SS_IOCARD) { 3301da177e4SLinus Torvalds if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG; 3311da177e4SLinus Torvalds } else { 3321da177e4SLinus Torvalds if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1; 3331da177e4SLinus Torvalds if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2; 3341da177e4SLinus Torvalds if (state->csc_mask & SS_READY) reg |= I365_CSC_READY; 3351da177e4SLinus Torvalds } 3361da177e4SLinus Torvalds exca_writeb(socket, I365_CSCINT, reg); 3371da177e4SLinus Torvalds exca_readb(socket, I365_CSC); 3381da177e4SLinus Torvalds if(sock->zoom_video) 3391da177e4SLinus Torvalds sock->zoom_video(sock, state->flags & SS_ZVCARD); 3401da177e4SLinus Torvalds } 3411da177e4SLinus Torvalds config_writew(socket, CB_BRIDGE_CONTROL, bridge); 3421da177e4SLinus Torvalds /* Socket event mask: get card insert/remove events.. */ 3431da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_EVENT, -1); 3441da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK); 345d250a481SDaniel Ritz 346d250a481SDaniel Ritz /* if powering up: do it as the last step when the socket is configured */ 347d250a481SDaniel Ritz if (state->Vcc != 0) 348d250a481SDaniel Ritz yenta_set_power(socket, state); 3491da177e4SLinus Torvalds return 0; 3501da177e4SLinus Torvalds } 3511da177e4SLinus Torvalds 3521da177e4SLinus Torvalds static int yenta_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io) 3531da177e4SLinus Torvalds { 3541da177e4SLinus Torvalds struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); 3551da177e4SLinus Torvalds int map; 3561da177e4SLinus Torvalds unsigned char ioctl, addr, enable; 3571da177e4SLinus Torvalds 3581da177e4SLinus Torvalds map = io->map; 3591da177e4SLinus Torvalds 3601da177e4SLinus Torvalds if (map > 1) 3611da177e4SLinus Torvalds return -EINVAL; 3621da177e4SLinus Torvalds 3631da177e4SLinus Torvalds enable = I365_ENA_IO(map); 3641da177e4SLinus Torvalds addr = exca_readb(socket, I365_ADDRWIN); 3651da177e4SLinus Torvalds 3661da177e4SLinus Torvalds /* Disable the window before changing it.. */ 3671da177e4SLinus Torvalds if (addr & enable) { 3681da177e4SLinus Torvalds addr &= ~enable; 3691da177e4SLinus Torvalds exca_writeb(socket, I365_ADDRWIN, addr); 3701da177e4SLinus Torvalds } 3711da177e4SLinus Torvalds 3721da177e4SLinus Torvalds exca_writew(socket, I365_IO(map)+I365_W_START, io->start); 3731da177e4SLinus Torvalds exca_writew(socket, I365_IO(map)+I365_W_STOP, io->stop); 3741da177e4SLinus Torvalds 3751da177e4SLinus Torvalds ioctl = exca_readb(socket, I365_IOCTL) & ~I365_IOCTL_MASK(map); 3761da177e4SLinus Torvalds if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map); 3771da177e4SLinus Torvalds if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map); 3781da177e4SLinus Torvalds if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map); 3791da177e4SLinus Torvalds exca_writeb(socket, I365_IOCTL, ioctl); 3801da177e4SLinus Torvalds 3811da177e4SLinus Torvalds if (io->flags & MAP_ACTIVE) 3821da177e4SLinus Torvalds exca_writeb(socket, I365_ADDRWIN, addr | enable); 3831da177e4SLinus Torvalds return 0; 3841da177e4SLinus Torvalds } 3851da177e4SLinus Torvalds 3861da177e4SLinus Torvalds static int yenta_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem) 3871da177e4SLinus Torvalds { 3881da177e4SLinus Torvalds struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); 3891da177e4SLinus Torvalds struct pci_bus_region region; 3901da177e4SLinus Torvalds int map; 3911da177e4SLinus Torvalds unsigned char addr, enable; 3921da177e4SLinus Torvalds unsigned int start, stop, card_start; 3931da177e4SLinus Torvalds unsigned short word; 3941da177e4SLinus Torvalds 3951da177e4SLinus Torvalds pcibios_resource_to_bus(socket->dev, ®ion, mem->res); 3961da177e4SLinus Torvalds 3971da177e4SLinus Torvalds map = mem->map; 3981da177e4SLinus Torvalds start = region.start; 3991da177e4SLinus Torvalds stop = region.end; 4001da177e4SLinus Torvalds card_start = mem->card_start; 4011da177e4SLinus Torvalds 4021da177e4SLinus Torvalds if (map > 4 || start > stop || ((start ^ stop) >> 24) || 4031da177e4SLinus Torvalds (card_start >> 26) || mem->speed > 1000) 4041da177e4SLinus Torvalds return -EINVAL; 4051da177e4SLinus Torvalds 4061da177e4SLinus Torvalds enable = I365_ENA_MEM(map); 4071da177e4SLinus Torvalds addr = exca_readb(socket, I365_ADDRWIN); 4081da177e4SLinus Torvalds if (addr & enable) { 4091da177e4SLinus Torvalds addr &= ~enable; 4101da177e4SLinus Torvalds exca_writeb(socket, I365_ADDRWIN, addr); 4111da177e4SLinus Torvalds } 4121da177e4SLinus Torvalds 4131da177e4SLinus Torvalds exca_writeb(socket, CB_MEM_PAGE(map), start >> 24); 4141da177e4SLinus Torvalds 4151da177e4SLinus Torvalds word = (start >> 12) & 0x0fff; 4161da177e4SLinus Torvalds if (mem->flags & MAP_16BIT) 4171da177e4SLinus Torvalds word |= I365_MEM_16BIT; 4181da177e4SLinus Torvalds if (mem->flags & MAP_0WS) 4191da177e4SLinus Torvalds word |= I365_MEM_0WS; 4201da177e4SLinus Torvalds exca_writew(socket, I365_MEM(map) + I365_W_START, word); 4211da177e4SLinus Torvalds 4221da177e4SLinus Torvalds word = (stop >> 12) & 0x0fff; 4231da177e4SLinus Torvalds switch (to_cycles(mem->speed)) { 4241da177e4SLinus Torvalds case 0: break; 4251da177e4SLinus Torvalds case 1: word |= I365_MEM_WS0; break; 4261da177e4SLinus Torvalds case 2: word |= I365_MEM_WS1; break; 4271da177e4SLinus Torvalds default: word |= I365_MEM_WS1 | I365_MEM_WS0; break; 4281da177e4SLinus Torvalds } 4291da177e4SLinus Torvalds exca_writew(socket, I365_MEM(map) + I365_W_STOP, word); 4301da177e4SLinus Torvalds 4311da177e4SLinus Torvalds word = ((card_start - start) >> 12) & 0x3fff; 4321da177e4SLinus Torvalds if (mem->flags & MAP_WRPROT) 4331da177e4SLinus Torvalds word |= I365_MEM_WRPROT; 4341da177e4SLinus Torvalds if (mem->flags & MAP_ATTRIB) 4351da177e4SLinus Torvalds word |= I365_MEM_REG; 4361da177e4SLinus Torvalds exca_writew(socket, I365_MEM(map) + I365_W_OFF, word); 4371da177e4SLinus Torvalds 4381da177e4SLinus Torvalds if (mem->flags & MAP_ACTIVE) 4391da177e4SLinus Torvalds exca_writeb(socket, I365_ADDRWIN, addr | enable); 4401da177e4SLinus Torvalds return 0; 4411da177e4SLinus Torvalds } 4421da177e4SLinus Torvalds 4431da177e4SLinus Torvalds 444fa912bcbSDaniel Ritz 4457d12e780SDavid Howells static irqreturn_t yenta_interrupt(int irq, void *dev_id) 4461da177e4SLinus Torvalds { 447fa912bcbSDaniel Ritz unsigned int events; 448fa912bcbSDaniel Ritz struct yenta_socket *socket = (struct yenta_socket *) dev_id; 4491da177e4SLinus Torvalds u8 csc; 4501da177e4SLinus Torvalds u32 cb_event; 4511da177e4SLinus Torvalds 4521da177e4SLinus Torvalds /* Clear interrupt status for the event */ 4531da177e4SLinus Torvalds cb_event = cb_readl(socket, CB_SOCKET_EVENT); 4541da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_EVENT, cb_event); 4551da177e4SLinus Torvalds 4561da177e4SLinus Torvalds csc = exca_readb(socket, I365_CSC); 4571da177e4SLinus Torvalds 458e4115805SDaniel Ritz if (!(cb_event || csc)) 459e4115805SDaniel Ritz return IRQ_NONE; 460e4115805SDaniel Ritz 4611da177e4SLinus Torvalds events = (cb_event & (CB_CD1EVENT | CB_CD2EVENT)) ? SS_DETECT : 0 ; 4621da177e4SLinus Torvalds events |= (csc & I365_CSC_DETECT) ? SS_DETECT : 0; 4631da177e4SLinus Torvalds if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) { 4641da177e4SLinus Torvalds events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0; 4651da177e4SLinus Torvalds } else { 4661da177e4SLinus Torvalds events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0; 4671da177e4SLinus Torvalds events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0; 4681da177e4SLinus Torvalds events |= (csc & I365_CSC_READY) ? SS_READY : 0; 4691da177e4SLinus Torvalds } 4701da177e4SLinus Torvalds 471fa912bcbSDaniel Ritz if (events) 4721da177e4SLinus Torvalds pcmcia_parse_events(&socket->socket, events); 473fa912bcbSDaniel Ritz 4741da177e4SLinus Torvalds return IRQ_HANDLED; 4751da177e4SLinus Torvalds } 4761da177e4SLinus Torvalds 4771da177e4SLinus Torvalds static void yenta_interrupt_wrapper(unsigned long data) 4781da177e4SLinus Torvalds { 4791da177e4SLinus Torvalds struct yenta_socket *socket = (struct yenta_socket *) data; 4801da177e4SLinus Torvalds 4817d12e780SDavid Howells yenta_interrupt(0, (void *)socket); 4821da177e4SLinus Torvalds socket->poll_timer.expires = jiffies + HZ; 4831da177e4SLinus Torvalds add_timer(&socket->poll_timer); 4841da177e4SLinus Torvalds } 4851da177e4SLinus Torvalds 4861da177e4SLinus Torvalds static void yenta_clear_maps(struct yenta_socket *socket) 4871da177e4SLinus Torvalds { 4881da177e4SLinus Torvalds int i; 4891da177e4SLinus Torvalds struct resource res = { .start = 0, .end = 0x0fff }; 4901da177e4SLinus Torvalds pccard_io_map io = { 0, 0, 0, 0, 1 }; 4911da177e4SLinus Torvalds pccard_mem_map mem = { .res = &res, }; 4921da177e4SLinus Torvalds 4931da177e4SLinus Torvalds yenta_set_socket(&socket->socket, &dead_socket); 4941da177e4SLinus Torvalds for (i = 0; i < 2; i++) { 4951da177e4SLinus Torvalds io.map = i; 4961da177e4SLinus Torvalds yenta_set_io_map(&socket->socket, &io); 4971da177e4SLinus Torvalds } 4981da177e4SLinus Torvalds for (i = 0; i < 5; i++) { 4991da177e4SLinus Torvalds mem.map = i; 5001da177e4SLinus Torvalds yenta_set_mem_map(&socket->socket, &mem); 5011da177e4SLinus Torvalds } 5021da177e4SLinus Torvalds } 5031da177e4SLinus Torvalds 504fa912bcbSDaniel Ritz /* redoes voltage interrogation if required */ 505fa912bcbSDaniel Ritz static void yenta_interrogate(struct yenta_socket *socket) 506fa912bcbSDaniel Ritz { 507fa912bcbSDaniel Ritz u32 state; 508fa912bcbSDaniel Ritz 509fa912bcbSDaniel Ritz state = cb_readl(socket, CB_SOCKET_STATE); 510fa912bcbSDaniel Ritz if (!(state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) || 511fa912bcbSDaniel Ritz (state & (CB_CDETECT1 | CB_CDETECT2 | CB_NOTACARD | CB_BADVCCREQ)) || 512fa912bcbSDaniel Ritz ((state & (CB_16BITCARD | CB_CBCARD)) == (CB_16BITCARD | CB_CBCARD))) 513fa912bcbSDaniel Ritz cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST); 514fa912bcbSDaniel Ritz } 515fa912bcbSDaniel Ritz 5161da177e4SLinus Torvalds /* Called at resume and initialization events */ 5171da177e4SLinus Torvalds static int yenta_sock_init(struct pcmcia_socket *sock) 5181da177e4SLinus Torvalds { 5191da177e4SLinus Torvalds struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); 5201da177e4SLinus Torvalds 5211da177e4SLinus Torvalds exca_writeb(socket, I365_GBLCTL, 0x00); 5221da177e4SLinus Torvalds exca_writeb(socket, I365_GENCTL, 0x00); 5231da177e4SLinus Torvalds 5241da177e4SLinus Torvalds /* Redo card voltage interrogation */ 525fa912bcbSDaniel Ritz yenta_interrogate(socket); 5261da177e4SLinus Torvalds 5271da177e4SLinus Torvalds yenta_clear_maps(socket); 5281da177e4SLinus Torvalds 5291da177e4SLinus Torvalds if (socket->type && socket->type->sock_init) 5301da177e4SLinus Torvalds socket->type->sock_init(socket); 5311da177e4SLinus Torvalds 5321da177e4SLinus Torvalds /* Re-enable CSC interrupts */ 5331da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK); 5341da177e4SLinus Torvalds 5351da177e4SLinus Torvalds return 0; 5361da177e4SLinus Torvalds } 5371da177e4SLinus Torvalds 5381da177e4SLinus Torvalds static int yenta_sock_suspend(struct pcmcia_socket *sock) 5391da177e4SLinus Torvalds { 5401da177e4SLinus Torvalds struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); 5411da177e4SLinus Torvalds 5421da177e4SLinus Torvalds /* Disable CSC interrupts */ 5431da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_MASK, 0x0); 5441da177e4SLinus Torvalds 5451da177e4SLinus Torvalds return 0; 5461da177e4SLinus Torvalds } 5471da177e4SLinus Torvalds 5481da177e4SLinus Torvalds /* 5491da177e4SLinus Torvalds * Use an adaptive allocation for the memory resource, 5501da177e4SLinus Torvalds * sometimes the memory behind pci bridges is limited: 5511da177e4SLinus Torvalds * 1/8 of the size of the io window of the parent. 552eb0a90b4SDominik Brodowski * max 4 MB, min 16 kB. We try very hard to not get below 553eb0a90b4SDominik Brodowski * the "ACC" values, though. 5541da177e4SLinus Torvalds */ 5551da177e4SLinus Torvalds #define BRIDGE_MEM_MAX 4*1024*1024 556eb0a90b4SDominik Brodowski #define BRIDGE_MEM_ACC 128*1024 5571da177e4SLinus Torvalds #define BRIDGE_MEM_MIN 16*1024 5581da177e4SLinus Torvalds 559eb0a90b4SDominik Brodowski #define BRIDGE_IO_MAX 512 560eb0a90b4SDominik Brodowski #define BRIDGE_IO_ACC 256 5611da177e4SLinus Torvalds #define BRIDGE_IO_MIN 32 5621da177e4SLinus Torvalds 5631da177e4SLinus Torvalds #ifndef PCIBIOS_MIN_CARDBUS_IO 5641da177e4SLinus Torvalds #define PCIBIOS_MIN_CARDBUS_IO PCIBIOS_MIN_IO 5651da177e4SLinus Torvalds #endif 5661da177e4SLinus Torvalds 567eb0a90b4SDominik Brodowski static int yenta_search_one_res(struct resource *root, struct resource *res, 568eb0a90b4SDominik Brodowski u32 min) 569eb0a90b4SDominik Brodowski { 570eb0a90b4SDominik Brodowski u32 align, size, start, end; 571eb0a90b4SDominik Brodowski 572eb0a90b4SDominik Brodowski if (res->flags & IORESOURCE_IO) { 573eb0a90b4SDominik Brodowski align = 1024; 574eb0a90b4SDominik Brodowski size = BRIDGE_IO_MAX; 575eb0a90b4SDominik Brodowski start = PCIBIOS_MIN_CARDBUS_IO; 576eb0a90b4SDominik Brodowski end = ~0U; 577eb0a90b4SDominik Brodowski } else { 578eb0a90b4SDominik Brodowski unsigned long avail = root->end - root->start; 579eb0a90b4SDominik Brodowski int i; 580eb0a90b4SDominik Brodowski size = BRIDGE_MEM_MAX; 581eb0a90b4SDominik Brodowski if (size > avail/8) { 582eb0a90b4SDominik Brodowski size=(avail+1)/8; 583eb0a90b4SDominik Brodowski /* round size down to next power of 2 */ 584eb0a90b4SDominik Brodowski i = 0; 585eb0a90b4SDominik Brodowski while ((size /= 2) != 0) 586eb0a90b4SDominik Brodowski i++; 587eb0a90b4SDominik Brodowski size = 1 << i; 588eb0a90b4SDominik Brodowski } 589eb0a90b4SDominik Brodowski if (size < min) 590eb0a90b4SDominik Brodowski size = min; 591eb0a90b4SDominik Brodowski align = size; 592eb0a90b4SDominik Brodowski start = PCIBIOS_MIN_MEM; 593eb0a90b4SDominik Brodowski end = ~0U; 594eb0a90b4SDominik Brodowski } 595eb0a90b4SDominik Brodowski 596eb0a90b4SDominik Brodowski do { 597eb0a90b4SDominik Brodowski if (allocate_resource(root, res, size, start, end, align, 598eb0a90b4SDominik Brodowski NULL, NULL)==0) { 599eb0a90b4SDominik Brodowski return 1; 600eb0a90b4SDominik Brodowski } 601eb0a90b4SDominik Brodowski size = size/2; 602eb0a90b4SDominik Brodowski align = size; 603eb0a90b4SDominik Brodowski } while (size >= min); 604eb0a90b4SDominik Brodowski 605eb0a90b4SDominik Brodowski return 0; 606eb0a90b4SDominik Brodowski } 607eb0a90b4SDominik Brodowski 608eb0a90b4SDominik Brodowski 609eb0a90b4SDominik Brodowski static int yenta_search_res(struct yenta_socket *socket, struct resource *res, 610eb0a90b4SDominik Brodowski u32 min) 611eb0a90b4SDominik Brodowski { 612eb0a90b4SDominik Brodowski int i; 613eb0a90b4SDominik Brodowski for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) { 614eb0a90b4SDominik Brodowski struct resource * root = socket->dev->bus->resource[i]; 615eb0a90b4SDominik Brodowski if (!root) 616eb0a90b4SDominik Brodowski continue; 617eb0a90b4SDominik Brodowski 618eb0a90b4SDominik Brodowski if ((res->flags ^ root->flags) & 619eb0a90b4SDominik Brodowski (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH)) 620eb0a90b4SDominik Brodowski continue; /* Wrong type */ 621eb0a90b4SDominik Brodowski 622eb0a90b4SDominik Brodowski if (yenta_search_one_res(root, res, min)) 623eb0a90b4SDominik Brodowski return 1; 624eb0a90b4SDominik Brodowski } 625eb0a90b4SDominik Brodowski return 0; 626eb0a90b4SDominik Brodowski } 627eb0a90b4SDominik Brodowski 628b3743fa4SDominik Brodowski static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end) 6291da177e4SLinus Torvalds { 6301da177e4SLinus Torvalds struct resource *root, *res; 63143c34735SDominik Brodowski struct pci_bus_region region; 6321da177e4SLinus Torvalds unsigned mask; 6331da177e4SLinus Torvalds 6347925407aSIvan Kokshaysky res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr; 6357925407aSIvan Kokshaysky /* Already allocated? */ 6367925407aSIvan Kokshaysky if (res->parent) 637b3743fa4SDominik Brodowski return 0; 6387925407aSIvan Kokshaysky 6391da177e4SLinus Torvalds /* The granularity of the memory limit is 4kB, on IO it's 4 bytes */ 6401da177e4SLinus Torvalds mask = ~0xfff; 6411da177e4SLinus Torvalds if (type & IORESOURCE_IO) 6421da177e4SLinus Torvalds mask = ~3; 6431da177e4SLinus Torvalds 64443c34735SDominik Brodowski res->name = socket->dev->subordinate->name; 6451da177e4SLinus Torvalds res->flags = type; 6461da177e4SLinus Torvalds 64743c34735SDominik Brodowski region.start = config_readl(socket, addr_start) & mask; 64843c34735SDominik Brodowski region.end = config_readl(socket, addr_end) | ~mask; 64943c34735SDominik Brodowski if (region.start && region.end > region.start && !override_bios) { 65043c34735SDominik Brodowski pcibios_bus_to_resource(socket->dev, res, ®ion); 651862104e5SDominik Brodowski root = pci_find_parent_resource(socket->dev, res); 652862104e5SDominik Brodowski if (root && (request_resource(root, res) == 0)) 653b3743fa4SDominik Brodowski return 0; 654862104e5SDominik Brodowski printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n", 6551da177e4SLinus Torvalds pci_name(socket->dev), nr); 6561da177e4SLinus Torvalds } 6571da177e4SLinus Torvalds 6581da177e4SLinus Torvalds if (type & IORESOURCE_IO) { 659eb0a90b4SDominik Brodowski if ((yenta_search_res(socket, res, BRIDGE_IO_MAX)) || 660eb0a90b4SDominik Brodowski (yenta_search_res(socket, res, BRIDGE_IO_ACC)) || 661b3743fa4SDominik Brodowski (yenta_search_res(socket, res, BRIDGE_IO_MIN))) 662b3743fa4SDominik Brodowski return 1; 663eb0a90b4SDominik Brodowski } else { 664eb0a90b4SDominik Brodowski if (type & IORESOURCE_PREFETCH) { 665eb0a90b4SDominik Brodowski if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) || 666eb0a90b4SDominik Brodowski (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) || 667b3743fa4SDominik Brodowski (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) 668b3743fa4SDominik Brodowski return 1; 669eb0a90b4SDominik Brodowski /* Approximating prefetchable by non-prefetchable */ 670eb0a90b4SDominik Brodowski res->flags = IORESOURCE_MEM; 671eb0a90b4SDominik Brodowski } 672eb0a90b4SDominik Brodowski if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) || 673eb0a90b4SDominik Brodowski (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) || 674b3743fa4SDominik Brodowski (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) 675b3743fa4SDominik Brodowski return 1; 676eb0a90b4SDominik Brodowski } 677eb0a90b4SDominik Brodowski 6781da177e4SLinus Torvalds printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n", 6791da177e4SLinus Torvalds pci_name(socket->dev), type); 680eb0a90b4SDominik Brodowski res->start = res->end = res->flags = 0; 681b3743fa4SDominik Brodowski return 0; 6821da177e4SLinus Torvalds } 6831da177e4SLinus Torvalds 6841da177e4SLinus Torvalds /* 6851da177e4SLinus Torvalds * Allocate the bridge mappings for the device.. 6861da177e4SLinus Torvalds */ 6871da177e4SLinus Torvalds static void yenta_allocate_resources(struct yenta_socket *socket) 6881da177e4SLinus Torvalds { 689b3743fa4SDominik Brodowski int program = 0; 690b3743fa4SDominik Brodowski program += yenta_allocate_res(socket, 0, IORESOURCE_IO, 69127879835SDominik Brodowski PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0); 692b3743fa4SDominik Brodowski program += yenta_allocate_res(socket, 1, IORESOURCE_IO, 69327879835SDominik Brodowski PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1); 694b3743fa4SDominik Brodowski program += yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH, 69527879835SDominik Brodowski PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0); 696b3743fa4SDominik Brodowski program += yenta_allocate_res(socket, 3, IORESOURCE_MEM, 69727879835SDominik Brodowski PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1); 698b3743fa4SDominik Brodowski if (program) 699b3743fa4SDominik Brodowski pci_setup_cardbus(socket->dev->subordinate); 7001da177e4SLinus Torvalds } 7011da177e4SLinus Torvalds 7021da177e4SLinus Torvalds 7031da177e4SLinus Torvalds /* 7041da177e4SLinus Torvalds * Free the bridge mappings for the device.. 7051da177e4SLinus Torvalds */ 7061da177e4SLinus Torvalds static void yenta_free_resources(struct yenta_socket *socket) 7071da177e4SLinus Torvalds { 7081da177e4SLinus Torvalds int i; 7091da177e4SLinus Torvalds for (i=0;i<4;i++) { 7101da177e4SLinus Torvalds struct resource *res; 7111da177e4SLinus Torvalds res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i; 7121da177e4SLinus Torvalds if (res->start != 0 && res->end != 0) 7131da177e4SLinus Torvalds release_resource(res); 714b3743fa4SDominik Brodowski res->start = res->end = res->flags = 0; 7151da177e4SLinus Torvalds } 7161da177e4SLinus Torvalds } 7171da177e4SLinus Torvalds 7181da177e4SLinus Torvalds 7191da177e4SLinus Torvalds /* 7201da177e4SLinus Torvalds * Close it down - release our resources and go home.. 7211da177e4SLinus Torvalds */ 7221da177e4SLinus Torvalds static void yenta_close(struct pci_dev *dev) 7231da177e4SLinus Torvalds { 7241da177e4SLinus Torvalds struct yenta_socket *sock = pci_get_drvdata(dev); 7251da177e4SLinus Torvalds 726030ee39cSLinus Torvalds /* Remove the register attributes */ 727030ee39cSLinus Torvalds device_remove_file(&dev->dev, &dev_attr_yenta_registers); 728030ee39cSLinus Torvalds 7291da177e4SLinus Torvalds /* we don't want a dying socket registered */ 7301da177e4SLinus Torvalds pcmcia_unregister_socket(&sock->socket); 7311da177e4SLinus Torvalds 7321da177e4SLinus Torvalds /* Disable all events so we don't die in an IRQ storm */ 7331da177e4SLinus Torvalds cb_writel(sock, CB_SOCKET_MASK, 0x0); 7341da177e4SLinus Torvalds exca_writeb(sock, I365_CSCINT, 0); 7351da177e4SLinus Torvalds 7361da177e4SLinus Torvalds if (sock->cb_irq) 7371da177e4SLinus Torvalds free_irq(sock->cb_irq, sock); 7381da177e4SLinus Torvalds else 7391da177e4SLinus Torvalds del_timer_sync(&sock->poll_timer); 7401da177e4SLinus Torvalds 7411da177e4SLinus Torvalds if (sock->base) 7421da177e4SLinus Torvalds iounmap(sock->base); 7431da177e4SLinus Torvalds yenta_free_resources(sock); 7441da177e4SLinus Torvalds 7451da177e4SLinus Torvalds pci_release_regions(dev); 7461da177e4SLinus Torvalds pci_disable_device(dev); 7471da177e4SLinus Torvalds pci_set_drvdata(dev, NULL); 7481da177e4SLinus Torvalds } 7491da177e4SLinus Torvalds 7501da177e4SLinus Torvalds 7511da177e4SLinus Torvalds static struct pccard_operations yenta_socket_operations = { 7521da177e4SLinus Torvalds .init = yenta_sock_init, 7531da177e4SLinus Torvalds .suspend = yenta_sock_suspend, 7541da177e4SLinus Torvalds .get_status = yenta_get_status, 7551da177e4SLinus Torvalds .set_socket = yenta_set_socket, 7561da177e4SLinus Torvalds .set_io_map = yenta_set_io_map, 7571da177e4SLinus Torvalds .set_mem_map = yenta_set_mem_map, 7581da177e4SLinus Torvalds }; 7591da177e4SLinus Torvalds 7601da177e4SLinus Torvalds 76163e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_TI 7621da177e4SLinus Torvalds #include "ti113x.h" 76363e7ebd0SDaniel Ritz #endif 76463e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_RICOH 7651da177e4SLinus Torvalds #include "ricoh.h" 76663e7ebd0SDaniel Ritz #endif 76763e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_TOSHIBA 7681da177e4SLinus Torvalds #include "topic.h" 76963e7ebd0SDaniel Ritz #endif 77063e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_O2 7711da177e4SLinus Torvalds #include "o2micro.h" 77263e7ebd0SDaniel Ritz #endif 7731da177e4SLinus Torvalds 7741da177e4SLinus Torvalds enum { 7751da177e4SLinus Torvalds CARDBUS_TYPE_DEFAULT = -1, 7761da177e4SLinus Torvalds CARDBUS_TYPE_TI, 7771da177e4SLinus Torvalds CARDBUS_TYPE_TI113X, 7781da177e4SLinus Torvalds CARDBUS_TYPE_TI12XX, 7791da177e4SLinus Torvalds CARDBUS_TYPE_TI1250, 7801da177e4SLinus Torvalds CARDBUS_TYPE_RICOH, 781ea2f1590SDaniel Ritz CARDBUS_TYPE_TOPIC95, 7821da177e4SLinus Torvalds CARDBUS_TYPE_TOPIC97, 7831da177e4SLinus Torvalds CARDBUS_TYPE_O2MICRO, 7848c3520d4SDaniel Ritz CARDBUS_TYPE_ENE, 7851da177e4SLinus Torvalds }; 7861da177e4SLinus Torvalds 7871da177e4SLinus Torvalds /* 7881da177e4SLinus Torvalds * Different cardbus controllers have slightly different 7891da177e4SLinus Torvalds * initialization sequences etc details. List them here.. 7901da177e4SLinus Torvalds */ 7911da177e4SLinus Torvalds static struct cardbus_type cardbus_type[] = { 79263e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_TI 7931da177e4SLinus Torvalds [CARDBUS_TYPE_TI] = { 7941da177e4SLinus Torvalds .override = ti_override, 7951da177e4SLinus Torvalds .save_state = ti_save_state, 7961da177e4SLinus Torvalds .restore_state = ti_restore_state, 7971da177e4SLinus Torvalds .sock_init = ti_init, 7981da177e4SLinus Torvalds }, 7991da177e4SLinus Torvalds [CARDBUS_TYPE_TI113X] = { 8001da177e4SLinus Torvalds .override = ti113x_override, 8011da177e4SLinus Torvalds .save_state = ti_save_state, 8021da177e4SLinus Torvalds .restore_state = ti_restore_state, 8031da177e4SLinus Torvalds .sock_init = ti_init, 8041da177e4SLinus Torvalds }, 8051da177e4SLinus Torvalds [CARDBUS_TYPE_TI12XX] = { 8061da177e4SLinus Torvalds .override = ti12xx_override, 8071da177e4SLinus Torvalds .save_state = ti_save_state, 8081da177e4SLinus Torvalds .restore_state = ti_restore_state, 8091da177e4SLinus Torvalds .sock_init = ti_init, 8101da177e4SLinus Torvalds }, 8111da177e4SLinus Torvalds [CARDBUS_TYPE_TI1250] = { 8121da177e4SLinus Torvalds .override = ti1250_override, 8131da177e4SLinus Torvalds .save_state = ti_save_state, 8141da177e4SLinus Torvalds .restore_state = ti_restore_state, 8151da177e4SLinus Torvalds .sock_init = ti_init, 8161da177e4SLinus Torvalds }, 81763e7ebd0SDaniel Ritz #endif 81863e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_RICOH 8191da177e4SLinus Torvalds [CARDBUS_TYPE_RICOH] = { 8201da177e4SLinus Torvalds .override = ricoh_override, 8211da177e4SLinus Torvalds .save_state = ricoh_save_state, 8221da177e4SLinus Torvalds .restore_state = ricoh_restore_state, 8231da177e4SLinus Torvalds }, 82463e7ebd0SDaniel Ritz #endif 82563e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_TOSHIBA 826ea2f1590SDaniel Ritz [CARDBUS_TYPE_TOPIC95] = { 827ea2f1590SDaniel Ritz .override = topic95_override, 828ea2f1590SDaniel Ritz }, 8291da177e4SLinus Torvalds [CARDBUS_TYPE_TOPIC97] = { 8301da177e4SLinus Torvalds .override = topic97_override, 8311da177e4SLinus Torvalds }, 83263e7ebd0SDaniel Ritz #endif 83363e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_O2 8341da177e4SLinus Torvalds [CARDBUS_TYPE_O2MICRO] = { 8351da177e4SLinus Torvalds .override = o2micro_override, 8361da177e4SLinus Torvalds .restore_state = o2micro_restore_state, 8371da177e4SLinus Torvalds }, 83863e7ebd0SDaniel Ritz #endif 83963e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_TI 8408c3520d4SDaniel Ritz [CARDBUS_TYPE_ENE] = { 8418c3520d4SDaniel Ritz .override = ene_override, 8428c3520d4SDaniel Ritz .save_state = ti_save_state, 8438c3520d4SDaniel Ritz .restore_state = ti_restore_state, 8448c3520d4SDaniel Ritz .sock_init = ti_init, 8458c3520d4SDaniel Ritz }, 84663e7ebd0SDaniel Ritz #endif 8471da177e4SLinus Torvalds }; 8481da177e4SLinus Torvalds 8491da177e4SLinus Torvalds 8501da177e4SLinus Torvalds /* 8511da177e4SLinus Torvalds * Only probe "regular" interrupts, don't 8521da177e4SLinus Torvalds * touch dangerous spots like the mouse irq, 8531da177e4SLinus Torvalds * because there are mice that apparently 8541da177e4SLinus Torvalds * get really confused if they get fondled 8551da177e4SLinus Torvalds * too intimately. 8561da177e4SLinus Torvalds * 8571da177e4SLinus Torvalds * Default to 11, 10, 9, 7, 6, 5, 4, 3. 8581da177e4SLinus Torvalds */ 8591da177e4SLinus Torvalds static u32 isa_interrupts = 0x0ef8; 8601da177e4SLinus Torvalds 8611da177e4SLinus Torvalds static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask) 8621da177e4SLinus Torvalds { 8631da177e4SLinus Torvalds int i; 8641da177e4SLinus Torvalds unsigned long val; 8651da177e4SLinus Torvalds u32 mask; 8661da177e4SLinus Torvalds 8671da177e4SLinus Torvalds /* 8681da177e4SLinus Torvalds * Probe for usable interrupts using the force 8691da177e4SLinus Torvalds * register to generate bogus card status events. 8701da177e4SLinus Torvalds */ 8711da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_EVENT, -1); 8721da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); 8731da177e4SLinus Torvalds exca_writeb(socket, I365_CSCINT, 0); 8741da177e4SLinus Torvalds val = probe_irq_on() & isa_irq_mask; 8751da177e4SLinus Torvalds for (i = 1; i < 16; i++) { 8761da177e4SLinus Torvalds if (!((val >> i) & 1)) 8771da177e4SLinus Torvalds continue; 8781da177e4SLinus Torvalds exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG | (i << 4)); 8791da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); 8801da177e4SLinus Torvalds udelay(100); 8811da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_EVENT, -1); 8821da177e4SLinus Torvalds } 8831da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_MASK, 0); 8841da177e4SLinus Torvalds exca_writeb(socket, I365_CSCINT, 0); 8851da177e4SLinus Torvalds 8861da177e4SLinus Torvalds mask = probe_irq_mask(val) & 0xffff; 8871da177e4SLinus Torvalds 8881da177e4SLinus Torvalds return mask; 8891da177e4SLinus Torvalds } 8901da177e4SLinus Torvalds 8911da177e4SLinus Torvalds 89263e7ebd0SDaniel Ritz /** 89363e7ebd0SDaniel Ritz * yenta PCI irq probing. 89463e7ebd0SDaniel Ritz * currently only used in the TI/EnE initialization code 89563e7ebd0SDaniel Ritz */ 89663e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_TI 89763e7ebd0SDaniel Ritz 8981da177e4SLinus Torvalds /* interrupt handler, only used during probing */ 8997d12e780SDavid Howells static irqreturn_t yenta_probe_handler(int irq, void *dev_id) 9001da177e4SLinus Torvalds { 9011da177e4SLinus Torvalds struct yenta_socket *socket = (struct yenta_socket *) dev_id; 9021da177e4SLinus Torvalds u8 csc; 9031da177e4SLinus Torvalds u32 cb_event; 9041da177e4SLinus Torvalds 9051da177e4SLinus Torvalds /* Clear interrupt status for the event */ 9061da177e4SLinus Torvalds cb_event = cb_readl(socket, CB_SOCKET_EVENT); 9071da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_EVENT, -1); 9081da177e4SLinus Torvalds csc = exca_readb(socket, I365_CSC); 9091da177e4SLinus Torvalds 9101da177e4SLinus Torvalds if (cb_event || csc) { 9111da177e4SLinus Torvalds socket->probe_status = 1; 9121da177e4SLinus Torvalds return IRQ_HANDLED; 9131da177e4SLinus Torvalds } 9141da177e4SLinus Torvalds 9151da177e4SLinus Torvalds return IRQ_NONE; 9161da177e4SLinus Torvalds } 9171da177e4SLinus Torvalds 9181da177e4SLinus Torvalds /* probes the PCI interrupt, use only on override functions */ 9191da177e4SLinus Torvalds static int yenta_probe_cb_irq(struct yenta_socket *socket) 9201da177e4SLinus Torvalds { 9211da177e4SLinus Torvalds if (!socket->cb_irq) 9221da177e4SLinus Torvalds return -1; 9231da177e4SLinus Torvalds 9241da177e4SLinus Torvalds socket->probe_status = 0; 9251da177e4SLinus Torvalds 926dace1453SThomas Gleixner if (request_irq(socket->cb_irq, yenta_probe_handler, IRQF_SHARED, "yenta", socket)) { 9271da177e4SLinus Torvalds printk(KERN_WARNING "Yenta: request_irq() in yenta_probe_cb_irq() failed!\n"); 9281da177e4SLinus Torvalds return -1; 9291da177e4SLinus Torvalds } 9301da177e4SLinus Torvalds 9311da177e4SLinus Torvalds /* generate interrupt, wait */ 9321da177e4SLinus Torvalds exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG); 9331da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_EVENT, -1); 9341da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); 9351da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); 9361da177e4SLinus Torvalds 9371da177e4SLinus Torvalds msleep(100); 9381da177e4SLinus Torvalds 9391da177e4SLinus Torvalds /* disable interrupts */ 9401da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_MASK, 0); 9411da177e4SLinus Torvalds exca_writeb(socket, I365_CSCINT, 0); 9421da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_EVENT, -1); 9431da177e4SLinus Torvalds exca_readb(socket, I365_CSC); 9441da177e4SLinus Torvalds 9451da177e4SLinus Torvalds free_irq(socket->cb_irq, socket); 9461da177e4SLinus Torvalds 9471da177e4SLinus Torvalds return (int) socket->probe_status; 9481da177e4SLinus Torvalds } 9491da177e4SLinus Torvalds 95063e7ebd0SDaniel Ritz #endif /* CONFIG_YENTA_TI */ 9511da177e4SLinus Torvalds 9521da177e4SLinus Torvalds 9531da177e4SLinus Torvalds /* 9541da177e4SLinus Torvalds * Set static data that doesn't need re-initializing.. 9551da177e4SLinus Torvalds */ 9561da177e4SLinus Torvalds static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask) 9571da177e4SLinus Torvalds { 9581da177e4SLinus Torvalds socket->socket.pci_irq = socket->cb_irq; 959fa912bcbSDaniel Ritz if (isa_probe) 9601da177e4SLinus Torvalds socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask); 961fa912bcbSDaniel Ritz else 962fa912bcbSDaniel Ritz socket->socket.irq_mask = 0; 9631da177e4SLinus Torvalds 9641da177e4SLinus Torvalds printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n", 9651da177e4SLinus Torvalds socket->socket.irq_mask, socket->cb_irq); 9661da177e4SLinus Torvalds } 9671da177e4SLinus Torvalds 9681da177e4SLinus Torvalds /* 9691da177e4SLinus Torvalds * Initialize the standard cardbus registers 9701da177e4SLinus Torvalds */ 9711da177e4SLinus Torvalds static void yenta_config_init(struct yenta_socket *socket) 9721da177e4SLinus Torvalds { 9731da177e4SLinus Torvalds u16 bridge; 9741da177e4SLinus Torvalds struct pci_dev *dev = socket->dev; 9758e5d17ebSDominik Brodowski struct pci_bus_region region; 9761da177e4SLinus Torvalds 9778e5d17ebSDominik Brodowski pcibios_resource_to_bus(socket->dev, ®ion, &dev->resource[0]); 9781da177e4SLinus Torvalds 9791da177e4SLinus Torvalds config_writel(socket, CB_LEGACY_MODE_BASE, 0); 9808e5d17ebSDominik Brodowski config_writel(socket, PCI_BASE_ADDRESS_0, region.start); 9811da177e4SLinus Torvalds config_writew(socket, PCI_COMMAND, 9821da177e4SLinus Torvalds PCI_COMMAND_IO | 9831da177e4SLinus Torvalds PCI_COMMAND_MEMORY | 9841da177e4SLinus Torvalds PCI_COMMAND_MASTER | 9851da177e4SLinus Torvalds PCI_COMMAND_WAIT); 9861da177e4SLinus Torvalds 9871da177e4SLinus Torvalds /* MAGIC NUMBERS! Fixme */ 9881da177e4SLinus Torvalds config_writeb(socket, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4); 9891da177e4SLinus Torvalds config_writeb(socket, PCI_LATENCY_TIMER, 168); 9901da177e4SLinus Torvalds config_writel(socket, PCI_PRIMARY_BUS, 9911da177e4SLinus Torvalds (176 << 24) | /* sec. latency timer */ 9921da177e4SLinus Torvalds (dev->subordinate->subordinate << 16) | /* subordinate bus */ 9931da177e4SLinus Torvalds (dev->subordinate->secondary << 8) | /* secondary bus */ 9941da177e4SLinus Torvalds dev->subordinate->primary); /* primary bus */ 9951da177e4SLinus Torvalds 9961da177e4SLinus Torvalds /* 9971da177e4SLinus Torvalds * Set up the bridging state: 9981da177e4SLinus Torvalds * - enable write posting. 9991da177e4SLinus Torvalds * - memory window 0 prefetchable, window 1 non-prefetchable 10001da177e4SLinus Torvalds * - PCI interrupts enabled if a PCI interrupt exists.. 10011da177e4SLinus Torvalds */ 10021da177e4SLinus Torvalds bridge = config_readw(socket, CB_BRIDGE_CONTROL); 1003a413c090SDaniel Ritz bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN); 1004a413c090SDaniel Ritz bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN; 10051da177e4SLinus Torvalds config_writew(socket, CB_BRIDGE_CONTROL, bridge); 10061da177e4SLinus Torvalds } 10071da177e4SLinus Torvalds 1008b435261bSBernhard Kaindl /** 100966005216SRandy Dunlap * yenta_fixup_parent_bridge - Fix subordinate bus# of the parent bridge 1010b435261bSBernhard Kaindl * @cardbus_bridge: The PCI bus which the CardBus bridge bridges to 1011b435261bSBernhard Kaindl * 1012b435261bSBernhard Kaindl * Checks if devices on the bus which the CardBus bridge bridges to would be 1013b435261bSBernhard Kaindl * invisible during PCI scans because of a misconfigured subordinate number 1014b435261bSBernhard Kaindl * of the parent brige - some BIOSes seem to be too lazy to set it right. 1015b435261bSBernhard Kaindl * Does the fixup carefully by checking how far it can go without conflicts. 1016b435261bSBernhard Kaindl * See http://bugzilla.kernel.org/show_bug.cgi?id=2944 for more information. 1017b435261bSBernhard Kaindl */ 1018b435261bSBernhard Kaindl static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) 1019b435261bSBernhard Kaindl { 1020b435261bSBernhard Kaindl struct list_head *tmp; 1021b435261bSBernhard Kaindl unsigned char upper_limit; 1022b435261bSBernhard Kaindl /* 1023b435261bSBernhard Kaindl * We only check and fix the parent bridge: All systems which need 1024b435261bSBernhard Kaindl * this fixup that have been reviewed are laptops and the only bridge 1025b435261bSBernhard Kaindl * which needed fixing was the parent bridge of the CardBus bridge: 1026b435261bSBernhard Kaindl */ 1027b435261bSBernhard Kaindl struct pci_bus *bridge_to_fix = cardbus_bridge->parent; 1028b435261bSBernhard Kaindl 1029b435261bSBernhard Kaindl /* Check bus numbers are already set up correctly: */ 1030b435261bSBernhard Kaindl if (bridge_to_fix->subordinate >= cardbus_bridge->subordinate) 1031b435261bSBernhard Kaindl return; /* The subordinate number is ok, nothing to do */ 1032b435261bSBernhard Kaindl 1033b435261bSBernhard Kaindl if (!bridge_to_fix->parent) 1034b435261bSBernhard Kaindl return; /* Root bridges are ok */ 1035b435261bSBernhard Kaindl 1036b435261bSBernhard Kaindl /* stay within the limits of the bus range of the parent: */ 1037b435261bSBernhard Kaindl upper_limit = bridge_to_fix->parent->subordinate; 1038b435261bSBernhard Kaindl 1039b435261bSBernhard Kaindl /* check the bus ranges of all silbling bridges to prevent overlap */ 1040b435261bSBernhard Kaindl list_for_each(tmp, &bridge_to_fix->parent->children) { 1041b435261bSBernhard Kaindl struct pci_bus * silbling = pci_bus_b(tmp); 1042b435261bSBernhard Kaindl /* 1043b435261bSBernhard Kaindl * If the silbling has a higher secondary bus number 1044b435261bSBernhard Kaindl * and it's secondary is equal or smaller than our 1045b435261bSBernhard Kaindl * current upper limit, set the new upper limit to 1046b435261bSBernhard Kaindl * the bus number below the silbling's range: 1047b435261bSBernhard Kaindl */ 1048b435261bSBernhard Kaindl if (silbling->secondary > bridge_to_fix->subordinate 1049b435261bSBernhard Kaindl && silbling->secondary <= upper_limit) 1050b435261bSBernhard Kaindl upper_limit = silbling->secondary - 1; 1051b435261bSBernhard Kaindl } 1052b435261bSBernhard Kaindl 1053b435261bSBernhard Kaindl /* Show that the wanted subordinate number is not possible: */ 1054b435261bSBernhard Kaindl if (cardbus_bridge->subordinate > upper_limit) 1055b435261bSBernhard Kaindl printk(KERN_WARNING "Yenta: Upper limit for fixing this " 1056b435261bSBernhard Kaindl "bridge's parent bridge: #%02x\n", upper_limit); 1057b435261bSBernhard Kaindl 1058b435261bSBernhard Kaindl /* If we have room to increase the bridge's subordinate number, */ 1059b435261bSBernhard Kaindl if (bridge_to_fix->subordinate < upper_limit) { 1060b435261bSBernhard Kaindl 1061b435261bSBernhard Kaindl /* use the highest number of the hidden bus, within limits */ 1062b435261bSBernhard Kaindl unsigned char subordinate_to_assign = 1063b435261bSBernhard Kaindl min(cardbus_bridge->subordinate, upper_limit); 1064b435261bSBernhard Kaindl 1065b435261bSBernhard Kaindl printk(KERN_INFO "Yenta: Raising subordinate bus# of parent " 1066b435261bSBernhard Kaindl "bus (#%02x) from #%02x to #%02x\n", 1067b435261bSBernhard Kaindl bridge_to_fix->number, 1068b435261bSBernhard Kaindl bridge_to_fix->subordinate, subordinate_to_assign); 1069b435261bSBernhard Kaindl 1070b435261bSBernhard Kaindl /* Save the new subordinate in the bus struct of the bridge */ 1071b435261bSBernhard Kaindl bridge_to_fix->subordinate = subordinate_to_assign; 1072b435261bSBernhard Kaindl 1073b435261bSBernhard Kaindl /* and update the PCI config space with the new subordinate */ 1074b435261bSBernhard Kaindl pci_write_config_byte(bridge_to_fix->self, 1075b435261bSBernhard Kaindl PCI_SUBORDINATE_BUS, bridge_to_fix->subordinate); 1076b435261bSBernhard Kaindl } 1077b435261bSBernhard Kaindl } 1078b435261bSBernhard Kaindl 10791da177e4SLinus Torvalds /* 10801da177e4SLinus Torvalds * Initialize a cardbus controller. Make sure we have a usable 10811da177e4SLinus Torvalds * interrupt, and that we can map the cardbus area. Fill in the 10821da177e4SLinus Torvalds * socket information structure.. 10831da177e4SLinus Torvalds */ 10841da177e4SLinus Torvalds static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_id *id) 10851da177e4SLinus Torvalds { 10861da177e4SLinus Torvalds struct yenta_socket *socket; 10871da177e4SLinus Torvalds int ret; 10881da177e4SLinus Torvalds 1089c7fb0b35SIvan Kokshaysky /* 1090c7fb0b35SIvan Kokshaysky * If we failed to assign proper bus numbers for this cardbus 1091c7fb0b35SIvan Kokshaysky * controller during PCI probe, its subordinate pci_bus is NULL. 1092c7fb0b35SIvan Kokshaysky * Bail out if so. 1093c7fb0b35SIvan Kokshaysky */ 1094c7fb0b35SIvan Kokshaysky if (!dev->subordinate) { 10955a23f347SLinus Torvalds printk(KERN_ERR "Yenta: no bus associated with %s! " 10965a23f347SLinus Torvalds "(try 'pci=assign-busses')\n", pci_name(dev)); 1097c7fb0b35SIvan Kokshaysky return -ENODEV; 1098c7fb0b35SIvan Kokshaysky } 1099c7fb0b35SIvan Kokshaysky 11008084b372SDominik Brodowski socket = kzalloc(sizeof(struct yenta_socket), GFP_KERNEL); 11011da177e4SLinus Torvalds if (!socket) 11021da177e4SLinus Torvalds return -ENOMEM; 11031da177e4SLinus Torvalds 11041da177e4SLinus Torvalds /* prepare pcmcia_socket */ 11051da177e4SLinus Torvalds socket->socket.ops = ¥ta_socket_operations; 11061da177e4SLinus Torvalds socket->socket.resource_ops = &pccard_nonstatic_ops; 11071da177e4SLinus Torvalds socket->socket.dev.dev = &dev->dev; 11081da177e4SLinus Torvalds socket->socket.driver_data = socket; 11091da177e4SLinus Torvalds socket->socket.owner = THIS_MODULE; 11105bc6b68aSRussell King socket->socket.features = SS_CAP_PAGE_REGS | SS_CAP_PCCARD; 11115bc6b68aSRussell King socket->socket.map_size = 0x1000; 11125bc6b68aSRussell King socket->socket.cb_dev = dev; 11131da177e4SLinus Torvalds 11141da177e4SLinus Torvalds /* prepare struct yenta_socket */ 11151da177e4SLinus Torvalds socket->dev = dev; 11161da177e4SLinus Torvalds pci_set_drvdata(dev, socket); 11171da177e4SLinus Torvalds 11181da177e4SLinus Torvalds /* 11191da177e4SLinus Torvalds * Do some basic sanity checking.. 11201da177e4SLinus Torvalds */ 11211da177e4SLinus Torvalds if (pci_enable_device(dev)) { 11221da177e4SLinus Torvalds ret = -EBUSY; 11231da177e4SLinus Torvalds goto free; 11241da177e4SLinus Torvalds } 11251da177e4SLinus Torvalds 11261da177e4SLinus Torvalds ret = pci_request_regions(dev, "yenta_socket"); 11271da177e4SLinus Torvalds if (ret) 11281da177e4SLinus Torvalds goto disable; 11291da177e4SLinus Torvalds 11301da177e4SLinus Torvalds if (!pci_resource_start(dev, 0)) { 11311da177e4SLinus Torvalds printk(KERN_ERR "No cardbus resource!\n"); 11321da177e4SLinus Torvalds ret = -ENODEV; 11331da177e4SLinus Torvalds goto release; 11341da177e4SLinus Torvalds } 11351da177e4SLinus Torvalds 11361da177e4SLinus Torvalds /* 11371da177e4SLinus Torvalds * Ok, start setup.. Map the cardbus registers, 11381da177e4SLinus Torvalds * and request the IRQ. 11391da177e4SLinus Torvalds */ 11401da177e4SLinus Torvalds socket->base = ioremap(pci_resource_start(dev, 0), 0x1000); 11411da177e4SLinus Torvalds if (!socket->base) { 11421da177e4SLinus Torvalds ret = -ENOMEM; 11431da177e4SLinus Torvalds goto release; 11441da177e4SLinus Torvalds } 11451da177e4SLinus Torvalds 11461da177e4SLinus Torvalds /* 11471da177e4SLinus Torvalds * report the subsystem vendor and device for help debugging 11481da177e4SLinus Torvalds * the irq stuff... 11491da177e4SLinus Torvalds */ 11501da177e4SLinus Torvalds printk(KERN_INFO "Yenta: CardBus bridge found at %s [%04x:%04x]\n", 11511da177e4SLinus Torvalds pci_name(dev), dev->subsystem_vendor, dev->subsystem_device); 11521da177e4SLinus Torvalds 11531da177e4SLinus Torvalds yenta_config_init(socket); 11541da177e4SLinus Torvalds 11551da177e4SLinus Torvalds /* Disable all events */ 11561da177e4SLinus Torvalds cb_writel(socket, CB_SOCKET_MASK, 0x0); 11571da177e4SLinus Torvalds 11581da177e4SLinus Torvalds /* Set up the bridge regions.. */ 11591da177e4SLinus Torvalds yenta_allocate_resources(socket); 11601da177e4SLinus Torvalds 11611da177e4SLinus Torvalds socket->cb_irq = dev->irq; 11621da177e4SLinus Torvalds 11631da177e4SLinus Torvalds /* Do we have special options for the device? */ 11641da177e4SLinus Torvalds if (id->driver_data != CARDBUS_TYPE_DEFAULT && 11651da177e4SLinus Torvalds id->driver_data < ARRAY_SIZE(cardbus_type)) { 11661da177e4SLinus Torvalds socket->type = &cardbus_type[id->driver_data]; 11671da177e4SLinus Torvalds 11681da177e4SLinus Torvalds ret = socket->type->override(socket); 11691da177e4SLinus Torvalds if (ret < 0) 11701da177e4SLinus Torvalds goto unmap; 11711da177e4SLinus Torvalds } 11721da177e4SLinus Torvalds 11731da177e4SLinus Torvalds /* We must finish initialization here */ 11741da177e4SLinus Torvalds 1175dace1453SThomas Gleixner if (!socket->cb_irq || request_irq(socket->cb_irq, yenta_interrupt, IRQF_SHARED, "yenta", socket)) { 11761da177e4SLinus Torvalds /* No IRQ or request_irq failed. Poll */ 11771da177e4SLinus Torvalds socket->cb_irq = 0; /* But zero is a valid IRQ number. */ 11781da177e4SLinus Torvalds init_timer(&socket->poll_timer); 11791da177e4SLinus Torvalds socket->poll_timer.function = yenta_interrupt_wrapper; 11801da177e4SLinus Torvalds socket->poll_timer.data = (unsigned long)socket; 11811da177e4SLinus Torvalds socket->poll_timer.expires = jiffies + HZ; 11821da177e4SLinus Torvalds add_timer(&socket->poll_timer); 11835bc6b68aSRussell King printk(KERN_INFO "Yenta: no PCI IRQ, CardBus support disabled for this socket.\n" 11845bc6b68aSRussell King KERN_INFO "Yenta: check your BIOS CardBus, BIOS IRQ or ACPI settings.\n"); 11855bc6b68aSRussell King } else { 11865bc6b68aSRussell King socket->socket.features |= SS_CAP_CARDBUS; 11871da177e4SLinus Torvalds } 11881da177e4SLinus Torvalds 11891da177e4SLinus Torvalds /* Figure out what the dang thing can do for the PCMCIA layer... */ 1190fa912bcbSDaniel Ritz yenta_interrogate(socket); 11911da177e4SLinus Torvalds yenta_get_socket_capabilities(socket, isa_interrupts); 11921da177e4SLinus Torvalds printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); 11931da177e4SLinus Torvalds 1194b435261bSBernhard Kaindl yenta_fixup_parent_bridge(dev->subordinate); 1195b435261bSBernhard Kaindl 11961da177e4SLinus Torvalds /* Register it with the pcmcia layer.. */ 11971da177e4SLinus Torvalds ret = pcmcia_register_socket(&socket->socket); 1198030ee39cSLinus Torvalds if (ret == 0) { 1199030ee39cSLinus Torvalds /* Add the yenta register attributes */ 1200030ee39cSLinus Torvalds device_create_file(&dev->dev, &dev_attr_yenta_registers); 12011da177e4SLinus Torvalds goto out; 1202030ee39cSLinus Torvalds } 12031da177e4SLinus Torvalds 12041da177e4SLinus Torvalds unmap: 12051da177e4SLinus Torvalds iounmap(socket->base); 12061da177e4SLinus Torvalds release: 12071da177e4SLinus Torvalds pci_release_regions(dev); 12081da177e4SLinus Torvalds disable: 12091da177e4SLinus Torvalds pci_disable_device(dev); 12101da177e4SLinus Torvalds free: 12111da177e4SLinus Torvalds kfree(socket); 12121da177e4SLinus Torvalds out: 12131da177e4SLinus Torvalds return ret; 12141da177e4SLinus Torvalds } 12151da177e4SLinus Torvalds 12161da177e4SLinus Torvalds 12171da177e4SLinus Torvalds static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state) 12181da177e4SLinus Torvalds { 12191da177e4SLinus Torvalds struct yenta_socket *socket = pci_get_drvdata(dev); 12201da177e4SLinus Torvalds int ret; 12211da177e4SLinus Torvalds 12221da177e4SLinus Torvalds ret = pcmcia_socket_dev_suspend(&dev->dev, state); 12231da177e4SLinus Torvalds 12241da177e4SLinus Torvalds if (socket) { 12251da177e4SLinus Torvalds if (socket->type && socket->type->save_state) 12261da177e4SLinus Torvalds socket->type->save_state(socket); 12271da177e4SLinus Torvalds 12281da177e4SLinus Torvalds /* FIXME: pci_save_state needs to have a better interface */ 12291da177e4SLinus Torvalds pci_save_state(dev); 12301da177e4SLinus Torvalds pci_read_config_dword(dev, 16*4, &socket->saved_state[0]); 12311da177e4SLinus Torvalds pci_read_config_dword(dev, 17*4, &socket->saved_state[1]); 1232d58da590SDavid Shaohua Li pci_disable_device(dev); 12331da177e4SLinus Torvalds 12341da177e4SLinus Torvalds /* 12351da177e4SLinus Torvalds * Some laptops (IBM T22) do not like us putting the Cardbus 12361da177e4SLinus Torvalds * bridge into D3. At a guess, some other laptop will 12371da177e4SLinus Torvalds * probably require this, so leave it commented out for now. 12381da177e4SLinus Torvalds */ 12391da177e4SLinus Torvalds /* pci_set_power_state(dev, 3); */ 12401da177e4SLinus Torvalds } 12411da177e4SLinus Torvalds 12421da177e4SLinus Torvalds return ret; 12431da177e4SLinus Torvalds } 12441da177e4SLinus Torvalds 12451da177e4SLinus Torvalds 12461da177e4SLinus Torvalds static int yenta_dev_resume (struct pci_dev *dev) 12471da177e4SLinus Torvalds { 12481da177e4SLinus Torvalds struct yenta_socket *socket = pci_get_drvdata(dev); 12491da177e4SLinus Torvalds 12501da177e4SLinus Torvalds if (socket) { 12511da177e4SLinus Torvalds pci_set_power_state(dev, 0); 12521da177e4SLinus Torvalds /* FIXME: pci_restore_state needs to have a better interface */ 12531da177e4SLinus Torvalds pci_restore_state(dev); 12541da177e4SLinus Torvalds pci_write_config_dword(dev, 16*4, socket->saved_state[0]); 12551da177e4SLinus Torvalds pci_write_config_dword(dev, 17*4, socket->saved_state[1]); 1256d58da590SDavid Shaohua Li pci_enable_device(dev); 1257d58da590SDavid Shaohua Li pci_set_master(dev); 12581da177e4SLinus Torvalds 12591da177e4SLinus Torvalds if (socket->type && socket->type->restore_state) 12601da177e4SLinus Torvalds socket->type->restore_state(socket); 12611da177e4SLinus Torvalds } 12621da177e4SLinus Torvalds 12631da177e4SLinus Torvalds return pcmcia_socket_dev_resume(&dev->dev); 12641da177e4SLinus Torvalds } 12651da177e4SLinus Torvalds 12661da177e4SLinus Torvalds 12671da177e4SLinus Torvalds #define CB_ID(vend,dev,type) \ 12681da177e4SLinus Torvalds { \ 12691da177e4SLinus Torvalds .vendor = vend, \ 12701da177e4SLinus Torvalds .device = dev, \ 12711da177e4SLinus Torvalds .subvendor = PCI_ANY_ID, \ 12721da177e4SLinus Torvalds .subdevice = PCI_ANY_ID, \ 12731da177e4SLinus Torvalds .class = PCI_CLASS_BRIDGE_CARDBUS << 8, \ 12741da177e4SLinus Torvalds .class_mask = ~0, \ 12751da177e4SLinus Torvalds .driver_data = CARDBUS_TYPE_##type, \ 12761da177e4SLinus Torvalds } 12771da177e4SLinus Torvalds 12781da177e4SLinus Torvalds static struct pci_device_id yenta_table [] = { 12791da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1031, TI), 12801da177e4SLinus Torvalds 12811da177e4SLinus Torvalds /* 12821da177e4SLinus Torvalds * TBD: Check if these TI variants can use more 12831da177e4SLinus Torvalds * advanced overrides instead. (I can't get the 12841da177e4SLinus Torvalds * data sheets for these devices. --rmk) 12851da177e4SLinus Torvalds */ 128663e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_TI 12871da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1210, TI), 12881da177e4SLinus Torvalds 12891da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1130, TI113X), 12901da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1131, TI113X), 12911da177e4SLinus Torvalds 12921da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1211, TI12XX), 12931da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1220, TI12XX), 12941da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1221, TI12XX), 12951da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1225, TI12XX), 12961da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1251A, TI12XX), 12971da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1251B, TI12XX), 12981da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1420, TI12XX), 12991da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1450, TI12XX), 13001da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1451A, TI12XX), 13011da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1510, TI12XX), 13021da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, TI12XX), 13031da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1620, TI12XX), 13041da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4410, TI12XX), 13051da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4450, TI12XX), 13061da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4451, TI12XX), 13071da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4510, TI12XX), 13081da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4520, TI12XX), 13091da177e4SLinus Torvalds 13101da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1250, TI1250), 13111da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1410, TI1250), 13121da177e4SLinus Torvalds 13136c1a10dbSDaniel Ritz CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX21_XX11, TI12XX), 13146c1a10dbSDaniel Ritz CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X515, TI12XX), 131559e35ba1SAlex Williamson CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX12, TI12XX), 13166c1a10dbSDaniel Ritz CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X420, TI12XX), 13176c1a10dbSDaniel Ritz CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X620, TI12XX), 13186c1a10dbSDaniel Ritz CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7410, TI12XX), 13196c1a10dbSDaniel Ritz CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7510, TI12XX), 13206c1a10dbSDaniel Ritz CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7610, TI12XX), 13216c1a10dbSDaniel Ritz 1322f9cb8b71SDaniel Ritz CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_710, TI12XX), 1323f9cb8b71SDaniel Ritz CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_712, TI12XX), 1324f9cb8b71SDaniel Ritz CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_720, TI12XX), 1325f9cb8b71SDaniel Ritz CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_722, TI12XX), 13268c3520d4SDaniel Ritz CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1211, ENE), 13278c3520d4SDaniel Ritz CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE), 13288c3520d4SDaniel Ritz CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE), 13298c3520d4SDaniel Ritz CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE), 133063e7ebd0SDaniel Ritz #endif /* CONFIG_YENTA_TI */ 13311da177e4SLinus Torvalds 133263e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_RICOH 13331da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH), 13341da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH), 13351da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C475, RICOH), 13361da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH), 13371da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH), 133863e7ebd0SDaniel Ritz #endif 13391da177e4SLinus Torvalds 134063e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_TOSHIBA 1341ea2f1590SDaniel Ritz CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC95, TOPIC95), 13421da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97), 13431da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97), 134463e7ebd0SDaniel Ritz #endif 13451da177e4SLinus Torvalds 134663e7ebd0SDaniel Ritz #ifdef CONFIG_YENTA_O2 13471da177e4SLinus Torvalds CB_ID(PCI_VENDOR_ID_O2, PCI_ANY_ID, O2MICRO), 134863e7ebd0SDaniel Ritz #endif 13491da177e4SLinus Torvalds 13501da177e4SLinus Torvalds /* match any cardbus bridge */ 13511da177e4SLinus Torvalds CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT), 13521da177e4SLinus Torvalds { /* all zeroes */ } 13531da177e4SLinus Torvalds }; 13541da177e4SLinus Torvalds MODULE_DEVICE_TABLE(pci, yenta_table); 13551da177e4SLinus Torvalds 13561da177e4SLinus Torvalds 13571da177e4SLinus Torvalds static struct pci_driver yenta_cardbus_driver = { 13581da177e4SLinus Torvalds .name = "yenta_cardbus", 13591da177e4SLinus Torvalds .id_table = yenta_table, 13601da177e4SLinus Torvalds .probe = yenta_probe, 13611da177e4SLinus Torvalds .remove = __devexit_p(yenta_close), 13621da177e4SLinus Torvalds .suspend = yenta_dev_suspend, 13631da177e4SLinus Torvalds .resume = yenta_dev_resume, 13641da177e4SLinus Torvalds }; 13651da177e4SLinus Torvalds 13661da177e4SLinus Torvalds 13671da177e4SLinus Torvalds static int __init yenta_socket_init(void) 13681da177e4SLinus Torvalds { 13691da177e4SLinus Torvalds return pci_register_driver (¥ta_cardbus_driver); 13701da177e4SLinus Torvalds } 13711da177e4SLinus Torvalds 13721da177e4SLinus Torvalds 13731da177e4SLinus Torvalds static void __exit yenta_socket_exit (void) 13741da177e4SLinus Torvalds { 13751da177e4SLinus Torvalds pci_unregister_driver (¥ta_cardbus_driver); 13761da177e4SLinus Torvalds } 13771da177e4SLinus Torvalds 13781da177e4SLinus Torvalds 13791da177e4SLinus Torvalds module_init(yenta_socket_init); 13801da177e4SLinus Torvalds module_exit(yenta_socket_exit); 13811da177e4SLinus Torvalds 13821da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 1383