aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/arch-v10
diff options
context:
space:
mode:
authorJesper Nilsson <jesper.nilsson@axis.com>2008-01-29 05:27:19 -0500
committerJesper Nilsson <jesper.nilsson@axis.com>2008-02-08 05:06:32 -0500
commitb1220e2e7f03a0e86078c82819e802c25047638d (patch)
treeda1280d7199cf06d22939ac92da51f4664dcc372 /arch/cris/arch-v10
parent5f526d1467383fbd7d64b4f7de85b2889838e454 (diff)
CRIS v10: Update kernel/io_interface_mux.c
Fixed a bug where two interfaces using pins in the same pin group could not be allocated at the same time even if there where no pin collisions. Change all restore and returns into goto exit pattern. Also, remove useless CVS id and correct chapter reference for ETRAX100LX Designer's Reference in comment.
Diffstat (limited to 'arch/cris/arch-v10')
-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;