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