aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/cris/arch-v10/kernel/io_interface_mux.c515
1 files changed, 408 insertions, 107 deletions
diff --git a/arch/cris/arch-v10/kernel/io_interface_mux.c b/arch/cris/arch-v10/kernel/io_interface_mux.c
index f3b327d4ed9c..add98e0941b5 100644
--- a/arch/cris/arch-v10/kernel/io_interface_mux.c
+++ b/arch/cris/arch-v10/kernel/io_interface_mux.c
@@ -1,10 +1,9 @@
1/* IO interface mux allocator for ETRAX100LX. 1/* IO interface mux allocator for ETRAX100LX.
2 * Copyright 2004, Axis Communications AB 2 * Copyright 2004-2007, Axis Communications AB
3 * $Id: io_interface_mux.c,v 1.2 2004/12/21 12:08:38 starvik Exp $
4 */ 3 */
5 4
6 5
7/* C.f. ETRAX100LX Designer's Reference 20.9 */ 6/* C.f. ETRAX100LX Designer's Reference chapter 19.9 */
8 7
9#include <linux/kernel.h> 8#include <linux/kernel.h>
10#include <linux/slab.h> 9#include <linux/slab.h>
@@ -45,17 +44,39 @@ struct watcher
45struct if_group 44struct if_group
46{ 45{
47 enum io_if_group group; 46 enum io_if_group group;
48 unsigned char used; 47 /* name - the name of the group 'A' to 'F' */
49 enum cris_io_interface owner; 48 char *name;
49 /* used - a bit mask of all pins in the group in the order listed
50 * in the tables in 19.9.1 to 19.9.6. Note that no
51 * distinction is made between in, out and in/out pins. */
52 unsigned int used;
50}; 53};
51 54
52 55
53struct interface 56struct interface
54{ 57{
55 enum cris_io_interface ioif; 58 enum cris_io_interface ioif;
59 /* name - the name of the interface */
60 char *name;
61 /* groups - OR'ed together io_if_group flags describing what pin groups
62 * the interface uses pins in. */
56 unsigned char groups; 63 unsigned char groups;
64 /* used - set when the interface is allocated. */
57 unsigned char used; 65 unsigned char used;
58 char *owner; 66 char *owner;
67 /* group_a through group_f - bit masks describing what pins in the
68 * pin groups the interface uses. */
69 unsigned int group_a;
70 unsigned int group_b;
71 unsigned int group_c;
72 unsigned int group_d;
73 unsigned int group_e;
74 unsigned int group_f;
75
76 /* gpio_g_in, gpio_g_out, gpio_b - bit masks telling what pins in the
77 * GPIO ports the interface uses. This could be reconstucted using
78 * the group_X masks and a table of what pins the GPIO ports use,
79 * but that would be messy. */
59 unsigned int gpio_g_in; 80 unsigned int gpio_g_in;
60 unsigned int gpio_g_out; 81 unsigned int gpio_g_out;
61 unsigned char gpio_b; 82 unsigned char gpio_b;
@@ -64,26 +85,32 @@ struct interface
64static struct if_group if_groups[6] = { 85static struct if_group if_groups[6] = {
65 { 86 {
66 .group = group_a, 87 .group = group_a,
88 .name = "A",
67 .used = 0, 89 .used = 0,
68 }, 90 },
69 { 91 {
70 .group = group_b, 92 .group = group_b,
93 .name = "B",
71 .used = 0, 94 .used = 0,
72 }, 95 },
73 { 96 {
74 .group = group_c, 97 .group = group_c,
98 .name = "C",
75 .used = 0, 99 .used = 0,
76 }, 100 },
77 { 101 {
78 .group = group_d, 102 .group = group_d,
103 .name = "D",
79 .used = 0, 104 .used = 0,
80 }, 105 },
81 { 106 {
82 .group = group_e, 107 .group = group_e,
108 .name = "E",
83 .used = 0, 109 .used = 0,
84 }, 110 },
85 { 111 {
86 .group = group_f, 112 .group = group_f,
113 .name = "F",
87 .used = 0, 114 .used = 0,
88 } 115 }
89}; 116};
@@ -94,14 +121,32 @@ static struct interface interfaces[] = {
94 /* Begin Non-multiplexed interfaces */ 121 /* Begin Non-multiplexed interfaces */
95 { 122 {
96 .ioif = if_eth, 123 .ioif = if_eth,
124 .name = "ethernet",
97 .groups = 0, 125 .groups = 0,
126
127 .group_a = 0,
128 .group_b = 0,
129 .group_c = 0,
130 .group_d = 0,
131 .group_e = 0,
132 .group_f = 0,
133
98 .gpio_g_in = 0, 134 .gpio_g_in = 0,
99 .gpio_g_out = 0, 135 .gpio_g_out = 0,
100 .gpio_b = 0 136 .gpio_b = 0
101 }, 137 },
102 { 138 {
103 .ioif = if_serial_0, 139 .ioif = if_serial_0,
140 .name = "serial_0",
104 .groups = 0, 141 .groups = 0,
142
143 .group_a = 0,
144 .group_b = 0,
145 .group_c = 0,
146 .group_d = 0,
147 .group_e = 0,
148 .group_f = 0,
149
105 .gpio_g_in = 0, 150 .gpio_g_in = 0,
106 .gpio_g_out = 0, 151 .gpio_g_out = 0,
107 .gpio_b = 0 152 .gpio_b = 0
@@ -109,172 +154,385 @@ static struct interface interfaces[] = {
109 /* End Non-multiplexed interfaces */ 154 /* End Non-multiplexed interfaces */
110 { 155 {
111 .ioif = if_serial_1, 156 .ioif = if_serial_1,
157 .name = "serial_1",
112 .groups = group_e, 158 .groups = group_e,
159
160 .group_a = 0,
161 .group_b = 0,
162 .group_c = 0,
163 .group_d = 0,
164 .group_e = 0x0f,
165 .group_f = 0,
166
113 .gpio_g_in = 0x00000000, 167 .gpio_g_in = 0x00000000,
114 .gpio_g_out = 0x00000000, 168 .gpio_g_out = 0x00000000,
115 .gpio_b = 0x00 169 .gpio_b = 0x00
116 }, 170 },
117 { 171 {
118 .ioif = if_serial_2, 172 .ioif = if_serial_2,
173 .name = "serial_2",
119 .groups = group_b, 174 .groups = group_b,
175
176 .group_a = 0,
177 .group_b = 0x0f,
178 .group_c = 0,
179 .group_d = 0,
180 .group_e = 0,
181 .group_f = 0,
182
120 .gpio_g_in = 0x000000c0, 183 .gpio_g_in = 0x000000c0,
121 .gpio_g_out = 0x000000c0, 184 .gpio_g_out = 0x000000c0,
122 .gpio_b = 0x00 185 .gpio_b = 0x00
123 }, 186 },
124 { 187 {
125 .ioif = if_serial_3, 188 .ioif = if_serial_3,
189 .name = "serial_3",
126 .groups = group_c, 190 .groups = group_c,
191
192 .group_a = 0,
193 .group_b = 0,
194 .group_c = 0x0f,
195 .group_d = 0,
196 .group_e = 0,
197 .group_f = 0,
198
127 .gpio_g_in = 0xc0000000, 199 .gpio_g_in = 0xc0000000,
128 .gpio_g_out = 0xc0000000, 200 .gpio_g_out = 0xc0000000,
129 .gpio_b = 0x00 201 .gpio_b = 0x00
130 }, 202 },
131 { 203 {
132 .ioif = if_sync_serial_1, 204 .ioif = if_sync_serial_1,
133 .groups = group_e | group_f, /* if_sync_serial_1 and if_sync_serial_3 205 .name = "sync_serial_1",
134 can be used simultaneously */ 206 .groups = group_e | group_f,
207
208 .group_a = 0,
209 .group_b = 0,
210 .group_c = 0,
211 .group_d = 0,
212 .group_e = 0x0f,
213 .group_f = 0x10,
214
135 .gpio_g_in = 0x00000000, 215 .gpio_g_in = 0x00000000,
136 .gpio_g_out = 0x00000000, 216 .gpio_g_out = 0x00000000,
137 .gpio_b = 0x10 217 .gpio_b = 0x10
138 }, 218 },
139 { 219 {
140 .ioif = if_sync_serial_3, 220 .ioif = if_sync_serial_3,
221 .name = "sync_serial_3",
141 .groups = group_c | group_f, 222 .groups = group_c | group_f,
223
224 .group_a = 0,
225 .group_b = 0,
226 .group_c = 0x0f,
227 .group_d = 0,
228 .group_e = 0,
229 .group_f = 0x80,
230
142 .gpio_g_in = 0xc0000000, 231 .gpio_g_in = 0xc0000000,
143 .gpio_g_out = 0xc0000000, 232 .gpio_g_out = 0xc0000000,
144 .gpio_b = 0x80 233 .gpio_b = 0x80
145 }, 234 },
146 { 235 {
147 .ioif = if_shared_ram, 236 .ioif = if_shared_ram,
237 .name = "shared_ram",
148 .groups = group_a, 238 .groups = group_a,
239
240 .group_a = 0x7f8ff,
241 .group_b = 0,
242 .group_c = 0,
243 .group_d = 0,
244 .group_e = 0,
245 .group_f = 0,
246
149 .gpio_g_in = 0x0000ff3e, 247 .gpio_g_in = 0x0000ff3e,
150 .gpio_g_out = 0x0000ff38, 248 .gpio_g_out = 0x0000ff38,
151 .gpio_b = 0x00 249 .gpio_b = 0x00
152 }, 250 },
153 { 251 {
154 .ioif = if_shared_ram_w, 252 .ioif = if_shared_ram_w,
253 .name = "shared_ram_w",
155 .groups = group_a | group_d, 254 .groups = group_a | group_d,
255
256 .group_a = 0x7f8ff,
257 .group_b = 0,
258 .group_c = 0,
259 .group_d = 0xff,
260 .group_e = 0,
261 .group_f = 0,
262
156 .gpio_g_in = 0x00ffff3e, 263 .gpio_g_in = 0x00ffff3e,
157 .gpio_g_out = 0x00ffff38, 264 .gpio_g_out = 0x00ffff38,
158 .gpio_b = 0x00 265 .gpio_b = 0x00
159 }, 266 },
160 { 267 {
161 .ioif = if_par_0, 268 .ioif = if_par_0,
269 .name = "par_0",
162 .groups = group_a, 270 .groups = group_a,
271
272 .group_a = 0x7fbff,
273 .group_b = 0,
274 .group_c = 0,
275 .group_d = 0,
276 .group_e = 0,
277 .group_f = 0,
278
163 .gpio_g_in = 0x0000ff3e, 279 .gpio_g_in = 0x0000ff3e,
164 .gpio_g_out = 0x0000ff3e, 280 .gpio_g_out = 0x0000ff3e,
165 .gpio_b = 0x00 281 .gpio_b = 0x00
166 }, 282 },
167 { 283 {
168 .ioif = if_par_1, 284 .ioif = if_par_1,
285 .name = "par_1",
169 .groups = group_d, 286 .groups = group_d,
287
288 .group_a = 0,
289 .group_b = 0,
290 .group_c = 0,
291 .group_d = 0x7feff,
292 .group_e = 0,
293 .group_f = 0,
294
170 .gpio_g_in = 0x3eff0000, 295 .gpio_g_in = 0x3eff0000,
171 .gpio_g_out = 0x3eff0000, 296 .gpio_g_out = 0x3eff0000,
172 .gpio_b = 0x00 297 .gpio_b = 0x00
173 }, 298 },
174 { 299 {
175 .ioif = if_par_w, 300 .ioif = if_par_w,
301 .name = "par_w",
176 .groups = group_a | group_d, 302 .groups = group_a | group_d,
303
304 .group_a = 0x7fbff,
305 .group_b = 0,
306 .group_c = 0,
307 .group_d = 0xff,
308 .group_e = 0,
309 .group_f = 0,
310
177 .gpio_g_in = 0x00ffff3e, 311 .gpio_g_in = 0x00ffff3e,
178 .gpio_g_out = 0x00ffff3e, 312 .gpio_g_out = 0x00ffff3e,
179 .gpio_b = 0x00 313 .gpio_b = 0x00
180 }, 314 },
181 { 315 {
182 .ioif = if_scsi8_0, 316 .ioif = if_scsi8_0,
183 .groups = group_a | group_b | group_f, /* if_scsi8_0 and if_scsi8_1 317 .name = "scsi8_0",
184 can be used simultaneously */ 318 .groups = group_a | group_b | group_f,
319
320 .group_a = 0x7ffff,
321 .group_b = 0x0f,
322 .group_c = 0,
323 .group_d = 0,
324 .group_e = 0,
325 .group_f = 0x10,
326
185 .gpio_g_in = 0x0000ffff, 327 .gpio_g_in = 0x0000ffff,
186 .gpio_g_out = 0x0000ffff, 328 .gpio_g_out = 0x0000ffff,
187 .gpio_b = 0x10 329 .gpio_b = 0x10
188 }, 330 },
189 { 331 {
190 .ioif = if_scsi8_1, 332 .ioif = if_scsi8_1,
191 .groups = group_c | group_d | group_f, /* if_scsi8_0 and if_scsi8_1 333 .name = "scsi8_1",
192 can be used simultaneously */ 334 .groups = group_c | group_d | group_f,
335
336 .group_a = 0,
337 .group_b = 0,
338 .group_c = 0x0f,
339 .group_d = 0x7ffff,
340 .group_e = 0,
341 .group_f = 0x80,
342
193 .gpio_g_in = 0xffff0000, 343 .gpio_g_in = 0xffff0000,
194 .gpio_g_out = 0xffff0000, 344 .gpio_g_out = 0xffff0000,
195 .gpio_b = 0x80 345 .gpio_b = 0x80
196 }, 346 },
197 { 347 {
198 .ioif = if_scsi_w, 348 .ioif = if_scsi_w,
349 .name = "scsi_w",
199 .groups = group_a | group_b | group_d | group_f, 350 .groups = group_a | group_b | group_d | group_f,
351
352 .group_a = 0x7ffff,
353 .group_b = 0x0f,
354 .group_c = 0,
355 .group_d = 0x601ff,
356 .group_e = 0,
357 .group_f = 0x90,
358
200 .gpio_g_in = 0x01ffffff, 359 .gpio_g_in = 0x01ffffff,
201 .gpio_g_out = 0x07ffffff, 360 .gpio_g_out = 0x07ffffff,
202 .gpio_b = 0x80 361 .gpio_b = 0x80
203 }, 362 },
204 { 363 {
205 .ioif = if_ata, 364 .ioif = if_ata,
365 .name = "ata",
206 .groups = group_a | group_b | group_c | group_d, 366 .groups = group_a | group_b | group_c | group_d,
367
368 .group_a = 0x7ffff,
369 .group_b = 0x0f,
370 .group_c = 0x0f,
371 .group_d = 0x7cfff,
372 .group_e = 0,
373 .group_f = 0,
374
207 .gpio_g_in = 0xf9ffffff, 375 .gpio_g_in = 0xf9ffffff,
208 .gpio_g_out = 0xffffffff, 376 .gpio_g_out = 0xffffffff,
209 .gpio_b = 0x80 377 .gpio_b = 0x80
210 }, 378 },
211 { 379 {
212 .ioif = if_csp, 380 .ioif = if_csp,
213 .groups = group_f, /* if_csp and if_i2c can be used simultaneously */ 381 .name = "csp",
382 .groups = group_f,
383
384 .group_a = 0,
385 .group_b = 0,
386 .group_c = 0,
387 .group_d = 0,
388 .group_e = 0,
389 .group_f = 0xfc,
390
214 .gpio_g_in = 0x00000000, 391 .gpio_g_in = 0x00000000,
215 .gpio_g_out = 0x00000000, 392 .gpio_g_out = 0x00000000,
216 .gpio_b = 0xfc 393 .gpio_b = 0xfc
217 }, 394 },
218 { 395 {
219 .ioif = if_i2c, 396 .ioif = if_i2c,
220 .groups = group_f, /* if_csp and if_i2c can be used simultaneously */ 397 .name = "i2c",
398 .groups = group_f,
399
400 .group_a = 0,
401 .group_b = 0,
402 .group_c = 0,
403 .group_d = 0,
404 .group_e = 0,
405 .group_f = 0x03,
406
221 .gpio_g_in = 0x00000000, 407 .gpio_g_in = 0x00000000,
222 .gpio_g_out = 0x00000000, 408 .gpio_g_out = 0x00000000,
223 .gpio_b = 0x03 409 .gpio_b = 0x03
224 }, 410 },
225 { 411 {
226 .ioif = if_usb_1, 412 .ioif = if_usb_1,
413 .name = "usb_1",
227 .groups = group_e | group_f, 414 .groups = group_e | group_f,
415
416 .group_a = 0,
417 .group_b = 0,
418 .group_c = 0,
419 .group_d = 0,
420 .group_e = 0x0f,
421 .group_f = 0x2c,
422
228 .gpio_g_in = 0x00000000, 423 .gpio_g_in = 0x00000000,
229 .gpio_g_out = 0x00000000, 424 .gpio_g_out = 0x00000000,
230 .gpio_b = 0x2c 425 .gpio_b = 0x2c
231 }, 426 },
232 { 427 {
233 .ioif = if_usb_2, 428 .ioif = if_usb_2,
429 .name = "usb_2",
234 .groups = group_d, 430 .groups = group_d,
235 .gpio_g_in = 0x0e000000, 431
236 .gpio_g_out = 0x3c000000, 432 .group_a = 0,
433 .group_b = 0,
434 .group_c = 0,
435 .group_d = 0,
436 .group_e = 0x33e00,
437 .group_f = 0,
438
439 .gpio_g_in = 0x3e000000,
440 .gpio_g_out = 0x0c000000,
237 .gpio_b = 0x00 441 .gpio_b = 0x00
238 }, 442 },
239 /* GPIO pins */ 443 /* GPIO pins */
240 { 444 {
241 .ioif = if_gpio_grp_a, 445 .ioif = if_gpio_grp_a,
446 .name = "gpio_a",
242 .groups = group_a, 447 .groups = group_a,
448
449 .group_a = 0,
450 .group_b = 0,
451 .group_c = 0,
452 .group_d = 0,
453 .group_e = 0,
454 .group_f = 0,
455
243 .gpio_g_in = 0x0000ff3f, 456 .gpio_g_in = 0x0000ff3f,
244 .gpio_g_out = 0x0000ff3f, 457 .gpio_g_out = 0x0000ff3f,
245 .gpio_b = 0x00 458 .gpio_b = 0x00
246 }, 459 },
247 { 460 {
248 .ioif = if_gpio_grp_b, 461 .ioif = if_gpio_grp_b,
462 .name = "gpio_b",
249 .groups = group_b, 463 .groups = group_b,
464
465 .group_a = 0,
466 .group_b = 0,
467 .group_c = 0,
468 .group_d = 0,
469 .group_e = 0,
470 .group_f = 0,
471
250 .gpio_g_in = 0x000000c0, 472 .gpio_g_in = 0x000000c0,
251 .gpio_g_out = 0x000000c0, 473 .gpio_g_out = 0x000000c0,
252 .gpio_b = 0x00 474 .gpio_b = 0x00
253 }, 475 },
254 { 476 {
255 .ioif = if_gpio_grp_c, 477 .ioif = if_gpio_grp_c,
478 .name = "gpio_c",
256 .groups = group_c, 479 .groups = group_c,
480
481 .group_a = 0,
482 .group_b = 0,
483 .group_c = 0,
484 .group_d = 0,
485 .group_e = 0,
486 .group_f = 0,
487
257 .gpio_g_in = 0xc0000000, 488 .gpio_g_in = 0xc0000000,
258 .gpio_g_out = 0xc0000000, 489 .gpio_g_out = 0xc0000000,
259 .gpio_b = 0x00 490 .gpio_b = 0x00
260 }, 491 },
261 { 492 {
262 .ioif = if_gpio_grp_d, 493 .ioif = if_gpio_grp_d,
494 .name = "gpio_d",
263 .groups = group_d, 495 .groups = group_d,
496
497 .group_a = 0,
498 .group_b = 0,
499 .group_c = 0,
500 .group_d = 0,
501 .group_e = 0,
502 .group_f = 0,
503
264 .gpio_g_in = 0x3fff0000, 504 .gpio_g_in = 0x3fff0000,
265 .gpio_g_out = 0x3fff0000, 505 .gpio_g_out = 0x3fff0000,
266 .gpio_b = 0x00 506 .gpio_b = 0x00
267 }, 507 },
268 { 508 {
269 .ioif = if_gpio_grp_e, 509 .ioif = if_gpio_grp_e,
510 .name = "gpio_e",
270 .groups = group_e, 511 .groups = group_e,
512
513 .group_a = 0,
514 .group_b = 0,
515 .group_c = 0,
516 .group_d = 0,
517 .group_e = 0,
518 .group_f = 0,
519
271 .gpio_g_in = 0x00000000, 520 .gpio_g_in = 0x00000000,
272 .gpio_g_out = 0x00000000, 521 .gpio_g_out = 0x00000000,
273 .gpio_b = 0x00 522 .gpio_b = 0x00
274 }, 523 },
275 { 524 {
276 .ioif = if_gpio_grp_f, 525 .ioif = if_gpio_grp_f,
526 .name = "gpio_f",
277 .groups = group_f, 527 .groups = group_f,
528
529 .group_a = 0,
530 .group_b = 0,
531 .group_c = 0,
532 .group_d = 0,
533 .group_e = 0,
534 .group_f = 0,
535
278 .gpio_g_in = 0x00000000, 536 .gpio_g_in = 0x00000000,
279 .gpio_g_out = 0x00000000, 537 .gpio_g_out = 0x00000000,
280 .gpio_b = 0xff 538 .gpio_b = 0xff
@@ -284,11 +542,13 @@ static struct interface interfaces[] = {
284 542
285static struct watcher *watchers = NULL; 543static struct watcher *watchers = NULL;
286 544
545/* The pins that are free to use in the GPIO ports. */
287static unsigned int gpio_in_pins = 0xffffffff; 546static unsigned int gpio_in_pins = 0xffffffff;
288static unsigned int gpio_out_pins = 0xffffffff; 547static unsigned int gpio_out_pins = 0xffffffff;
289static unsigned char gpio_pb_pins = 0xff; 548static unsigned char gpio_pb_pins = 0xff;
290static unsigned char gpio_pa_pins = 0xff; 549static unsigned char gpio_pa_pins = 0xff;
291 550
551/* Identifiers for the owners of the GPIO pins. */
292static enum cris_io_interface gpio_pa_owners[8]; 552static enum cris_io_interface gpio_pa_owners[8];
293static enum cris_io_interface gpio_pb_owners[8]; 553static enum cris_io_interface gpio_pb_owners[8];
294static enum cris_io_interface gpio_pg_owners[32]; 554static enum cris_io_interface gpio_pg_owners[32];
@@ -338,13 +598,15 @@ int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id
338 struct if_group *grp; 598 struct if_group *grp;
339 unsigned char group_set; 599 unsigned char group_set;
340 unsigned long flags; 600 unsigned long flags;
601 int res = 0;
341 602
342 (void)cris_io_interface_init(); 603 (void)cris_io_interface_init();
343 604
344 DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id)); 605 DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id));
345 606
346 if ((ioif >= if_max_interfaces) || (ioif < 0)) { 607 if ((ioif >= if_max_interfaces) || (ioif < 0)) {
347 printk(KERN_CRIT "cris_request_io_interface: Bad interface %u submitted for %s\n", 608 printk(KERN_CRIT "cris_request_io_interface: Bad interface "
609 "%u submitted for %s\n",
348 ioif, 610 ioif,
349 device_id); 611 device_id);
350 return -EINVAL; 612 return -EINVAL;
@@ -353,59 +615,69 @@ int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id
353 local_irq_save(flags); 615 local_irq_save(flags);
354 616
355 if (interfaces[ioif].used) { 617 if (interfaces[ioif].used) {
356 local_irq_restore(flags); 618 printk(KERN_CRIT "cris_io_interface: Cannot allocate interface "
357 printk(KERN_CRIT "cris_io_interface: Cannot allocate interface for %s, in use by %s\n", 619 "%s for %s, in use by %s\n",
620 interfaces[ioif].name,
358 device_id, 621 device_id,
359 interfaces[ioif].owner); 622 interfaces[ioif].owner);
360 return -EBUSY; 623 res = -EBUSY;
624 goto exit;
361 } 625 }
362 626
363 /* Check that all required groups are free before allocating, */ 627 /* Check that all required pins in the used groups are free
628 * before allocating. */
364 group_set = interfaces[ioif].groups; 629 group_set = interfaces[ioif].groups;
365 while (NULL != (grp = get_group(group_set))) { 630 while (NULL != (grp = get_group(group_set))) {
366 if (grp->used) { 631 unsigned int if_group_use = 0;
367 if (grp->group == group_f) { 632
368 if ((if_sync_serial_1 == ioif) || 633 switch (grp->group) {
369 (if_sync_serial_3 == ioif)) { 634 case group_a:
370 if ((grp->owner != if_sync_serial_1) && 635 if_group_use = interfaces[ioif].group_a;
371 (grp->owner != if_sync_serial_3)) { 636 break;
372 local_irq_restore(flags); 637 case group_b:
373 return -EBUSY; 638 if_group_use = interfaces[ioif].group_b;
374 } 639 break;
375 } else if ((if_scsi8_0 == ioif) || 640 case group_c:
376 (if_scsi8_1 == ioif)) { 641 if_group_use = interfaces[ioif].group_c;
377 if ((grp->owner != if_scsi8_0) && 642 break;
378 (grp->owner != if_scsi8_1)) { 643 case group_d:
379 local_irq_restore(flags); 644 if_group_use = interfaces[ioif].group_d;
380 return -EBUSY; 645 break;
381 } 646 case group_e:
382 } 647 if_group_use = interfaces[ioif].group_e;
383 } else { 648 break;
384 local_irq_restore(flags); 649 case group_f:
385 return -EBUSY; 650 if_group_use = interfaces[ioif].group_f;
386 } 651 break;
652 default:
653 BUG_ON(1);
387 } 654 }
655
656 if (if_group_use & grp->used) {
657 printk(KERN_INFO "cris_request_io_interface: group "
658 "%s needed by %s not available\n",
659 grp->name, interfaces[ioif].name);
660 res = -EBUSY;
661 goto exit;
662 }
663
388 group_set = clear_group_from_set(group_set, grp); 664 group_set = clear_group_from_set(group_set, grp);
389 } 665 }
390 666
391 /* Are the required GPIO pins available too? */ 667 /* Are the required GPIO pins available too? */
392 if (((interfaces[ioif].gpio_g_in & gpio_in_pins) != interfaces[ioif].gpio_g_in) || 668 if (((interfaces[ioif].gpio_g_in & gpio_in_pins) !=
393 ((interfaces[ioif].gpio_g_out & gpio_out_pins) != interfaces[ioif].gpio_g_out) || 669 interfaces[ioif].gpio_g_in) ||
394 ((interfaces[ioif].gpio_b & gpio_pb_pins) != interfaces[ioif].gpio_b)) { 670 ((interfaces[ioif].gpio_g_out & gpio_out_pins) !=
395 local_irq_restore(flags); 671 interfaces[ioif].gpio_g_out) ||
396 printk(KERN_CRIT "cris_request_io_interface: Could not get required pins for interface %u\n", 672 ((interfaces[ioif].gpio_b & gpio_pb_pins) !=
397 ioif); 673 interfaces[ioif].gpio_b)) {
398 return -EBUSY; 674 printk(KERN_CRIT "cris_request_io_interface: Could not get "
399 } 675 "required pins for interface %u\n", ioif);
400 676 res = -EBUSY;
401 /* All needed I/O pins and pin groups are free, allocate. */ 677 goto exit;
402 group_set = interfaces[ioif].groups;
403 while (NULL != (grp = get_group(group_set))) {
404 grp->used = 1;
405 grp->owner = ioif;
406 group_set = clear_group_from_set(group_set, grp);
407 } 678 }
408 679
680 /* Check which registers need to be reconfigured. */
409 gens = genconfig_shadow; 681 gens = genconfig_shadow;
410 gens_ii = gen_config_ii_shadow; 682 gens_ii = gen_config_ii_shadow;
411 683
@@ -495,9 +767,43 @@ int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id
495 set_gen_config = 0; 767 set_gen_config = 0;
496 break; 768 break;
497 default: 769 default:
498 panic("cris_request_io_interface: Bad interface %u submitted for %s\n", 770 printk(KERN_INFO "cris_request_io_interface: Bad interface "
499 ioif, 771 "%u submitted for %s\n",
500 device_id); 772 ioif, device_id);
773 res = -EBUSY;
774 goto exit;
775 }
776
777 /* All needed I/O pins and pin groups are free, allocate. */
778 group_set = interfaces[ioif].groups;
779 while (NULL != (grp = get_group(group_set))) {
780 unsigned int if_group_use = 0;
781
782 switch (grp->group) {
783 case group_a:
784 if_group_use = interfaces[ioif].group_a;
785 break;
786 case group_b:
787 if_group_use = interfaces[ioif].group_b;
788 break;
789 case group_c:
790 if_group_use = interfaces[ioif].group_c;
791 break;
792 case group_d:
793 if_group_use = interfaces[ioif].group_d;
794 break;
795 case group_e:
796 if_group_use = interfaces[ioif].group_e;
797 break;
798 case group_f:
799 if_group_use = interfaces[ioif].group_f;
800 break;
801 default:
802 BUG_ON(1);
803 }
804 grp->used |= if_group_use;
805
806 group_set = clear_group_from_set(group_set, grp);
501 } 807 }
502 808
503 interfaces[ioif].used = 1; 809 interfaces[ioif].used = 1;
@@ -516,25 +822,28 @@ int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id
516 *R_GEN_CONFIG_II = gen_config_ii_shadow; 822 *R_GEN_CONFIG_II = gen_config_ii_shadow;
517 } 823 }
518 824
519 DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", 825 DBG(printk(KERN_DEBUG "GPIO pins: available before: "
520 gpio_in_pins, gpio_out_pins, gpio_pb_pins)); 826 "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
521 DBG(printk("grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", 827 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
522 interfaces[ioif].gpio_g_in, 828 DBG(printk(KERN_DEBUG
523 interfaces[ioif].gpio_g_out, 829 "grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
524 interfaces[ioif].gpio_b)); 830 interfaces[ioif].gpio_g_in,
831 interfaces[ioif].gpio_g_out,
832 interfaces[ioif].gpio_b));
525 833
526 gpio_in_pins &= ~interfaces[ioif].gpio_g_in; 834 gpio_in_pins &= ~interfaces[ioif].gpio_g_in;
527 gpio_out_pins &= ~interfaces[ioif].gpio_g_out; 835 gpio_out_pins &= ~interfaces[ioif].gpio_g_out;
528 gpio_pb_pins &= ~interfaces[ioif].gpio_b; 836 gpio_pb_pins &= ~interfaces[ioif].gpio_b;
529 837
530 DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", 838 DBG(printk(KERN_DEBUG "GPIO pins: available after: "
531 gpio_in_pins, gpio_out_pins, gpio_pb_pins)); 839 "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
840 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
532 841
842exit:
533 local_irq_restore(flags); 843 local_irq_restore(flags);
534 844 if (res == 0)
535 notify_watchers(); 845 notify_watchers();
536 846 return res;
537 return 0;
538} 847}
539 848
540 849
@@ -560,43 +869,35 @@ void cris_free_io_interface(enum cris_io_interface ioif)
560 } 869 }
561 group_set = interfaces[ioif].groups; 870 group_set = interfaces[ioif].groups;
562 while (NULL != (grp = get_group(group_set))) { 871 while (NULL != (grp = get_group(group_set))) {
563 if (grp->group == group_f) { 872 unsigned int if_group_use = 0;
564 switch (ioif) 873
565 { 874 switch (grp->group) {
566 case if_sync_serial_1: 875 case group_a:
567 if ((grp->owner == if_sync_serial_1) && 876 if_group_use = interfaces[ioif].group_a;
568 interfaces[if_sync_serial_3].used) { 877 break;
569 grp->owner = if_sync_serial_3; 878 case group_b:
570 } else 879 if_group_use = interfaces[ioif].group_b;
571 grp->used = 0; 880 break;
572 break; 881 case group_c:
573 case if_sync_serial_3: 882 if_group_use = interfaces[ioif].group_c;
574 if ((grp->owner == if_sync_serial_3) && 883 break;
575 interfaces[if_sync_serial_1].used) { 884 case group_d:
576 grp->owner = if_sync_serial_1; 885 if_group_use = interfaces[ioif].group_d;
577 } else 886 break;
578 grp->used = 0; 887 case group_e:
579 break; 888 if_group_use = interfaces[ioif].group_e;
580 case if_scsi8_0: 889 break;
581 if ((grp->owner == if_scsi8_0) && 890 case group_f:
582 interfaces[if_scsi8_1].used) { 891 if_group_use = interfaces[ioif].group_f;
583 grp->owner = if_scsi8_1; 892 break;
584 } else 893 default:
585 grp->used = 0; 894 BUG_ON(1);
586 break;
587 case if_scsi8_1:
588 if ((grp->owner == if_scsi8_1) &&
589 interfaces[if_scsi8_0].used) {
590 grp->owner = if_scsi8_0;
591 } else
592 grp->used = 0;
593 break;
594 default:
595 grp->used = 0;
596 }
597 } else {
598 grp->used = 0;
599 } 895 }
896
897 if ((grp->used & if_group_use) != if_group_use)
898 BUG_ON(1);
899 grp->used = grp->used & ~if_group_use;
900
600 group_set = clear_group_from_set(group_set, grp); 901 group_set = clear_group_from_set(group_set, grp);
601 } 902 }
602 interfaces[ioif].used = 0; 903 interfaces[ioif].used = 0;