|
|
1.1 ! root 1: /*====================================================================== ! 2: ! 3: Device driver for Intel 82365 and compatible PC Card controllers, ! 4: and Yenta-compatible PCI-to-CardBus controllers. ! 5: ! 6: i82365.c 1.358 2003/09/13 17:34:01 ! 7: ! 8: The contents of this file are subject to the Mozilla Public ! 9: License Version 1.1 (the "License"); you may not use this file ! 10: except in compliance with the License. You may obtain a copy of ! 11: the License at http://www.mozilla.org/MPL/ ! 12: ! 13: Software distributed under the License is distributed on an "AS ! 14: IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ! 15: implied. See the License for the specific language governing ! 16: rights and limitations under the License. ! 17: ! 18: The initial developer of the original code is David A. Hinds ! 19: <[email protected]>. Portions created by David A. Hinds ! 20: are Copyright (C) 1999 David A. Hinds. All Rights Reserved. ! 21: ! 22: Alternatively, the contents of this file may be used under the ! 23: terms of the GNU General Public License version 2 (the "GPL"), in ! 24: which case the provisions of the GPL are applicable instead of the ! 25: above. If you wish to allow the use of your version of this file ! 26: only under the terms of the GPL and not to allow others to use ! 27: your version of this file under the MPL, indicate your decision ! 28: by deleting the provisions above and replace them with the notice ! 29: and other provisions required by the GPL. If you do not delete ! 30: the provisions above, a recipient may use your version of this ! 31: file under either the MPL or the GPL. ! 32: ! 33: ======================================================================*/ ! 34: ! 35: #include <linux/module.h> ! 36: #include <linux/init.h> ! 37: #include <linux/config.h> ! 38: #include <linux/types.h> ! 39: #include <linux/fcntl.h> ! 40: #include <linux/string.h> ! 41: #include <linux/kernel.h> ! 42: #include <linux/errno.h> ! 43: #include <linux/timer.h> ! 44: #include <linux/sched.h> ! 45: #include <linux/slab.h> ! 46: #include <linux/pci.h> ! 47: #include <linux/ioport.h> ! 48: #include <linux/delay.h> ! 49: #include <linux/proc_fs.h> ! 50: #include <linux/spinlock.h> ! 51: #include <asm/irq.h> ! 52: #include <asm/io.h> ! 53: #include <asm/bitops.h> ! 54: #include <asm/system.h> ! 55: ! 56: #include <pcmcia/version.h> ! 57: #include <pcmcia/cs_types.h> ! 58: #include <pcmcia/ss.h> ! 59: #include <pcmcia/cs.h> ! 60: ! 61: /* ISA-bus controllers */ ! 62: #include "i82365.h" ! 63: #include "cirrus.h" ! 64: #include "vg468.h" ! 65: #include "ricoh.h" ! 66: #include "o2micro.h" ! 67: ! 68: /* PCI-bus controllers */ ! 69: #include "yenta.h" ! 70: #include "ti113x.h" ! 71: #include "smc34c90.h" ! 72: #include "topic.h" ! 73: #include "ene.h" ! 74: ! 75: /*====================================================================*/ ! 76: ! 77: /* Module parameters */ ! 78: ! 79: MODULE_AUTHOR("David Hinds <[email protected]>"); ! 80: MODULE_DESCRIPTION("Intel ExCA/Yenta PCMCIA socket driver"); ! 81: MODULE_LICENSE("Dual MPL/GPL"); ! 82: ! 83: #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") ! 84: ! 85: /* General options */ ! 86: INT_MODULE_PARM(poll_interval, 0); /* in ticks, 0 means never */ ! 87: INT_MODULE_PARM(cycle_time, 120); /* in ns, 120 ns = 8.33 MHz */ ! 88: INT_MODULE_PARM(do_scan, 1); /* Probe free interrupts? */ ! 89: ! 90: /* Cirrus options */ ! 91: INT_MODULE_PARM(has_dma, -1); ! 92: INT_MODULE_PARM(has_led, -1); ! 93: INT_MODULE_PARM(has_ring, -1); ! 94: INT_MODULE_PARM(has_vsense, 0); ! 95: INT_MODULE_PARM(dynamic_mode, 0); ! 96: INT_MODULE_PARM(freq_bypass, -1); ! 97: INT_MODULE_PARM(setup_time, -1); ! 98: INT_MODULE_PARM(cmd_time, -1); ! 99: INT_MODULE_PARM(recov_time, -1); ! 100: ! 101: #ifdef CONFIG_ISA ! 102: INT_MODULE_PARM(i365_base, 0x3e0); /* IO address for probes */ ! 103: INT_MODULE_PARM(extra_sockets, 0); /* Probe at i365_base+2? */ ! 104: INT_MODULE_PARM(ignore, -1); /* Ignore this socket # */ ! 105: INT_MODULE_PARM(cs_irq, 0); /* card status irq */ ! 106: INT_MODULE_PARM(irq_mask, 0xffff); /* bit map of irq's to use */ ! 107: static int irq_list[16] = { -1 }; ! 108: MODULE_PARM(irq_list, "1-16i"); ! 109: INT_MODULE_PARM(async_clock, -1); /* Vadem specific */ ! 110: INT_MODULE_PARM(cable_mode, -1); ! 111: INT_MODULE_PARM(wakeup, 0); /* Cirrus specific */ ! 112: #endif ! 113: ! 114: #ifdef CONFIG_PCI ! 115: static int pci_irq_list[8] = { 0 }; /* PCI interrupt assignments */ ! 116: MODULE_PARM(pci_irq_list, "1-8i"); ! 117: INT_MODULE_PARM(do_pci_probe, 1); /* Scan for PCI bridges? */ ! 118: INT_MODULE_PARM(fast_pci, -1); ! 119: INT_MODULE_PARM(cb_write_post, -1); ! 120: INT_MODULE_PARM(irq_mode, -1); /* Override BIOS routing? */ ! 121: INT_MODULE_PARM(hold_time, -1); /* Ricoh specific */ ! 122: INT_MODULE_PARM(p2cclk, -1); /* TI specific */ ! 123: #endif ! 124: ! 125: #if defined(CONFIG_ISA) && defined(CONFIG_PCI) ! 126: INT_MODULE_PARM(pci_csc, 1); /* PCI card status irqs? */ ! 127: INT_MODULE_PARM(pci_int, 1); /* PCI IO card irqs? */ ! 128: #elif defined(CONFIG_ISA) && !defined(CONFIG_PCI) ! 129: #define pci_csc 0 ! 130: #define pci_int 0 ! 131: #elif !defined(CONFIG_ISA) && defined(CONFIG_PCI) ! 132: #define pci_csc 0 ! 133: #define pci_int 1 /* We must use PCI irq's */ ! 134: #else ! 135: #error "No bus architectures defined!" ! 136: #endif ! 137: ! 138: #ifdef PCMCIA_DEBUG ! 139: INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG); ! 140: #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) ! 141: static const char *version = ! 142: "i82365.c 1.358 2003/09/13 17:34:01 (David Hinds)"; ! 143: #else ! 144: #define DEBUG(n, args...) do { } while (0) ! 145: #endif ! 146: ! 147: /*====================================================================*/ ! 148: ! 149: typedef struct socket_info_t { ! 150: u_short type, flags; ! 151: socket_cap_t cap; ! 152: ioaddr_t ioaddr; ! 153: u_short psock; ! 154: u_char cs_irq, intr; ! 155: void (*handler)(void *info, u_int events); ! 156: void *info; ! 157: #ifdef HAS_PROC_BUS ! 158: struct proc_dir_entry *proc; ! 159: #endif ! 160: u_char pci_irq_code; ! 161: #ifdef CONFIG_PCI ! 162: u_short vendor, device; ! 163: u_char revision, bus, devfn; ! 164: u_short bcr; ! 165: u_char pci_lat, cb_lat, sub_bus, cache; ! 166: u_int cb_phys; ! 167: char *cb_virt; ! 168: #endif ! 169: union { ! 170: cirrus_state_t cirrus; ! 171: vg46x_state_t vg46x; ! 172: o2micro_state_t o2micro; ! 173: ti113x_state_t ti113x; ! 174: ricoh_state_t ricoh; ! 175: topic_state_t topic; ! 176: } state; ! 177: } socket_info_t; ! 178: ! 179: /* Where we keep track of our sockets... */ ! 180: static int sockets = 0; ! 181: static socket_info_t socket[8] = { ! 182: { 0, }, /* ... */ ! 183: }; ! 184: ! 185: #ifdef CONFIG_ISA ! 186: static int grab_irq; ! 187: #ifdef __SMP__ ! 188: static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED; ! 189: #endif ! 190: #define ISA_LOCK(s, f) \ ! 191: if (!((s)->flags & IS_CARDBUS)) spin_lock_irqsave(&isa_lock, f) ! 192: #define ISA_UNLOCK(n, f) \ ! 193: if (!((s)->flags & IS_CARDBUS)) spin_unlock_irqrestore(&isa_lock, f) ! 194: #else ! 195: #define ISA_LOCK(n, f) do { } while (0) ! 196: #define ISA_UNLOCK(n, f) do { } while (0) ! 197: #endif ! 198: ! 199: static void pcic_interrupt_wrapper(u_long data); ! 200: static struct timer_list poll_timer = { ! 201: function: pcic_interrupt_wrapper ! 202: }; ! 203: ! 204: #define flip(v,b,f) (v = ((f)<0) ? v : ((f) ? ((v)|(b)) : ((v)&(~b)))) ! 205: ! 206: /*====================================================================*/ ! 207: ! 208: /* Some PCI shortcuts */ ! 209: ! 210: #ifdef CONFIG_PCI ! 211: static int pci_readb(socket_info_t *s, int r, u_char *v) ! 212: { return pcibios_read_config_byte(s->bus, s->devfn, r, v); } ! 213: static int pci_writeb(socket_info_t *s, int r, u_char v) ! 214: { return pcibios_write_config_byte(s->bus, s->devfn, r, v); } ! 215: static int pci_readw(socket_info_t *s, int r, u_short *v) ! 216: { return pcibios_read_config_word(s->bus, s->devfn, r, v); } ! 217: static int pci_writew(socket_info_t *s, int r, u_short v) ! 218: { return pcibios_write_config_word(s->bus, s->devfn, r, v); } ! 219: static int pci_readl(socket_info_t *s, int r, u_int *v) ! 220: { return pcibios_read_config_dword(s->bus, s->devfn, r, v); } ! 221: static int pci_writel(socket_info_t *s, int r, u_int v) ! 222: { return pcibios_write_config_dword(s->bus, s->devfn, r, v); } ! 223: #endif ! 224: ! 225: #define cb_readb(s, r) readb((s)->cb_virt + (r)) ! 226: #define cb_readl(s, r) readl((s)->cb_virt + (r)) ! 227: #define cb_writeb(s, r, v) writeb(v, (s)->cb_virt + (r)) ! 228: #define cb_writel(s, r, v) writel(v, (s)->cb_virt + (r)) ! 229: ! 230: /*====================================================================*/ ! 231: ! 232: /* These definitions must match the pcic table! */ ! 233: typedef enum pcic_id { ! 234: #ifdef CONFIG_ISA ! 235: IS_I82365A, IS_I82365B, IS_I82365DF, IS_IBM, IS_RF5Cx96, ! 236: IS_VLSI, IS_VG468, IS_VG469, IS_PD6710, IS_PD672X, IS_VT83C469, ! 237: #endif ! 238: #ifdef CONFIG_PCI ! 239: IS_I82092AA, IS_OM82C092G, CIRRUS_PCIC_ID, O2MICRO_PCIC_ID, ! 240: RICOH_PCIC_ID, SMC_PCIC_ID, TI_PCIC_ID, ENE_PCIC_ID, ! 241: TOPIC_PCIC_ID, IS_UNK_PCI, IS_UNK_CARDBUS ! 242: #endif ! 243: } pcic_id; ! 244: ! 245: /* Flags for classifying groups of controllers */ ! 246: #define IS_VADEM 0x0001 ! 247: #define IS_CIRRUS 0x0002 ! 248: #define IS_TI 0x0004 ! 249: #define IS_O2MICRO 0x0008 ! 250: #define IS_TOPIC 0x0020 ! 251: #define IS_RICOH 0x0040 ! 252: #define IS_UNKNOWN 0x0400 ! 253: #define IS_VG_PWR 0x0800 ! 254: #define IS_DF_PWR 0x1000 ! 255: #define IS_PCI 0x2000 ! 256: #define IS_CARDBUS 0x4000 ! 257: #define IS_ALIVE 0x8000 ! 258: ! 259: typedef struct pcic_t { ! 260: char *name; ! 261: u_short flags; ! 262: #ifdef CONFIG_PCI ! 263: u_short vendor, device; ! 264: #endif ! 265: } pcic_t; ! 266: ! 267: #define ID(a,b) PCI_VENDOR_ID_##a,PCI_DEVICE_ID_##a##_##b ! 268: ! 269: static pcic_t pcic[] = { ! 270: #ifdef CONFIG_ISA ! 271: { "Intel i82365sl A step", 0 }, ! 272: { "Intel i82365sl B step", 0 }, ! 273: { "Intel i82365sl DF", IS_DF_PWR }, ! 274: { "IBM Clone", 0 }, ! 275: { "Ricoh RF5C296/396", 0 }, ! 276: { "VLSI 82C146", 0 }, ! 277: { "Vadem VG-468", IS_VADEM }, ! 278: { "Vadem VG-469", IS_VADEM|IS_VG_PWR }, ! 279: { "Cirrus PD6710", IS_CIRRUS }, ! 280: { "Cirrus PD672x", IS_CIRRUS }, ! 281: { "VIA VT83C469", IS_CIRRUS }, ! 282: #endif ! 283: #ifdef CONFIG_PCI ! 284: { "Intel 82092AA", IS_PCI, ID(INTEL, 82092AA_0) }, ! 285: { "Omega Micro 82C092G", IS_PCI, ID(OMEGA, 82C092G) }, ! 286: CIRRUS_PCIC_INFO, O2MICRO_PCIC_INFO, RICOH_PCIC_INFO, ! 287: SMC_PCIC_INFO, TI_PCIC_INFO, ENE_PCIC_INFO, TOPIC_PCIC_INFO, ! 288: { "Unknown", IS_PCI|IS_UNKNOWN, 0, 0 }, ! 289: { "Unknown", IS_CARDBUS|IS_UNKNOWN, 0, 0 } ! 290: #endif ! 291: }; ! 292: ! 293: #define PCIC_COUNT (sizeof(pcic)/sizeof(pcic_t)) ! 294: ! 295: /*====================================================================*/ ! 296: ! 297: static u_char i365_get(socket_info_t *s, u_short reg) ! 298: { ! 299: #ifdef CONFIG_PCI ! 300: if (s->cb_virt) ! 301: return cb_readb(s, 0x0800 + reg); ! 302: #endif ! 303: outb(I365_REG(s->psock, reg), s->ioaddr); ! 304: return inb(s->ioaddr+1); ! 305: } ! 306: ! 307: static void i365_set(socket_info_t *s, u_short reg, u_char data) ! 308: { ! 309: #ifdef CONFIG_PCI ! 310: if (s->cb_virt) { ! 311: cb_writeb(s, 0x0800 + reg, data); ! 312: return; ! 313: } ! 314: #endif ! 315: outb(I365_REG(s->psock, reg), s->ioaddr); ! 316: outb(data, s->ioaddr+1); ! 317: } ! 318: ! 319: static void i365_bset(socket_info_t *s, u_short reg, u_char mask) ! 320: { ! 321: i365_set(s, reg, i365_get(s, reg) | mask); ! 322: } ! 323: ! 324: static void i365_bclr(socket_info_t *s, u_short reg, u_char mask) ! 325: { ! 326: i365_set(s, reg, i365_get(s, reg) & ~mask); ! 327: } ! 328: ! 329: static void i365_bflip(socket_info_t *s, u_short reg, u_char mask, int b) ! 330: { ! 331: u_char d = i365_get(s, reg); ! 332: i365_set(s, reg, (b) ? (d | mask) : (d & ~mask)); ! 333: } ! 334: ! 335: static u_short i365_get_pair(socket_info_t *s, u_short reg) ! 336: { ! 337: return (i365_get(s, reg) + (i365_get(s, reg+1) << 8)); ! 338: } ! 339: ! 340: static void i365_set_pair(socket_info_t *s, u_short reg, u_short data) ! 341: { ! 342: i365_set(s, reg, data & 0xff); ! 343: i365_set(s, reg+1, data >> 8); ! 344: } ! 345: ! 346: /*====================================================================== ! 347: ! 348: Code to save and restore global state information for Cirrus ! 349: PD67xx controllers, and to set and report global configuration ! 350: options. ! 351: ! 352: The VIA controllers also use these routines, as they are mostly ! 353: Cirrus lookalikes, without the timing registers. ! 354: ! 355: ======================================================================*/ ! 356: ! 357: #ifdef CONFIG_PCI ! 358: ! 359: static int __init get_pci_irq(socket_info_t *s) ! 360: { ! 361: u8 irq = pci_irq_list[s - socket]; ! 362: if (!irq) ! 363: irq = pci_find_slot(s->bus, s->devfn)->irq; ! 364: if (irq >= NR_IRQS) irq = 0; ! 365: s->cap.pci_irq = irq; ! 366: return irq; ! 367: } ! 368: ! 369: #endif ! 370: ! 371: static void __init cirrus_get_state(socket_info_t *s) ! 372: { ! 373: cirrus_state_t *p = &s->state.cirrus; ! 374: int i; ! 375: ! 376: p->misc1 = i365_get(s, PD67_MISC_CTL_1); ! 377: p->misc1 &= (PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA); ! 378: p->misc2 = i365_get(s, PD67_MISC_CTL_2); ! 379: if (s->flags & IS_PCI) ! 380: p->ectl1 = pd67_ext_get(s, PD67_EXT_CTL_1); ! 381: for (i = 0; i < 6; i++) ! 382: p->timer[i] = i365_get(s, PD67_TIME_SETUP(0)+i); ! 383: } ! 384: ! 385: static void cirrus_set_state(socket_info_t *s) ! 386: { ! 387: cirrus_state_t *p = &s->state.cirrus; ! 388: u_char misc; ! 389: int i; ! 390: ! 391: misc = i365_get(s, PD67_MISC_CTL_2); ! 392: i365_set(s, PD67_MISC_CTL_2, p->misc2); ! 393: if (misc & PD67_MC2_SUSPEND) mdelay(50); ! 394: misc = i365_get(s, PD67_MISC_CTL_1); ! 395: misc &= ~(PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA); ! 396: i365_set(s, PD67_MISC_CTL_1, misc | p->misc1); ! 397: if (s->flags & IS_PCI) ! 398: pd67_ext_set(s, PD67_EXT_CTL_1, p->ectl1); ! 399: else if (has_vsense) { ! 400: socket_info_t *t = (s->psock) ? s : s+1; ! 401: pd67_ext_set(t, PD67_EXT_CTL_2, PD67_EC2_GPSTB_IOR); ! 402: } ! 403: for (i = 0; i < 6; i++) ! 404: i365_set(s, PD67_TIME_SETUP(0)+i, p->timer[i]); ! 405: } ! 406: ! 407: #ifdef CONFIG_PCI ! 408: static int cirrus_set_irq_mode(socket_info_t *s, int pcsc, int pint) ! 409: { ! 410: flip(s->bcr, PD6832_BCR_MGMT_IRQ_ENA, !pcsc); ! 411: return 0; ! 412: } ! 413: #endif ! 414: ! 415: static u_int __init cirrus_set_opts(socket_info_t *s, char *buf) ! 416: { ! 417: cirrus_state_t *p = &s->state.cirrus; ! 418: u_int mask = 0xffff; ! 419: ! 420: p->misc1 |= PD67_MC1_SPKR_ENA; ! 421: if (has_ring == -1) has_ring = 1; ! 422: flip(p->misc2, PD67_MC2_IRQ15_RI, has_ring); ! 423: flip(p->misc2, PD67_MC2_DYNAMIC_MODE, dynamic_mode); ! 424: if (p->misc2 & PD67_MC2_IRQ15_RI) ! 425: strcat(buf, " [ring]"); ! 426: if (p->misc2 & PD67_MC2_DYNAMIC_MODE) ! 427: strcat(buf, " [dyn mode]"); ! 428: if (p->misc1 & PD67_MC1_INPACK_ENA) ! 429: strcat(buf, " [inpack]"); ! 430: if (!(s->flags & (IS_PCI|IS_CARDBUS))) { ! 431: flip(p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass); ! 432: if (p->misc2 & PD67_MC2_FREQ_BYPASS) ! 433: strcat(buf, " [freq bypass]"); ! 434: if (p->misc2 & PD67_MC2_IRQ15_RI) ! 435: mask &= ~0x8000; ! 436: if (has_led > 0) { ! 437: strcat(buf, " [led]"); ! 438: mask &= ~0x1000; ! 439: } ! 440: if (has_dma > 0) { ! 441: strcat(buf, " [dma]"); ! 442: mask &= ~0x0600; ! 443: } ! 444: #ifdef CONFIG_PCI ! 445: } else { ! 446: p->misc1 &= ~PD67_MC1_MEDIA_ENA; ! 447: p->misc1 &= ~(PD67_MC1_PULSE_MGMT | PD67_MC1_PULSE_IRQ); ! 448: p->ectl1 &= ~(PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ); ! 449: flip(p->misc2, PD67_MC2_FAST_PCI, fast_pci); ! 450: if (p->misc2 & PD67_MC2_IRQ15_RI) ! 451: mask &= (s->type == IS_PD6730) ? ~0x0400 : ~0x8000; ! 452: if ((s->flags & IS_PCI) && (irq_mode == 1) && get_pci_irq(s)) { ! 453: /* Configure PD6729 bridge for PCI interrupts */ ! 454: p->ectl1 |= PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ; ! 455: s->pci_irq_code = 3; /* PCI INTA = "irq 3" */ ! 456: buf += strlen(buf); ! 457: sprintf(buf, " [pci irq %d]", s->cap.pci_irq); ! 458: mask = 0; ! 459: } ! 460: #endif ! 461: } ! 462: #ifdef CONFIG_ISA ! 463: if (s->type != IS_VT83C469) ! 464: #endif ! 465: { ! 466: if (setup_time >= 0) ! 467: p->timer[0] = p->timer[3] = setup_time; ! 468: if (cmd_time > 0) { ! 469: p->timer[1] = cmd_time; ! 470: p->timer[4] = cmd_time*2+4; ! 471: } ! 472: if (p->timer[1] == 0) { ! 473: p->timer[1] = 6; p->timer[4] = 16; ! 474: if (p->timer[0] == 0) ! 475: p->timer[0] = p->timer[3] = 1; ! 476: } ! 477: if (recov_time >= 0) ! 478: p->timer[2] = p->timer[5] = recov_time; ! 479: buf += strlen(buf); ! 480: sprintf(buf, " [%d/%d/%d] [%d/%d/%d]", p->timer[0], p->timer[1], ! 481: p->timer[2], p->timer[3], p->timer[4], p->timer[5]); ! 482: } ! 483: return mask; ! 484: } ! 485: ! 486: /*====================================================================== ! 487: ! 488: Code to save and restore global state information for Vadem VG468 ! 489: and VG469 controllers, and to set and report global configuration ! 490: options. ! 491: ! 492: ======================================================================*/ ! 493: ! 494: #ifdef CONFIG_ISA ! 495: ! 496: static void __init vg46x_get_state(socket_info_t *s) ! 497: { ! 498: vg46x_state_t *p = &s->state.vg46x; ! 499: p->ctl = i365_get(s, VG468_CTL); ! 500: if (s->type == IS_VG469) ! 501: p->ema = i365_get(s, VG469_EXT_MODE); ! 502: } ! 503: ! 504: static void vg46x_set_state(socket_info_t *s) ! 505: { ! 506: vg46x_state_t *p = &s->state.vg46x; ! 507: i365_set(s, VG468_CTL, p->ctl); ! 508: if (s->type == IS_VG469) ! 509: i365_set(s, VG469_EXT_MODE, p->ema); ! 510: } ! 511: ! 512: static u_int __init vg46x_set_opts(socket_info_t *s, char *buf) ! 513: { ! 514: vg46x_state_t *p = &s->state.vg46x; ! 515: ! 516: flip(p->ctl, VG468_CTL_ASYNC, async_clock); ! 517: flip(p->ema, VG469_MODE_CABLE, cable_mode); ! 518: if (p->ctl & VG468_CTL_ASYNC) ! 519: strcat(buf, " [async]"); ! 520: if (p->ctl & VG468_CTL_INPACK) ! 521: strcat(buf, " [inpack]"); ! 522: if (s->type == IS_VG469) { ! 523: u_char vsel = i365_get(s, VG469_VSELECT); ! 524: if (vsel & VG469_VSEL_EXT_STAT) { ! 525: strcat(buf, " [ext mode]"); ! 526: if (vsel & VG469_VSEL_EXT_BUS) ! 527: strcat(buf, " [isa buf]"); ! 528: } ! 529: if (p->ema & VG469_MODE_CABLE) ! 530: strcat(buf, " [cable]"); ! 531: if (p->ema & VG469_MODE_COMPAT) ! 532: strcat(buf, " [c step]"); ! 533: } ! 534: return 0xffff; ! 535: } ! 536: ! 537: #endif ! 538: ! 539: /*====================================================================== ! 540: ! 541: Code to save and restore global state information for TI 1130 and ! 542: TI 1131 controllers, and to set and report global configuration ! 543: options. ! 544: ! 545: ======================================================================*/ ! 546: ! 547: #ifdef CONFIG_PCI ! 548: ! 549: static void __init ti113x_get_state(socket_info_t *s) ! 550: { ! 551: ti113x_state_t *p = &s->state.ti113x; ! 552: pci_readl(s, TI113X_SYSTEM_CONTROL, &p->sysctl); ! 553: pci_readb(s, TI113X_CARD_CONTROL, &p->cardctl); ! 554: pci_readb(s, TI113X_DEVICE_CONTROL, &p->devctl); ! 555: pci_readb(s, TI1250_DIAGNOSTIC, &p->diag); ! 556: pci_readl(s, TI12XX_IRQMUX, &p->irqmux); ! 557: } ! 558: ! 559: static void ti113x_set_state(socket_info_t *s) ! 560: { ! 561: ti113x_state_t *p = &s->state.ti113x; ! 562: pci_writel(s, TI113X_SYSTEM_CONTROL, p->sysctl); ! 563: pci_writeb(s, TI113X_CARD_CONTROL, p->cardctl); ! 564: pci_writeb(s, TI113X_DEVICE_CONTROL, p->devctl); ! 565: pci_writeb(s, TI1250_MULTIMEDIA_CTL, 0); ! 566: pci_writeb(s, TI1250_DIAGNOSTIC, p->diag); ! 567: pci_writel(s, TI12XX_IRQMUX, p->irqmux); ! 568: i365_set_pair(s, TI113X_IO_OFFSET(0), 0); ! 569: i365_set_pair(s, TI113X_IO_OFFSET(1), 0); ! 570: } ! 571: ! 572: static int ti113x_set_irq_mode(socket_info_t *s, int pcsc, int pint) ! 573: { ! 574: ti113x_state_t *p = &s->state.ti113x; ! 575: s->intr = (pcsc) ? I365_INTR_ENA : 0; ! 576: if (s->type <= IS_TI1131) { ! 577: p->cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | ! 578: TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC); ! 579: if (pcsc) ! 580: p->cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC; ! 581: if (pint) ! 582: p->cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ; ! 583: } else if (s->type == IS_TI1250A) { ! 584: p->diag &= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ; ! 585: if (pcsc) ! 586: p->diag |= TI1250_DIAG_PCI_CSC; ! 587: if (pint) ! 588: p->diag |= TI1250_DIAG_PCI_IREQ; ! 589: } ! 590: return 0; ! 591: } ! 592: ! 593: static u_int __init ti113x_set_opts(socket_info_t *s, char *buf) ! 594: { ! 595: ti113x_state_t *p = &s->state.ti113x; ! 596: u_int mask = 0xffff; ! 597: int old = (s->type <= IS_TI1131); ! 598: ! 599: flip(p->cardctl, TI113X_CCR_RIENB, has_ring); ! 600: p->cardctl &= ~TI113X_CCR_ZVENABLE; ! 601: p->cardctl |= TI113X_CCR_SPKROUTEN; ! 602: if (!old) flip(p->sysctl, TI122X_SCR_P2CCLK, p2cclk); ! 603: switch (irq_mode) { ! 604: case 0: ! 605: p->devctl &= ~TI113X_DCR_IMODE_MASK; ! 606: p->irqmux = (p->irqmux & ~0x0f) | 0x02; /* route INTA */ ! 607: if (!(p->sysctl & TI122X_SCR_INTRTIE)) ! 608: p->irqmux = (p->irqmux & ~0xf0) | 0x20; /* route INTB */ ! 609: break; ! 610: case 1: ! 611: p->devctl &= ~TI113X_DCR_IMODE_MASK; ! 612: p->devctl |= TI113X_DCR_IMODE_ISA; ! 613: break; ! 614: case 2: ! 615: p->devctl &= ~TI113X_DCR_IMODE_MASK; ! 616: p->devctl |= TI113X_DCR_IMODE_SERIAL; ! 617: break; ! 618: case 3: ! 619: p->devctl &= ~TI113X_DCR_IMODE_MASK; ! 620: p->devctl |= TI12XX_DCR_IMODE_ALL_SERIAL; ! 621: break; ! 622: default: ! 623: /* Feeble fallback: if PCI-only but no PCI irq, try ISA */ ! 624: if (((p->devctl & TI113X_DCR_IMODE_MASK) == 0) && ! 625: (s->cap.pci_irq == 0)) ! 626: p->devctl |= TI113X_DCR_IMODE_ISA; ! 627: } ! 628: if (p->cardctl & TI113X_CCR_RIENB) { ! 629: strcat(buf, " [ring]"); ! 630: if (old) mask &= ~0x8000; ! 631: } ! 632: if (old && (p->sysctl & TI113X_SCR_CLKRUN_ENA)) { ! 633: if (p->sysctl & TI113X_SCR_CLKRUN_SEL) { ! 634: strcat(buf, " [clkrun irq 12]"); ! 635: mask &= ~0x1000; ! 636: } else { ! 637: strcat(buf, " [clkrun irq 10]"); ! 638: mask &= ~0x0400; ! 639: } ! 640: } ! 641: switch (p->devctl & TI113X_DCR_IMODE_MASK) { ! 642: case TI12XX_DCR_IMODE_PCI_ONLY: ! 643: strcat(buf, " [pci only]"); ! 644: mask = 0; ! 645: break; ! 646: case TI113X_DCR_IMODE_ISA: ! 647: strcat(buf, " [isa irq]"); ! 648: if (old) mask &= ~0x0018; ! 649: break; ! 650: case TI113X_DCR_IMODE_SERIAL: ! 651: strcat(buf, " [pci + serial irq]"); ! 652: mask = 0xffff; ! 653: break; ! 654: case TI12XX_DCR_IMODE_ALL_SERIAL: ! 655: strcat(buf, " [serial pci & irq]"); ! 656: mask = 0xffff; ! 657: break; ! 658: } ! 659: return mask; ! 660: } ! 661: ! 662: #endif ! 663: ! 664: /*====================================================================== ! 665: ! 666: Code to save and restore global state information for the Ricoh ! 667: RL5C4XX controllers, and to set and report global configuration ! 668: options. ! 669: ! 670: The interrupt test doesn't seem to be reliable with Ricoh ! 671: bridges. It seems to depend on what type of card is in the ! 672: socket, and on the history of that socket, in some way that ! 673: doesn't show up in the current socket state. ! 674: ! 675: ======================================================================*/ ! 676: ! 677: #ifdef CONFIG_PCI ! 678: ! 679: static void __init ricoh_get_state(socket_info_t *s) ! 680: { ! 681: ricoh_state_t *p = &s->state.ricoh; ! 682: pci_readw(s, RL5C4XX_CONFIG, &p->config); ! 683: pci_readw(s, RL5C4XX_MISC, &p->misc); ! 684: pci_readw(s, RL5C4XX_16BIT_CTL, &p->ctl); ! 685: pci_readw(s, RL5C4XX_16BIT_IO_0, &p->io); ! 686: pci_readw(s, RL5C4XX_16BIT_MEM_0, &p->mem); ! 687: } ! 688: ! 689: static void ricoh_set_state(socket_info_t *s) ! 690: { ! 691: ricoh_state_t *p = &s->state.ricoh; ! 692: pci_writew(s, RL5C4XX_CONFIG, p->config); ! 693: pci_writew(s, RL5C4XX_MISC, p->misc); ! 694: pci_writew(s, RL5C4XX_16BIT_CTL, p->ctl); ! 695: pci_writew(s, RL5C4XX_16BIT_IO_0, p->io); ! 696: pci_writew(s, RL5C4XX_16BIT_MEM_0, p->mem); ! 697: } ! 698: ! 699: static u_int __init ricoh_set_opts(socket_info_t *s, char *buf) ! 700: { ! 701: ricoh_state_t *p = &s->state.ricoh; ! 702: u_int mask = 0xffff; ! 703: int old = (s->type < IS_RL5C475); ! 704: ! 705: p->ctl = RL5C4XX_16CTL_IO_TIMING | RL5C4XX_16CTL_MEM_TIMING; ! 706: if (old) ! 707: p->ctl |= RL5C46X_16CTL_LEVEL_1 | RL5C46X_16CTL_LEVEL_2; ! 708: else ! 709: p->config |= RL5C4XX_CONFIG_PREFETCH; ! 710: ! 711: if (setup_time >= 0) { ! 712: p->io = (p->io & ~RL5C4XX_SETUP_MASK) + ! 713: ((setup_time+1) << RL5C4XX_SETUP_SHIFT); ! 714: p->mem = (p->mem & ~RL5C4XX_SETUP_MASK) + ! 715: (setup_time << RL5C4XX_SETUP_SHIFT); ! 716: } ! 717: if (cmd_time >= 0) { ! 718: p->io = (p->io & ~RL5C4XX_CMD_MASK) + ! 719: (cmd_time << RL5C4XX_CMD_SHIFT); ! 720: p->mem = (p->mem & ~RL5C4XX_CMD_MASK) + ! 721: (cmd_time << RL5C4XX_CMD_SHIFT); ! 722: } ! 723: if (hold_time >= 0) { ! 724: p->io = (p->io & ~RL5C4XX_HOLD_MASK) + ! 725: (hold_time << RL5C4XX_HOLD_SHIFT); ! 726: p->mem = (p->mem & ~RL5C4XX_HOLD_MASK) + ! 727: (hold_time << RL5C4XX_HOLD_SHIFT); ! 728: } ! 729: if (irq_mode == 0) { ! 730: mask = 0; ! 731: p->misc &= ~RL5C47X_MISC_SRIRQ_ENA; ! 732: sprintf(buf, " [pci only]"); ! 733: buf += strlen(buf); ! 734: } else if (!old) { ! 735: switch (irq_mode) { ! 736: case 1: ! 737: p->misc &= ~RL5C47X_MISC_SRIRQ_ENA; break; ! 738: case 2: ! 739: p->misc |= RL5C47X_MISC_SRIRQ_ENA; break; ! 740: } ! 741: if (p->misc & RL5C47X_MISC_SRIRQ_ENA) ! 742: sprintf(buf, " [serial irq]"); ! 743: else ! 744: sprintf(buf, " [isa irq]"); ! 745: buf += strlen(buf); ! 746: } ! 747: sprintf(buf, " [io %d/%d/%d] [mem %d/%d/%d]", ! 748: (p->io & RL5C4XX_SETUP_MASK) >> RL5C4XX_SETUP_SHIFT, ! 749: (p->io & RL5C4XX_CMD_MASK) >> RL5C4XX_CMD_SHIFT, ! 750: (p->io & RL5C4XX_HOLD_MASK) >> RL5C4XX_HOLD_SHIFT, ! 751: (p->mem & RL5C4XX_SETUP_MASK) >> RL5C4XX_SETUP_SHIFT, ! 752: (p->mem & RL5C4XX_CMD_MASK) >> RL5C4XX_CMD_SHIFT, ! 753: (p->mem & RL5C4XX_HOLD_MASK) >> RL5C4XX_HOLD_SHIFT); ! 754: return mask; ! 755: } ! 756: ! 757: #endif ! 758: ! 759: /*====================================================================== ! 760: ! 761: Code to save and restore global state information for O2Micro ! 762: controllers, and to set and report global configuration options. ! 763: ! 764: ======================================================================*/ ! 765: ! 766: #ifdef CONFIG_PCI ! 767: ! 768: static void __init o2micro_get_state(socket_info_t *s) ! 769: { ! 770: o2micro_state_t *p = &s->state.o2micro; ! 771: if ((s->revision == 0x34) || (s->revision == 0x62) || ! 772: (s->type == IS_OZ6812)) { ! 773: p->mode_a = i365_get(s, O2_MODE_A_2); ! 774: p->mode_b = i365_get(s, O2_MODE_B_2); ! 775: } else { ! 776: p->mode_a = i365_get(s, O2_MODE_A); ! 777: p->mode_b = i365_get(s, O2_MODE_B); ! 778: } ! 779: p->mode_c = i365_get(s, O2_MODE_C); ! 780: p->mode_d = i365_get(s, O2_MODE_D); ! 781: if (s->flags & IS_CARDBUS) { ! 782: p->mhpg = i365_get(s, O2_MHPG_DMA); ! 783: p->fifo = i365_get(s, O2_FIFO_ENA); ! 784: p->mode_e = i365_get(s, O2_MODE_E); ! 785: } ! 786: } ! 787: ! 788: static void o2micro_set_state(socket_info_t *s) ! 789: { ! 790: o2micro_state_t *p = &s->state.o2micro; ! 791: if ((s->revision == 0x34) || (s->revision == 0x62) || ! 792: (s->type == IS_OZ6812)) { ! 793: i365_set(s, O2_MODE_A_2, p->mode_a); ! 794: i365_set(s, O2_MODE_B_2, p->mode_b); ! 795: } else { ! 796: i365_set(s, O2_MODE_A, p->mode_a); ! 797: i365_set(s, O2_MODE_B, p->mode_b); ! 798: } ! 799: i365_set(s, O2_MODE_C, p->mode_c); ! 800: i365_set(s, O2_MODE_D, p->mode_d); ! 801: if (s->flags & IS_CARDBUS) { ! 802: i365_set(s, O2_MHPG_DMA, p->mhpg); ! 803: i365_set(s, O2_FIFO_ENA, p->fifo); ! 804: i365_set(s, O2_MODE_E, p->mode_e); ! 805: } ! 806: } ! 807: ! 808: static u_int __init o2micro_set_opts(socket_info_t *s, char *buf) ! 809: { ! 810: o2micro_state_t *p = &s->state.o2micro; ! 811: u_int mask = 0xffff; ! 812: ! 813: p->mode_b = (p->mode_b & ~O2_MODE_B_IDENT) | O2_MODE_B_ID_CSTEP; ! 814: flip(p->mode_b, O2_MODE_B_IRQ15_RI, has_ring); ! 815: p->mode_c &= ~(O2_MODE_C_ZVIDEO | O2_MODE_C_DREQ_MASK); ! 816: if (s->flags & IS_CARDBUS) { ! 817: p->mode_d &= ~O2_MODE_D_W97_IRQ; ! 818: p->mode_e &= ~O2_MODE_E_MHPG_DMA; ! 819: p->mhpg = O2_MHPG_CINT_ENA | O2_MHPG_CSC_ENA; ! 820: if (s->revision == 0x34) ! 821: p->mode_c = 0x20; ! 822: } else { ! 823: if (p->mode_b & O2_MODE_B_IRQ15_RI) mask &= ~0x8000; ! 824: } ! 825: if (p->mode_b & O2_MODE_B_IRQ15_RI) ! 826: strcat(buf, " [ring]"); ! 827: if (irq_mode != -1) ! 828: p->mode_d = irq_mode; ! 829: if (p->mode_d & O2_MODE_D_ISA_IRQ) { ! 830: strcat(buf, " [pci+isa]"); ! 831: } else { ! 832: switch (p->mode_d & O2_MODE_D_IRQ_MODE) { ! 833: case O2_MODE_D_IRQ_PCPCI: ! 834: strcat(buf, " [pc/pci]"); break; ! 835: case O2_MODE_D_IRQ_PCIWAY: ! 836: strcat(buf, " [pci/way]"); break; ! 837: case O2_MODE_D_IRQ_PCI: ! 838: strcat(buf, " [pci only]"); mask = 0; break; ! 839: } ! 840: } ! 841: if (s->flags & IS_CARDBUS) { ! 842: if (p->mode_d & O2_MODE_D_W97_IRQ) ! 843: strcat(buf, " [win97]"); ! 844: } ! 845: return mask; ! 846: } ! 847: ! 848: #endif ! 849: ! 850: /*====================================================================== ! 851: ! 852: Code to save and restore global state information for the Toshiba ! 853: ToPIC 95 and 97 controllers, and to set and report global ! 854: configuration options. ! 855: ! 856: ======================================================================*/ ! 857: ! 858: #ifdef CONFIG_PCI ! 859: ! 860: static void __init topic_get_state(socket_info_t *s) ! 861: { ! 862: topic_state_t *p = &s->state.topic; ! 863: pci_readb(s, TOPIC_SLOT_CONTROL, &p->slot); ! 864: pci_readb(s, TOPIC_CARD_CONTROL, &p->ccr); ! 865: pci_readb(s, TOPIC_CARD_DETECT, &p->cdr); ! 866: pci_readl(s, TOPIC_REGISTER_CONTROL, &p->rcr); ! 867: p->fcr = i365_get(s, TOPIC_FUNCTION_CONTROL); ! 868: } ! 869: ! 870: static void topic_set_state(socket_info_t *s) ! 871: { ! 872: topic_state_t *p = &s->state.topic; ! 873: u_int state; ! 874: pci_writeb(s, TOPIC_SLOT_CONTROL, p->slot); ! 875: pci_writeb(s, TOPIC_CARD_CONTROL, p->ccr); ! 876: pci_writeb(s, TOPIC_CARD_DETECT, p->cdr); ! 877: pci_writel(s, TOPIC_REGISTER_CONTROL, p->rcr); ! 878: i365_set(s, TOPIC_FUNCTION_CONTROL, p->fcr); ! 879: state = cb_readl(s, CB_SOCKET_STATE); ! 880: if (!(state & CB_SS_32BIT)) ! 881: cb_writel(s, CB_SOCKET_CONTROL, 0); ! 882: if (!(state & CB_SS_VSENSE)) ! 883: cb_writel(s, CB_SOCKET_FORCE, CB_SF_CVSTEST); ! 884: } ! 885: ! 886: static u_int __init topic_set_opts(socket_info_t *s, char *buf) ! 887: { ! 888: topic_state_t *p = &s->state.topic; ! 889: ! 890: p->slot |= TOPIC_SLOT_SLOTON|TOPIC_SLOT_SLOTEN; ! 891: p->slot &= ~TOPIC_SLOT_ID_LOCK; ! 892: p->cdr |= TOPIC_CDR_MODE_PC32; ! 893: p->cdr &= ~(TOPIC_CDR_SW_DETECT); ! 894: p->ccr |= TOPIC97_ICR_IRQSEL; ! 895: p->fcr |= TOPIC_FCR_3V_ENA; ! 896: sprintf(buf, " [slot 0x%02x] [ccr 0x%02x] [cdr 0x%02x] [rcr 0x%02x]", ! 897: p->slot, p->ccr, p->cdr, p->rcr); ! 898: return 0xffff; ! 899: } ! 900: ! 901: #endif ! 902: ! 903: /*====================================================================== ! 904: ! 905: Routines to handle common CardBus options ! 906: ! 907: ======================================================================*/ ! 908: ! 909: /* Default settings for PCI command configuration register */ ! 910: #define CMD_DFLT (PCI_COMMAND_IO|PCI_COMMAND_MEMORY| \ ! 911: PCI_COMMAND_MASTER|PCI_COMMAND_WAIT) ! 912: ! 913: #ifdef CONFIG_PCI ! 914: ! 915: static void __init cb_get_state(socket_info_t *s) ! 916: { ! 917: pci_readb(s, PCI_CACHE_LINE_SIZE, &s->cache); ! 918: pci_readb(s, PCI_LATENCY_TIMER, &s->pci_lat); ! 919: pci_readb(s, CB_LATENCY_TIMER, &s->cb_lat); ! 920: pci_readb(s, CB_CARDBUS_BUS, &s->cap.cardbus); ! 921: pci_readb(s, CB_SUBORD_BUS, &s->sub_bus); ! 922: pci_readw(s, CB_BRIDGE_CONTROL, &s->bcr); ! 923: get_pci_irq(s); ! 924: } ! 925: ! 926: static void cb_set_state(socket_info_t *s) ! 927: { ! 928: pci_set_power_state(pci_find_slot(s->bus, s->devfn), 0); ! 929: pci_writel(s, CB_LEGACY_MODE_BASE, 0); ! 930: pci_writel(s, PCI_BASE_ADDRESS_0, s->cb_phys); ! 931: pci_writew(s, PCI_COMMAND, CMD_DFLT); ! 932: pci_writeb(s, PCI_CACHE_LINE_SIZE, s->cache); ! 933: pci_writeb(s, PCI_LATENCY_TIMER, s->pci_lat); ! 934: pci_writeb(s, CB_LATENCY_TIMER, s->cb_lat); ! 935: pci_writeb(s, CB_CARDBUS_BUS, s->cap.cardbus); ! 936: pci_writeb(s, CB_SUBORD_BUS, s->sub_bus); ! 937: pci_writew(s, CB_BRIDGE_CONTROL, s->bcr); ! 938: } ! 939: ! 940: static int cb_get_irq_mode(socket_info_t *s) ! 941: { ! 942: return (!(s->bcr & CB_BCR_ISA_IRQ)); ! 943: } ! 944: ! 945: static int cb_set_irq_mode(socket_info_t *s, int pcsc, int pint) ! 946: { ! 947: flip(s->bcr, CB_BCR_ISA_IRQ, !(pint)); ! 948: if (s->flags & IS_CIRRUS) ! 949: return cirrus_set_irq_mode(s, pcsc, pint); ! 950: else if (s->flags & IS_TI) ! 951: return ti113x_set_irq_mode(s, pcsc, pint); ! 952: /* By default, assume that we can't do ISA status irqs */ ! 953: return (!pcsc); ! 954: } ! 955: ! 956: static void __init cb_set_opts(socket_info_t *s, char *buf) ! 957: { ! 958: s->bcr |= CB_BCR_WRITE_POST; ! 959: /* some TI1130's seem to exhibit problems with write posting */ ! 960: if (((s->type == IS_TI1130) && (s->revision == 4) && ! 961: (cb_write_post < 0)) || (cb_write_post == 0)) ! 962: s->bcr &= ~CB_BCR_WRITE_POST; ! 963: if (s->cache == 0) s->cache = 8; ! 964: if (s->pci_lat == 0) s->pci_lat = 0xa8; ! 965: if (s->cb_lat == 0) s->cb_lat = 0xb0; ! 966: if (s->cap.pci_irq == 0) ! 967: strcat(buf, " [no pci irq]"); ! 968: else ! 969: sprintf(buf, " [pci irq %d]", s->cap.pci_irq); ! 970: buf += strlen(buf); ! 971: if (!(s->flags & IS_TOPIC)) ! 972: s->cap.features |= SS_CAP_PAGE_REGS; ! 973: sprintf(buf, " [lat %d/%d] [bus %d/%d]", ! 974: s->pci_lat, s->cb_lat, s->cap.cardbus, s->sub_bus); ! 975: } ! 976: ! 977: #endif ! 978: ! 979: /*====================================================================== ! 980: ! 981: Power control for Cardbus controllers: used both for 16-bit and ! 982: Cardbus cards. ! 983: ! 984: ======================================================================*/ ! 985: ! 986: #ifdef CONFIG_PCI ! 987: ! 988: static void cb_get_power(socket_info_t *s, socket_state_t *state) ! 989: { ! 990: u_int reg = cb_readl(s, CB_SOCKET_CONTROL); ! 991: state->Vcc = state->Vpp = 0; ! 992: switch (reg & CB_SC_VCC_MASK) { ! 993: case CB_SC_VCC_3V: state->Vcc = 33; break; ! 994: case CB_SC_VCC_5V: state->Vcc = 50; break; ! 995: } ! 996: switch (reg & CB_SC_VPP_MASK) { ! 997: case CB_SC_VPP_3V: state->Vpp = 33; break; ! 998: case CB_SC_VPP_5V: state->Vpp = 50; break; ! 999: case CB_SC_VPP_12V: state->Vpp = 120; break; ! 1000: } ! 1001: } ! 1002: ! 1003: static int cb_set_power(socket_info_t *s, socket_state_t *state) ! 1004: { ! 1005: u_int reg = 0; ! 1006: /* restart card voltage detection if it seems appropriate */ ! 1007: if ((state->Vcc == 0) && (state->Vpp == 0) && ! 1008: !(cb_readl(s, CB_SOCKET_STATE) & CB_SS_VSENSE)) ! 1009: cb_writel(s, CB_SOCKET_FORCE, CB_SF_CVSTEST); ! 1010: switch (state->Vcc) { ! 1011: case 0: reg = 0; break; ! 1012: case 33: reg = CB_SC_VCC_3V; break; ! 1013: case 50: reg = CB_SC_VCC_5V; break; ! 1014: default: return -EINVAL; ! 1015: } ! 1016: switch (state->Vpp) { ! 1017: case 0: break; ! 1018: case 33: reg |= CB_SC_VPP_3V; break; ! 1019: case 50: reg |= CB_SC_VPP_5V; break; ! 1020: case 120: reg |= CB_SC_VPP_12V; break; ! 1021: default: return -EINVAL; ! 1022: } ! 1023: if (reg != cb_readl(s, CB_SOCKET_CONTROL)) ! 1024: cb_writel(s, CB_SOCKET_CONTROL, reg); ! 1025: return 0; ! 1026: } ! 1027: ! 1028: #endif ! 1029: ! 1030: /*====================================================================== ! 1031: ! 1032: Generic routines to get and set controller options ! 1033: ! 1034: ======================================================================*/ ! 1035: ! 1036: static void __init get_bridge_state(socket_info_t *s) ! 1037: { ! 1038: if (s->flags & IS_CIRRUS) ! 1039: cirrus_get_state(s); ! 1040: #ifdef CONFIG_ISA ! 1041: else if (s->flags & IS_VADEM) ! 1042: vg46x_get_state(s); ! 1043: #endif ! 1044: #ifdef CONFIG_PCI ! 1045: else if (s->flags & IS_O2MICRO) ! 1046: o2micro_get_state(s); ! 1047: else if (s->flags & IS_TI) ! 1048: ti113x_get_state(s); ! 1049: else if (s->flags & IS_RICOH) ! 1050: ricoh_get_state(s); ! 1051: else if (s->flags & IS_TOPIC) ! 1052: topic_get_state(s); ! 1053: if (s->flags & IS_CARDBUS) ! 1054: cb_get_state(s); ! 1055: #endif ! 1056: } ! 1057: ! 1058: static void set_bridge_state(socket_info_t *s) ! 1059: { ! 1060: #ifdef CONFIG_PCI ! 1061: if (s->flags & IS_CARDBUS) ! 1062: cb_set_state(s); ! 1063: #endif ! 1064: if (s->flags & IS_CIRRUS) { ! 1065: cirrus_set_state(s); ! 1066: } else { ! 1067: i365_set(s, I365_GBLCTL, 0x00); ! 1068: i365_set(s, I365_GENCTL, 0x00); ! 1069: /* Trouble: changes timing of memory operations */ ! 1070: /* i365_bset(s, I365_ADDRWIN, I365_ADDR_MEMCS16); */ ! 1071: } ! 1072: i365_bflip(s, I365_INTCTL, I365_INTR_ENA, s->intr); ! 1073: #ifdef CONFIG_ISA ! 1074: if (s->flags & IS_VADEM) ! 1075: vg46x_set_state(s); ! 1076: #endif ! 1077: #ifdef CONFIG_PCI ! 1078: if (s->flags & IS_O2MICRO) ! 1079: o2micro_set_state(s); ! 1080: else if (s->flags & IS_TI) ! 1081: ti113x_set_state(s); ! 1082: else if (s->flags & IS_RICOH) ! 1083: ricoh_set_state(s); ! 1084: else if (s->flags & IS_TOPIC) ! 1085: topic_set_state(s); ! 1086: #endif ! 1087: } ! 1088: ! 1089: static u_int __init set_bridge_opts(socket_info_t *s, u_short ns) ! 1090: { ! 1091: u_short i; ! 1092: u_int m = 0xffff; ! 1093: char buf[128]; ! 1094: ! 1095: for (i = 0; i < ns; i++) { ! 1096: if (s[i].flags & IS_ALIVE) { ! 1097: printk(KERN_INFO " host opts [%d]: already alive!\n", i); ! 1098: continue; ! 1099: } ! 1100: buf[0] = '\0'; ! 1101: get_bridge_state(s+i); ! 1102: if (s[i].flags & IS_CIRRUS) ! 1103: m = cirrus_set_opts(s+i, buf); ! 1104: #ifdef CONFIG_ISA ! 1105: else if (s[i].flags & IS_VADEM) ! 1106: m = vg46x_set_opts(s+i, buf); ! 1107: #endif ! 1108: #ifdef CONFIG_PCI ! 1109: else if (s[i].flags & IS_O2MICRO) ! 1110: m = o2micro_set_opts(s+i, buf); ! 1111: else if (s[i].flags & IS_TI) ! 1112: m = ti113x_set_opts(s+i, buf); ! 1113: else if (s[i].flags & IS_RICOH) ! 1114: m = ricoh_set_opts(s+i, buf); ! 1115: else if (s[i].flags & IS_TOPIC) ! 1116: m = topic_set_opts(s+i, buf); ! 1117: if (s[i].flags & IS_CARDBUS) ! 1118: cb_set_opts(s+i, buf+strlen(buf)); ! 1119: #endif ! 1120: set_bridge_state(s+i); ! 1121: printk(KERN_INFO " host opts [%d]:%s\n", i, ! 1122: (*buf) ? buf : " none"); ! 1123: } ! 1124: #ifdef CONFIG_PCI ! 1125: m &= ~pci_irq_mask; ! 1126: #endif ! 1127: return m; ! 1128: } ! 1129: ! 1130: /*====================================================================== ! 1131: ! 1132: Interrupt testing code, for ISA and PCI interrupts ! 1133: ! 1134: ======================================================================*/ ! 1135: ! 1136: static volatile u_int irq_hits, irq_shared; ! 1137: static volatile socket_info_t *irq_sock; ! 1138: ! 1139: static void irq_count(int irq, void *dev, struct pt_regs *regs) ! 1140: { ! 1141: irq_hits++; ! 1142: DEBUG(2, "-> hit on irq %d\n", irq); ! 1143: if (!irq_shared && (irq_hits > 100)) { ! 1144: printk(KERN_INFO " PCI irq %d seems to be wedged!\n", irq); ! 1145: disable_irq(irq); ! 1146: return; ! 1147: } ! 1148: #ifdef CONFIG_PCI ! 1149: if (irq_sock->flags & IS_CARDBUS) { ! 1150: cb_writel(irq_sock, CB_SOCKET_EVENT, -1); ! 1151: } else ! 1152: #endif ! 1153: i365_get((socket_info_t *)irq_sock, I365_CSC); ! 1154: return; ! 1155: } ! 1156: ! 1157: static u_int __init test_irq(socket_info_t *s, int irq, int pci) ! 1158: { ! 1159: u_char csc = (pci) ? 0 : irq; ! 1160: ! 1161: #ifdef CONFIG_PNP_BIOS ! 1162: extern int check_pnp_irq(int); ! 1163: if (!pci && check_pnp_irq(irq)) return 1; ! 1164: #endif ! 1165: ! 1166: DEBUG(2, " testing %s irq %d\n", pci ? "PCI" : "ISA", irq); ! 1167: irq_sock = s; irq_shared = irq_hits = 0; ! 1168: if (request_irq(irq, irq_count, 0, "scan", socket)) { ! 1169: irq_shared++; ! 1170: if (!pci || request_irq(irq, irq_count, SA_SHIRQ, "scan", socket)) ! 1171: return 1; ! 1172: } ! 1173: irq_hits = 0; ! 1174: ! 1175: #ifndef MACH ! 1176: __set_current_state(TASK_UNINTERRUPTIBLE); ! 1177: schedule_timeout(HZ/100); ! 1178: #else ! 1179: /* TODO: Is this really what we want? */ ! 1180: { ! 1181: unsigned long flags; ! 1182: ! 1183: save_flags(flags); ! 1184: ! 1185: mdelay(1); ! 1186: #endif ! 1187: ! 1188: if (irq_hits && !irq_shared) { ! 1189: free_irq(irq, socket); ! 1190: DEBUG(2, " spurious hit!\n"); ! 1191: return 1; ! 1192: } ! 1193: ! 1194: /* Generate one interrupt */ ! 1195: #ifdef CONFIG_PCI ! 1196: if (s->flags & IS_CARDBUS) { ! 1197: cb_writel(s, CB_SOCKET_EVENT, -1); ! 1198: i365_set(s, I365_CSCINT, I365_CSC_STSCHG | (csc << 4)); ! 1199: cb_writel(s, CB_SOCKET_EVENT, -1); ! 1200: cb_writel(s, CB_SOCKET_MASK, CB_SM_CSTSCHG); ! 1201: cb_writel(s, CB_SOCKET_FORCE, CB_SE_CSTSCHG); ! 1202: mdelay(1); ! 1203: cb_writel(s, CB_SOCKET_EVENT, -1); ! 1204: cb_writel(s, CB_SOCKET_MASK, 0); ! 1205: } else ! 1206: #endif ! 1207: { ! 1208: i365_set(s, I365_CSCINT, I365_CSC_DETECT | (csc << 4)); ! 1209: i365_bset(s, I365_GENCTL, I365_CTL_SW_IRQ); ! 1210: mdelay(1); ! 1211: } ! 1212: ! 1213: #ifdef MACH ! 1214: restore_flags(flags); ! 1215: } ! 1216: ! 1217: #endif ! 1218: ! 1219: free_irq(irq, socket); ! 1220: ! 1221: /* mask all interrupts */ ! 1222: i365_set(s, I365_CSCINT, 0); ! 1223: DEBUG(2, " hits = %d\n", irq_hits); ! 1224: ! 1225: return pci ? (irq_hits == 0) : (irq_hits != 1); ! 1226: } ! 1227: ! 1228: #ifdef CONFIG_ISA ! 1229: static int _check_irq(int irq, int flags) ! 1230: { ! 1231: #ifdef CONFIG_PNP_BIOS ! 1232: extern int check_pnp_irq(int); ! 1233: if ((flags != SA_SHIRQ) && check_pnp_irq(irq)) ! 1234: return -1; ! 1235: #endif ! 1236: if (request_irq(irq, irq_count, flags, "x", irq_count) != 0) ! 1237: return -1; ! 1238: free_irq(irq, irq_count); ! 1239: return 0; ! 1240: } ! 1241: ! 1242: static u_int __init isa_scan(socket_info_t *s, u_int mask0) ! 1243: { ! 1244: u_int mask1 = 0; ! 1245: int i; ! 1246: ! 1247: #ifdef CONFIG_PCI ! 1248: /* Only scan if we can select ISA csc irq's */ ! 1249: if (!(s->flags & IS_CARDBUS) || (cb_set_irq_mode(s, 0, 0) == 0)) ! 1250: #endif ! 1251: if (do_scan) { ! 1252: set_bridge_state(s); ! 1253: i365_set(s, I365_CSCINT, 0); ! 1254: for (i = 0; i < 16; i++) ! 1255: if ((mask0 & (1 << i)) && (test_irq(s, i, 0) == 0)) ! 1256: mask1 |= (1 << i); ! 1257: for (i = 0; i < 16; i++) ! 1258: if ((mask1 & (1 << i)) && (test_irq(s, i, 0) != 0)) ! 1259: mask1 ^= (1 << i); ! 1260: } ! 1261: ! 1262: printk(KERN_INFO " ISA irqs ("); ! 1263: /* we trust TI bridges to do this right */ ! 1264: if (mask1 || (s->flags & IS_TI)) { ! 1265: printk("scanned"); ! 1266: } else { ! 1267: /* Fallback: just find interrupts that aren't in use */ ! 1268: for (i = 0; i < 16; i++) ! 1269: if ((mask0 & (1 << i)) && (_check_irq(i, 0) == 0)) ! 1270: mask1 |= (1 << i); ! 1271: printk("default"); ! 1272: /* If scan failed, default to polled status */ ! 1273: if (!cs_irq && (poll_interval == 0)) poll_interval = HZ; ! 1274: } ! 1275: printk(") = "); ! 1276: ! 1277: for (i = 0; i < 16; i++) ! 1278: if (mask1 & (1<<i)) ! 1279: printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i); ! 1280: if (mask1 == 0) printk("none!"); ! 1281: ! 1282: return mask1; ! 1283: } ! 1284: #endif /* CONFIG_ISA */ ! 1285: ! 1286: #ifdef CONFIG_PCI ! 1287: static int __init pci_scan(socket_info_t *s) ! 1288: { ! 1289: int ret; ! 1290: if ((s->flags & IS_RICOH) || !(s->flags & IS_CARDBUS) || !do_scan) { ! 1291: /* for PCI-to-PCMCIA bridges, just check for wedged irq */ ! 1292: irq_sock = s; irq_hits = 0; ! 1293: if (request_irq(s->cap.pci_irq, irq_count, 0, "scan", socket)) ! 1294: return 1; ! 1295: udelay(50); ! 1296: free_irq(s->cap.pci_irq, socket); ! 1297: return (!irq_hits); ! 1298: } ! 1299: cb_set_irq_mode(s, 1, 0); ! 1300: set_bridge_state(s); ! 1301: i365_set(s, I365_CSCINT, 0); ! 1302: ret = ((test_irq(s, s->cap.pci_irq, 1) == 0) && ! 1303: (test_irq(s, s->cap.pci_irq, 1) == 0)); ! 1304: if (!ret) ! 1305: printk(KERN_INFO " PCI irq %d test failed\n", ! 1306: s->cap.pci_irq); ! 1307: return ret; ! 1308: } ! 1309: #endif /* CONFIG_PCI */ ! 1310: ! 1311: /*====================================================================*/ ! 1312: ! 1313: #ifdef CONFIG_ISA ! 1314: ! 1315: static int __init isa_identify(u_short port, u_short sock) ! 1316: { ! 1317: socket_info_t *s = socket+sockets; ! 1318: u_char val; ! 1319: int type = -1; ! 1320: ! 1321: /* Use the next free entry in the socket table */ ! 1322: s->ioaddr = port; ! 1323: s->psock = sock; ! 1324: ! 1325: /* Wake up a sleepy Cirrus controller */ ! 1326: if (wakeup) { ! 1327: i365_bclr(s, PD67_MISC_CTL_2, PD67_MC2_SUSPEND); ! 1328: /* Pause at least 50 ms */ ! 1329: mdelay(50); ! 1330: } ! 1331: ! 1332: if ((val = i365_get(s, I365_IDENT)) & 0x70) ! 1333: return -1; ! 1334: switch (val) { ! 1335: case 0x82: ! 1336: type = IS_I82365A; break; ! 1337: case 0x83: ! 1338: type = IS_I82365B; break; ! 1339: case 0x84: ! 1340: type = IS_I82365DF; break; ! 1341: case 0x88: case 0x89: case 0x8a: ! 1342: type = IS_IBM; break; ! 1343: } ! 1344: ! 1345: /* Check for Vadem VG-468 chips */ ! 1346: outb(0x0e, port); ! 1347: outb(0x37, port); ! 1348: i365_bset(s, VG468_MISC, VG468_MISC_VADEMREV); ! 1349: val = i365_get(s, I365_IDENT); ! 1350: if (val & I365_IDENT_VADEM) { ! 1351: i365_bclr(s, VG468_MISC, VG468_MISC_VADEMREV); ! 1352: type = ((val & 7) >= 4) ? IS_VG469 : IS_VG468; ! 1353: } ! 1354: ! 1355: /* Check for Ricoh chips */ ! 1356: val = i365_get(s, RF5C_CHIP_ID); ! 1357: if ((val == RF5C_CHIP_RF5C296) || (val == RF5C_CHIP_RF5C396)) ! 1358: type = IS_RF5Cx96; ! 1359: ! 1360: /* Check for Cirrus CL-PD67xx chips */ ! 1361: i365_set(s, PD67_CHIP_INFO, 0); ! 1362: val = i365_get(s, PD67_CHIP_INFO); ! 1363: if ((val & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID) { ! 1364: val = i365_get(s, PD67_CHIP_INFO); ! 1365: if ((val & PD67_INFO_CHIP_ID) == 0) { ! 1366: type = (val & PD67_INFO_SLOTS) ? IS_PD672X : IS_PD6710; ! 1367: i365_set(s, PD67_EXT_INDEX, 0xe5); ! 1368: if (i365_get(s, PD67_EXT_INDEX) != 0xe5) ! 1369: type = IS_VT83C469; ! 1370: } ! 1371: } ! 1372: return type; ! 1373: } /* isa_identify */ ! 1374: ! 1375: #endif ! 1376: ! 1377: /*====================================================================== ! 1378: ! 1379: See if a card is present, powered up, in IO mode, and already ! 1380: bound to a (non PC Card) Linux driver. We leave these alone. ! 1381: ! 1382: We make an exception for cards that seem to be serial devices. ! 1383: ! 1384: ======================================================================*/ ! 1385: ! 1386: static int __init is_alive(socket_info_t *s) ! 1387: { ! 1388: u_char stat; ! 1389: u_short start, stop; ! 1390: ! 1391: stat = i365_get(s, I365_STATUS); ! 1392: start = i365_get_pair(s, I365_IO(0)+I365_W_START); ! 1393: stop = i365_get_pair(s, I365_IO(0)+I365_W_STOP); ! 1394: if ((stop - start < 0x40) && (stop - start >= 0x07) && ! 1395: ((start & 0xfeef) != 0x02e8) && (start >= 0x100) && ! 1396: (stat & I365_CS_DETECT) && (stat & I365_CS_POWERON) && ! 1397: (i365_get(s, I365_INTCTL) & I365_PC_IOCARD) && ! 1398: (i365_get(s, I365_ADDRWIN) & I365_ENA_IO(0)) && ! 1399: (check_region(start, stop-start+1) != 0)) ! 1400: return 1; ! 1401: else ! 1402: return 0; ! 1403: } ! 1404: ! 1405: /*====================================================================*/ ! 1406: ! 1407: static void __init add_socket(u_int port, int psock, int type) ! 1408: { ! 1409: socket_info_t *s = socket+sockets; ! 1410: s->ioaddr = port; ! 1411: s->psock = psock; ! 1412: s->type = type; ! 1413: s->flags = pcic[type].flags; ! 1414: if (is_alive(s)) ! 1415: s->flags |= IS_ALIVE; ! 1416: sockets++; ! 1417: } ! 1418: ! 1419: static void __init add_pcic(int ns, int type) ! 1420: { ! 1421: u_int mask = 0, i; ! 1422: int use_pci = 0, isa_irq = 0; ! 1423: socket_info_t *s = &socket[sockets-ns]; ! 1424: ! 1425: if (s->ioaddr > 0) request_region(s->ioaddr, 2, "i82365"); ! 1426: ! 1427: printk(KERN_INFO " %s", pcic[type].name); ! 1428: #ifdef CONFIG_PCI ! 1429: if (s->flags & IS_UNKNOWN) ! 1430: printk(" [%04x %04x]", s->vendor, s->device); ! 1431: printk(" rev %02x", s->revision); ! 1432: if (s->flags & IS_CARDBUS) ! 1433: printk(" PCI-to-CardBus at slot %02x:%02x, mem %#08x\n", ! 1434: s->bus, PCI_SLOT(s->devfn), s->cb_phys); ! 1435: else if (s->flags & IS_PCI) ! 1436: printk(" PCI-to-PCMCIA at slot %02x:%02x, port %#x\n", ! 1437: s->bus, PCI_SLOT(s->devfn), s->ioaddr); ! 1438: else ! 1439: #endif ! 1440: printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x\n", ! 1441: s->ioaddr, s->psock*0x40); ! 1442: ! 1443: #ifdef CONFIG_ISA ! 1444: if (irq_list[0] == -1) ! 1445: mask = irq_mask; ! 1446: else ! 1447: for (i = mask = 0; i < 16; i++) ! 1448: mask |= (1<<irq_list[i]); ! 1449: #endif ! 1450: /* Set host options, build basic interrupt mask */ ! 1451: mask &= I365_ISA_IRQ_MASK & set_bridge_opts(s, ns); ! 1452: ! 1453: #ifdef CONFIG_PCI ! 1454: /* Can we use PCI interrupts for card status changes? */ ! 1455: if (pci_csc || pci_int) { ! 1456: for (i = 0; i < ns; i++) ! 1457: if (!s[i].cap.pci_irq || !pci_scan(&s[i])) break; ! 1458: use_pci = (i == ns); ! 1459: } ! 1460: #endif ! 1461: #ifdef CONFIG_ISA ! 1462: /* Scan, report ISA card interrupts */ ! 1463: if (mask) ! 1464: mask = isa_scan(s, mask); ! 1465: #endif ! 1466: ! 1467: #ifdef CONFIG_PCI ! 1468: if (!mask) ! 1469: printk(KERN_INFO " %s card interrupts,", ! 1470: (use_pci && pci_int) ? "PCI" : "*NO*"); ! 1471: if (use_pci && pci_csc) ! 1472: printk(" PCI status changes\n"); ! 1473: #endif ! 1474: ! 1475: #ifdef CONFIG_ISA ! 1476: /* Poll if only two sensible interrupts available */ ! 1477: if (!(use_pci && pci_csc) && !poll_interval) { ! 1478: u_int tmp = (mask & 0xff20); ! 1479: tmp = tmp & (tmp-1); ! 1480: if ((tmp & (tmp-1)) == 0) ! 1481: poll_interval = HZ; ! 1482: } ! 1483: /* Only try an ISA cs_irq if this is the first controller */ ! 1484: if (!(use_pci && pci_csc) && !grab_irq && ! 1485: (cs_irq || !poll_interval)) { ! 1486: /* Avoid irq 12 unless it is explicitly requested */ ! 1487: u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12)); ! 1488: for (isa_irq = 15; isa_irq > 0; isa_irq--) ! 1489: if (cs_mask & (1 << isa_irq)) break; ! 1490: if (isa_irq) { ! 1491: grab_irq = 1; ! 1492: cs_irq = isa_irq; ! 1493: printk(" status change on irq %d\n", isa_irq); ! 1494: } ! 1495: } ! 1496: #endif ! 1497: ! 1498: if (!(use_pci && pci_csc) && !isa_irq) { ! 1499: if (poll_interval == 0) ! 1500: poll_interval = HZ; ! 1501: printk(" polling interval = %d ms\n", poll_interval*1000/HZ); ! 1502: } ! 1503: ! 1504: /* Update socket interrupt information, capabilities */ ! 1505: for (i = 0; i < ns; i++) { ! 1506: s[i].cap.features |= SS_CAP_PCCARD; ! 1507: s[i].cap.map_size = 0x1000; ! 1508: s[i].cap.irq_mask = mask; ! 1509: if (!use_pci) ! 1510: s[i].cap.pci_irq = 0; ! 1511: s[i].cs_irq = isa_irq; ! 1512: #ifdef CONFIG_PCI ! 1513: if (s[i].flags & IS_CARDBUS) { ! 1514: s[i].cap.features |= SS_CAP_CARDBUS; ! 1515: cb_set_irq_mode(s+i, pci_csc && s[i].cap.pci_irq, 0); ! 1516: } ! 1517: #endif ! 1518: } ! 1519: ! 1520: } /* add_pcic */ ! 1521: ! 1522: /*====================================================================*/ ! 1523: ! 1524: #ifdef CONFIG_PCI ! 1525: ! 1526: static int __init pci_lookup(u_int class, struct pci_dev **id, ! 1527: u_char *bus, u_char *devfn) ! 1528: { ! 1529: if ((*id = pci_find_class(class<<8, *id)) != NULL) { ! 1530: *bus = (*id)->bus->number; ! 1531: *devfn = (*id)->devfn; ! 1532: return 0; ! 1533: } else return -1; ! 1534: } ! 1535: ! 1536: static void __init add_pci_bridge(int type, u_short v, u_short d) ! 1537: { ! 1538: socket_info_t *s = &socket[sockets]; ! 1539: u_int addr, ns; ! 1540: ! 1541: pci_enable_device(pci_find_slot(s->bus, s->devfn)); ! 1542: pci_writew(s, PCI_COMMAND, CMD_DFLT); ! 1543: ! 1544: if (type == PCIC_COUNT) type = IS_UNK_PCI; ! 1545: pci_readl(s, PCI_BASE_ADDRESS_0, &addr); ! 1546: addr &= ~0x1; ! 1547: for (ns = 0; ns < ((type == IS_I82092AA) ? 4 : 2); ns++) { ! 1548: s[ns].bus = s->bus; s[ns].devfn = s->devfn; ! 1549: s[ns].vendor = v; s[ns].device = d; ! 1550: add_socket(addr, ns, type); ! 1551: } ! 1552: add_pcic(ns, type); ! 1553: } ! 1554: ! 1555: static int check_cb_mapping(socket_info_t *s) ! 1556: { ! 1557: u_int state = cb_readl(s, CB_SOCKET_STATE) >> 16; ! 1558: /* A few sanity checks to validate the bridge mapping */ ! 1559: if ((cb_readb(s, 0x800+I365_IDENT) & 0x70) || ! 1560: (cb_readb(s, 0x800+I365_CSC) && cb_readb(s, 0x800+I365_CSC) && ! 1561: cb_readb(s, 0x800+I365_CSC)) || cb_readl(s, CB_SOCKET_FORCE) || ! 1562: ((state & ~0x3000) || !(state & 0x3000))) ! 1563: return 1; ! 1564: return 0; ! 1565: } ! 1566: ! 1567: static void __init add_cb_bridge(int type, u_short v, u_short d0) ! 1568: { ! 1569: socket_info_t *s = &socket[sockets]; ! 1570: u_char bus = s->bus, devfn = s->devfn; ! 1571: u_short d, ns; ! 1572: u_char a, r, max; ! 1573: ! 1574: /* PCI bus enumeration is broken on some systems */ ! 1575: for (ns = 0; ns < sockets; ns++) ! 1576: if ((socket[ns].bus == bus) && ! 1577: (socket[ns].devfn == devfn)) ! 1578: return; ! 1579: ! 1580: if (type == PCIC_COUNT) type = IS_UNK_CARDBUS; ! 1581: pci_readb(s, PCI_HEADER_TYPE, &a); ! 1582: pci_readb(s, PCI_CLASS_REVISION, &r); ! 1583: max = (a & 0x80) ? 8 : 1; ! 1584: for (ns = 0; ns < max; ns++, s++, devfn++) { ! 1585: s->bus = bus; s->devfn = devfn; ! 1586: if (pci_readw(s, PCI_DEVICE_ID, &d) || (d != d0)) ! 1587: break; ! 1588: s->vendor = v; s->device = d; s->revision = r; ! 1589: ! 1590: pci_enable_device(pci_find_slot(bus, devfn)); ! 1591: pci_set_power_state(pci_find_slot(bus, devfn), 0); ! 1592: pci_writew(s, PCI_COMMAND, CMD_DFLT); ! 1593: ! 1594: /* Set up CardBus register mapping */ ! 1595: pci_writel(s, CB_LEGACY_MODE_BASE, 0); ! 1596: pci_readl(s, PCI_BASE_ADDRESS_0, &s->cb_phys); ! 1597: if (s->cb_phys == 0) { ! 1598: printk("\n" KERN_NOTICE " Bridge register mapping failed:" ! 1599: " check cb_mem_base setting\n"); ! 1600: break; ! 1601: } ! 1602: s->cb_virt = ioremap(s->cb_phys, 0x1000); ! 1603: if (check_cb_mapping(s) != 0) { ! 1604: printk("\n" KERN_NOTICE " Bad bridge mapping at " ! 1605: "0x%08x!\n", s->cb_phys); ! 1606: break; ! 1607: } ! 1608: ! 1609: request_mem_region(s->cb_phys, 0x1000, "i82365"); ! 1610: add_socket(0, 0, type); ! 1611: } ! 1612: if (ns == 0) return; ! 1613: ! 1614: add_pcic(ns, type); ! 1615: ! 1616: /* Look up PCI bus bridge structures if needed */ ! 1617: s -= ns; ! 1618: for (a = 0; a < ns; a++) { ! 1619: struct pci_dev *self = pci_find_slot(bus, s[a].devfn); ! 1620: #if (LINUX_VERSION_CODE >= VERSION(2,3,40)) ! 1621: s[a].cap.cb_bus = self->subordinate; ! 1622: #else ! 1623: struct pci_bus *child; ! 1624: for (child = self->bus->children; child; child = child->next) ! 1625: if (child->number == s[a].cap.cardbus) break; ! 1626: s[a].cap.cb_bus = child; ! 1627: #endif ! 1628: } ! 1629: } ! 1630: ! 1631: static void __init pci_probe(u_int class) ! 1632: { ! 1633: socket_info_t *s = &socket[sockets]; ! 1634: u_short i, v, d; ! 1635: struct pci_dev *id; ! 1636: ! 1637: id = 0; ! 1638: while (pci_lookup(class, &id, &s->bus, &s->devfn) == 0) { ! 1639: if (PCI_FUNC(s->devfn) != 0) continue; ! 1640: pci_readw(s, PCI_VENDOR_ID, &v); ! 1641: pci_readw(s, PCI_DEVICE_ID, &d); ! 1642: for (i = 0; i < PCIC_COUNT; i++) ! 1643: if ((pcic[i].vendor == v) && (pcic[i].device == d)) break; ! 1644: /* The "ToPIC95-A" is unusable as a CardBus bridge */ ! 1645: if (i == IS_TOPIC95_A) ! 1646: continue; ! 1647: if (((i < PCIC_COUNT) && (pcic[i].flags & IS_CARDBUS)) || ! 1648: (class == PCI_CLASS_BRIDGE_CARDBUS)) ! 1649: add_cb_bridge(i, v, d); ! 1650: else ! 1651: add_pci_bridge(i, v, d); ! 1652: s = &socket[sockets]; ! 1653: } ! 1654: } ! 1655: ! 1656: #endif ! 1657: ! 1658: /*====================================================================*/ ! 1659: ! 1660: #ifdef CONFIG_ISA ! 1661: ! 1662: static void __init isa_probe(ioaddr_t base) ! 1663: { ! 1664: int i, j, sock, k, ns, id; ! 1665: ioaddr_t port; ! 1666: ! 1667: if (check_region(base, 2) != 0) { ! 1668: if (sockets == 0) ! 1669: printk("port conflict at %#x\n", base); ! 1670: return; ! 1671: } ! 1672: ! 1673: id = isa_identify(base, 0); ! 1674: if ((id == IS_I82365DF) && (isa_identify(base, 1) != id)) { ! 1675: for (i = 0; i < 4; i++) { ! 1676: if (i == ignore) continue; ! 1677: port = base + ((i & 1) << 2) + ((i & 2) << 1); ! 1678: sock = (i & 1) << 1; ! 1679: if (isa_identify(port, sock) == IS_I82365DF) { ! 1680: add_socket(port, sock, IS_VLSI); ! 1681: add_pcic(1, IS_VLSI); ! 1682: } ! 1683: } ! 1684: } else { ! 1685: for (i = 0; i < 4; i += 2) { ! 1686: port = base + 2*(i>>2); ! 1687: sock = (i & 3); ! 1688: id = isa_identify(port, sock); ! 1689: if (id < 0) continue; ! 1690: ! 1691: for (j = ns = 0; j < 2; j++) { ! 1692: /* Does the socket exist? */ ! 1693: if ((ignore == i+j) || (isa_identify(port, sock+j) < 0)) ! 1694: continue; ! 1695: /* Check for bad socket decode */ ! 1696: for (k = 0; k <= sockets; k++) ! 1697: i365_set(socket+k, I365_MEM(0)+I365_W_OFF, k); ! 1698: for (k = 0; k <= sockets; k++) ! 1699: if (i365_get(socket+k, I365_MEM(0)+I365_W_OFF) != k) ! 1700: break; ! 1701: if (k <= sockets) break; ! 1702: add_socket(port, sock+j, id); ns++; ! 1703: } ! 1704: if (ns != 0) add_pcic(ns, id); ! 1705: } ! 1706: } ! 1707: } ! 1708: ! 1709: #endif ! 1710: ! 1711: /*====================================================================== ! 1712: ! 1713: The card status event handler. This may either be interrupt ! 1714: driven or polled. It monitors mainly for card insert and eject ! 1715: events; there are various other kinds of events that can be ! 1716: monitored (ready/busy, status change, etc), but they are almost ! 1717: never used. ! 1718: ! 1719: ======================================================================*/ ! 1720: ! 1721: static void pcic_interrupt(int irq, void *dev, struct pt_regs *regs) ! 1722: { ! 1723: int i, j, csc; ! 1724: u_int events, active; ! 1725: #ifdef CONFIG_ISA ! 1726: u_long flags = 0; ! 1727: #endif ! 1728: ! 1729: DEBUG(2, "i82365: pcic_interrupt(%d)\n", irq); ! 1730: ! 1731: for (j = 0; j < 20; j++) { ! 1732: active = 0; ! 1733: for (i = 0; i < sockets; i++) { ! 1734: socket_info_t *s = &socket[i]; ! 1735: if ((s->cs_irq != irq) && (s->cap.pci_irq != irq)) ! 1736: continue; ! 1737: ISA_LOCK(s, flags); ! 1738: csc = i365_get(s, I365_CSC); ! 1739: #ifdef CONFIG_PCI ! 1740: if ((s->flags & IS_CARDBUS) && ! 1741: (cb_readl(s, CB_SOCKET_EVENT) & CB_SE_CCD)) { ! 1742: cb_writel(s, CB_SOCKET_EVENT, CB_SE_CCD); ! 1743: csc |= I365_CSC_DETECT; ! 1744: } ! 1745: #endif ! 1746: if ((csc == 0) || (!s->handler) || ! 1747: (i365_get(s, I365_IDENT) & 0x70)) { ! 1748: ISA_UNLOCK(s, flags); ! 1749: continue; ! 1750: } ! 1751: events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0; ! 1752: if (i365_get(s, I365_INTCTL) & I365_PC_IOCARD) { ! 1753: events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0; ! 1754: } else { ! 1755: events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0; ! 1756: events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0; ! 1757: events |= (csc & I365_CSC_READY) ? SS_READY : 0; ! 1758: } ! 1759: ISA_UNLOCK(s, flags); ! 1760: DEBUG(1, "i82365: socket %d event 0x%04x\n", i, events); ! 1761: if (events) ! 1762: s->handler(s->info, events); ! 1763: active |= events; ! 1764: } ! 1765: if (!active) break; ! 1766: } ! 1767: if (j == 20) ! 1768: printk(KERN_NOTICE "i82365: infinite loop in interrupt " ! 1769: "handler: active = 0x%04x\n", active); ! 1770: ! 1771: DEBUG(2, "i82365: interrupt done\n"); ! 1772: } /* pcic_interrupt */ ! 1773: ! 1774: static void pcic_interrupt_wrapper(u_long data) ! 1775: { ! 1776: pcic_interrupt(0, NULL, NULL); ! 1777: poll_timer.expires = jiffies + poll_interval; ! 1778: add_timer(&poll_timer); ! 1779: } ! 1780: ! 1781: /*====================================================================*/ ! 1782: ! 1783: static int pcic_register_callback(socket_info_t *s, ss_callback_t *call) ! 1784: { ! 1785: if (call == NULL) { ! 1786: s->handler = NULL; ! 1787: MOD_DEC_USE_COUNT; ! 1788: } else { ! 1789: MOD_INC_USE_COUNT; ! 1790: s->handler = call->handler; ! 1791: s->info = call->info; ! 1792: } ! 1793: return 0; ! 1794: } /* pcic_register_callback */ ! 1795: ! 1796: /*====================================================================*/ ! 1797: ! 1798: static int pcic_inquire_socket(socket_info_t *s, socket_cap_t *cap) ! 1799: { ! 1800: *cap = s->cap; ! 1801: return 0; ! 1802: } ! 1803: ! 1804: /*====================================================================*/ ! 1805: ! 1806: static int i365_get_status(socket_info_t *s, u_int *value) ! 1807: { ! 1808: u_int status; ! 1809: ! 1810: status = i365_get(s, I365_STATUS); ! 1811: *value = ((status & I365_CS_DETECT) == I365_CS_DETECT) ! 1812: ? SS_DETECT : 0; ! 1813: if (i365_get(s, I365_INTCTL) & I365_PC_IOCARD) { ! 1814: *value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG; ! 1815: } else { ! 1816: *value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD; ! 1817: *value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN; ! 1818: } ! 1819: *value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0; ! 1820: *value |= (status & I365_CS_READY) ? SS_READY : 0; ! 1821: *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0; ! 1822: ! 1823: #ifdef CONFIG_PCI ! 1824: if (s->flags & IS_CARDBUS) { ! 1825: status = cb_readl(s, CB_SOCKET_STATE); ! 1826: *value |= (status & CB_SS_32BIT) ? SS_CARDBUS : 0; ! 1827: *value |= (status & CB_SS_3VCARD) ? SS_3VCARD : 0; ! 1828: *value |= (status & CB_SS_XVCARD) ? SS_XVCARD : 0; ! 1829: *value |= (status & CB_SS_VSENSE) ? 0 : SS_PENDING; ! 1830: } else if (s->flags & IS_O2MICRO) { ! 1831: status = i365_get(s, O2_MODE_B); ! 1832: *value |= (status & O2_MODE_B_VS1) ? 0 : SS_3VCARD; ! 1833: *value |= (status & O2_MODE_B_VS2) ? 0 : SS_XVCARD; ! 1834: } ! 1835: #endif ! 1836: if ((s->flags & IS_CIRRUS) && ! 1837: ((s->flags & IS_PCI) || has_vsense)) { ! 1838: socket_info_t *t = (s->psock) ? s : s+1; ! 1839: status = pd67_ext_get(t, PD67_EXTERN_DATA); ! 1840: *value |= (status & PD67_EXD_VS1(s->psock)) ? 0 : SS_3VCARD; ! 1841: *value |= (status & PD67_EXD_VS2(s->psock)) ? 0 : SS_XVCARD; ! 1842: } ! 1843: #ifdef CONFIG_ISA ! 1844: if (s->type == IS_VG469) { ! 1845: status = i365_get(s, VG469_VSENSE); ! 1846: if (s->psock & 1) { ! 1847: *value |= (status & VG469_VSENSE_B_VS1) ? 0 : SS_3VCARD; ! 1848: *value |= (status & VG469_VSENSE_B_VS2) ? 0 : SS_XVCARD; ! 1849: } else { ! 1850: *value |= (status & VG469_VSENSE_A_VS1) ? 0 : SS_3VCARD; ! 1851: *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD; ! 1852: } ! 1853: } ! 1854: #endif ! 1855: /* For now, ignore cards with unsupported voltage keys */ ! 1856: if (*value & SS_XVCARD) ! 1857: *value &= ~(SS_DETECT|SS_3VCARD|SS_XVCARD); ! 1858: DEBUG(1, "i82365: GetStatus(%d) = %#4.4x\n", s-socket, *value); ! 1859: return 0; ! 1860: } /* i365_get_status */ ! 1861: ! 1862: /*====================================================================*/ ! 1863: ! 1864: static int i365_get_socket(socket_info_t *s, socket_state_t *state) ! 1865: { ! 1866: u_char reg, vcc, vpp; ! 1867: ! 1868: reg = i365_get(s, I365_POWER); ! 1869: state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0; ! 1870: state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0; ! 1871: vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK; ! 1872: state->Vcc = state->Vpp = 0; ! 1873: #ifdef CONFIG_PCI ! 1874: if ((s->flags & IS_CARDBUS) && !(s->flags & IS_TOPIC)) { ! 1875: cb_get_power(s, state); ! 1876: } else ! 1877: #endif ! 1878: { ! 1879: if ((s->flags & IS_CIRRUS) && (reg & I365_VCC_5V)) { ! 1880: state->Vcc = (i365_get(s, PD67_MISC_CTL_1) & ! 1881: PD67_MC1_VCC_3V) ? 33 : 50; ! 1882: } else if ((s->flags & IS_VG_PWR) && (reg & I365_VCC_5V)) { ! 1883: state->Vcc = (i365_get(s, VG469_VSELECT) & ! 1884: VG469_VSEL_VCC) ? 33 : 50; ! 1885: } else if ((s->flags & IS_DF_PWR) || (s->flags & IS_TOPIC)) { ! 1886: if (vcc == I365_VCC_3V) state->Vcc = 33; ! 1887: if (vcc == I365_VCC_5V) state->Vcc = 50; ! 1888: } else { ! 1889: if (reg & I365_VCC_5V) state->Vcc = 50; ! 1890: } ! 1891: if (vpp == I365_VPP1_5V) ! 1892: state->Vpp = (s->flags & IS_DF_PWR) ? 50 : state->Vcc; ! 1893: if (vpp == I365_VPP1_12V) state->Vpp = 120; ! 1894: } ! 1895: ! 1896: /* IO card, RESET flags, IO interrupt */ ! 1897: reg = i365_get(s, I365_INTCTL); ! 1898: state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET; ! 1899: state->flags |= (reg & I365_PC_IOCARD) ? SS_IOCARD : 0; ! 1900: #ifdef CONFIG_PCI ! 1901: if (cb_get_irq_mode(s) != 0) ! 1902: state->io_irq = s->cap.pci_irq; ! 1903: else ! 1904: #endif ! 1905: state->io_irq = reg & I365_IRQ_MASK; ! 1906: ! 1907: /* Card status change mask */ ! 1908: reg = i365_get(s, I365_CSCINT); ! 1909: state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0; ! 1910: if (state->flags & SS_IOCARD) { ! 1911: state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0; ! 1912: } else { ! 1913: state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0; ! 1914: state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0; ! 1915: state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0; ! 1916: } ! 1917: ! 1918: DEBUG(2, "i82365: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " ! 1919: "io_irq %d, csc_mask %#2.2x\n", s-socket, state->flags, ! 1920: state->Vcc, state->Vpp, state->io_irq, state->csc_mask); ! 1921: return 0; ! 1922: } /* i365_get_socket */ ! 1923: ! 1924: /*====================================================================*/ ! 1925: ! 1926: static int i365_set_socket(socket_info_t *s, socket_state_t *state) ! 1927: { ! 1928: u_char reg; ! 1929: ! 1930: DEBUG(2, "i82365: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " ! 1931: "io_irq %d, csc_mask %#2.2x)\n", s-socket, state->flags, ! 1932: state->Vcc, state->Vpp, state->io_irq, state->csc_mask); ! 1933: ! 1934: /* First set global controller options */ ! 1935: #ifdef CONFIG_PCI ! 1936: if (s->cap.pci_irq) ! 1937: cb_set_irq_mode(s, pci_csc, (s->cap.pci_irq == state->io_irq)); ! 1938: s->bcr &= ~CB_BCR_CB_RESET; ! 1939: #endif ! 1940: set_bridge_state(s); ! 1941: ! 1942: /* IO card, RESET flag, IO interrupt */ ! 1943: reg = s->intr | ((state->io_irq == s->cap.pci_irq) ? ! 1944: s->pci_irq_code : state->io_irq); ! 1945: reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET; ! 1946: reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0; ! 1947: i365_set(s, I365_INTCTL, reg); ! 1948: ! 1949: reg = I365_PWR_NORESET; ! 1950: if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO; ! 1951: if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT; ! 1952: ! 1953: #ifdef CONFIG_PCI ! 1954: if ((s->flags & IS_CARDBUS) && !(s->flags & IS_TOPIC)) { ! 1955: cb_set_power(s, state); ! 1956: reg |= i365_get(s, I365_POWER) & (I365_VCC_MASK|I365_VPP1_MASK); ! 1957: } else ! 1958: #endif ! 1959: { ! 1960: int new = s->flags & (IS_TOPIC|IS_CIRRUS|IS_VG_PWR|IS_DF_PWR); ! 1961: int vcc3 = (state->Vcc == 33), df = (s->flags & IS_DF_PWR); ! 1962: ! 1963: if (state->Vcc == 50) { ! 1964: reg |= I365_VCC_5V; ! 1965: } else if (new && vcc3) { ! 1966: reg |= ((s->flags & (IS_TOPIC|IS_DF_PWR)) ? ! 1967: I365_VCC_3V : I365_VCC_5V); ! 1968: } else if (state->Vcc) ! 1969: return -EINVAL; ! 1970: if (s->flags & IS_CIRRUS) ! 1971: i365_bflip(s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V, vcc3); ! 1972: if (s->flags & IS_VG_PWR) ! 1973: i365_bflip(s, VG469_VSELECT, VG469_VSEL_VCC, vcc3); ! 1974: ! 1975: if (state->Vpp == 120) { ! 1976: reg |= I365_VPP1_12V | (new ? 0 : I365_VPP2_12V); ! 1977: } else if (state->Vpp == (df ? 50 : state->Vcc)) { ! 1978: reg |= I365_VPP1_5V | (new ? 0 : I365_VPP2_5V); ! 1979: } else if (state->Vpp) ! 1980: return -EINVAL; ! 1981: } ! 1982: ! 1983: if (reg != i365_get(s, I365_POWER)) ! 1984: i365_set(s, I365_POWER, reg); ! 1985: ! 1986: /* Card status change interrupt mask */ ! 1987: reg = (s->cap.pci_irq ? s->pci_irq_code : s->cs_irq) << 4; ! 1988: if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT; ! 1989: if (state->flags & SS_IOCARD) { ! 1990: if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG; ! 1991: } else { ! 1992: if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1; ! 1993: if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2; ! 1994: if (state->csc_mask & SS_READY) reg |= I365_CSC_READY; ! 1995: } ! 1996: i365_set(s, I365_CSCINT, reg); ! 1997: i365_get(s, I365_CSC); ! 1998: #ifdef CONFIG_PCI ! 1999: if (s->flags & IS_CARDBUS) { ! 2000: if (s->cs_irq || (pci_csc && s->cap.pci_irq)) ! 2001: cb_writel(s, CB_SOCKET_MASK, CB_SM_CCD); ! 2002: cb_writel(s, CB_SOCKET_EVENT, -1); ! 2003: } ! 2004: #endif ! 2005: ! 2006: return 0; ! 2007: } /* i365_set_socket */ ! 2008: ! 2009: /*====================================================================*/ ! 2010: ! 2011: static int i365_get_io_map(socket_info_t *s, struct pccard_io_map *io) ! 2012: { ! 2013: u_char map, ioctl, addr; ! 2014: ! 2015: map = io->map; ! 2016: if (map > 1) return -EINVAL; ! 2017: io->start = i365_get_pair(s, I365_IO(map)+I365_W_START); ! 2018: io->stop = i365_get_pair(s, I365_IO(map)+I365_W_STOP); ! 2019: ioctl = i365_get(s, I365_IOCTL); ! 2020: addr = i365_get(s, I365_ADDRWIN); ! 2021: io->speed = (ioctl & I365_IOCTL_WAIT(map)) ? cycle_time : 0; ! 2022: io->flags = (addr & I365_ENA_IO(map)) ? MAP_ACTIVE : 0; ! 2023: io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0; ! 2024: io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0; ! 2025: io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0; ! 2026: DEBUG(3, "i82365: GetIOMap(%d, %d) = %#2.2x, %d ns, %#4.4x-%#4.4x\n", ! 2027: s-socket, map, io->flags, io->speed, io->start, io->stop); ! 2028: return 0; ! 2029: } /* i365_get_io_map */ ! 2030: ! 2031: /*====================================================================*/ ! 2032: ! 2033: static int i365_set_io_map(socket_info_t *s, struct pccard_io_map *io) ! 2034: { ! 2035: u_char map, ioctl; ! 2036: ! 2037: DEBUG(3, "i82365: SetIOMap(%d, %d, %#2.2x, %d ns, %#4.4x-%#4.4x)\n", ! 2038: s-socket, io->map, io->flags, io->speed, io->start, io->stop); ! 2039: map = io->map; ! 2040: if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) || ! 2041: (io->stop < io->start)) return -EINVAL; ! 2042: /* Turn off the window before changing anything */ ! 2043: if (i365_get(s, I365_ADDRWIN) & I365_ENA_IO(map)) ! 2044: i365_bclr(s, I365_ADDRWIN, I365_ENA_IO(map)); ! 2045: i365_set_pair(s, I365_IO(map)+I365_W_START, io->start); ! 2046: i365_set_pair(s, I365_IO(map)+I365_W_STOP, io->stop); ! 2047: ioctl = i365_get(s, I365_IOCTL) & ~I365_IOCTL_MASK(map); ! 2048: if (io->speed) ioctl |= I365_IOCTL_WAIT(map); ! 2049: if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map); ! 2050: if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map); ! 2051: if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map); ! 2052: i365_set(s, I365_IOCTL, ioctl); ! 2053: /* Turn on the window if necessary */ ! 2054: if (io->flags & MAP_ACTIVE) ! 2055: i365_bset(s, I365_ADDRWIN, I365_ENA_IO(map)); ! 2056: return 0; ! 2057: } /* i365_set_io_map */ ! 2058: ! 2059: /*====================================================================*/ ! 2060: ! 2061: static int i365_get_mem_map(socket_info_t *s, struct pccard_mem_map *mem) ! 2062: { ! 2063: u_short base, i; ! 2064: u_char map, addr; ! 2065: ! 2066: map = mem->map; ! 2067: if (map > 4) return -EINVAL; ! 2068: addr = i365_get(s, I365_ADDRWIN); ! 2069: mem->flags = (addr & I365_ENA_MEM(map)) ? MAP_ACTIVE : 0; ! 2070: base = I365_MEM(map); ! 2071: ! 2072: i = i365_get_pair(s, base+I365_W_START); ! 2073: mem->flags |= (i & I365_MEM_16BIT) ? MAP_16BIT : 0; ! 2074: mem->flags |= (i & I365_MEM_0WS) ? MAP_0WS : 0; ! 2075: mem->sys_start = ((u_long)(i & 0x0fff) << 12); ! 2076: ! 2077: i = i365_get_pair(s, base+I365_W_STOP); ! 2078: mem->speed = (i & I365_MEM_WS0) ? 1 : 0; ! 2079: mem->speed += (i & I365_MEM_WS1) ? 2 : 0; ! 2080: mem->speed *= cycle_time; ! 2081: mem->sys_stop = ((u_long)(i & 0x0fff) << 12) + 0x0fff; ! 2082: ! 2083: i = i365_get_pair(s, base+I365_W_OFF); ! 2084: mem->flags |= (i & I365_MEM_WRPROT) ? MAP_WRPROT : 0; ! 2085: mem->flags |= (i & I365_MEM_REG) ? MAP_ATTRIB : 0; ! 2086: mem->card_start = ((u_int)(i & 0x3fff) << 12) + mem->sys_start; ! 2087: mem->card_start &= 0x3ffffff; ! 2088: ! 2089: #ifdef CONFIG_PCI ! 2090: /* Take care of high byte, for PCI controllers */ ! 2091: if (s->type == IS_PD6729) { ! 2092: addr = pd67_ext_get(s, PD67_MEM_PAGE(map)) << 24; ! 2093: mem->sys_stop += addr; mem->sys_start += addr; ! 2094: } else if (s->flags & IS_CARDBUS) { ! 2095: addr = i365_get(s, CB_MEM_PAGE(map)) << 24; ! 2096: mem->sys_stop += addr; mem->sys_start += addr; ! 2097: } ! 2098: #endif ! 2099: ! 2100: DEBUG(3, "i82365: GetMemMap(%d, %d) = %#2.2x, %d ns, %#5.5lx-%#5." ! 2101: "5lx, %#5.5x\n", s-socket, mem->map, mem->flags, mem->speed, ! 2102: mem->sys_start, mem->sys_stop, mem->card_start); ! 2103: return 0; ! 2104: } /* i365_get_mem_map */ ! 2105: ! 2106: /*====================================================================*/ ! 2107: ! 2108: static int i365_set_mem_map(socket_info_t *s, struct pccard_mem_map *mem) ! 2109: { ! 2110: u_short base, i; ! 2111: u_char map; ! 2112: ! 2113: DEBUG(3, "i82365: SetMemMap(%d, %d, %#2.2x, %d ns, %#5.5lx-%#5.5" ! 2114: "lx, %#5.5x)\n", s-socket, mem->map, mem->flags, mem->speed, ! 2115: mem->sys_start, mem->sys_stop, mem->card_start); ! 2116: ! 2117: map = mem->map; ! 2118: if ((map > 4) || (mem->card_start > 0x3ffffff) || ! 2119: (mem->sys_start > mem->sys_stop) || (mem->speed > 1000)) ! 2120: return -EINVAL; ! 2121: if (!(s->flags & (IS_PCI|IS_CARDBUS)) && ! 2122: ((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff))) ! 2123: return -EINVAL; ! 2124: ! 2125: /* Turn off the window before changing anything */ ! 2126: if (i365_get(s, I365_ADDRWIN) & I365_ENA_MEM(map)) ! 2127: i365_bclr(s, I365_ADDRWIN, I365_ENA_MEM(map)); ! 2128: ! 2129: #ifdef CONFIG_PCI ! 2130: /* Take care of high byte, for PCI controllers */ ! 2131: if (s->type == IS_PD6729) { ! 2132: pd67_ext_set(s, PD67_MEM_PAGE(map), (mem->sys_start >> 24)); ! 2133: } else if (s->flags & IS_CARDBUS) ! 2134: i365_set(s, CB_MEM_PAGE(map), mem->sys_start >> 24); ! 2135: #endif ! 2136: ! 2137: base = I365_MEM(map); ! 2138: i = (mem->sys_start >> 12) & 0x0fff; ! 2139: if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT; ! 2140: if (mem->flags & MAP_0WS) i |= I365_MEM_0WS; ! 2141: i365_set_pair(s, base+I365_W_START, i); ! 2142: ! 2143: i = (mem->sys_stop >> 12) & 0x0fff; ! 2144: switch (mem->speed / cycle_time) { ! 2145: case 0: break; ! 2146: case 1: i |= I365_MEM_WS0; break; ! 2147: case 2: i |= I365_MEM_WS1; break; ! 2148: default: i |= I365_MEM_WS1 | I365_MEM_WS0; break; ! 2149: } ! 2150: i365_set_pair(s, base+I365_W_STOP, i); ! 2151: ! 2152: i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff; ! 2153: if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT; ! 2154: if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG; ! 2155: i365_set_pair(s, base+I365_W_OFF, i); ! 2156: ! 2157: /* Turn on the window if necessary */ ! 2158: if (mem->flags & MAP_ACTIVE) ! 2159: i365_bset(s, I365_ADDRWIN, I365_ENA_MEM(map)); ! 2160: return 0; ! 2161: } /* i365_set_mem_map */ ! 2162: ! 2163: /*====================================================================== ! 2164: ! 2165: The few things that are strictly for Cardbus cards goes here. ! 2166: ! 2167: ======================================================================*/ ! 2168: ! 2169: #ifdef CONFIG_CARDBUS ! 2170: ! 2171: static int cb_get_status(socket_info_t *s, u_int *value) ! 2172: { ! 2173: u_int state = cb_readl(s, CB_SOCKET_STATE); ! 2174: *value = (state & CB_SS_32BIT) ? SS_CARDBUS : 0; ! 2175: *value |= (state & CB_SS_CCD) ? 0 : SS_DETECT; ! 2176: *value |= (state & CB_SS_CSTSCHG) ? SS_STSCHG : 0; ! 2177: *value |= (state & CB_SS_PWRCYCLE) ? (SS_POWERON|SS_READY) : 0; ! 2178: *value |= (state & CB_SS_3VCARD) ? SS_3VCARD : 0; ! 2179: *value |= (state & CB_SS_XVCARD) ? SS_XVCARD : 0; ! 2180: *value |= (state & CB_SS_VSENSE) ? 0 : SS_PENDING; ! 2181: DEBUG(1, "yenta: GetStatus(%d) = %#4.4x\n", s-socket, *value); ! 2182: return 0; ! 2183: } /* cb_get_status */ ! 2184: ! 2185: static int cb_get_socket(socket_info_t *s, socket_state_t *state) ! 2186: { ! 2187: u_short bcr; ! 2188: ! 2189: cb_get_power(s, state); ! 2190: pci_readw(s, CB_BRIDGE_CONTROL, &bcr); ! 2191: state->flags |= (bcr & CB_BCR_CB_RESET) ? SS_RESET : 0; ! 2192: if (cb_get_irq_mode(s) != 0) ! 2193: state->io_irq = s->cap.pci_irq; ! 2194: else ! 2195: state->io_irq = i365_get(s, I365_INTCTL) & I365_IRQ_MASK; ! 2196: DEBUG(2, "yenta: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d" ! 2197: ", io_irq %d, csc_mask %#2.2x\n", s-socket, state->flags, ! 2198: state->Vcc, state->Vpp, state->io_irq, state->csc_mask); ! 2199: return 0; ! 2200: } /* cb_get_socket */ ! 2201: ! 2202: static int cb_set_socket(socket_info_t *s, socket_state_t *state) ! 2203: { ! 2204: u_int reg; ! 2205: ! 2206: DEBUG(2, "yenta: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " ! 2207: "io_irq %d, csc_mask %#2.2x)\n", s-socket, state->flags, ! 2208: state->Vcc, state->Vpp, state->io_irq, state->csc_mask); ! 2209: ! 2210: /* First set global controller options */ ! 2211: if (s->cap.pci_irq) ! 2212: cb_set_irq_mode(s, pci_csc, (s->cap.pci_irq == state->io_irq)); ! 2213: s->bcr &= ~CB_BCR_CB_RESET; ! 2214: s->bcr |= (state->flags & SS_RESET) ? CB_BCR_CB_RESET : 0; ! 2215: set_bridge_state(s); ! 2216: ! 2217: cb_set_power(s, state); ! 2218: ! 2219: /* Handle IO interrupt using ISA routing */ ! 2220: reg = s->intr; ! 2221: if (state->io_irq != s->cap.pci_irq) reg |= state->io_irq; ! 2222: i365_set(s, I365_INTCTL, reg); ! 2223: ! 2224: /* Handle CSC mask */ ! 2225: if (!s->cs_irq && (!pci_csc || !s->cap.pci_irq)) ! 2226: return 0; ! 2227: reg = (s->cs_irq << 4); ! 2228: if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT; ! 2229: i365_set(s, I365_CSCINT, reg); ! 2230: i365_get(s, I365_CSC); ! 2231: cb_writel(s, CB_SOCKET_MASK, CB_SM_CCD); ! 2232: cb_writel(s, CB_SOCKET_EVENT, -1); ! 2233: ! 2234: return 0; ! 2235: } /* cb_set_socket */ ! 2236: ! 2237: static int cb_get_bridge(socket_info_t *s, struct cb_bridge_map *m) ! 2238: { ! 2239: u_char map = m->map; ! 2240: ! 2241: if (map > 1) return -EINVAL; ! 2242: m->flags &= MAP_IOSPACE; ! 2243: map += (m->flags & MAP_IOSPACE) ? 2 : 0; ! 2244: pci_readl(s, CB_MEM_BASE(map), &m->start); ! 2245: pci_readl(s, CB_MEM_LIMIT(map), &m->stop); ! 2246: if (m->start || m->stop) { ! 2247: m->flags |= MAP_ACTIVE; ! 2248: m->stop |= (map > 1) ? 3 : 0x0fff; ! 2249: } ! 2250: if (map > 1) { ! 2251: u_short bcr; ! 2252: pci_readw(s, CB_BRIDGE_CONTROL, &bcr); ! 2253: m->flags |= (bcr & CB_BCR_PREFETCH(map)) ? MAP_PREFETCH : 0; ! 2254: } ! 2255: DEBUG(3, "yenta: GetBridge(%d, %d) = %#2.2x, %#4.4x-%#4.4x\n", ! 2256: s-socket, map, m->flags, m->start, m->stop); ! 2257: return 0; ! 2258: } ! 2259: ! 2260: static int cb_set_bridge(socket_info_t *s, struct cb_bridge_map *m) ! 2261: { ! 2262: u_char map; ! 2263: ! 2264: DEBUG(3, "yenta: SetBridge(%d, %d, %#2.2x, %#4.4x-%#4.4x)\n", ! 2265: s-socket, m->map, m->flags, m->start, m->stop); ! 2266: map = m->map; ! 2267: if (!(s->flags & IS_CARDBUS) || (map > 1) || (m->stop < m->start)) ! 2268: return -EINVAL; ! 2269: if (m->flags & MAP_IOSPACE) { ! 2270: if ((m->stop > 0xffff) || (m->start & 3) || ! 2271: ((m->stop & 3) != 3)) ! 2272: return -EINVAL; ! 2273: map += 2; ! 2274: } else { ! 2275: if ((m->start & 0x0fff) || ((m->stop & 0x0fff) != 0x0fff)) ! 2276: return -EINVAL; ! 2277: s->bcr &= ~CB_BCR_PREFETCH(map); ! 2278: s->bcr |= (m->flags & MAP_PREFETCH) ? CB_BCR_PREFETCH(map) : 0; ! 2279: pci_writew(s, CB_BRIDGE_CONTROL, s->bcr); ! 2280: } ! 2281: if (m->flags & MAP_ACTIVE) { ! 2282: pci_writel(s, CB_MEM_BASE(map), m->start); ! 2283: pci_writel(s, CB_MEM_LIMIT(map), m->stop); ! 2284: } else { ! 2285: pci_writel(s, CB_MEM_LIMIT(map), 0); ! 2286: pci_writel(s, CB_MEM_BASE(map), 0); ! 2287: } ! 2288: return 0; ! 2289: } ! 2290: ! 2291: #endif /* CONFIG_CARDBUS */ ! 2292: ! 2293: /*====================================================================== ! 2294: ! 2295: Routines for accessing socket information and register dumps via ! 2296: /proc/bus/pccard/... ! 2297: ! 2298: ======================================================================*/ ! 2299: ! 2300: #ifdef HAS_PROC_BUS ! 2301: ! 2302: static int proc_read_info(char *buf, char **start, off_t pos, ! 2303: int count, int *eof, void *data) ! 2304: { ! 2305: socket_info_t *s = data; ! 2306: char *p = buf; ! 2307: p += sprintf(p, "type: %s\npsock: %d\n", ! 2308: pcic[s->type].name, s->psock); ! 2309: #ifdef CONFIG_PCI ! 2310: if (s->flags & (IS_PCI|IS_CARDBUS)) ! 2311: p += sprintf(p, "bus: %02x\ndevfn: %02x.%1x\n", ! 2312: s->bus, PCI_SLOT(s->devfn), PCI_FUNC(s->devfn)); ! 2313: if (s->flags & IS_CARDBUS) ! 2314: p += sprintf(p, "cardbus: %02x\n", s->cap.cardbus); ! 2315: #endif ! 2316: return (p - buf); ! 2317: } ! 2318: ! 2319: static int proc_read_exca(char *buf, char **start, off_t pos, ! 2320: int count, int *eof, void *data) ! 2321: { ! 2322: socket_info_t *s = data; ! 2323: char *p = buf; ! 2324: int i, top; ! 2325: ! 2326: #ifdef CONFIG_ISA ! 2327: u_long flags = 0; ! 2328: #endif ! 2329: ISA_LOCK(s, flags); ! 2330: top = 0x40; ! 2331: if (s->flags & IS_CARDBUS) ! 2332: top = (s->flags & IS_CIRRUS) ? 0x140 : 0x50; ! 2333: for (i = 0; i < top; i += 4) { ! 2334: if (i == 0x50) { ! 2335: p += sprintf(p, "\n"); ! 2336: i = 0x100; ! 2337: } ! 2338: p += sprintf(p, "%02x %02x %02x %02x%s", ! 2339: i365_get(s,i), i365_get(s,i+1), ! 2340: i365_get(s,i+2), i365_get(s,i+3), ! 2341: ((i % 16) == 12) ? "\n" : " "); ! 2342: } ! 2343: ISA_UNLOCK(s, flags); ! 2344: return (p - buf); ! 2345: } ! 2346: ! 2347: #ifdef CONFIG_PCI ! 2348: static int proc_read_pci(char *buf, char **start, off_t pos, ! 2349: int count, int *eof, void *data) ! 2350: { ! 2351: socket_info_t *s = data; ! 2352: char *p = buf; ! 2353: u_int a, b, c, d; ! 2354: int i; ! 2355: ! 2356: for (i = 0; i < 0xc0; i += 0x10) { ! 2357: pci_readl(s, i, &a); ! 2358: pci_readl(s, i+4, &b); ! 2359: pci_readl(s, i+8, &c); ! 2360: pci_readl(s, i+12, &d); ! 2361: p += sprintf(p, "%08x %08x %08x %08x\n", a, b, c, d); ! 2362: } ! 2363: return (p - buf); ! 2364: } ! 2365: ! 2366: static int proc_read_cardbus(char *buf, char **start, off_t pos, ! 2367: int count, int *eof, void *data) ! 2368: { ! 2369: socket_info_t *s = data; ! 2370: char *p = buf; ! 2371: int i, top; ! 2372: ! 2373: top = (s->flags & IS_O2MICRO) ? 0x30 : 0x20; ! 2374: for (i = 0; i < top; i += 0x10) ! 2375: p += sprintf(p, "%08x %08x %08x %08x\n", ! 2376: cb_readl(s,i+0x00), cb_readl(s,i+0x04), ! 2377: cb_readl(s,i+0x08), cb_readl(s,i+0x0c)); ! 2378: return (p - buf); ! 2379: } ! 2380: #endif ! 2381: ! 2382: static void pcic_proc_setup(socket_info_t *s, struct proc_dir_entry *base) ! 2383: { ! 2384: create_proc_read_entry("info", 0, base, proc_read_info, s); ! 2385: create_proc_read_entry("exca", 0, base, proc_read_exca, s); ! 2386: #ifdef CONFIG_PCI ! 2387: if (s->flags & (IS_PCI|IS_CARDBUS)) ! 2388: create_proc_read_entry("pci", 0, base, proc_read_pci, s); ! 2389: if (s->flags & IS_CARDBUS) ! 2390: create_proc_read_entry("cardbus", 0, base, proc_read_cardbus, s); ! 2391: #endif ! 2392: s->proc = base; ! 2393: } ! 2394: ! 2395: static void pcic_proc_remove(socket_info_t *s) ! 2396: { ! 2397: struct proc_dir_entry *base = s->proc; ! 2398: if (base == NULL) return; ! 2399: remove_proc_entry("info", base); ! 2400: remove_proc_entry("exca", base); ! 2401: #ifdef CONFIG_PCI ! 2402: if (s->flags & (IS_PCI|IS_CARDBUS)) ! 2403: remove_proc_entry("pci", base); ! 2404: if (s->flags & IS_CARDBUS) ! 2405: remove_proc_entry("cardbus", base); ! 2406: #endif ! 2407: } ! 2408: ! 2409: #endif /* HAS_PROC_BUS */ ! 2410: ! 2411: /*====================================================================*/ ! 2412: ! 2413: typedef int (*subfn_t)(socket_info_t *, void *); ! 2414: ! 2415: static subfn_t pcic_service_table[] = { ! 2416: (subfn_t)&pcic_register_callback, ! 2417: (subfn_t)&pcic_inquire_socket, ! 2418: (subfn_t)&i365_get_status, ! 2419: (subfn_t)&i365_get_socket, ! 2420: (subfn_t)&i365_set_socket, ! 2421: (subfn_t)&i365_get_io_map, ! 2422: (subfn_t)&i365_set_io_map, ! 2423: (subfn_t)&i365_get_mem_map, ! 2424: (subfn_t)&i365_set_mem_map, ! 2425: #ifdef CONFIG_CARDBUS ! 2426: (subfn_t)&cb_get_bridge, ! 2427: (subfn_t)&cb_set_bridge, ! 2428: #else ! 2429: NULL, NULL, ! 2430: #endif ! 2431: #ifdef HAS_PROC_BUS ! 2432: (subfn_t)&pcic_proc_setup ! 2433: #endif ! 2434: }; ! 2435: ! 2436: #define NFUNC (sizeof(pcic_service_table)/sizeof(subfn_t)) ! 2437: ! 2438: static int pcic_service(u_int sock, u_int cmd, void *arg) ! 2439: { ! 2440: socket_info_t *s = &socket[sock]; ! 2441: subfn_t fn; ! 2442: int ret; ! 2443: #ifdef CONFIG_ISA ! 2444: u_long flags = 0; ! 2445: #endif ! 2446: ! 2447: if (cmd >= NFUNC) ! 2448: return -EINVAL; ! 2449: ! 2450: if (s->flags & IS_ALIVE) { ! 2451: if (cmd == SS_GetStatus) ! 2452: *(u_int *)arg = 0; ! 2453: return -EINVAL; ! 2454: } ! 2455: ! 2456: fn = pcic_service_table[cmd]; ! 2457: #ifdef CONFIG_CARDBUS ! 2458: if ((s->flags & IS_CARDBUS) && ! 2459: (cb_readl(s, CB_SOCKET_STATE) & CB_SS_32BIT)) { ! 2460: if (cmd == SS_GetStatus) ! 2461: fn = (subfn_t)&cb_get_status; ! 2462: else if (cmd == SS_GetSocket) ! 2463: fn = (subfn_t)&cb_get_socket; ! 2464: else if (cmd == SS_SetSocket) ! 2465: fn = (subfn_t)&cb_set_socket; ! 2466: } ! 2467: #endif ! 2468: ! 2469: ISA_LOCK(s, flags); ! 2470: ret = (fn == NULL) ? -EINVAL : fn(s, arg); ! 2471: ISA_UNLOCK(s, flags); ! 2472: return ret; ! 2473: } /* pcic_service */ ! 2474: ! 2475: /*====================================================================*/ ! 2476: ! 2477: int __init init_i82365(void) ! 2478: { ! 2479: servinfo_t serv; ! 2480: CardServices(GetCardServicesInfo, &serv); ! 2481: if (serv.Revision != CS_RELEASE_CODE) { ! 2482: printk(KERN_NOTICE "i82365: Card Services release " ! 2483: "does not match!\n"); ! 2484: return -EINVAL; ! 2485: } ! 2486: DEBUG(0, "%s\n", version); ! 2487: ! 2488: #ifdef CONFIG_PCI ! 2489: if (pcic[IS_UNK_CARDBUS].flags != (IS_CARDBUS|IS_UNKNOWN)) { ! 2490: printk(KERN_NOTICE "i82365: bad pcic_id enumeration!\n"); ! 2491: return -EINVAL; ! 2492: } ! 2493: #endif ! 2494: ! 2495: printk(KERN_INFO "Intel ISA/PCI/CardBus PCIC probe:\n"); ! 2496: sockets = 0; ! 2497: ! 2498: #ifdef CONFIG_PCI ! 2499: if (do_pci_probe && pcibios_present()) { ! 2500: pci_probe(PCI_CLASS_BRIDGE_CARDBUS); ! 2501: pci_probe(PCI_CLASS_BRIDGE_PCMCIA); ! 2502: } ! 2503: #endif ! 2504: ! 2505: #ifdef CONFIG_ISA ! 2506: isa_probe(i365_base); ! 2507: if (!sockets || extra_sockets) ! 2508: isa_probe(i365_base+2); ! 2509: #endif ! 2510: ! 2511: if (sockets == 0) { ! 2512: printk(KERN_INFO " no bridges found.\n"); ! 2513: return -ENODEV; ! 2514: } ! 2515: ! 2516: /* Set up interrupt handler(s) */ ! 2517: #ifdef CONFIG_ISA ! 2518: if (grab_irq != 0) ! 2519: request_irq(cs_irq, pcic_interrupt, 0, "i82365", socket); ! 2520: #endif ! 2521: #ifdef CONFIG_PCI ! 2522: if (pci_csc) { ! 2523: u_int i, irq, mask = 0; ! 2524: for (i = 0; i < sockets; i++) { ! 2525: irq = socket[i].cap.pci_irq; ! 2526: if (irq && !(mask & (1<<irq))) ! 2527: request_irq(irq, pcic_interrupt, SA_SHIRQ, "i82365", socket); ! 2528: mask |= (1<<irq); ! 2529: } ! 2530: } ! 2531: #endif ! 2532: ! 2533: if (register_ss_entry(sockets, &pcic_service) != 0) ! 2534: printk(KERN_NOTICE "i82365: register_ss_entry() failed\n"); ! 2535: ! 2536: /* Finally, schedule a polling interrupt */ ! 2537: if (poll_interval != 0) { ! 2538: poll_timer.expires = jiffies + poll_interval; ! 2539: add_timer(&poll_timer); ! 2540: } ! 2541: ! 2542: return 0; ! 2543: ! 2544: } /* init_i82365 */ ! 2545: ! 2546: static void __exit exit_i82365(void) ! 2547: { ! 2548: int i; ! 2549: #ifdef HAS_PROC_BUS ! 2550: for (i = 0; i < sockets; i++) ! 2551: pcic_proc_remove(&socket[i]); ! 2552: #endif ! 2553: unregister_ss_entry(&pcic_service); ! 2554: if (poll_interval != 0) ! 2555: del_timer(&poll_timer); ! 2556: #ifdef CONFIG_ISA ! 2557: if (grab_irq != 0) ! 2558: free_irq(cs_irq, socket); ! 2559: #endif ! 2560: #ifdef CONFIG_PCI ! 2561: if (pci_csc) { ! 2562: u_int irq, mask = 0; ! 2563: for (i = 0; i < sockets; i++) { ! 2564: irq = socket[i].cap.pci_irq; ! 2565: if (irq && !(mask & (1<<irq))) ! 2566: free_irq(irq, socket); ! 2567: mask |= (1<<irq); ! 2568: } ! 2569: } ! 2570: #endif ! 2571: for (i = 0; i < sockets; i++) { ! 2572: socket_info_t *s = &socket[i]; ! 2573: /* Turn off all interrupt sources! */ ! 2574: i365_set(s, I365_CSCINT, 0); ! 2575: #ifdef CONFIG_PCI ! 2576: if (s->flags & IS_CARDBUS) ! 2577: cb_writel(s, CB_SOCKET_MASK, 0); ! 2578: if (s->cb_virt) { ! 2579: iounmap(s->cb_virt); ! 2580: release_mem_region(s->cb_phys, 0x1000); ! 2581: } else ! 2582: #endif ! 2583: release_region(s->ioaddr, 2); ! 2584: } ! 2585: } /* exit_i82365 */ ! 2586: ! 2587: module_init(init_i82365); ! 2588: module_exit(exit_i82365);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.