1 /* IO interface mux allocator for ETRAX100LX.
2 * Copyright 2004-2007, Axis Communications AB
3 */
4
5
6 /* C.f. ETRAX100LX Designer's Reference chapter 19.9 */
7
8 #include <linux/kernel.h>
9 #include <linux/slab.h>
10 #include <linux/errno.h>
11 #include <linux/module.h>
12 #include <linux/init.h>
13
14 #include <arch/svinto.h>
15 #include <asm/io.h>
16 #include <arch/io_interface_mux.h>
17 #include <arch/system.h>
18
19
20 #define DBG(s)
21
22 /* Macro to access ETRAX 100 registers */
23 #define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
24 IO_STATE_(reg##_, field##_, _##val)
25
26 enum io_if_group {
27 group_a = (1<<0),
28 group_b = (1<<1),
29 group_c = (1<<2),
30 group_d = (1<<3),
31 group_e = (1<<4),
32 group_f = (1<<5)
33 };
34
35 struct watcher
36 {
37 void (*notify)(const unsigned int gpio_in_available,
38 const unsigned int gpio_out_available,
39 const unsigned char pa_available,
40 const unsigned char pb_available);
41 struct watcher *next;
42 };
43
44
45 struct if_group
46 {
47 enum io_if_group group;
48 /* name - the name of the group 'A' to 'F' */
49 char *name;
50 /* used - a bit mask of all pins in the group in the order listed
51 * in the tables in 19.9.1 to 19.9.6. Note that no
52 * distinction is made between in, out and in/out pins. */
53 unsigned int used;
54 };
55
56
57 struct interface
58 {
59 enum cris_io_interface ioif;
60 /* name - the name of the interface */
61 char *name;
62 /* groups - OR'ed together io_if_group flags describing what pin groups
63 * the interface uses pins in. */
64 unsigned char groups;
65 /* used - set when the interface is allocated. */
66 unsigned char used;
67 char *owner;
68 /* group_a through group_f - bit masks describing what pins in the
69 * pin groups the interface uses. */
70 unsigned int group_a;
71 unsigned int group_b;
72 unsigned int group_c;
73 unsigned int group_d;
74 unsigned int group_e;
75 unsigned int group_f;
76
77 /* gpio_g_in, gpio_g_out, gpio_b - bit masks telling what pins in the
78 * GPIO ports the interface uses. This could be reconstucted using
79 * the group_X masks and a table of what pins the GPIO ports use,
80 * but that would be messy. */
81 unsigned int gpio_g_in;
82 unsigned int gpio_g_out;
83 unsigned char gpio_b;
84 };
85
86 static struct if_group if_groups[6] = {
87 {
88 .group = group_a,
89 .name = "A",
90 .used = 0,
91 },
92 {
93 .group = group_b,
94 .name = "B",
95 .used = 0,
96 },
97 {
98 .group = group_c,
99 .name = "C",
100 .used = 0,
101 },
102 {
103 .group = group_d,
104 .name = "D",
105 .used = 0,
106 },
107 {
108 .group = group_e,
109 .name = "E",
110 .used = 0,
111 },
112 {
113 .group = group_f,
114 .name = "F",
115 .used = 0,
116 }
117 };
118
119 /* The order in the array must match the order of enum
120 * cris_io_interface in io_interface_mux.h */
121 static struct interface interfaces[] = {
122 /* Begin Non-multiplexed interfaces */
123 {
124 .ioif = if_eth,
125 .name = "ethernet",
126 .groups = 0,
127
128 .group_a = 0,
129 .group_b = 0,
130 .group_c = 0,
131 .group_d = 0,
132 .group_e = 0,
133 .group_f = 0,
134
135 .gpio_g_in = 0,
136 .gpio_g_out = 0,
137 .gpio_b = 0
138 },
139 {
140 .ioif = if_serial_0,
141 .name = "serial_0",
142 .groups = 0,
143
144 .group_a = 0,
145 .group_b = 0,
146 .group_c = 0,
147 .group_d = 0,
148 .group_e = 0,
149 .group_f = 0,
150
151 .gpio_g_in = 0,
152 .gpio_g_out = 0,
153 .gpio_b = 0
154 },
155 /* End Non-multiplexed interfaces */
156 {
157 .ioif = if_serial_1,
158 .name = "serial_1",
159 .groups = group_e,
160
161 .group_a = 0,
162 .group_b = 0,
163 .group_c = 0,
164 .group_d = 0,
165 .group_e = 0x0f,
166 .group_f = 0,
167
168 .gpio_g_in = 0x00000000,
169 .gpio_g_out = 0x00000000,
170 .gpio_b = 0x00
171 },
172 {
173 .ioif = if_serial_2,
174 .name = "serial_2",
175 .groups = group_b,
176
177 .group_a = 0,
178 .group_b = 0x0f,
179 .group_c = 0,
180 .group_d = 0,
181 .group_e = 0,
182 .group_f = 0,
183
184 .gpio_g_in = 0x000000c0,
185 .gpio_g_out = 0x000000c0,
186 .gpio_b = 0x00
187 },
188 {
189 .ioif = if_serial_3,
190 .name = "serial_3",
191 .groups = group_c,
192
193 .group_a = 0,
194 .group_b = 0,
195 .group_c = 0x0f,
196 .group_d = 0,
197 .group_e = 0,
198 .group_f = 0,
199
200 .gpio_g_in = 0xc0000000,
201 .gpio_g_out = 0xc0000000,
202 .gpio_b = 0x00
203 },
204 {
205 .ioif = if_sync_serial_1,
206 .name = "sync_serial_1",
207 .groups = group_e | group_f,
208
209 .group_a = 0,
210 .group_b = 0,
211 .group_c = 0,
212 .group_d = 0,
213 .group_e = 0x0f,
214 .group_f = 0x10,
215
216 .gpio_g_in = 0x00000000,
217 .gpio_g_out = 0x00000000,
218 .gpio_b = 0x10
219 },
220 {
221 .ioif = if_sync_serial_3,
222 .name = "sync_serial_3",
223 .groups = group_c | group_f,
224
225 .group_a = 0,
226 .group_b = 0,
227 .group_c = 0x0f,
228 .group_d = 0,
229 .group_e = 0,
230 .group_f = 0x80,
231
232 .gpio_g_in = 0xc0000000,
233 .gpio_g_out = 0xc0000000,
234 .gpio_b = 0x80
235 },
236 {
237 .ioif = if_shared_ram,
238 .name = "shared_ram",
239 .groups = group_a,
240
241 .group_a = 0x7f8ff,
242 .group_b = 0,
243 .group_c = 0,
244 .group_d = 0,
245 .group_e = 0,
246 .group_f = 0,
247
248 .gpio_g_in = 0x0000ff3e,
249 .gpio_g_out = 0x0000ff38,
250 .gpio_b = 0x00
251 },
252 {
253 .ioif = if_shared_ram_w,
254 .name = "shared_ram_w",
255 .groups = group_a | group_d,
256
257 .group_a = 0x7f8ff,
258 .group_b = 0,
259 .group_c = 0,
260 .group_d = 0xff,
261 .group_e = 0,
262 .group_f = 0,
263
264 .gpio_g_in = 0x00ffff3e,
265 .gpio_g_out = 0x00ffff38,
266 .gpio_b = 0x00
267 },
268 {
269 .ioif = if_par_0,
270 .name = "par_0",
271 .groups = group_a,
272
273 .group_a = 0x7fbff,
274 .group_b = 0,
275 .group_c = 0,
276 .group_d = 0,
277 .group_e = 0,
278 .group_f = 0,
279
280 .gpio_g_in = 0x0000ff3e,
281 .gpio_g_out = 0x0000ff3e,
282 .gpio_b = 0x00
283 },
284 {
285 .ioif = if_par_1,
286 .name = "par_1",
287 .groups = group_d,
288
289 .group_a = 0,
290 .group_b = 0,
291 .group_c = 0,
292 .group_d = 0x7feff,
293 .group_e = 0,
294 .group_f = 0,
295
296 .gpio_g_in = 0x3eff0000,
297 .gpio_g_out = 0x3eff0000,
298 .gpio_b = 0x00
299 },
300 {
301 .ioif = if_par_w,
302 .name = "par_w",
303 .groups = group_a | group_d,
304
305 .group_a = 0x7fbff,
306 .group_b = 0,
307 .group_c = 0,
308 .group_d = 0xff,
309 .group_e = 0,
310 .group_f = 0,
311
312 .gpio_g_in = 0x00ffff3e,
313 .gpio_g_out = 0x00ffff3e,
314 .gpio_b = 0x00
315 },
316 {
317 .ioif = if_scsi8_0,
318 .name = "scsi8_0",
319 .groups = group_a | group_b | group_f,
320
321 .group_a = 0x7ffff,
322 .group_b = 0x0f,
323 .group_c = 0,
324 .group_d = 0,
325 .group_e = 0,
326 .group_f = 0x10,
327
328 .gpio_g_in = 0x0000ffff,
329 .gpio_g_out = 0x0000ffff,
330 .gpio_b = 0x10
331 },
332 {
333 .ioif = if_scsi8_1,
334 .name = "scsi8_1",
335 .groups = group_c | group_d | group_f,
336
337 .group_a = 0,
338 .group_b = 0,
339 .group_c = 0x0f,
340 .group_d = 0x7ffff,
341 .group_e = 0,
342 .group_f = 0x80,
343
344 .gpio_g_in = 0xffff0000,
345 .gpio_g_out = 0xffff0000,
346 .gpio_b = 0x80
347 },
348 {
349 .ioif = if_scsi_w,
350 .name = "scsi_w",
351 .groups = group_a | group_b | group_d | group_f,
352
353 .group_a = 0x7ffff,
354 .group_b = 0x0f,
355 .group_c = 0,
356 .group_d = 0x601ff,
357 .group_e = 0,
358 .group_f = 0x90,
359
360 .gpio_g_in = 0x01ffffff,
361 .gpio_g_out = 0x07ffffff,
362 .gpio_b = 0x80
363 },
364 {
365 .ioif = if_ata,
366 .name = "ata",
367 .groups = group_a | group_b | group_c | group_d,
368
369 .group_a = 0x7ffff,
370 .group_b = 0x0f,
371 .group_c = 0x0f,
372 .group_d = 0x7cfff,
373 .group_e = 0,
374 .group_f = 0,
375
376 .gpio_g_in = 0xf9ffffff,
377 .gpio_g_out = 0xffffffff,
378 .gpio_b = 0x80
379 },
380 {
381 .ioif = if_csp,
382 .name = "csp",
383 .groups = group_f,
384
385 .group_a = 0,
386 .group_b = 0,
387 .group_c = 0,
388 .group_d = 0,
389 .group_e = 0,
390 .group_f = 0xfc,
391
392 .gpio_g_in = 0x00000000,
393 .gpio_g_out = 0x00000000,
394 .gpio_b = 0xfc
395 },
396 {
397 .ioif = if_i2c,
398 .name = "i2c",
399 .groups = group_f,
400
401 .group_a = 0,
402 .group_b = 0,
403 .group_c = 0,
404 .group_d = 0,
405 .group_e = 0,
406 .group_f = 0x03,
407
408 .gpio_g_in = 0x00000000,
409 .gpio_g_out = 0x00000000,
410 .gpio_b = 0x03
411 },
412 {
413 .ioif = if_usb_1,
414 .name = "usb_1",
415 .groups = group_e | group_f,
416
417 .group_a = 0,
418 .group_b = 0,
419 .group_c = 0,
420 .group_d = 0,
421 .group_e = 0x0f,
422 .group_f = 0x2c,
423
424 .gpio_g_in = 0x00000000,
425 .gpio_g_out = 0x00000000,
426 .gpio_b = 0x2c
427 },
428 {
429 .ioif = if_usb_2,
430 .name = "usb_2",
431 .groups = group_d,
432
433 .group_a = 0,
434 .group_b = 0,
435 .group_c = 0,
436 .group_d = 0,
437 .group_e = 0x33e00,
438 .group_f = 0,
439
440 .gpio_g_in = 0x3e000000,
441 .gpio_g_out = 0x0c000000,
442 .gpio_b = 0x00
443 },
444 /* GPIO pins */
445 {
446 .ioif = if_gpio_grp_a,
447 .name = "gpio_a",
448 .groups = group_a,
449
450 .group_a = 0,
451 .group_b = 0,
452 .group_c = 0,
453 .group_d = 0,
454 .group_e = 0,
455 .group_f = 0,
456
457 .gpio_g_in = 0x0000ff3f,
458 .gpio_g_out = 0x0000ff3f,
459 .gpio_b = 0x00
460 },
461 {
462 .ioif = if_gpio_grp_b,
463 .name = "gpio_b",
464 .groups = group_b,
465
466 .group_a = 0,
467 .group_b = 0,
468 .group_c = 0,
469 .group_d = 0,
470 .group_e = 0,
471 .group_f = 0,
472
473 .gpio_g_in = 0x000000c0,
474 .gpio_g_out = 0x000000c0,
475 .gpio_b = 0x00
476 },
477 {
478 .ioif = if_gpio_grp_c,
479 .name = "gpio_c",
480 .groups = group_c,
481
482 .group_a = 0,
483 .group_b = 0,
484 .group_c = 0,
485 .group_d = 0,
486 .group_e = 0,
487 .group_f = 0,
488
489 .gpio_g_in = 0xc0000000,
490 .gpio_g_out = 0xc0000000,
491 .gpio_b = 0x00
492 },
493 {
494 .ioif = if_gpio_grp_d,
495 .name = "gpio_d",
496 .groups = group_d,
497
498 .group_a = 0,
499 .group_b = 0,
500 .group_c = 0,
501 .group_d = 0,
502 .group_e = 0,
503 .group_f = 0,
504
505 .gpio_g_in = 0x3fff0000,
506 .gpio_g_out = 0x3fff0000,
507 .gpio_b = 0x00
508 },
509 {
510 .ioif = if_gpio_grp_e,
511 .name = "gpio_e",
512 .groups = group_e,
513
514 .group_a = 0,
515 .group_b = 0,
516 .group_c = 0,
517 .group_d = 0,
518 .group_e = 0,
519 .group_f = 0,
520
521 .gpio_g_in = 0x00000000,
522 .gpio_g_out = 0x00000000,
523 .gpio_b = 0x00
524 },
525 {
526 .ioif = if_gpio_grp_f,
527 .name = "gpio_f",
528 .groups = group_f,
529
530 .group_a = 0,
531 .group_b = 0,
532 .group_c = 0,
533 .group_d = 0,
534 .group_e = 0,
535 .group_f = 0,
536
537 .gpio_g_in = 0x00000000,
538 .gpio_g_out = 0x00000000,
539 .gpio_b = 0xff
540 }
541 /* Array end */
542 };
543
544 static struct watcher *watchers = NULL;
545
546 /* The pins that are free to use in the GPIO ports. */
547 static unsigned int gpio_in_pins = 0xffffffff;
548 static unsigned int gpio_out_pins = 0xffffffff;
549 static unsigned char gpio_pb_pins = 0xff;
550 static unsigned char gpio_pa_pins = 0xff;
551
552 /* Identifiers for the owners of the GPIO pins. */
553 static enum cris_io_interface gpio_pa_owners[8];
554 static enum cris_io_interface gpio_pb_owners[8];
555 static enum cris_io_interface gpio_pg_owners[32];
556
557 static int cris_io_interface_init(void);
558
clear_group_from_set(const unsigned char groups,struct if_group * group)559 static unsigned char clear_group_from_set(const unsigned char groups, struct if_group *group)
560 {
561 return (groups & ~group->group);
562 }
563
564
get_group(const unsigned char groups)565 static struct if_group *get_group(const unsigned char groups)
566 {
567 int i;
568 for (i = 0; i < ARRAY_SIZE(if_groups); i++) {
569 if (groups & if_groups[i].group) {
570 return &if_groups[i];
571 }
572 }
573 return NULL;
574 }
575
576
notify_watchers(void)577 static void notify_watchers(void)
578 {
579 struct watcher *w = watchers;
580
581 DBG(printk("io_interface_mux: notifying watchers\n"));
582
583 while (NULL != w) {
584 w->notify((const unsigned int)gpio_in_pins,
585 (const unsigned int)gpio_out_pins,
586 (const unsigned char)gpio_pa_pins,
587 (const unsigned char)gpio_pb_pins);
588 w = w->next;
589 }
590 }
591
592
cris_request_io_interface(enum cris_io_interface ioif,const char * device_id)593 int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id)
594 {
595 int set_gen_config = 0;
596 int set_gen_config_ii = 0;
597 unsigned long int gens;
598 unsigned long int gens_ii;
599 struct if_group *grp;
600 unsigned char group_set;
601 unsigned long flags;
602 int res = 0;
603
604 (void)cris_io_interface_init();
605
606 DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id));
607
608 if ((ioif >= if_max_interfaces) || (ioif < 0)) {
609 printk(KERN_CRIT "cris_request_io_interface: Bad interface "
610 "%u submitted for %s\n",
611 ioif,
612 device_id);
613 return -EINVAL;
614 }
615
616 local_irq_save(flags);
617
618 if (interfaces[ioif].used) {
619 printk(KERN_CRIT "cris_io_interface: Cannot allocate interface "
620 "%s for %s, in use by %s\n",
621 interfaces[ioif].name,
622 device_id,
623 interfaces[ioif].owner);
624 res = -EBUSY;
625 goto exit;
626 }
627
628 /* Check that all required pins in the used groups are free
629 * before allocating. */
630 group_set = interfaces[ioif].groups;
631 while (NULL != (grp = get_group(group_set))) {
632 unsigned int if_group_use = 0;
633
634 switch (grp->group) {
635 case group_a:
636 if_group_use = interfaces[ioif].group_a;
637 break;
638 case group_b:
639 if_group_use = interfaces[ioif].group_b;
640 break;
641 case group_c:
642 if_group_use = interfaces[ioif].group_c;
643 break;
644 case group_d:
645 if_group_use = interfaces[ioif].group_d;
646 break;
647 case group_e:
648 if_group_use = interfaces[ioif].group_e;
649 break;
650 case group_f:
651 if_group_use = interfaces[ioif].group_f;
652 break;
653 default:
654 BUG_ON(1);
655 }
656
657 if (if_group_use & grp->used) {
658 printk(KERN_INFO "cris_request_io_interface: group "
659 "%s needed by %s not available\n",
660 grp->name, interfaces[ioif].name);
661 res = -EBUSY;
662 goto exit;
663 }
664
665 group_set = clear_group_from_set(group_set, grp);
666 }
667
668 /* Are the required GPIO pins available too? */
669 if (((interfaces[ioif].gpio_g_in & gpio_in_pins) !=
670 interfaces[ioif].gpio_g_in) ||
671 ((interfaces[ioif].gpio_g_out & gpio_out_pins) !=
672 interfaces[ioif].gpio_g_out) ||
673 ((interfaces[ioif].gpio_b & gpio_pb_pins) !=
674 interfaces[ioif].gpio_b)) {
675 printk(KERN_CRIT "cris_request_io_interface: Could not get "
676 "required pins for interface %u\n", ioif);
677 res = -EBUSY;
678 goto exit;
679 }
680
681 /* Check which registers need to be reconfigured. */
682 gens = genconfig_shadow;
683 gens_ii = gen_config_ii_shadow;
684
685 set_gen_config = 1;
686 switch (ioif)
687 {
688 /* Begin Non-multiplexed interfaces */
689 case if_eth:
690 /* fall through */
691 case if_serial_0:
692 set_gen_config = 0;
693 break;
694 /* End Non-multiplexed interfaces */
695 case if_serial_1:
696 set_gen_config_ii = 1;
697 SETS(gens_ii, R_GEN_CONFIG_II, sermode1, async);
698 break;
699 case if_serial_2:
700 SETS(gens, R_GEN_CONFIG, ser2, select);
701 break;
702 case if_serial_3:
703 SETS(gens, R_GEN_CONFIG, ser3, select);
704 set_gen_config_ii = 1;
705 SETS(gens_ii, R_GEN_CONFIG_II, sermode3, async);
706 break;
707 case if_sync_serial_1:
708 set_gen_config_ii = 1;
709 SETS(gens_ii, R_GEN_CONFIG_II, sermode1, sync);
710 break;
711 case if_sync_serial_3:
712 SETS(gens, R_GEN_CONFIG, ser3, select);
713 set_gen_config_ii = 1;
714 SETS(gens_ii, R_GEN_CONFIG_II, sermode3, sync);
715 break;
716 case if_shared_ram:
717 SETS(gens, R_GEN_CONFIG, mio, select);
718 break;
719 case if_shared_ram_w:
720 SETS(gens, R_GEN_CONFIG, mio_w, select);
721 break;
722 case if_par_0:
723 SETS(gens, R_GEN_CONFIG, par0, select);
724 break;
725 case if_par_1:
726 SETS(gens, R_GEN_CONFIG, par1, select);
727 break;
728 case if_par_w:
729 SETS(gens, R_GEN_CONFIG, par0, select);
730 SETS(gens, R_GEN_CONFIG, par_w, select);
731 break;
732 case if_scsi8_0:
733 SETS(gens, R_GEN_CONFIG, scsi0, select);
734 break;
735 case if_scsi8_1:
736 SETS(gens, R_GEN_CONFIG, scsi1, select);
737 break;
738 case if_scsi_w:
739 SETS(gens, R_GEN_CONFIG, scsi0, select);
740 SETS(gens, R_GEN_CONFIG, scsi0w, select);
741 break;
742 case if_ata:
743 SETS(gens, R_GEN_CONFIG, ata, select);
744 break;
745 case if_csp:
746 /* fall through */
747 case if_i2c:
748 set_gen_config = 0;
749 break;
750 case if_usb_1:
751 SETS(gens, R_GEN_CONFIG, usb1, select);
752 break;
753 case if_usb_2:
754 SETS(gens, R_GEN_CONFIG, usb2, select);
755 break;
756 case if_gpio_grp_a:
757 /* GPIO groups are only accounted, don't do configuration changes. */
758 /* fall through */
759 case if_gpio_grp_b:
760 /* fall through */
761 case if_gpio_grp_c:
762 /* fall through */
763 case if_gpio_grp_d:
764 /* fall through */
765 case if_gpio_grp_e:
766 /* fall through */
767 case if_gpio_grp_f:
768 set_gen_config = 0;
769 break;
770 default:
771 printk(KERN_INFO "cris_request_io_interface: Bad interface "
772 "%u submitted for %s\n",
773 ioif, device_id);
774 res = -EBUSY;
775 goto exit;
776 }
777
778 /* All needed I/O pins and pin groups are free, allocate. */
779 group_set = interfaces[ioif].groups;
780 while (NULL != (grp = get_group(group_set))) {
781 unsigned int if_group_use = 0;
782
783 switch (grp->group) {
784 case group_a:
785 if_group_use = interfaces[ioif].group_a;
786 break;
787 case group_b:
788 if_group_use = interfaces[ioif].group_b;
789 break;
790 case group_c:
791 if_group_use = interfaces[ioif].group_c;
792 break;
793 case group_d:
794 if_group_use = interfaces[ioif].group_d;
795 break;
796 case group_e:
797 if_group_use = interfaces[ioif].group_e;
798 break;
799 case group_f:
800 if_group_use = interfaces[ioif].group_f;
801 break;
802 default:
803 BUG_ON(1);
804 }
805 grp->used |= if_group_use;
806
807 group_set = clear_group_from_set(group_set, grp);
808 }
809
810 interfaces[ioif].used = 1;
811 interfaces[ioif].owner = (char*)device_id;
812
813 if (set_gen_config) {
814 volatile int i;
815 genconfig_shadow = gens;
816 *R_GEN_CONFIG = genconfig_shadow;
817 /* Wait 12 cycles before doing any DMA command */
818 for(i = 6; i > 0; i--)
819 nop();
820 }
821 if (set_gen_config_ii) {
822 gen_config_ii_shadow = gens_ii;
823 *R_GEN_CONFIG_II = gen_config_ii_shadow;
824 }
825
826 DBG(printk(KERN_DEBUG "GPIO pins: available before: "
827 "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
828 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
829 DBG(printk(KERN_DEBUG
830 "grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
831 interfaces[ioif].gpio_g_in,
832 interfaces[ioif].gpio_g_out,
833 interfaces[ioif].gpio_b));
834
835 gpio_in_pins &= ~interfaces[ioif].gpio_g_in;
836 gpio_out_pins &= ~interfaces[ioif].gpio_g_out;
837 gpio_pb_pins &= ~interfaces[ioif].gpio_b;
838
839 DBG(printk(KERN_DEBUG "GPIO pins: available after: "
840 "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
841 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
842
843 exit:
844 local_irq_restore(flags);
845 if (res == 0)
846 notify_watchers();
847 return res;
848 }
849
850
cris_free_io_interface(enum cris_io_interface ioif)851 void cris_free_io_interface(enum cris_io_interface ioif)
852 {
853 struct if_group *grp;
854 unsigned char group_set;
855 unsigned long flags;
856
857 (void)cris_io_interface_init();
858
859 if ((ioif >= if_max_interfaces) || (ioif < 0)) {
860 printk(KERN_CRIT "cris_free_io_interface: Bad interface %u\n",
861 ioif);
862 return;
863 }
864 local_irq_save(flags);
865 if (!interfaces[ioif].used) {
866 printk(KERN_CRIT "cris_free_io_interface: Freeing free interface %u\n",
867 ioif);
868 local_irq_restore(flags);
869 return;
870 }
871 group_set = interfaces[ioif].groups;
872 while (NULL != (grp = get_group(group_set))) {
873 unsigned int if_group_use = 0;
874
875 switch (grp->group) {
876 case group_a:
877 if_group_use = interfaces[ioif].group_a;
878 break;
879 case group_b:
880 if_group_use = interfaces[ioif].group_b;
881 break;
882 case group_c:
883 if_group_use = interfaces[ioif].group_c;
884 break;
885 case group_d:
886 if_group_use = interfaces[ioif].group_d;
887 break;
888 case group_e:
889 if_group_use = interfaces[ioif].group_e;
890 break;
891 case group_f:
892 if_group_use = interfaces[ioif].group_f;
893 break;
894 default:
895 BUG_ON(1);
896 }
897
898 if ((grp->used & if_group_use) != if_group_use)
899 BUG_ON(1);
900 grp->used = grp->used & ~if_group_use;
901
902 group_set = clear_group_from_set(group_set, grp);
903 }
904 interfaces[ioif].used = 0;
905 interfaces[ioif].owner = NULL;
906
907 DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
908 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
909 DBG(printk("freeing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
910 interfaces[ioif].gpio_g_in,
911 interfaces[ioif].gpio_g_out,
912 interfaces[ioif].gpio_b));
913
914 gpio_in_pins |= interfaces[ioif].gpio_g_in;
915 gpio_out_pins |= interfaces[ioif].gpio_g_out;
916 gpio_pb_pins |= interfaces[ioif].gpio_b;
917
918 DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
919 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
920
921 local_irq_restore(flags);
922
923 notify_watchers();
924 }
925
926 /* Create a bitmask from bit 0 (inclusive) to bit stop_bit
927 (non-inclusive). stop_bit == 0 returns 0x0 */
create_mask(const unsigned stop_bit)928 static inline unsigned int create_mask(const unsigned stop_bit)
929 {
930 /* Avoid overflow */
931 if (stop_bit >= 32) {
932 return 0xffffffff;
933 }
934 return (1<<stop_bit)-1;
935 }
936
937
938 /* port can be 'a', 'b' or 'g' */
cris_io_interface_allocate_pins(const enum cris_io_interface ioif,const char port,const unsigned start_bit,const unsigned stop_bit)939 int cris_io_interface_allocate_pins(const enum cris_io_interface ioif,
940 const char port,
941 const unsigned start_bit,
942 const unsigned stop_bit)
943 {
944 unsigned int i;
945 unsigned int mask = 0;
946 unsigned int tmp_mask;
947 unsigned long int flags;
948 enum cris_io_interface *owners;
949
950 (void)cris_io_interface_init();
951
952 DBG(printk("cris_io_interface_allocate_pins: if=%d port=%c start=%u stop=%u\n",
953 ioif, port, start_bit, stop_bit));
954
955 if (!((start_bit <= stop_bit) &&
956 ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
957 ((port == 'g') && (stop_bit < 32))))) {
958 return -EINVAL;
959 }
960
961 mask = create_mask(stop_bit + 1);
962 tmp_mask = create_mask(start_bit);
963 mask &= ~tmp_mask;
964
965 DBG(printk("cris_io_interface_allocate_pins: port=%c start=%u stop=%u mask=0x%08x\n",
966 port, start_bit, stop_bit, mask));
967
968 local_irq_save(flags);
969
970 switch (port) {
971 case 'a':
972 if ((gpio_pa_pins & mask) != mask) {
973 local_irq_restore(flags);
974 return -EBUSY;
975 }
976 owners = gpio_pa_owners;
977 gpio_pa_pins &= ~mask;
978 break;
979 case 'b':
980 if ((gpio_pb_pins & mask) != mask) {
981 local_irq_restore(flags);
982 return -EBUSY;
983 }
984 owners = gpio_pb_owners;
985 gpio_pb_pins &= ~mask;
986 break;
987 case 'g':
988 if (((gpio_in_pins & mask) != mask) ||
989 ((gpio_out_pins & mask) != mask)) {
990 local_irq_restore(flags);
991 return -EBUSY;
992 }
993 owners = gpio_pg_owners;
994 gpio_in_pins &= ~mask;
995 gpio_out_pins &= ~mask;
996 break;
997 default:
998 local_irq_restore(flags);
999 return -EINVAL;
1000 }
1001
1002 for (i = start_bit; i <= stop_bit; i++) {
1003 owners[i] = ioif;
1004 }
1005 local_irq_restore(flags);
1006
1007 notify_watchers();
1008 return 0;
1009 }
1010
1011
1012 /* port can be 'a', 'b' or 'g' */
cris_io_interface_free_pins(const enum cris_io_interface ioif,const char port,const unsigned start_bit,const unsigned stop_bit)1013 int cris_io_interface_free_pins(const enum cris_io_interface ioif,
1014 const char port,
1015 const unsigned start_bit,
1016 const unsigned stop_bit)
1017 {
1018 unsigned int i;
1019 unsigned int mask = 0;
1020 unsigned int tmp_mask;
1021 unsigned long int flags;
1022 enum cris_io_interface *owners;
1023
1024 (void)cris_io_interface_init();
1025
1026 if (!((start_bit <= stop_bit) &&
1027 ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
1028 ((port == 'g') && (stop_bit < 32))))) {
1029 return -EINVAL;
1030 }
1031
1032 mask = create_mask(stop_bit + 1);
1033 tmp_mask = create_mask(start_bit);
1034 mask &= ~tmp_mask;
1035
1036 DBG(printk("cris_io_interface_free_pins: port=%c start=%u stop=%u mask=0x%08x\n",
1037 port, start_bit, stop_bit, mask));
1038
1039 local_irq_save(flags);
1040
1041 switch (port) {
1042 case 'a':
1043 if ((~gpio_pa_pins & mask) != mask) {
1044 local_irq_restore(flags);
1045 printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
1046 }
1047 owners = gpio_pa_owners;
1048 break;
1049 case 'b':
1050 if ((~gpio_pb_pins & mask) != mask) {
1051 local_irq_restore(flags);
1052 printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
1053 }
1054 owners = gpio_pb_owners;
1055 break;
1056 case 'g':
1057 if (((~gpio_in_pins & mask) != mask) ||
1058 ((~gpio_out_pins & mask) != mask)) {
1059 local_irq_restore(flags);
1060 printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
1061 }
1062 owners = gpio_pg_owners;
1063 break;
1064 default:
1065 owners = NULL; /* Cannot happen. Shut up, gcc! */
1066 }
1067
1068 for (i = start_bit; i <= stop_bit; i++) {
1069 if (owners[i] != ioif) {
1070 printk(KERN_CRIT "cris_io_interface_free_pins: Freeing unowned pins");
1071 }
1072 }
1073
1074 /* All was ok, change data. */
1075 switch (port) {
1076 case 'a':
1077 gpio_pa_pins |= mask;
1078 break;
1079 case 'b':
1080 gpio_pb_pins |= mask;
1081 break;
1082 case 'g':
1083 gpio_in_pins |= mask;
1084 gpio_out_pins |= mask;
1085 break;
1086 }
1087
1088 for (i = start_bit; i <= stop_bit; i++) {
1089 owners[i] = if_unclaimed;
1090 }
1091 local_irq_restore(flags);
1092 notify_watchers();
1093
1094 return 0;
1095 }
1096
1097
cris_io_interface_register_watcher(void (* notify)(const unsigned int gpio_in_available,const unsigned int gpio_out_available,const unsigned char pa_available,const unsigned char pb_available))1098 int cris_io_interface_register_watcher(void (*notify)(const unsigned int gpio_in_available,
1099 const unsigned int gpio_out_available,
1100 const unsigned char pa_available,
1101 const unsigned char pb_available))
1102 {
1103 struct watcher *w;
1104
1105 (void)cris_io_interface_init();
1106
1107 if (NULL == notify) {
1108 return -EINVAL;
1109 }
1110 w = kmalloc(sizeof(*w), GFP_KERNEL);
1111 if (!w) {
1112 return -ENOMEM;
1113 }
1114 w->notify = notify;
1115 w->next = watchers;
1116 watchers = w;
1117
1118 w->notify((const unsigned int)gpio_in_pins,
1119 (const unsigned int)gpio_out_pins,
1120 (const unsigned char)gpio_pa_pins,
1121 (const unsigned char)gpio_pb_pins);
1122
1123 return 0;
1124 }
1125
cris_io_interface_delete_watcher(void (* notify)(const unsigned int gpio_in_available,const unsigned int gpio_out_available,const unsigned char pa_available,const unsigned char pb_available))1126 void cris_io_interface_delete_watcher(void (*notify)(const unsigned int gpio_in_available,
1127 const unsigned int gpio_out_available,
1128 const unsigned char pa_available,
1129 const unsigned char pb_available))
1130 {
1131 struct watcher *w = watchers, *prev = NULL;
1132
1133 (void)cris_io_interface_init();
1134
1135 while ((NULL != w) && (w->notify != notify)){
1136 prev = w;
1137 w = w->next;
1138 }
1139 if (NULL != w) {
1140 if (NULL != prev) {
1141 prev->next = w->next;
1142 } else {
1143 watchers = w->next;
1144 }
1145 kfree(w);
1146 return;
1147 }
1148 printk(KERN_WARNING "cris_io_interface_delete_watcher: Deleting unknown watcher 0x%p\n", notify);
1149 }
1150
1151
cris_io_interface_init(void)1152 static int cris_io_interface_init(void)
1153 {
1154 static int first = 1;
1155 int i;
1156
1157 if (!first) {
1158 return 0;
1159 }
1160 first = 0;
1161
1162 for (i = 0; i<8; i++) {
1163 gpio_pa_owners[i] = if_unclaimed;
1164 gpio_pb_owners[i] = if_unclaimed;
1165 gpio_pg_owners[i] = if_unclaimed;
1166 }
1167 for (; i<32; i++) {
1168 gpio_pg_owners[i] = if_unclaimed;
1169 }
1170 return 0;
1171 }
1172
1173
1174 module_init(cris_io_interface_init);
1175
1176
1177 EXPORT_SYMBOL(cris_request_io_interface);
1178 EXPORT_SYMBOL(cris_free_io_interface);
1179 EXPORT_SYMBOL(cris_io_interface_allocate_pins);
1180 EXPORT_SYMBOL(cris_io_interface_free_pins);
1181 EXPORT_SYMBOL(cris_io_interface_register_watcher);
1182 EXPORT_SYMBOL(cris_io_interface_delete_watcher);
1183