Back to home page

OSCL-LXR

 
 

    


0001 /*======================================================================
0002 
0003     Device driver for Intel 82365 and compatible PC Card controllers.
0004 
0005     i82365.c 1.265 1999/11/10 18:36:21
0006 
0007     The contents of this file are subject to the Mozilla Public
0008     License Version 1.1 (the "License"); you may not use this file
0009     except in compliance with the License. You may obtain a copy of
0010     the License at http://www.mozilla.org/MPL/
0011 
0012     Software distributed under the License is distributed on an "AS
0013     IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
0014     implied. See the License for the specific language governing
0015     rights and limitations under the License.
0016 
0017     The initial developer of the original code is David A. Hinds
0018     <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
0019     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
0020 
0021     Alternatively, the contents of this file may be used under the
0022     terms of the GNU General Public License version 2 (the "GPL"), in which
0023     case the provisions of the GPL are applicable instead of the
0024     above.  If you wish to allow the use of your version of this file
0025     only under the terms of the GPL and not to allow others to use
0026     your version of this file under the MPL, indicate your decision
0027     by deleting the provisions above and replace them with the notice
0028     and other provisions required by the GPL.  If you do not delete
0029     the provisions above, a recipient may use your version of this
0030     file under either the MPL or the GPL.
0031     
0032 ======================================================================*/
0033 
0034 #include <linux/module.h>
0035 #include <linux/moduleparam.h>
0036 #include <linux/init.h>
0037 #include <linux/types.h>
0038 #include <linux/fcntl.h>
0039 #include <linux/string.h>
0040 #include <linux/kernel.h>
0041 #include <linux/errno.h>
0042 #include <linux/timer.h>
0043 #include <linux/ioport.h>
0044 #include <linux/delay.h>
0045 #include <linux/workqueue.h>
0046 #include <linux/interrupt.h>
0047 #include <linux/platform_device.h>
0048 #include <linux/bitops.h>
0049 #include <asm/irq.h>
0050 #include <asm/io.h>
0051 
0052 #include <pcmcia/ss.h>
0053 
0054 #include <linux/isapnp.h>
0055 
0056 /* ISA-bus controllers */
0057 #include "i82365.h"
0058 #include "cirrus.h"
0059 #include "vg468.h"
0060 #include "ricoh.h"
0061 
0062 
0063 static irqreturn_t i365_count_irq(int, void *);
0064 static inline int _check_irq(int irq, int flags)
0065 {
0066     if (request_irq(irq, i365_count_irq, flags, "x", i365_count_irq) != 0)
0067     return -1;
0068     free_irq(irq, i365_count_irq);
0069     return 0;
0070 }
0071 
0072 /*====================================================================*/
0073 
0074 /* Parameters that can be set with 'insmod' */
0075 
0076 /* Default base address for i82365sl and other ISA chips */
0077 static unsigned long i365_base = 0x3e0;
0078 /* Should we probe at 0x3e2 for an extra ISA controller? */
0079 static int extra_sockets = 0;
0080 /* Specify a socket number to ignore */
0081 static int ignore = -1;
0082 /* Bit map or list of interrupts to choose from */
0083 static u_int irq_mask = 0xffff;
0084 static int irq_list[16];
0085 static unsigned int irq_list_count;
0086 /* The card status change interrupt -- 0 means autoselect */
0087 static int cs_irq = 0;
0088 
0089 /* Probe for safe interrupts? */
0090 static int do_scan = 1;
0091 /* Poll status interval -- 0 means default to interrupt */
0092 static int poll_interval = 0;
0093 /* External clock time, in nanoseconds.  120 ns = 8.33 MHz */
0094 static int cycle_time = 120;
0095 
0096 /* Cirrus options */
0097 static int has_dma = -1;
0098 static int has_led = -1;
0099 static int has_ring = -1;
0100 static int dynamic_mode = 0;
0101 static int freq_bypass = -1;
0102 static int setup_time = -1;
0103 static int cmd_time = -1;
0104 static int recov_time = -1;
0105 
0106 /* Vadem options */
0107 static int async_clock = -1;
0108 static int cable_mode = -1;
0109 static int wakeup = 0;
0110 
0111 module_param_hw(i365_base, ulong, ioport, 0444);
0112 module_param(ignore, int, 0444);
0113 module_param(extra_sockets, int, 0444);
0114 module_param_hw(irq_mask, int, other, 0444);
0115 module_param_hw_array(irq_list, int, irq, &irq_list_count, 0444);
0116 module_param_hw(cs_irq, int, irq, 0444);
0117 module_param(async_clock, int, 0444);
0118 module_param(cable_mode, int, 0444);
0119 module_param(wakeup, int, 0444);
0120 
0121 module_param(do_scan, int, 0444);
0122 module_param(poll_interval, int, 0444);
0123 module_param(cycle_time, int, 0444);
0124 module_param(has_dma, int, 0444);
0125 module_param(has_led, int, 0444);
0126 module_param(has_ring, int, 0444);
0127 module_param(dynamic_mode, int, 0444);
0128 module_param(freq_bypass, int, 0444);
0129 module_param(setup_time, int, 0444);
0130 module_param(cmd_time, int, 0444);
0131 module_param(recov_time, int, 0444);
0132 
0133 /*====================================================================*/
0134 
0135 struct cirrus_state {
0136     u_char      misc1, misc2;
0137     u_char      timer[6];
0138 };
0139 
0140 struct vg46x_state {
0141     u_char      ctl, ema;
0142 };
0143 
0144 struct i82365_socket {
0145     u_short     type, flags;
0146     struct pcmcia_socket    socket;
0147     unsigned int    number;
0148     unsigned int    ioaddr;
0149     u_short     psock;
0150     u_char      cs_irq, intr;
0151     union {
0152     struct cirrus_state     cirrus;
0153     struct vg46x_state      vg46x;
0154     } state;
0155 };
0156 
0157 /* Where we keep track of our sockets... */
0158 static int sockets = 0;
0159 static struct i82365_socket socket[8] = {
0160     { 0, }, /* ... */
0161 };
0162 
0163 /* Default ISA interrupt mask */
0164 #define I365_MASK   0xdeb8  /* irq 15,14,12,11,10,9,7,5,4,3 */
0165 
0166 static int grab_irq;
0167 static DEFINE_SPINLOCK(isa_lock);
0168 #define ISA_LOCK(n, f) spin_lock_irqsave(&isa_lock, f)
0169 #define ISA_UNLOCK(n, f) spin_unlock_irqrestore(&isa_lock, f)
0170 
0171 static struct timer_list poll_timer;
0172 
0173 /*====================================================================*/
0174 
0175 /* These definitions must match the pcic table! */
0176 enum pcic_id {
0177     IS_I82365A, IS_I82365B, IS_I82365DF,
0178     IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469,
0179     IS_PD6710, IS_PD672X, IS_VT83C469,
0180 };
0181 
0182 /* Flags for classifying groups of controllers */
0183 #define IS_VADEM    0x0001
0184 #define IS_CIRRUS   0x0002
0185 #define IS_VIA      0x0010
0186 #define IS_UNKNOWN  0x0400
0187 #define IS_VG_PWR   0x0800
0188 #define IS_DF_PWR   0x1000
0189 #define IS_REGISTERED   0x2000
0190 #define IS_ALIVE    0x8000
0191 
0192 struct pcic {
0193     char        *name;
0194     u_short     flags;
0195 };
0196 
0197 static struct pcic pcic[] = {
0198     { "Intel i82365sl A step", 0 },
0199     { "Intel i82365sl B step", 0 },
0200     { "Intel i82365sl DF", IS_DF_PWR },
0201     { "IBM Clone", 0 },
0202     { "Ricoh RF5C296/396", 0 },
0203     { "VLSI 82C146", 0 },
0204     { "Vadem VG-468", IS_VADEM },
0205     { "Vadem VG-469", IS_VADEM|IS_VG_PWR },
0206     { "Cirrus PD6710", IS_CIRRUS },
0207     { "Cirrus PD672x", IS_CIRRUS },
0208     { "VIA VT83C469", IS_CIRRUS|IS_VIA },
0209 };
0210 
0211 #define PCIC_COUNT  ARRAY_SIZE(pcic)
0212 
0213 /*====================================================================*/
0214 
0215 static DEFINE_SPINLOCK(bus_lock);
0216 
0217 static u_char i365_get(u_short sock, u_short reg)
0218 {
0219     unsigned long flags;
0220     spin_lock_irqsave(&bus_lock,flags);
0221     {
0222     unsigned int port = socket[sock].ioaddr;
0223     u_char val;
0224     reg = I365_REG(socket[sock].psock, reg);
0225     outb(reg, port); val = inb(port+1);
0226     spin_unlock_irqrestore(&bus_lock,flags);
0227     return val;
0228     }
0229 }
0230 
0231 static void i365_set(u_short sock, u_short reg, u_char data)
0232 {
0233     unsigned long flags;
0234     spin_lock_irqsave(&bus_lock,flags);
0235     {
0236     unsigned int port = socket[sock].ioaddr;
0237     u_char val = I365_REG(socket[sock].psock, reg);
0238     outb(val, port); outb(data, port+1);
0239     spin_unlock_irqrestore(&bus_lock,flags);
0240     }
0241 }
0242 
0243 static void i365_bset(u_short sock, u_short reg, u_char mask)
0244 {
0245     u_char d = i365_get(sock, reg);
0246     d |= mask;
0247     i365_set(sock, reg, d);
0248 }
0249 
0250 static void i365_bclr(u_short sock, u_short reg, u_char mask)
0251 {
0252     u_char d = i365_get(sock, reg);
0253     d &= ~mask;
0254     i365_set(sock, reg, d);
0255 }
0256 
0257 static void i365_bflip(u_short sock, u_short reg, u_char mask, int b)
0258 {
0259     u_char d = i365_get(sock, reg);
0260     if (b)
0261     d |= mask;
0262     else
0263     d &= ~mask;
0264     i365_set(sock, reg, d);
0265 }
0266 
0267 static u_short i365_get_pair(u_short sock, u_short reg)
0268 {
0269     u_short a, b;
0270     a = i365_get(sock, reg);
0271     b = i365_get(sock, reg+1);
0272     return (a + (b<<8));
0273 }
0274 
0275 static void i365_set_pair(u_short sock, u_short reg, u_short data)
0276 {
0277     i365_set(sock, reg, data & 0xff);
0278     i365_set(sock, reg+1, data >> 8);
0279 }
0280 
0281 /*======================================================================
0282 
0283     Code to save and restore global state information for Cirrus
0284     PD67xx controllers, and to set and report global configuration
0285     options.
0286 
0287     The VIA controllers also use these routines, as they are mostly
0288     Cirrus lookalikes, without the timing registers.
0289     
0290 ======================================================================*/
0291 
0292 #define flip(v,b,f) (v = ((f)<0) ? v : ((f) ? ((v)|(b)) : ((v)&(~b))))
0293 
0294 static void cirrus_get_state(u_short s)
0295 {
0296     int i;
0297     struct cirrus_state *p = &socket[s].state.cirrus;
0298     p->misc1 = i365_get(s, PD67_MISC_CTL_1);
0299     p->misc1 &= (PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
0300     p->misc2 = i365_get(s, PD67_MISC_CTL_2);
0301     for (i = 0; i < 6; i++)
0302     p->timer[i] = i365_get(s, PD67_TIME_SETUP(0)+i);
0303 }
0304 
0305 static void cirrus_set_state(u_short s)
0306 {
0307     int i;
0308     u_char misc;
0309     struct cirrus_state *p = &socket[s].state.cirrus;
0310 
0311     misc = i365_get(s, PD67_MISC_CTL_2);
0312     i365_set(s, PD67_MISC_CTL_2, p->misc2);
0313     if (misc & PD67_MC2_SUSPEND) mdelay(50);
0314     misc = i365_get(s, PD67_MISC_CTL_1);
0315     misc &= ~(PD67_MC1_MEDIA_ENA | PD67_MC1_INPACK_ENA);
0316     i365_set(s, PD67_MISC_CTL_1, misc | p->misc1);
0317     for (i = 0; i < 6; i++)
0318     i365_set(s, PD67_TIME_SETUP(0)+i, p->timer[i]);
0319 }
0320 
0321 static u_int __init cirrus_set_opts(u_short s, char *buf)
0322 {
0323     struct i82365_socket *t = &socket[s];
0324     struct cirrus_state *p = &socket[s].state.cirrus;
0325     u_int mask = 0xffff;
0326 
0327     if (has_ring == -1) has_ring = 1;
0328     flip(p->misc2, PD67_MC2_IRQ15_RI, has_ring);
0329     flip(p->misc2, PD67_MC2_DYNAMIC_MODE, dynamic_mode);
0330     flip(p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass);
0331     if (p->misc2 & PD67_MC2_IRQ15_RI)
0332     strcat(buf, " [ring]");
0333     if (p->misc2 & PD67_MC2_DYNAMIC_MODE)
0334     strcat(buf, " [dyn mode]");
0335     if (p->misc2 & PD67_MC2_FREQ_BYPASS)
0336     strcat(buf, " [freq bypass]");
0337     if (p->misc1 & PD67_MC1_INPACK_ENA)
0338     strcat(buf, " [inpack]");
0339     if (p->misc2 & PD67_MC2_IRQ15_RI)
0340     mask &= ~0x8000;
0341     if (has_led > 0) {
0342     strcat(buf, " [led]");
0343     mask &= ~0x1000;
0344     }
0345     if (has_dma > 0) {
0346     strcat(buf, " [dma]");
0347     mask &= ~0x0600;
0348     }
0349     if (!(t->flags & IS_VIA)) {
0350     if (setup_time >= 0)
0351         p->timer[0] = p->timer[3] = setup_time;
0352     if (cmd_time > 0) {
0353         p->timer[1] = cmd_time;
0354         p->timer[4] = cmd_time*2+4;
0355     }
0356     if (p->timer[1] == 0) {
0357         p->timer[1] = 6; p->timer[4] = 16;
0358         if (p->timer[0] == 0)
0359         p->timer[0] = p->timer[3] = 1;
0360     }
0361     if (recov_time >= 0)
0362         p->timer[2] = p->timer[5] = recov_time;
0363     buf += strlen(buf);
0364     sprintf(buf, " [%d/%d/%d] [%d/%d/%d]", p->timer[0], p->timer[1],
0365         p->timer[2], p->timer[3], p->timer[4], p->timer[5]);
0366     }
0367     return mask;
0368 }
0369 
0370 /*======================================================================
0371 
0372     Code to save and restore global state information for Vadem VG468
0373     and VG469 controllers, and to set and report global configuration
0374     options.
0375     
0376 ======================================================================*/
0377 
0378 static void vg46x_get_state(u_short s)
0379 {
0380     struct vg46x_state *p = &socket[s].state.vg46x;
0381     p->ctl = i365_get(s, VG468_CTL);
0382     if (socket[s].type == IS_VG469)
0383     p->ema = i365_get(s, VG469_EXT_MODE);
0384 }
0385 
0386 static void vg46x_set_state(u_short s)
0387 {
0388     struct vg46x_state *p = &socket[s].state.vg46x;
0389     i365_set(s, VG468_CTL, p->ctl);
0390     if (socket[s].type == IS_VG469)
0391     i365_set(s, VG469_EXT_MODE, p->ema);
0392 }
0393 
0394 static u_int __init vg46x_set_opts(u_short s, char *buf)
0395 {
0396     struct vg46x_state *p = &socket[s].state.vg46x;
0397     
0398     flip(p->ctl, VG468_CTL_ASYNC, async_clock);
0399     flip(p->ema, VG469_MODE_CABLE, cable_mode);
0400     if (p->ctl & VG468_CTL_ASYNC)
0401     strcat(buf, " [async]");
0402     if (p->ctl & VG468_CTL_INPACK)
0403     strcat(buf, " [inpack]");
0404     if (socket[s].type == IS_VG469) {
0405     u_char vsel = i365_get(s, VG469_VSELECT);
0406     if (vsel & VG469_VSEL_EXT_STAT) {
0407         strcat(buf, " [ext mode]");
0408         if (vsel & VG469_VSEL_EXT_BUS)
0409         strcat(buf, " [isa buf]");
0410     }
0411     if (p->ema & VG469_MODE_CABLE)
0412         strcat(buf, " [cable]");
0413     if (p->ema & VG469_MODE_COMPAT)
0414         strcat(buf, " [c step]");
0415     }
0416     return 0xffff;
0417 }
0418 
0419 /*======================================================================
0420 
0421     Generic routines to get and set controller options
0422     
0423 ======================================================================*/
0424 
0425 static void get_bridge_state(u_short s)
0426 {
0427     struct i82365_socket *t = &socket[s];
0428     if (t->flags & IS_CIRRUS)
0429     cirrus_get_state(s);
0430     else if (t->flags & IS_VADEM)
0431     vg46x_get_state(s);
0432 }
0433 
0434 static void set_bridge_state(u_short s)
0435 {
0436     struct i82365_socket *t = &socket[s];
0437     if (t->flags & IS_CIRRUS)
0438     cirrus_set_state(s);
0439     else {
0440     i365_set(s, I365_GBLCTL, 0x00);
0441     i365_set(s, I365_GENCTL, 0x00);
0442     }
0443     i365_bflip(s, I365_INTCTL, I365_INTR_ENA, t->intr);
0444     if (t->flags & IS_VADEM)
0445     vg46x_set_state(s);
0446 }
0447 
0448 static u_int __init set_bridge_opts(u_short s, u_short ns)
0449 {
0450     u_short i;
0451     u_int m = 0xffff;
0452     char buf[128];
0453 
0454     for (i = s; i < s+ns; i++) {
0455     if (socket[i].flags & IS_ALIVE) {
0456         printk(KERN_INFO "    host opts [%d]: already alive!\n", i);
0457         continue;
0458     }
0459     buf[0] = '\0';
0460     get_bridge_state(i);
0461     if (socket[i].flags & IS_CIRRUS)
0462         m = cirrus_set_opts(i, buf);
0463     else if (socket[i].flags & IS_VADEM)
0464         m = vg46x_set_opts(i, buf);
0465     set_bridge_state(i);
0466     printk(KERN_INFO "    host opts [%d]:%s\n", i,
0467            (*buf) ? buf : " none");
0468     }
0469     return m;
0470 }
0471 
0472 /*======================================================================
0473 
0474     Interrupt testing code, for ISA and PCI interrupts
0475     
0476 ======================================================================*/
0477 
0478 static volatile u_int irq_hits;
0479 static u_short irq_sock;
0480 
0481 static irqreturn_t i365_count_irq(int irq, void *dev)
0482 {
0483     i365_get(irq_sock, I365_CSC);
0484     irq_hits++;
0485     pr_debug("i82365: -> hit on irq %d\n", irq);
0486     return IRQ_HANDLED;
0487 }
0488 
0489 static u_int __init test_irq(u_short sock, int irq)
0490 {
0491     pr_debug("i82365:  testing ISA irq %d\n", irq);
0492     if (request_irq(irq, i365_count_irq, IRQF_PROBE_SHARED, "scan",
0493             i365_count_irq) != 0)
0494     return 1;
0495     irq_hits = 0; irq_sock = sock;
0496     msleep(10);
0497     if (irq_hits) {
0498     free_irq(irq, i365_count_irq);
0499     pr_debug("i82365:    spurious hit!\n");
0500     return 1;
0501     }
0502 
0503     /* Generate one interrupt */
0504     i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (irq << 4));
0505     i365_bset(sock, I365_GENCTL, I365_CTL_SW_IRQ);
0506     udelay(1000);
0507 
0508     free_irq(irq, i365_count_irq);
0509 
0510     /* mask all interrupts */
0511     i365_set(sock, I365_CSCINT, 0);
0512     pr_debug("i82365:    hits = %d\n", irq_hits);
0513     
0514     return (irq_hits != 1);
0515 }
0516 
0517 static u_int __init isa_scan(u_short sock, u_int mask0)
0518 {
0519     u_int mask1 = 0;
0520     int i;
0521 
0522 #ifdef __alpha__
0523 #define PIC 0x4d0
0524     /* Don't probe level-triggered interrupts -- reserved for PCI */
0525     mask0 &= ~(inb(PIC) | (inb(PIC+1) << 8));
0526 #endif
0527     
0528     if (do_scan) {
0529     set_bridge_state(sock);
0530     i365_set(sock, I365_CSCINT, 0);
0531     for (i = 0; i < 16; i++)
0532         if ((mask0 & (1 << i)) && (test_irq(sock, i) == 0))
0533         mask1 |= (1 << i);
0534     for (i = 0; i < 16; i++)
0535         if ((mask1 & (1 << i)) && (test_irq(sock, i) != 0))
0536         mask1 ^= (1 << i);
0537     }
0538     
0539     printk(KERN_INFO "    ISA irqs (");
0540     if (mask1) {
0541     printk("scanned");
0542     } else {
0543     /* Fallback: just find interrupts that aren't in use */
0544     for (i = 0; i < 16; i++)
0545         if ((mask0 & (1 << i)) && (_check_irq(i, IRQF_PROBE_SHARED) == 0))
0546         mask1 |= (1 << i);
0547     printk("default");
0548     /* If scan failed, default to polled status */
0549     if (!cs_irq && (poll_interval == 0)) poll_interval = HZ;
0550     }
0551     printk(") = ");
0552     
0553     for (i = 0; i < 16; i++)
0554     if (mask1 & (1<<i))
0555         printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
0556     if (mask1 == 0) printk("none!");
0557     
0558     return mask1;
0559 }
0560 
0561 /*====================================================================*/
0562 
0563 /* Time conversion functions */
0564 
0565 static int to_cycles(int ns)
0566 {
0567     return ns/cycle_time;
0568 }
0569 
0570 /*====================================================================*/
0571 
0572 static int __init identify(unsigned int port, u_short sock)
0573 {
0574     u_char val;
0575     int type = -1;
0576 
0577     /* Use the next free entry in the socket table */
0578     socket[sockets].ioaddr = port;
0579     socket[sockets].psock = sock;
0580     
0581     /* Wake up a sleepy Cirrus controller */
0582     if (wakeup) {
0583     i365_bclr(sockets, PD67_MISC_CTL_2, PD67_MC2_SUSPEND);
0584     /* Pause at least 50 ms */
0585     mdelay(50);
0586     }
0587     
0588     if ((val = i365_get(sockets, I365_IDENT)) & 0x70)
0589     return -1;
0590     switch (val) {
0591     case 0x82:
0592     type = IS_I82365A; break;
0593     case 0x83:
0594     type = IS_I82365B; break;
0595     case 0x84:
0596     type = IS_I82365DF; break;
0597     case 0x88: case 0x89: case 0x8a:
0598     type = IS_IBM; break;
0599     }
0600     
0601     /* Check for Vadem VG-468 chips */
0602     outb(0x0e, port);
0603     outb(0x37, port);
0604     i365_bset(sockets, VG468_MISC, VG468_MISC_VADEMREV);
0605     val = i365_get(sockets, I365_IDENT);
0606     if (val & I365_IDENT_VADEM) {
0607     i365_bclr(sockets, VG468_MISC, VG468_MISC_VADEMREV);
0608     type = ((val & 7) >= 4) ? IS_VG469 : IS_VG468;
0609     }
0610 
0611     /* Check for Ricoh chips */
0612     val = i365_get(sockets, RF5C_CHIP_ID);
0613     if ((val == RF5C_CHIP_RF5C296) || (val == RF5C_CHIP_RF5C396))
0614     type = IS_RF5Cx96;
0615     
0616     /* Check for Cirrus CL-PD67xx chips */
0617     i365_set(sockets, PD67_CHIP_INFO, 0);
0618     val = i365_get(sockets, PD67_CHIP_INFO);
0619     if ((val & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID) {
0620     val = i365_get(sockets, PD67_CHIP_INFO);
0621     if ((val & PD67_INFO_CHIP_ID) == 0) {
0622         type = (val & PD67_INFO_SLOTS) ? IS_PD672X : IS_PD6710;
0623         i365_set(sockets, PD67_EXT_INDEX, 0xe5);
0624         if (i365_get(sockets, PD67_EXT_INDEX) != 0xe5)
0625         type = IS_VT83C469;
0626     }
0627     }
0628     return type;
0629 } /* identify */
0630 
0631 /*======================================================================
0632 
0633     See if a card is present, powered up, in IO mode, and already
0634     bound to a (non PC Card) Linux driver.  We leave these alone.
0635 
0636     We make an exception for cards that seem to be serial devices.
0637     
0638 ======================================================================*/
0639 
0640 static int __init is_alive(u_short sock)
0641 {
0642     u_char stat;
0643     unsigned int start, stop;
0644     
0645     stat = i365_get(sock, I365_STATUS);
0646     start = i365_get_pair(sock, I365_IO(0)+I365_W_START);
0647     stop = i365_get_pair(sock, I365_IO(0)+I365_W_STOP);
0648     if ((stat & I365_CS_DETECT) && (stat & I365_CS_POWERON) &&
0649     (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD) &&
0650     (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(0)) &&
0651     ((start & 0xfeef) != 0x02e8)) {
0652     if (!request_region(start, stop-start+1, "i82365"))
0653         return 1;
0654     release_region(start, stop-start+1);
0655     }
0656 
0657     return 0;
0658 }
0659 
0660 /*====================================================================*/
0661 
0662 static void __init add_socket(unsigned int port, int psock, int type)
0663 {
0664     socket[sockets].ioaddr = port;
0665     socket[sockets].psock = psock;
0666     socket[sockets].type = type;
0667     socket[sockets].flags = pcic[type].flags;
0668     if (is_alive(sockets))
0669     socket[sockets].flags |= IS_ALIVE;
0670     sockets++;
0671 }
0672 
0673 static void __init add_pcic(int ns, int type)
0674 {
0675     u_int mask = 0, i, base;
0676     int isa_irq = 0;
0677     struct i82365_socket *t = &socket[sockets-ns];
0678 
0679     base = sockets-ns;
0680     if (base == 0) printk("\n");
0681     printk(KERN_INFO "  %s", pcic[type].name);
0682     printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x",
0683            t->ioaddr, t->psock*0x40);
0684     printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : ""));
0685 
0686     /* Set host options, build basic interrupt mask */
0687     if (irq_list_count == 0)
0688     mask = irq_mask;
0689     else
0690     for (i = mask = 0; i < irq_list_count; i++)
0691         mask |= (1<<irq_list[i]);
0692     mask &= I365_MASK & set_bridge_opts(base, ns);
0693     /* Scan for ISA interrupts */
0694     mask = isa_scan(base, mask);
0695         
0696     /* Poll if only two interrupts available */
0697     if (!poll_interval) {
0698     u_int tmp = (mask & 0xff20);
0699     tmp = tmp & (tmp-1);
0700     if ((tmp & (tmp-1)) == 0)
0701         poll_interval = HZ;
0702     }
0703     /* Only try an ISA cs_irq if this is the first controller */
0704     if (!grab_irq && (cs_irq || !poll_interval)) {
0705     /* Avoid irq 12 unless it is explicitly requested */
0706     u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
0707     for (cs_irq = 15; cs_irq > 0; cs_irq--)
0708         if ((cs_mask & (1 << cs_irq)) &&
0709         (_check_irq(cs_irq, IRQF_PROBE_SHARED) == 0))
0710         break;
0711     if (cs_irq) {
0712         grab_irq = 1;
0713         isa_irq = cs_irq;
0714         printk(" status change on irq %d\n", cs_irq);
0715     }
0716     }
0717     
0718     if (!isa_irq) {
0719     if (poll_interval == 0)
0720         poll_interval = HZ;
0721     printk(" polling interval = %d ms\n",
0722            poll_interval * 1000 / HZ);
0723     
0724     }
0725     
0726     /* Update socket interrupt information, capabilities */
0727     for (i = 0; i < ns; i++) {
0728     t[i].socket.features |= SS_CAP_PCCARD;
0729     t[i].socket.map_size = 0x1000;
0730     t[i].socket.irq_mask = mask;
0731     t[i].cs_irq = isa_irq;
0732     }
0733 
0734 } /* add_pcic */
0735 
0736 /*====================================================================*/
0737 
0738 #ifdef CONFIG_PNP
0739 static struct isapnp_device_id id_table[] __initdata = {
0740     {   ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
0741         ISAPNP_FUNCTION(0x0e00), (unsigned long) "Intel 82365-Compatible" },
0742     {   ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
0743         ISAPNP_FUNCTION(0x0e01), (unsigned long) "Cirrus Logic CL-PD6720" },
0744     {   ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
0745         ISAPNP_FUNCTION(0x0e02), (unsigned long) "VLSI VL82C146" },
0746     {   0 }
0747 };
0748 MODULE_DEVICE_TABLE(isapnp, id_table);
0749 
0750 static struct pnp_dev *i82365_pnpdev;
0751 #endif
0752 
0753 static void __init isa_probe(void)
0754 {
0755     int i, j, sock, k, ns, id;
0756     unsigned int port;
0757 #ifdef CONFIG_PNP
0758     struct isapnp_device_id *devid;
0759     struct pnp_dev *dev;
0760 
0761     for (devid = id_table; devid->vendor; devid++) {
0762     if ((dev = pnp_find_dev(NULL, devid->vendor, devid->function, NULL))) {
0763     
0764         if (pnp_device_attach(dev) < 0)
0765             continue;
0766 
0767         if (pnp_activate_dev(dev) < 0) {
0768         printk("activate failed\n");
0769         pnp_device_detach(dev);
0770         break;
0771         }
0772 
0773         if (!pnp_port_valid(dev, 0)) {
0774         printk("invalid resources ?\n");
0775         pnp_device_detach(dev);
0776         break;
0777         }
0778         i365_base = pnp_port_start(dev, 0);
0779         i82365_pnpdev = dev;
0780         break;
0781     }
0782     }
0783 #endif
0784 
0785     if (!request_region(i365_base, 2, "i82365")) {
0786     if (sockets == 0)
0787         printk("port conflict at %#lx\n", i365_base);
0788     return;
0789     }
0790 
0791     id = identify(i365_base, 0);
0792     if ((id == IS_I82365DF) && (identify(i365_base, 1) != id)) {
0793     for (i = 0; i < 4; i++) {
0794         if (i == ignore) continue;
0795         port = i365_base + ((i & 1) << 2) + ((i & 2) << 1);
0796         sock = (i & 1) << 1;
0797         if (identify(port, sock) == IS_I82365DF) {
0798         add_socket(port, sock, IS_VLSI);
0799         add_pcic(1, IS_VLSI);
0800         }
0801     }
0802     } else {
0803     for (i = 0; i < 8; i += 2) {
0804         if (sockets && !extra_sockets && (i == 4))
0805         break;
0806         port = i365_base + 2*(i>>2);
0807         sock = (i & 3);
0808         id = identify(port, sock);
0809         if (id < 0) continue;
0810 
0811         for (j = ns = 0; j < 2; j++) {
0812         /* Does the socket exist? */
0813         if ((ignore == i+j) || (identify(port, sock+j) < 0))
0814             continue;
0815         /* Check for bad socket decode */
0816         for (k = 0; k <= sockets; k++)
0817             i365_set(k, I365_MEM(0)+I365_W_OFF, k);
0818         for (k = 0; k <= sockets; k++)
0819             if (i365_get(k, I365_MEM(0)+I365_W_OFF) != k)
0820             break;
0821         if (k <= sockets) break;
0822         add_socket(port, sock+j, id); ns++;
0823         }
0824         if (ns != 0) add_pcic(ns, id);
0825     }
0826     }
0827 }
0828 
0829 /*====================================================================*/
0830 
0831 static irqreturn_t pcic_interrupt(int irq, void *dev)
0832 {
0833     int i, j, csc;
0834     u_int events, active;
0835     u_long flags = 0;
0836     int handled = 0;
0837 
0838     pr_debug("pcic_interrupt(%d)\n", irq);
0839 
0840     for (j = 0; j < 20; j++) {
0841     active = 0;
0842     for (i = 0; i < sockets; i++) {
0843         if (socket[i].cs_irq != irq)
0844         continue;
0845         handled = 1;
0846         ISA_LOCK(i, flags);
0847         csc = i365_get(i, I365_CSC);
0848         if ((csc == 0) || (i365_get(i, I365_IDENT) & 0x70)) {
0849         ISA_UNLOCK(i, flags);
0850         continue;
0851         }
0852         events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
0853 
0854         if (i365_get(i, I365_INTCTL) & I365_PC_IOCARD)
0855         events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
0856         else {
0857         events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
0858         events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
0859         events |= (csc & I365_CSC_READY) ? SS_READY : 0;
0860         }
0861         ISA_UNLOCK(i, flags);
0862         pr_debug("socket %d event 0x%02x\n", i, events);
0863 
0864         if (events)
0865         pcmcia_parse_events(&socket[i].socket, events);
0866 
0867         active |= events;
0868     }
0869     if (!active) break;
0870     }
0871     if (j == 20)
0872     printk(KERN_NOTICE "i82365: infinite loop in interrupt handler\n");
0873 
0874     pr_debug("pcic_interrupt done\n");
0875     return IRQ_RETVAL(handled);
0876 } /* pcic_interrupt */
0877 
0878 static void pcic_interrupt_wrapper(struct timer_list *unused)
0879 {
0880     pcic_interrupt(0, NULL);
0881     poll_timer.expires = jiffies + poll_interval;
0882     add_timer(&poll_timer);
0883 }
0884 
0885 /*====================================================================*/
0886 
0887 static int i365_get_status(u_short sock, u_int *value)
0888 {
0889     u_int status;
0890     
0891     status = i365_get(sock, I365_STATUS);
0892     *value = ((status & I365_CS_DETECT) == I365_CS_DETECT)
0893     ? SS_DETECT : 0;
0894     
0895     if (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD)
0896     *value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
0897     else {
0898     *value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
0899     *value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
0900     }
0901     *value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
0902     *value |= (status & I365_CS_READY) ? SS_READY : 0;
0903     *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
0904 
0905     if (socket[sock].type == IS_VG469) {
0906     status = i365_get(sock, VG469_VSENSE);
0907     if (socket[sock].psock & 1) {
0908         *value |= (status & VG469_VSENSE_B_VS1) ? 0 : SS_3VCARD;
0909         *value |= (status & VG469_VSENSE_B_VS2) ? 0 : SS_XVCARD;
0910     } else {
0911         *value |= (status & VG469_VSENSE_A_VS1) ? 0 : SS_3VCARD;
0912         *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD;
0913     }
0914     }
0915     
0916     pr_debug("GetStatus(%d) = %#4.4x\n", sock, *value);
0917     return 0;
0918 } /* i365_get_status */
0919 
0920 /*====================================================================*/
0921 
0922 static int i365_set_socket(u_short sock, socket_state_t *state)
0923 {
0924     struct i82365_socket *t = &socket[sock];
0925     u_char reg;
0926     
0927     pr_debug("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
0928       "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
0929       state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
0930     
0931     /* First set global controller options */
0932     set_bridge_state(sock);
0933     
0934     /* IO card, RESET flag, IO interrupt */
0935     reg = t->intr;
0936     reg |= state->io_irq;
0937     reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
0938     reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
0939     i365_set(sock, I365_INTCTL, reg);
0940     
0941     reg = I365_PWR_NORESET;
0942     if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
0943     if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
0944 
0945     if (t->flags & IS_CIRRUS) {
0946     if (state->Vpp != 0) {
0947         if (state->Vpp == 120)
0948         reg |= I365_VPP1_12V;
0949         else if (state->Vpp == state->Vcc)
0950         reg |= I365_VPP1_5V;
0951         else return -EINVAL;
0952     }
0953     if (state->Vcc != 0) {
0954         reg |= I365_VCC_5V;
0955         if (state->Vcc == 33)
0956         i365_bset(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
0957         else if (state->Vcc == 50)
0958         i365_bclr(sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
0959         else return -EINVAL;
0960     }
0961     } else if (t->flags & IS_VG_PWR) {
0962     if (state->Vpp != 0) {
0963         if (state->Vpp == 120)
0964         reg |= I365_VPP1_12V;
0965         else if (state->Vpp == state->Vcc)
0966         reg |= I365_VPP1_5V;
0967         else return -EINVAL;
0968     }
0969     if (state->Vcc != 0) {
0970         reg |= I365_VCC_5V;
0971         if (state->Vcc == 33)
0972         i365_bset(sock, VG469_VSELECT, VG469_VSEL_VCC);
0973         else if (state->Vcc == 50)
0974         i365_bclr(sock, VG469_VSELECT, VG469_VSEL_VCC);
0975         else return -EINVAL;
0976     }
0977     } else if (t->flags & IS_DF_PWR) {
0978     switch (state->Vcc) {
0979     case 0:     break;
0980     case 33:    reg |= I365_VCC_3V; break;
0981     case 50:    reg |= I365_VCC_5V; break;
0982     default:    return -EINVAL;
0983     }
0984     switch (state->Vpp) {
0985     case 0:     break;
0986     case 50:    reg |= I365_VPP1_5V; break;
0987     case 120:   reg |= I365_VPP1_12V; break;
0988     default:    return -EINVAL;
0989     }
0990     } else {
0991     switch (state->Vcc) {
0992     case 0:     break;
0993     case 50:    reg |= I365_VCC_5V; break;
0994     default:    return -EINVAL;
0995     }
0996     switch (state->Vpp) {
0997     case 0:     break;
0998     case 50:    reg |= I365_VPP1_5V | I365_VPP2_5V; break;
0999     case 120:   reg |= I365_VPP1_12V | I365_VPP2_12V; break;
1000     default:    return -EINVAL;
1001     }
1002     }
1003     
1004     if (reg != i365_get(sock, I365_POWER))
1005     i365_set(sock, I365_POWER, reg);
1006 
1007     /* Chipset-specific functions */
1008     if (t->flags & IS_CIRRUS) {
1009     /* Speaker control */
1010     i365_bflip(sock, PD67_MISC_CTL_1, PD67_MC1_SPKR_ENA,
1011            state->flags & SS_SPKR_ENA);
1012     }
1013     
1014     /* Card status change interrupt mask */
1015     reg = t->cs_irq << 4;
1016     if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;
1017     if (state->flags & SS_IOCARD) {
1018     if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
1019     } else {
1020     if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;
1021     if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;
1022     if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;
1023     }
1024     i365_set(sock, I365_CSCINT, reg);
1025     i365_get(sock, I365_CSC);
1026     
1027     return 0;
1028 } /* i365_set_socket */
1029 
1030 /*====================================================================*/
1031 
1032 static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
1033 {
1034     u_char map, ioctl;
1035     
1036     pr_debug("SetIOMap(%d, %d, %#2.2x, %d ns, "
1037       "%#llx-%#llx)\n", sock, io->map, io->flags, io->speed,
1038       (unsigned long long)io->start, (unsigned long long)io->stop);
1039     map = io->map;
1040     if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
1041     (io->stop < io->start)) return -EINVAL;
1042     /* Turn off the window before changing anything */
1043     if (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(map))
1044     i365_bclr(sock, I365_ADDRWIN, I365_ENA_IO(map));
1045     i365_set_pair(sock, I365_IO(map)+I365_W_START, io->start);
1046     i365_set_pair(sock, I365_IO(map)+I365_W_STOP, io->stop);
1047     ioctl = i365_get(sock, I365_IOCTL) & ~I365_IOCTL_MASK(map);
1048     if (io->speed) ioctl |= I365_IOCTL_WAIT(map);
1049     if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
1050     if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
1051     if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
1052     i365_set(sock, I365_IOCTL, ioctl);
1053     /* Turn on the window if necessary */
1054     if (io->flags & MAP_ACTIVE)
1055     i365_bset(sock, I365_ADDRWIN, I365_ENA_IO(map));
1056     return 0;
1057 } /* i365_set_io_map */
1058 
1059 /*====================================================================*/
1060 
1061 static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
1062 {
1063     u_short base, i;
1064     u_char map;
1065     
1066     pr_debug("SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, "
1067       "%#x)\n", sock, mem->map, mem->flags, mem->speed,
1068       (unsigned long long)mem->res->start,
1069       (unsigned long long)mem->res->end, mem->card_start);
1070 
1071     map = mem->map;
1072     if ((map > 4) || (mem->card_start > 0x3ffffff) ||
1073     (mem->res->start > mem->res->end) || (mem->speed > 1000))
1074     return -EINVAL;
1075     if ((mem->res->start > 0xffffff) || (mem->res->end > 0xffffff))
1076     return -EINVAL;
1077     
1078     /* Turn off the window before changing anything */
1079     if (i365_get(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
1080     i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map));
1081     
1082     base = I365_MEM(map);
1083     i = (mem->res->start >> 12) & 0x0fff;
1084     if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT;
1085     if (mem->flags & MAP_0WS) i |= I365_MEM_0WS;
1086     i365_set_pair(sock, base+I365_W_START, i);
1087     
1088     i = (mem->res->end >> 12) & 0x0fff;
1089     switch (to_cycles(mem->speed)) {
1090     case 0: break;
1091     case 1: i |= I365_MEM_WS0; break;
1092     case 2: i |= I365_MEM_WS1; break;
1093     default:    i |= I365_MEM_WS1 | I365_MEM_WS0; break;
1094     }
1095     i365_set_pair(sock, base+I365_W_STOP, i);
1096     
1097     i = ((mem->card_start - mem->res->start) >> 12) & 0x3fff;
1098     if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT;
1099     if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG;
1100     i365_set_pair(sock, base+I365_W_OFF, i);
1101     
1102     /* Turn on the window if necessary */
1103     if (mem->flags & MAP_ACTIVE)
1104     i365_bset(sock, I365_ADDRWIN, I365_ENA_MEM(map));
1105     return 0;
1106 } /* i365_set_mem_map */
1107 
1108 #if 0 /* driver model ordering issue */
1109 /*======================================================================
1110 
1111     Routines for accessing socket information and register dumps via
1112     /sys/class/pcmcia_socket/...
1113     
1114 ======================================================================*/
1115 
1116 static ssize_t show_info(struct class_device *class_dev, char *buf)
1117 {
1118     struct i82365_socket *s = container_of(class_dev, struct i82365_socket, socket.dev);
1119     return sprintf(buf, "type:     %s\npsock:    %d\n",
1120                pcic[s->type].name, s->psock);
1121 }
1122 
1123 static ssize_t show_exca(struct class_device *class_dev, char *buf)
1124 {
1125     struct i82365_socket *s = container_of(class_dev, struct i82365_socket, socket.dev);
1126     unsigned short sock;
1127     int i;
1128     ssize_t ret = 0;
1129     unsigned long flags = 0;
1130 
1131     sock = s->number;
1132 
1133     ISA_LOCK(sock, flags);
1134     for (i = 0; i < 0x40; i += 4) {
1135         ret += sprintf(buf, "%02x %02x %02x %02x%s",
1136                    i365_get(sock,i), i365_get(sock,i+1),
1137                    i365_get(sock,i+2), i365_get(sock,i+3),
1138                    ((i % 16) == 12) ? "\n" : " ");
1139         buf += ret;
1140     }
1141     ISA_UNLOCK(sock, flags);
1142 
1143     return ret;
1144 }
1145 
1146 static CLASS_DEVICE_ATTR(exca, S_IRUGO, show_exca, NULL);
1147 static CLASS_DEVICE_ATTR(info, S_IRUGO, show_info, NULL);
1148 #endif
1149 
1150 /*====================================================================*/
1151 
1152 /* this is horribly ugly... proper locking needs to be done here at 
1153  * some time... */
1154 #define LOCKED(x) do { \
1155     int retval; \
1156     unsigned long flags; \
1157     spin_lock_irqsave(&isa_lock, flags); \
1158     retval = x; \
1159     spin_unlock_irqrestore(&isa_lock, flags); \
1160     return retval; \
1161 } while (0)
1162     
1163 
1164 static int pcic_get_status(struct pcmcia_socket *s, u_int *value)
1165 {
1166     unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1167 
1168     if (socket[sock].flags & IS_ALIVE) {
1169         *value = 0;
1170         return -EINVAL;
1171     }
1172 
1173     LOCKED(i365_get_status(sock, value));
1174 }
1175 
1176 static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state)
1177 {
1178     unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1179 
1180     if (socket[sock].flags & IS_ALIVE)
1181         return -EINVAL;
1182 
1183     LOCKED(i365_set_socket(sock, state));
1184 }
1185 
1186 static int pcic_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
1187 {
1188     unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1189     if (socket[sock].flags & IS_ALIVE)
1190         return -EINVAL;
1191 
1192     LOCKED(i365_set_io_map(sock, io));
1193 }
1194 
1195 static int pcic_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
1196 {
1197     unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
1198     if (socket[sock].flags & IS_ALIVE)
1199         return -EINVAL;
1200 
1201     LOCKED(i365_set_mem_map(sock, mem));
1202 }
1203 
1204 static int pcic_init(struct pcmcia_socket *s)
1205 {
1206     int i;
1207     struct resource res = { .start = 0, .end = 0x1000 };
1208     pccard_io_map io = { 0, 0, 0, 0, 1 };
1209     pccard_mem_map mem = { .res = &res, };
1210 
1211     for (i = 0; i < 2; i++) {
1212         io.map = i;
1213         pcic_set_io_map(s, &io);
1214     }
1215     for (i = 0; i < 5; i++) {
1216         mem.map = i;
1217         pcic_set_mem_map(s, &mem);
1218     }
1219     return 0;
1220 }
1221 
1222 
1223 static struct pccard_operations pcic_operations = {
1224     .init           = pcic_init,
1225     .get_status     = pcic_get_status,
1226     .set_socket     = pcic_set_socket,
1227     .set_io_map     = pcic_set_io_map,
1228     .set_mem_map        = pcic_set_mem_map,
1229 };
1230 
1231 /*====================================================================*/
1232 
1233 static struct platform_driver i82365_driver = {
1234     .driver = {
1235         .name = "i82365",
1236     },
1237 };
1238 
1239 static struct platform_device *i82365_device;
1240 
1241 static int __init init_i82365(void)
1242 {
1243     int i, ret;
1244 
1245     ret = platform_driver_register(&i82365_driver);
1246     if (ret)
1247     goto err_out;
1248 
1249     i82365_device = platform_device_alloc("i82365", 0);
1250     if (i82365_device) {
1251         ret = platform_device_add(i82365_device);
1252         if (ret)
1253             platform_device_put(i82365_device);
1254     } else
1255         ret = -ENOMEM;
1256 
1257     if (ret)
1258     goto err_driver_unregister;
1259 
1260     printk(KERN_INFO "Intel ISA PCIC probe: ");
1261     sockets = 0;
1262 
1263     isa_probe();
1264 
1265     if (sockets == 0) {
1266     printk("not found.\n");
1267     ret = -ENODEV;
1268     goto err_dev_unregister;
1269     }
1270 
1271     /* Set up interrupt handler(s) */
1272     if (grab_irq != 0)
1273     ret = request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
1274 
1275     if (ret)
1276     goto err_socket_release;
1277 
1278     /* register sockets with the pcmcia core */
1279     for (i = 0; i < sockets; i++) {
1280         socket[i].socket.dev.parent = &i82365_device->dev;
1281         socket[i].socket.ops = &pcic_operations;
1282         socket[i].socket.resource_ops = &pccard_nonstatic_ops;
1283         socket[i].socket.owner = THIS_MODULE;
1284         socket[i].number = i;
1285         ret = pcmcia_register_socket(&socket[i].socket);
1286         if (!ret)
1287             socket[i].flags |= IS_REGISTERED;
1288     }
1289 
1290     /* Finally, schedule a polling interrupt */
1291     if (poll_interval != 0) {
1292     timer_setup(&poll_timer, pcic_interrupt_wrapper, 0);
1293         poll_timer.expires = jiffies + poll_interval;
1294     add_timer(&poll_timer);
1295     }
1296     
1297     return 0;
1298 err_socket_release:
1299     for (i = 0; i < sockets; i++) {
1300     /* Turn off all interrupt sources! */
1301     i365_set(i, I365_CSCINT, 0);
1302     release_region(socket[i].ioaddr, 2);
1303     }
1304 err_dev_unregister:
1305     platform_device_unregister(i82365_device);
1306     release_region(i365_base, 2);
1307 #ifdef CONFIG_PNP
1308     if (i82365_pnpdev)
1309     pnp_disable_dev(i82365_pnpdev);
1310 #endif
1311 err_driver_unregister:
1312     platform_driver_unregister(&i82365_driver);
1313 err_out:
1314     return ret;
1315 } /* init_i82365 */
1316 
1317 static void __exit exit_i82365(void)
1318 {
1319     int i;
1320 
1321     for (i = 0; i < sockets; i++) {
1322         if (socket[i].flags & IS_REGISTERED)
1323             pcmcia_unregister_socket(&socket[i].socket);
1324     }
1325     platform_device_unregister(i82365_device);
1326     if (poll_interval != 0)
1327     del_timer_sync(&poll_timer);
1328     if (grab_irq != 0)
1329     free_irq(cs_irq, pcic_interrupt);
1330     for (i = 0; i < sockets; i++) {
1331     /* Turn off all interrupt sources! */
1332     i365_set(i, I365_CSCINT, 0);
1333     release_region(socket[i].ioaddr, 2);
1334     }
1335     release_region(i365_base, 2);
1336 #ifdef CONFIG_PNP
1337     if (i82365_pnpdev)
1338             pnp_disable_dev(i82365_pnpdev);
1339 #endif
1340     platform_driver_unregister(&i82365_driver);
1341 } /* exit_i82365 */
1342 
1343 module_init(init_i82365);
1344 module_exit(exit_i82365);
1345 MODULE_LICENSE("Dual MPL/GPL");
1346 /*====================================================================*/