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