• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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