linux-bk/drivers/pcmcia/i82365.c
<<
>>
Prefs
   1/*======================================================================
   2
   3    Device driver for Intel 82365 and compatible PC Card controllers.
   4
   5    i82365.c 1.265 1999/11/10 18:36:21
   6
   7    The contents of this file are subject to the Mozilla Public
   8    License Version 1.1 (the "License"); you may not use this file
   9    except in compliance with the License. You may obtain a copy of
  10    the License at http://www.mozilla.org/MPL/
  11
  12    Software distributed under the License is distributed on an "AS
  13    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  14    implied. See the License for the specific language governing
  15    rights and limitations under the License.
  16
  17    The initial developer of the original code is David A. Hinds
  18    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  19    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  20
  21    Alternatively, the contents of this file may be used under the
  22    terms of the GNU General Public License version 2 (the "GPL"), in which
  23    case the provisions of the GPL are applicable instead of the
  24    above.  If you wish to allow the use of your version of this file
  25    only under the terms of the GPL and not to allow others to use
  26    your version of this file under the MPL, indicate your decision
  27    by deleting the provisions above and replace them with the notice
  28    and other provisions required by the GPL.  If you do not delete
  29    the provisions above, a recipient may use your version of this
  30    file under either the MPL or the GPL.
  31    
  32======================================================================*/
  33
  34#include <linux/module.h>
  35#include <linux/moduleparam.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/ioport.h>
  47#include <linux/delay.h>
  48#include <linux/workqueue.h>
  49#include <linux/interrupt.h>
  50#include <linux/device.h>
  51#include <linux/bitops.h>
  52#include <asm/irq.h>
  53#include <asm/io.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#include <linux/isapnp.h>
  62
  63/* ISA-bus controllers */
  64#include "i82365.h"
  65#include "cirrus.h"
  66#include "vg468.h"
  67#include "ricoh.h"
  68
  69#ifdef DEBUG
  70static const char version[] =
  71"i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)";
  72
  73static int pc_debug;
  74
  75module_param(pc_debug, int, 0644);
  76
  77#define debug(lvl, fmt, arg...) do {                            \
  78        if (pc_debug > (lvl))                                   \
  79                printk(KERN_DEBUG "i82365: " fmt , ## arg);     \
  80} while (0)
  81#else
  82#define debug(lvl, fmt, arg...) do { } while (0)
  83#endif
  84
  85static irqreturn_t i365_count_irq(int, void *, struct pt_regs *);
  86static inline int _check_irq(int irq, int flags)
  87{
  88    if (request_irq(irq, i365_count_irq, flags, "x", i365_count_irq) != 0)
  89        return -1;
  90    free_irq(irq, i365_count_irq);
  91    return 0;
  92}
  93
  94/*====================================================================*/
  95
  96/* Parameters that can be set with 'insmod' */
  97
  98/* Default base address for i82365sl and other ISA chips */
  99static unsigned long i365_base = 0x3e0;
 100/* Should we probe at 0x3e2 for an extra ISA controller? */
 101static int extra_sockets = 0;
 102/* Specify a socket number to ignore */
 103static int ignore = -1;
 104/* Bit map or list of interrupts to choose from */
 105static u_int irq_mask = 0xffff;
 106static int irq_list[16];
 107static int irq_list_count;
 108/* The card status change interrupt -- 0 means autoselect */
 109static int cs_irq = 0;
 110
 111/* Probe for safe interrupts? */
 112static int do_scan = 1;
 113/* Poll status interval -- 0 means default to interrupt */
 114static int poll_interval = 0;
 115/* External clock time, in nanoseconds.  120 ns = 8.33 MHz */
 116static int cycle_time = 120;
 117
 118/* Cirrus options */
 119static int has_dma = -1;
 120static int has_led = -1;
 121static int has_ring = -1;
 122static int dynamic_mode = 0;
 123static int freq_bypass = -1;
 124static int setup_time = -1;
 125static int cmd_time = -1;
 126static int recov_time = -1;
 127
 128/* Vadem options */
 129static int async_clock = -1;
 130static int cable_mode = -1;
 131static int wakeup = 0;
 132
 133module_param(i365_base, ulong, 0444);
 134module_param(ignore, int, 0444);
 135module_param(extra_sockets, int, 0444);
 136module_param(irq_mask, int, 0444);
 137module_param_array(irq_list, int, &irq_list_count, 0444);
 138module_param(cs_irq, int, 0444);
 139module_param(async_clock, int, 0444);
 140module_param(cable_mode, int, 0444);
 141module_param(wakeup, int, 0444);
 142
 143module_param(do_scan, int, 0444);
 144module_param(poll_interval, int, 0444);
 145module_param(cycle_time, int, 0444);
 146module_param(has_dma, int, 0444);
 147module_param(has_led, int, 0444);
 148module_param(has_ring, int, 0444);
 149module_param(dynamic_mode, int, 0444);
 150module_param(freq_bypass, int, 0444);
 151module_param(setup_time, int, 0444);
 152module_param(cmd_time, int, 0444);
 153module_param(recov_time, int, 0444);
 154
 155/*====================================================================*/
 156
 157typedef struct cirrus_state_t {
 158    u_char              misc1, misc2;
 159    u_char              timer[6];
 160} cirrus_state_t;
 161
 162typedef struct vg46x_state_t {
 163    u_char              ctl, ema;
 164} vg46x_state_t;
 165
 166struct i82365_socket {
 167    u_short             type, flags;
 168    struct pcmcia_socket        socket;
 169    unsigned int        number;
 170    kio_addr_t          ioaddr;
 171    u_short             psock;
 172    u_char              cs_irq, intr;
 173    union {
 174        cirrus_state_t          cirrus;
 175        vg46x_state_t           vg46x;
 176    } state;
 177};
 178
 179/* Where we keep track of our sockets... */
 180static int sockets = 0;
 181static struct i82365_socket socket[8] = {
 182    { 0, }, /* ... */
 183};
 184
 185/* Default ISA interrupt mask */
 186#define I365_MASK       0xdeb8  /* irq 15,14,12,11,10,9,7,5,4,3 */
 187
 188static int grab_irq;
 189static DEFINE_SPINLOCK(isa_lock);
 190#define ISA_LOCK(n, f) spin_lock_irqsave(&isa_lock, f)
 191#define ISA_UNLOCK(n, f) spin_unlock_irqrestore(&isa_lock, f)
 192
 193static struct timer_list poll_timer;
 194
 195/*====================================================================*/
 196
 197/* These definitions must match the pcic table! */
 198typedef enum pcic_id {
 199    IS_I82365A, IS_I82365B, IS_I82365DF,
 200    IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469,
 201    IS_PD6710, IS_PD672X, IS_VT83C469,
 202} pcic_id;
 203
 204/* Flags for classifying groups of controllers */
 205#define IS_VADEM        0x0001
 206#define IS_CIRRUS       0x0002
 207#define IS_VIA          0x0010
 208#define IS_UNKNOWN      0x0400
 209#define IS_VG_PWR       0x0800
 210#define IS_DF_PWR       0x1000
 211#define IS_REGISTERED   0x2000
 212#define IS_ALIVE        0x8000
 213
 214typedef struct pcic_t {
 215    char                *name;
 216    u_short             flags;
 217} pcic_t;
 218
 219static pcic_t pcic[] = {
 220    { "Intel i82365sl A step", 0 },
 221    { "Intel i82365sl B step", 0 },
 222    { "Intel i82365sl DF", IS_DF_PWR },
 223    { "IBM Clone", 0 },
 224    { "Ricoh RF5C296/396", 0 },
 225    { "VLSI 82C146", 0 },
 226    { "Vadem VG-468", IS_VADEM },
 227    { "Vadem VG-469", IS_VADEM|IS_VG_PWR },
 228    { "Cirrus PD6710", IS_CIRRUS },
 229    { "Cirrus PD672x", IS_CIRRUS },
 230    { "VIA VT83C469", IS_CIRRUS|IS_VIA },
 231};
 232
 233#define PCIC_COUNT      (sizeof(pcic)/sizeof(pcic_t))
 234
 235/*====================================================================*/
 236
 237static DEFINE_SPINLOCK(bus_lock);
 238
 239static u_char i365_get(u_short sock, u_short reg)
 240{
 241    unsigned long flags;
 242    spin_lock_irqsave(&bus_lock,flags);
 243    {
 244        kio_addr_t port = socket[sock].ioaddr;
 245        u_char val;
 246        reg = I365_REG(socket[sock].psock, reg);
 247        outb(reg, port); val = inb(port+1);
 248        spin_unlock_irqrestore(&bus_lock,flags);
 249        return val;
 250    }
 251}
 252
 253static void i365_set(u_short sock, u_short reg, u_char data)
 254{
 255    unsigned long flags;
 256    spin_lock_irqsave(&bus_lock,flags);
 257    {
 258        kio_addr_t port = socket[sock].ioaddr;
 259        u_char val = I365_REG(socket[sock].psock, reg);
 260        outb(val, port); outb(data, port+1);
 261        spin_unlock_irqrestore(&bus_lock,flags);
 262    }
 263}
 264
 265static void i365_bset(u_short sock, u_short reg, u_char mask)
 266{
 267    u_char d = i365_get(sock, reg);
 268    d |= mask;
 269    i365_set(sock, reg, d);
 270}
 271
 272static void i365_bclr(u_short sock, u_short reg, u_char mask)
 273{
 274    u_char d = i365_get(sock, reg);
 275    d &= ~mask;
 276    i365_set(sock, reg, d);
 277}
 278
 279static void i365_bflip(u_short sock, u_short reg, u_char mask, int b)
 280{
 281    u_char d = i365_get(sock, reg);
 282    if (b)
 283        d |= mask;
 284    else
 285        d &= ~mask;
 286    i365_set(sock, reg, d);
 287}
 288
 289static u_short i365_get_pair(u_short sock, u_short reg)
 290{
 291    u_short a, b;
 292    a = i365_get(sock, reg);
 293    b = i365_get(sock, reg+1);
 294    return (a + (b<<8));
 295}
 296
 297static void i365_set_pair(u_short sock, u_short reg, u_short data)
 298{
 299    i365_set(sock, reg, data & 0xff);
 300    i365_set(sock, reg+1, data >> 8);
 301}
 302
 303/*======================================================================
 304
 305    Code to save and restore global state information for Cirrus
 306    PD67xx controllers, and to set and report global configuration
 307    options.
 308
 309    The VIA controllers also use these routines, as they are mostly
 310    Cirrus lookalikes, without the timing registers.
 311    
 312======================================================================*/
 313
 314#define flip(v,b,f) (v = ((f)<0) ? v : ((f) ? ((v)|(b)) : ((v)&(~b))))
 315
 316static void cirrus_get_state(u_short s)
 317{
 318    int i;
 319    cirrus_state_t *p = &socket[s].state.cirrus;
 320    p->misc1 = i365_get(s, PD67_MISC_CTL_1);
 321    p->misc1 &= (PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
 322    p->misc2 = i365_get(s, PD67_MISC_CTL_2);
 323    for (i = 0; i < 6; i++)
 324        p->timer[i] = i365_get(s, PD67_TIME_SETUP(0)+i);
 325}
 326
 327static void cirrus_set_state(u_short s)
 328{
 329    int i;
 330    u_char misc;
 331    cirrus_state_t *p = &socket[s].state.cirrus;
 332
 333    misc = i365_get(s, PD67_MISC_CTL_2);
 334    i365_set(s, PD67_MISC_CTL_2, p->misc2);
 335    if (misc & PD67_MC2_SUSPEND) mdelay(50);
 336    misc = i365_get(s, PD67_MISC_CTL_1);
 337    misc &= ~(PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
 338    i365_set(s, PD67_MISC_CTL_1, misc | p->misc1);
 339    for (i = 0; i < 6; i++)
 340        i365_set(s, PD67_TIME_SETUP(0)+i, p->timer[i]);
 341}
 342
 343static u_int __init cirrus_set_opts(u_short s, char *buf)
 344{
 345    struct i82365_socket *t = &socket[s];
 346    cirrus_state_t *p = &socket[s].state.cirrus;
 347    u_int mask = 0xffff;
 348
 349    if (has_ring == -1) has_ring = 1;
 350    flip(p->misc2, PD67_MC2_IRQ15_RI, has_ring);
 351    flip(p->misc2, PD67_MC2_DYNAMIC_MODE, dynamic_mode);
 352    flip(p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass);
 353    if (p->misc2 & PD67_MC2_IRQ15_RI)
 354        strcat(buf, " [ring]");
 355    if (p->misc2 & PD67_MC2_DYNAMIC_MODE)
 356        strcat(buf, " [dyn mode]");
 357    if (p->misc2 & PD67_MC2_FREQ_BYPASS)
 358        strcat(buf, " [freq bypass]");
 359    if (p->misc1 & PD67_MC1_INPACK_ENA)
 360        strcat(buf, " [inpack]");
 361    if (p->misc2 & PD67_MC2_IRQ15_RI)
 362        mask &= ~0x8000;
 363    if (has_led > 0) {
 364        strcat(buf, " [led]");
 365        mask &= ~0x1000;
 366    }
 367    if (has_dma > 0) {
 368        strcat(buf, " [dma]");
 369        mask &= ~0x0600;
 370    }
 371    if (!(t->flags & IS_VIA)) {
 372        if (setup_time >= 0)
 373            p->timer[0] = p->timer[3] = setup_time;
 374        if (cmd_time > 0) {
 375            p->timer[1] = cmd_time;
 376            p->timer[4] = cmd_time*2+4;
 377        }
 378        if (p->timer[1] == 0) {
 379            p->timer[1] = 6; p->timer[4] = 16;
 380            if (p->timer[0] == 0)
 381                p->timer[0] = p->timer[3] = 1;
 382        }
 383        if (recov_time >= 0)
 384            p->timer[2] = p->timer[5] = recov_time;
 385        buf += strlen(buf);
 386        sprintf(buf, " [%d/%d/%d] [%d/%d/%d]", p->timer[0], p->timer[1],
 387                p->timer[2], p->timer[3], p->timer[4], p->timer[5]);
 388    }
 389    return mask;
 390}
 391
 392/*======================================================================
 393
 394    Code to save and restore global state information for Vadem VG468
 395    and VG469 controllers, and to set and report global configuration
 396    options.
 397    
 398======================================================================*/
 399
 400static void vg46x_get_state(u_short s)
 401{
 402    vg46x_state_t *p = &socket[s].state.vg46x;
 403    p->ctl = i365_get(s, VG468_CTL);
 404    if (socket[s].type == IS_VG469)
 405        p->ema = i365_get(s, VG469_EXT_MODE);
 406}
 407
 408static void vg46x_set_state(u_short s)
 409{
 410    vg46x_state_t *p = &socket[s].state.vg46x;
 411    i365_set(s, VG468_CTL, p->ctl);
 412    if (socket[s].type == IS_VG469)
 413        i365_set(s, VG469_EXT_MODE, p->ema);
 414}
 415
 416static u_int __init vg46x_set_opts(u_short s, char *buf)
 417{
 418    vg46x_state_t *p = &socket[s].state.vg46x;
 419    
 420    flip(p->ctl, VG468_CTL_ASYNC, async_clock);
 421    flip(p->ema, VG469_MODE_CABLE, cable_mode);
 422    if (p->ctl & VG468_CTL_ASYNC)
 423        strcat(buf, " [async]");
 424    if (p->ctl & VG468_CTL_INPACK)
 425        strcat(buf, " [inpack]");
 426    if (socket[s].type == IS_VG469) {
 427        u_char vsel = i365_get(s, VG469_VSELECT);
 428        if (vsel & VG469_VSEL_EXT_STAT) {
 429            strcat(buf, " [ext mode]");
 430            if (vsel & VG469_VSEL_EXT_BUS)
 431                strcat(buf, " [isa buf]");
 432        }
 433        if (p->ema & VG469_MODE_CABLE)
 434            strcat(buf, " [cable]");
 435        if (p->ema & VG469_MODE_COMPAT)
 436            strcat(buf, " [c step]");
 437    }
 438    return 0xffff;
 439}
 440
 441/*======================================================================
 442
 443    Generic routines to get and set controller options
 444    
 445======================================================================*/
 446
 447static void get_bridge_state(u_short s)
 448{
 449    struct i82365_socket *t = &socket[s];
 450    if (t->flags & IS_CIRRUS)
 451        cirrus_get_state(s);
 452    else if (t->flags & IS_VADEM)
 453        vg46x_get_state(s);
 454}
 455
 456static void set_bridge_state(u_short s)
 457{
 458    struct i82365_socket *t = &socket[s];
 459    if (t->flags & IS_CIRRUS)
 460        cirrus_set_state(s);
 461    else {
 462        i365_set(s, I365_GBLCTL, 0x00);
 463        i365_set(s, I365_GENCTL, 0x00);
 464    }
 465    i365_bflip(s, I365_INTCTL, I365_INTR_ENA, t->intr);
 466    if (t->flags & IS_VADEM)
 467        vg46x_set_state(s);
 468}
 469
 470static u_int __init set_bridge_opts(u_short s, u_short ns)
 471{
 472    u_short i;
 473    u_int m = 0xffff;
 474    char buf[128];
 475
 476    for (i = s; i < s+ns; i++) {
 477        if (socket[i].flags & IS_ALIVE) {
 478            printk(KERN_INFO "    host opts [%d]: already alive!\n", i);
 479            continue;
 480        }
 481        buf[0] = '\0';
 482        get_bridge_state(i);
 483        if (socket[i].flags & IS_CIRRUS)
 484            m = cirrus_set_opts(i, buf);
 485        else if (socket[i].flags & IS_VADEM)
 486            m = vg46x_set_opts(i, buf);
 487        set_bridge_state(i);
 488        printk(KERN_INFO "    host opts [%d]:%s\n", i,
 489               (*buf) ? buf : " none");
 490    }
 491    return m;
 492}
 493
 494/*======================================================================
 495
 496    Interrupt testing code, for ISA and PCI interrupts
 497    
 498======================================================================*/
 499
 500static volatile u_int irq_hits;
 501static u_short irq_sock;
 502
 503static irqreturn_t i365_count_irq(int irq, void *dev, struct pt_regs *regs)
 504{
 505    i365_get(irq_sock, I365_CSC);
 506    irq_hits++;
 507    debug(2, "-> hit on irq %d\n", irq);
 508    return IRQ_HANDLED;
 509}
 510
 511static u_int __init test_irq(u_short sock, int irq)
 512{
 513    debug(2, "  testing ISA irq %d\n", irq);
 514    if (request_irq(irq, i365_count_irq, 0, "scan", i365_count_irq) != 0)
 515        return 1;
 516    irq_hits = 0; irq_sock = sock;
 517    msleep(10);
 518    if (irq_hits) {
 519        free_irq(irq, i365_count_irq);
 520        debug(2, "    spurious hit!\n");
 521        return 1;
 522    }
 523
 524    /* Generate one interrupt */
 525    i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (irq << 4));
 526    i365_bset(sock, I365_GENCTL, I365_CTL_SW_IRQ);
 527    udelay(1000);
 528
 529    free_irq(irq, i365_count_irq);
 530
 531    /* mask all interrupts */
 532    i365_set(sock, I365_CSCINT, 0);
 533    debug(2, "    hits = %d\n", irq_hits);
 534    
 535    return (irq_hits != 1);
 536}
 537
 538static u_int __init isa_scan(u_short sock, u_int mask0)
 539{
 540    u_int mask1 = 0;
 541    int i;
 542
 543#ifdef __alpha__
 544#define PIC 0x4d0
 545    /* Don't probe level-triggered interrupts -- reserved for PCI */
 546    mask0 &= ~(inb(PIC) | (inb(PIC+1) << 8));
 547#endif
 548    
 549    if (do_scan) {
 550        set_bridge_state(sock);
 551        i365_set(sock, I365_CSCINT, 0);
 552        for (i = 0; i < 16; i++)
 553            if ((mask0 & (1 << i)) && (test_irq(sock, i) == 0))
 554                mask1 |= (1 << i);
 555        for (i = 0; i < 16; i++)
 556            if ((mask1 & (1 << i)) && (test_irq(sock, i) != 0))
 557                mask1 ^= (1 << i);
 558    }
 559    
 560    printk(KERN_INFO "    ISA irqs (");
 561    if (mask1) {
 562        printk("scanned");
 563    } else {
 564        /* Fallback: just find interrupts that aren't in use */
 565        for (i = 0; i < 16; i++)
 566            if ((mask0 & (1 << i)) && (_check_irq(i, 0) == 0))
 567                mask1 |= (1 << i);
 568        printk("default");
 569        /* If scan failed, default to polled status */
 570        if (!cs_irq && (poll_interval == 0)) poll_interval = HZ;
 571    }
 572    printk(") = ");
 573    
 574    for (i = 0; i < 16; i++)
 575        if (mask1 & (1<<i))
 576            printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
 577    if (mask1 == 0) printk("none!");
 578    
 579    return mask1;
 580}
 581
 582/*====================================================================*/
 583
 584/* Time conversion functions */
 585
 586static int to_cycles(int ns)
 587{
 588    return ns/cycle_time;
 589}
 590
 591/*====================================================================*/
 592
 593static int __init identify(kio_addr_t port, u_short sock)
 594{
 595    u_char val;
 596    int type = -1;
 597
 598    /* Use the next free entry in the socket table */
 599    socket[sockets].ioaddr = port;
 600    socket[sockets].psock = sock;
 601    
 602    /* Wake up a sleepy Cirrus controller */
 603    if (wakeup) {
 604        i365_bclr(sockets, PD67_MISC_CTL_2, PD67_MC2_SUSPEND);
 605        /* Pause at least 50 ms */
 606        mdelay(50);
 607    }
 608    
 609    if ((val = i365_get(sockets, I365_IDENT)) & 0x70)
 610        return -1;
 611    switch (val) {
 612    case 0x82:
 613        type = IS_I82365A; break;
 614    case 0x83:
 615        type = IS_I82365B; break;
 616    case 0x84:
 617        type = IS_I82365DF; break;
 618    case 0x88: case 0x89: case 0x8a:
 619        type = IS_IBM; break;
 620    }
 621    
 622    /* Check for Vadem VG-468 chips */
 623    outb(0x0e, port);
 624    outb(0x37, port);
 625    i365_bset(sockets, VG468_MISC, VG468_MISC_VADEMREV);
 626    val = i365_get(sockets, I365_IDENT);
 627    if (val & I365_IDENT_VADEM) {
 628        i365_bclr(sockets, VG468_MISC, VG468_MISC_VADEMREV);
 629        type = ((val & 7) >= 4) ? IS_VG469 : IS_VG468;
 630    }
 631
 632    /* Check for Ricoh chips */
 633    val = i365_get(sockets, RF5C_CHIP_ID);
 634    if ((val == RF5C_CHIP_RF5C296) || (val == RF5C_CHIP_RF5C396))
 635        type = IS_RF5Cx96;
 636    
 637    /* Check for Cirrus CL-PD67xx chips */
 638    i365_set(sockets, PD67_CHIP_INFO, 0);
 639    val = i365_get(sockets, PD67_CHIP_INFO);
 640    if ((val & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID) {
 641        val = i365_get(sockets, PD67_CHIP_INFO);
 642        if ((val & PD67_INFO_CHIP_ID) == 0) {
 643            type = (val & PD67_INFO_SLOTS) ? IS_PD672X : IS_PD6710;
 644            i365_set(sockets, PD67_EXT_INDEX, 0xe5);
 645            if (i365_get(sockets, PD67_EXT_INDEX) != 0xe5)
 646                type = IS_VT83C469;
 647        }
 648    }
 649    return type;
 650} /* identify */
 651
 652/*======================================================================
 653
 654    See if a card is present, powered up, in IO mode, and already
 655    bound to a (non PC Card) Linux driver.  We leave these alone.
 656
 657    We make an exception for cards that seem to be serial devices.
 658    
 659======================================================================*/
 660
 661static int __init is_alive(u_short sock)
 662{
 663    u_char stat;
 664    kio_addr_t start, stop;
 665    
 666    stat = i365_get(sock, I365_STATUS);
 667    start = i365_get_pair(sock, I365_IO(0)+I365_W_START);
 668    stop = i365_get_pair(sock, I365_IO(0)+I365_W_STOP);
 669    if ((stat & I365_CS_DETECT) && (stat & I365_CS_POWERON) &&
 670        (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD) &&
 671        (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(0)) &&
 672        (check_region(start, stop-start+1) != 0) &&
 673        ((start & 0xfeef) != 0x02e8))
 674        return 1;
 675    else
 676        return 0;
 677}
 678
 679/*====================================================================*/
 680
 681static void __init add_socket(kio_addr_t port, int psock, int type)
 682{
 683    socket[sockets].ioaddr = port;
 684    socket[sockets].psock = psock;
 685    socket[sockets].type = type;
 686    socket[sockets].flags = pcic[type].flags;
 687    if (is_alive(sockets))
 688        socket[sockets].flags |= IS_ALIVE;
 689    sockets++;
 690}
 691
 692static void __init add_pcic(int ns, int type)
 693{
 694    u_int mask = 0, i, base;
 695    int isa_irq = 0;
 696    struct i82365_socket *t = &socket[sockets-ns];
 697
 698    base = sockets-ns;
 699    if (t->ioaddr > 0) request_region(t->ioaddr, 2, "i82365");
 700    
 701    if (base == 0) printk("\n");
 702    printk(KERN_INFO "  %s", pcic[type].name);
 703    printk(" ISA-to-PCMCIA at port %#lx ofs 0x%02x",
 704               t->ioaddr, t->psock*0x40);
 705    printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : ""));
 706
 707    /* Set host options, build basic interrupt mask */
 708    if (irq_list_count == 0)
 709        mask = irq_mask;
 710    else
 711        for (i = mask = 0; i < irq_list_count; i++)
 712            mask |= (1<<irq_list[i]);
 713    mask &= I365_MASK & set_bridge_opts(base, ns);
 714    /* Scan for ISA interrupts */
 715    mask = isa_scan(base, mask);
 716        
 717    /* Poll if only two interrupts available */
 718    if (!poll_interval) {
 719        u_int tmp = (mask & 0xff20);
 720        tmp = tmp & (tmp-1);
 721        if ((tmp & (tmp-1)) == 0)
 722            poll_interval = HZ;
 723    }
 724    /* Only try an ISA cs_irq if this is the first controller */
 725    if (!grab_irq && (cs_irq || !poll_interval)) {
 726        /* Avoid irq 12 unless it is explicitly requested */
 727        u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
 728        for (cs_irq = 15; cs_irq > 0; cs_irq--)
 729            if ((cs_mask & (1 << cs_irq)) &&
 730                (_check_irq(cs_irq, 0) == 0))
 731                break;
 732        if (cs_irq) {
 733            grab_irq = 1;
 734            isa_irq = cs_irq;
 735            printk(" status change on irq %d\n", cs_irq);
 736        }
 737    }
 738    
 739    if (!isa_irq) {
 740        if (poll_interval == 0)
 741            poll_interval = HZ;
 742        printk(" polling interval = %d ms\n",
 743               poll_interval * 1000 / HZ);
 744        
 745    }
 746    
 747    /* Update socket interrupt information, capabilities */
 748    for (i = 0; i < ns; i++) {
 749        t[i].socket.features |= SS_CAP_PCCARD;
 750        t[i].socket.map_size = 0x1000;
 751        t[i].socket.irq_mask = mask;
 752        t[i].cs_irq = isa_irq;
 753    }
 754
 755} /* add_pcic */
 756
 757/*====================================================================*/
 758
 759#ifdef CONFIG_PNP
 760static struct isapnp_device_id id_table[] __initdata = {
 761        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
 762                ISAPNP_FUNCTION(0x0e00), (unsigned long) "Intel 82365-Compatible" },
 763        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
 764                ISAPNP_FUNCTION(0x0e01), (unsigned long) "Cirrus Logic CL-PD6720" },
 765        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
 766                ISAPNP_FUNCTION(0x0e02), (unsigned long) "VLSI VL82C146" },
 767        {       0 }
 768};
 769MODULE_DEVICE_TABLE(isapnp, id_table);
 770
 771static struct pnp_dev *i82365_pnpdev;
 772#endif
 773
 774static void __init isa_probe(void)
 775{
 776    int i, j, sock, k, ns, id;
 777    kio_addr_t port;
 778#ifdef CONFIG_PNP
 779    struct isapnp_device_id *devid;
 780    struct pnp_dev *dev;
 781
 782    for (devid = id_table; devid->vendor; devid++) {
 783        if ((dev = pnp_find_dev(NULL, devid->vendor, devid->function, NULL))) {
 784        
 785            if (pnp_device_attach(dev) < 0)
 786                continue;
 787
 788            if (pnp_activate_dev(dev) < 0) {
 789                printk("activate failed\n");
 790                pnp_device_detach(dev);
 791                break;
 792            }
 793
 794            if (!pnp_port_valid(dev, 0)) {
 795                printk("invalid resources ?\n");
 796                pnp_device_detach(dev);
 797                break;
 798            }
 799            i365_base = pnp_port_start(dev, 0);
 800            i82365_pnpdev = dev;
 801            break;
 802        }
 803    }
 804#endif
 805
 806    if (check_region(i365_base, 2) != 0) {
 807        if (sockets == 0)
 808            printk("port conflict at %#lx\n", i365_base);
 809        return;
 810    }
 811
 812    id = identify(i365_base, 0);
 813    if ((id == IS_I82365DF) && (identify(i365_base, 1) != id)) {
 814        for (i = 0; i < 4; i++) {
 815            if (i == ignore) continue;
 816            port = i365_base + ((i & 1) << 2) + ((i & 2) << 1);
 817            sock = (i & 1) << 1;
 818            if (identify(port, sock) == IS_I82365DF) {
 819                add_socket(port, sock, IS_VLSI);
 820                add_pcic(1, IS_VLSI);
 821            }
 822        }
 823    } else {
 824        for (i = 0; i < 8; i += 2) {
 825            if (sockets && !extra_sockets && (i == 4))
 826                break;
 827            port = i365_base + 2*(i>>2);
 828            sock = (i & 3);
 829            id = identify(port, sock);
 830            if (id < 0) continue;
 831
 832            for (j = ns = 0; j < 2; j++) {
 833                /* Does the socket exist? */
 834                if ((ignore == i+j) || (identify(port, sock+j) < 0))
 835                    continue;
 836                /* Check for bad socket decode */
 837                for (k = 0; k <= sockets; k++)
 838                    i365_set(k, I365_MEM(0)+I365_W_OFF, k);
 839                for (k = 0; k <= sockets; k++)
 840                    if (i365_get(k, I365_MEM(0)+I365_W_OFF) != k)
 841                        break;
 842                if (k <= sockets) break;
 843                add_socket(port, sock+j, id); ns++;
 844            }
 845            if (ns != 0) add_pcic(ns, id);
 846        }
 847    }
 848}
 849
 850/*====================================================================*/
 851
 852static irqreturn_t pcic_interrupt(int irq, void *dev,
 853                                    struct pt_regs *regs)
 854{
 855    int i, j, csc;
 856    u_int events, active;
 857    u_long flags = 0;
 858    int handled = 0;
 859
 860    debug(4, "pcic_interrupt(%d)\n", irq);
 861
 862    for (j = 0; j < 20; j++) {
 863        active = 0;
 864        for (i = 0; i < sockets; i++) {
 865            if (socket[i].cs_irq != irq)
 866                continue;
 867            handled = 1;
 868            ISA_LOCK(i, flags);
 869            csc = i365_get(i, I365_CSC);
 870            if ((csc == 0) || (i365_get(i, I365_IDENT) & 0x70)) {
 871                ISA_UNLOCK(i, flags);
 872                continue;
 873            }
 874            events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
 875
 876            if (i365_get(i, I365_INTCTL) & I365_PC_IOCARD)
 877                events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
 878            else {
 879                events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
 880                events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
 881                events |= (csc & I365_CSC_READY) ? SS_READY : 0;
 882            }
 883            ISA_UNLOCK(i, flags);
 884            debug(2, "socket %d event 0x%02x\n", i, events);
 885
 886            if (events)
 887                pcmcia_parse_events(&socket[i].socket, events);
 888
 889            active |= events;
 890        }
 891        if (!active) break;
 892    }
 893    if (j == 20)
 894        printk(KERN_NOTICE "i82365: infinite loop in interrupt handler\n");
 895
 896    debug(4, "interrupt done\n");
 897    return IRQ_RETVAL(handled);
 898} /* pcic_interrupt */
 899
 900static void pcic_interrupt_wrapper(u_long data)
 901{
 902    pcic_interrupt(0, NULL, NULL);
 903    poll_timer.expires = jiffies + poll_interval;
 904    add_timer(&poll_timer);
 905}
 906
 907/*====================================================================*/
 908
 909static int i365_get_status(u_short sock, u_int *value)
 910{
 911    u_int status;
 912    
 913    status = i365_get(sock, I365_STATUS);
 914    *value = ((status & I365_CS_DETECT) == I365_CS_DETECT)
 915        ? SS_DETECT : 0;
 916        
 917    if (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD)
 918        *value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
 919    else {
 920        *value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
 921        *value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
 922    }
 923    *value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
 924    *value |= (status & I365_CS_READY) ? SS_READY : 0;
 925    *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
 926
 927    if (socket[sock].type == IS_VG469) {
 928        status = i365_get(sock, VG469_VSENSE);
 929        if (socket[sock].psock & 1) {
 930            *value |= (status & VG469_VSENSE_B_VS1) ? 0 : SS_3VCARD;
 931            *value |= (status & VG469_VSENSE_B_VS2) ? 0 : SS_XVCARD;
 932        } else {
 933            *value |= (status & VG469_VSENSE_A_VS1) ? 0 : SS_3VCARD;
 934            *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD;
 935        }
 936    }
 937    
 938    debug(1, "GetStatus(%d) = %#4.4x\n", sock, *value);
 939    return 0;
 940} /* i365_get_status */
 941
 942/*====================================================================*/
 943
 944static int i365_get_socket(u_short sock, socket_state_t *state)
 945{
 946    struct i82365_socket *t = &socket[sock];
 947    u_char reg, vcc, vpp;
 948    
 949    reg = i365_get(sock, I365_POWER);
 950    state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
 951    state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
 952    vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK;
 953    state->Vcc = state->Vpp = 0;
 954    if (t->flags & IS_CIRRUS) {
 955        if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) {
 956            if (reg & I365_VCC_5V) state->Vcc = 33;
 957            if (vpp == I365_VPP1_5V) state->Vpp = 33;
 958        } else {
 959            if (reg & I365_VCC_5V) state->Vcc = 50;
 960            if (vpp == I365_VPP1_5V) state->Vpp = 50;
 961        }
 962        if (vpp == I365_VPP1_12V) state->Vpp = 120;
 963    } else if (t->flags & IS_VG_PWR) {
 964        if (i365_get(sock, VG469_VSELECT) & VG469_VSEL_VCC) {
 965            if (reg & I365_VCC_5V) state->Vcc = 33;
 966            if (vpp == I365_VPP1_5V) state->Vpp = 33;
 967        } else {
 968            if (reg & I365_VCC_5V) state->Vcc = 50;
 969            if (vpp == I365_VPP1_5V) state->Vpp = 50;
 970        }
 971        if (vpp == I365_VPP1_12V) state->Vpp = 120;
 972    } else if (t->flags & IS_DF_PWR) {
 973        if (vcc == I365_VCC_3V) state->Vcc = 33;
 974        if (vcc == I365_VCC_5V) state->Vcc = 50;
 975        if (vpp == I365_VPP1_5V) state->Vpp = 50;
 976        if (vpp == I365_VPP1_12V) state->Vpp = 120;
 977    } else {
 978        if (reg & I365_VCC_5V) {
 979            state->Vcc = 50;
 980            if (vpp == I365_VPP1_5V) state->Vpp = 50;
 981            if (vpp == I365_VPP1_12V) state->Vpp = 120;
 982        }
 983    }
 984
 985    /* IO card, RESET flags, IO interrupt */
 986    reg = i365_get(sock, I365_INTCTL);
 987    state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
 988    if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD;
 989    state->io_irq = reg & I365_IRQ_MASK;
 990    
 991    /* speaker control */
 992    if (t->flags & IS_CIRRUS) {
 993        if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA)
 994            state->flags |= SS_SPKR_ENA;
 995    }
 996    
 997    /* Card status change mask */
 998    reg = i365_get(sock, I365_CSCINT);
 999    state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
1000    if (state->flags & SS_IOCARD)
1001        state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
1002    else {
1003        state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
1004        state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
1005        state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
1006    }
1007    
1008    debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
1009          "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
1010          state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
1011    return 0;
1012} /* i365_get_socket */
1013
1014/*====================================================================*/
1015
1016static int i365_set_socket(u_short sock, socket_state_t *state)
1017{
1018    struct i82365_socket *t = &socket[sock];
1019    u_char reg;
1020    
1021    debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
1022          "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
1023          state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
1024    
1025    /* First set global controller options */
1026    set_bridge_state(sock);
1027    
1028    /* IO card, RESET flag, IO interrupt */
1029    reg = t->intr;
1030    reg |= state->io_irq;
1031    reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
1032    reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
1033    i365_set(sock, I365_INTCTL, reg);
1034    
1035    reg = I365_PWR_NORESET;
1036    if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
1037    if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
1038
1039    if (t->flags & IS_CIRRUS) {
1040        if (state->Vpp != 0) {
1041            if (state->Vpp == 120)
1042                reg |= I365_VPP1_12V;
1043            else if (state->Vpp == state->Vcc)
1044                reg |= I365_VPP1_5V;
1045            else return -EINVAL;
1046        }
1047        if (state->Vcc != 0) {
1048            reg |= I365_VCC_5V;
1049            if (state->Vcc == 33)
1050                i365_bset(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
1051            else if (state->Vcc == 50)
1052                i365_bclr(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
1053            else return -EINVAL;
1054        }
1055    } else if (t->flags & IS_VG_PWR) {
1056        if (state->Vpp != 0) {
1057            if (state->Vpp == 120)
1058                reg |= I365_VPP1_12V;
1059            else if (state->Vpp == state->Vcc)
1060                reg |= I365_VPP1_5V;
1061            else return -EINVAL;
1062        }
1063        if (state->Vcc != 0) {
1064            reg |= I365_VCC_5V;
1065            if (state->Vcc == 33)
1066                i365_bset(sock, VG469_VSELECT, VG469_VSEL_VCC);
1067            else if (state->Vcc == 50)
1068                i365_bclr(sock, VG469_VSELECT, VG469_VSEL_VCC);
1069            else return -EINVAL;
1070        }
1071    } else if (t->flags & IS_DF_PWR) {
1072        switch (state->Vcc) {
1073        case 0:         break;
1074        case 33:        reg |= I365_VCC_3V; break;
1075        case 50:        reg |= I365_VCC_5V; break;
1076        default:        return -EINVAL;
1077        }
1078        switch (state->Vpp) {
1079        case 0:         break;
1080        case 50:        reg |= I365_VPP1_5V; break;
1081        case 120:       reg |= I365_VPP1_12V; break;
1082        default:        return -EINVAL;
1083        }
1084    } else {
1085        switch (state->Vcc) {
1086        case 0:         break;
1087        case 50:        reg |= I365_VCC_5V; break;
1088        default:        return -EINVAL;
1089        }
1090        switch (state->Vpp) {
1091        case 0:         break;
1092        case 50:        reg |= I365_VPP1_5V | I365_VPP2_5V; break;
1093        case 120:       reg |= I365_VPP1_12V | I365_VPP2_12V; break;
1094        default:        return -EINVAL;
1095        }
1096    }
1097    
1098    if (reg != i365_get(sock, I365_POWER))
1099        i365_set(sock, I365_POWER, reg);
1100
1101    /* Chipset-specific functions */
1102    if (t->flags & IS_CIRRUS) {
1103        /* Speaker control */
1104        i365_bflip(sock, PD67_MISC_CTL_1, PD67_MC1_SPKR_ENA,
1105                   state->flags & SS_SPKR_ENA);
1106    }
1107    
1108    /* Card status change interrupt mask */
1109    reg = t->cs_irq << 4;
1110    if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;
1111    if (state->flags & SS_IOCARD) {
1112        if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
1113    } else {
1114        if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;
1115        if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;
1116        if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;
1117    }
1118    i365_set(sock, I365_CSCINT, reg);
1119    i365_get(sock, I365_CSC);
1120    
1121    return 0;
1122} /* i365_set_socket */
1123
1124/*====================================================================*/
1125
1126static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
1127{
1128    u_char map, ioctl;
1129    
1130    debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
1131          "%#lx-%#lx)\n", sock, io->map, io->flags,
1132          io->speed, io->start, io->stop);
1133    map = io->map;
1134    if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
1135        (io->stop < io->start)) return -EINVAL;
1136    /* Turn off the window before changing anything */
1137    if (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(map))
1138        i365_bclr(sock, I365_ADDRWIN, I365_ENA_IO(map));
1139    i365_set_pair(sock, I365_IO(map)+I365_W_START, io->start);
1140    i365_set_pair(sock, I365_IO(map)+I365_W_STOP, io->stop);
1141    ioctl = i365_get(sock, I365_IOCTL) & ~I365_IOCTL_MASK(map);
1142    if (io->speed) ioctl |= I365_IOCTL_WAIT(map);
1143    if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
1144    if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
1145    if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
1146    i365_set(sock, I365_IOCTL, ioctl);
1147    /* Turn on the window if necessary */
1148    if (io->flags & MAP_ACTIVE)
1149        i365_bset(sock, I365_ADDRWIN, I365_ENA_IO(map));
1150    return 0;
1151} /* i365_set_io_map */
1152
1153/*====================================================================*/
1154
1155static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
1156{
1157    u_short base, i;
1158    u_char map;
1159    
1160    debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#lx-%#lx, "
1161          "%#x)\n", sock, mem->map, mem->flags, mem->speed,
1162          mem->res->start, mem->res->end, mem->card_start);
1163
1164    map = mem->map;
1165    if ((map > 4) || (mem->card_start > 0x3ffffff) ||
1166        (mem->res->start > mem->res->end) || (mem->speed > 1000))
1167        return -EINVAL;
1168    if ((mem->res->start > 0xffffff) || (mem->res->end > 0xffffff))
1169        return -EINVAL;
1170        
1171    /* Turn off the window before changing anything */
1172    if (i365_get(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
1173        i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map));
1174    
1175    base = I365_MEM(map);
1176    i = (mem->res->start >> 12) & 0x0fff;
1177    if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT;
1178    if (mem->flags & MAP_0WS) i |= I365_MEM_0WS;
1179    i365_set_pair(sock, base+I365_W_START, i);
1180    
1181    i = (mem->res->end >> 12) & 0x0fff;
1182    switch (to_cycles(mem->speed)) {
1183    case 0:     break;
1184    case 1:     i |= I365_MEM_WS0; break;
1185    case 2:     i |= I365_MEM_WS1; break;
1186    default:    i |= I365_MEM_WS1 | I365_MEM_WS0; break;
1187    }
1188    i365_set_pair(sock, base+I365_W_STOP, i);
1189    
1190    i = ((mem->card_start - mem->res->start) >> 12) & 0x3fff;
1191    if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT;
1192    if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG;
1193    i365_set_pair(sock, base+I365_W_OFF, i);
1194    
1195    /* Turn on the window if necessary */
1196    if (mem->flags & MAP_ACTIVE)
1197        i365_bset(sock, I365_ADDRWIN, I365_ENA_MEM(map));
1198    return 0;
1199} /* i365_set_mem_map */
1200
1201#if 0 /* driver model ordering issue */
1202/*======================================================================
1203
1204    Routines for accessing socket information and register dumps via
1205    /sys/class/pcmcia_socket/...
1206    
1207======================================================================*/
1208
1209static ssize_t show_info(struct class_device *class_dev, char *buf)
1210{
1211        struct i82365_socket *s = container_of(class_dev, struct i82365_socket, socket.dev);
1212        return sprintf(buf, "type:     %s\npsock:    %d\n",
1213                       pcic[s->type].name, s->psock);
1214}
1215
1216static ssize_t show_exca(struct class_device *class_dev, char *buf)
1217{
1218        struct i82365_socket *s = container_of(class_dev, struct i82365_socket, socket.dev);
1219        unsigned short sock;
1220        int i;
1221        ssize_t ret = 0;
1222        unsigned long flags = 0;
1223
1224        sock = s->number;
1225
1226        ISA_LOCK(sock, flags);
1227        for (i = 0; i < 0x40; i += 4) {
1228                ret += sprintf(buf, "%02x %02x %02x %02x%s",
1229                               i365_get(sock,i), i365_get(sock,i+1),
1230                               i365_get(sock,i+2), i365_get(sock,i+3),
1231                               ((i % 16) == 12) ? "\n" : " ");
1232                buf += ret;
1233        }
1234        ISA_UNLOCK(sock, flags);
1235
1236        return ret;
1237}
1238
1239static CLASS_DEVICE_ATTR(exca, S_IRUGO, show_exca, NULL);
1240static CLASS_DEVICE_ATTR(info, S_IRUGO, show_info, NULL);
1241#endif
1242
1243/*====================================================================*/
1244
1245/* this is horribly ugly... proper locking needs to be done here at 
1246 * some time... */
1247#define LOCKED(x) do { \
1248        int retval; \
1249        unsigned long flags; \
1250        spin_lock_irqsave(&isa_lock, flags); \
1251        retval = x; \
1252        spin_unlock_irqrestore(&isa_lock, flags); \
1253        return retval; \
1254} while (0)
1255        
1256
1257static int pcic_get_status(struct pcmcia_socket *s, u_int *value)
1258{
1259        unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1260
1261        if (socket[sock].flags & IS_ALIVE) {
1262                *value = 0;
1263                return -EINVAL;
1264        }
1265
1266        LOCKED(i365_get_status(sock, value));
1267}
1268
1269static int pcic_get_socket(struct pcmcia_socket *s, socket_state_t *state)
1270{
1271        unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1272
1273        if (socket[sock].flags & IS_ALIVE)
1274                return -EINVAL;
1275
1276        LOCKED(i365_get_socket(sock, state));
1277}
1278
1279static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state)
1280{
1281        unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1282
1283        if (socket[sock].flags & IS_ALIVE)
1284                return -EINVAL;
1285
1286        LOCKED(i365_set_socket(sock, state));
1287}
1288
1289static int pcic_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
1290{
1291        unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1292        if (socket[sock].flags & IS_ALIVE)
1293                return -EINVAL;
1294
1295        LOCKED(i365_set_io_map(sock, io));
1296}
1297
1298static int pcic_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
1299{
1300        unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1301        if (socket[sock].flags & IS_ALIVE)
1302                return -EINVAL;
1303
1304        LOCKED(i365_set_mem_map(sock, mem));
1305}
1306
1307static int pcic_init(struct pcmcia_socket *s)
1308{
1309        int i;
1310        struct resource res = { .start = 0, .end = 0x1000 };
1311        pccard_io_map io = { 0, 0, 0, 0, 1 };
1312        pccard_mem_map mem = { .res = &res, };
1313
1314        for (i = 0; i < 2; i++) {
1315                io.map = i;
1316                pcic_set_io_map(s, &io);
1317        }
1318        for (i = 0; i < 5; i++) {
1319                mem.map = i;
1320                pcic_set_mem_map(s, &mem);
1321        }
1322        return 0;
1323}
1324
1325static int pcic_suspend(struct pcmcia_socket *sock)
1326{
1327        return pcic_set_socket(sock, &dead_socket);
1328}
1329
1330static struct pccard_operations pcic_operations = {
1331        .init                   = pcic_init,
1332        .suspend                = pcic_suspend,
1333        .get_status             = pcic_get_status,
1334        .get_socket             = pcic_get_socket,
1335        .set_socket             = pcic_set_socket,
1336        .set_io_map             = pcic_set_io_map,
1337        .set_mem_map            = pcic_set_mem_map,
1338};
1339
1340/*====================================================================*/
1341
1342static int i82365_suspend(struct device *dev, u32 state, u32 level)
1343{
1344        int ret = 0;
1345        if (level == SUSPEND_SAVE_STATE)
1346                ret = pcmcia_socket_dev_suspend(dev, state);
1347        return ret;
1348}
1349
1350static int i82365_resume(struct device *dev, u32 level)
1351{
1352        int ret = 0;
1353        if (level == RESUME_RESTORE_STATE)
1354                ret = pcmcia_socket_dev_resume(dev);
1355        return ret;
1356}
1357
1358static struct device_driver i82365_driver = {
1359        .name = "i82365",
1360        .bus = &platform_bus_type,
1361        .suspend = i82365_suspend,
1362        .resume = i82365_resume,
1363};
1364
1365static struct platform_device i82365_device = {
1366        .name = "i82365",
1367        .id = 0,
1368};
1369
1370static int __init init_i82365(void)
1371{
1372    int i, ret;
1373
1374    ret = driver_register(&i82365_driver);
1375    if (ret)
1376        return ret;
1377
1378    ret = platform_device_register(&i82365_device);
1379    if (ret) {
1380        driver_unregister(&i82365_driver);
1381        return ret;
1382    }
1383
1384    printk(KERN_INFO "Intel ISA PCIC probe: ");
1385    sockets = 0;
1386
1387    isa_probe();
1388
1389    if (sockets == 0) {
1390        printk("not found.\n");
1391        platform_device_unregister(&i82365_device);
1392        driver_unregister(&i82365_driver);
1393        return -ENODEV;
1394    }
1395
1396    /* Set up interrupt handler(s) */
1397    if (grab_irq != 0)
1398        request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
1399    
1400    /* register sockets with the pcmcia core */
1401    for (i = 0; i < sockets; i++) {
1402            socket[i].socket.dev.dev = &i82365_device.dev;
1403            socket[i].socket.ops = &pcic_operations;
1404            socket[i].socket.resource_ops = &pccard_nonstatic_ops;
1405            socket[i].socket.owner = THIS_MODULE;
1406            socket[i].number = i;
1407            ret = pcmcia_register_socket(&socket[i].socket);
1408            if (!ret)
1409                    socket[i].flags |= IS_REGISTERED;
1410
1411#if 0 /* driver model ordering issue */
1412           class_device_create_file(&socket[i].socket.dev,
1413                                    &class_device_attr_info);
1414           class_device_create_file(&socket[i].socket.dev,
1415                                    &class_device_attr_exca);
1416#endif
1417    }
1418
1419    /* Finally, schedule a polling interrupt */
1420    if (poll_interval != 0) {
1421        poll_timer.function = pcic_interrupt_wrapper;
1422        poll_timer.data = 0;
1423        init_timer(&poll_timer);
1424        poll_timer.expires = jiffies + poll_interval;
1425        add_timer(&poll_timer);
1426    }
1427    
1428    return 0;
1429    
1430} /* init_i82365 */
1431
1432static void __exit exit_i82365(void)
1433{
1434    int i;
1435
1436    for (i = 0; i < sockets; i++) {
1437            if (socket[i].flags & IS_REGISTERED)
1438                    pcmcia_unregister_socket(&socket[i].socket);
1439    }
1440    platform_device_unregister(&i82365_device);
1441    if (poll_interval != 0)
1442        del_timer_sync(&poll_timer);
1443    if (grab_irq != 0)
1444        free_irq(cs_irq, pcic_interrupt);
1445    for (i = 0; i < sockets; i++) {
1446        /* Turn off all interrupt sources! */
1447        i365_set(i, I365_CSCINT, 0);
1448        release_region(socket[i].ioaddr, 2);
1449    }
1450#ifdef CONFIG_PNP
1451    if (i82365_pnpdev)
1452                pnp_disable_dev(i82365_pnpdev);
1453#endif
1454    driver_unregister(&i82365_driver);
1455} /* exit_i82365 */
1456
1457module_init(init_i82365);
1458module_exit(exit_i82365);
1459MODULE_LICENSE("Dual MPL/GPL");
1460/*====================================================================*/
1461
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.