upload tizen1.0 source
[kernel/linux-2.6.36.git] / arch / cris / arch-v10 / kernel / io_interface_mux.c
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
18
19 #define DBG(s)
20
21 /* Macro to access ETRAX 100 registers */
22 #define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
23                                           IO_STATE_(reg##_, field##_, _##val)
24
25 enum io_if_group {
26         group_a = (1<<0),
27         group_b = (1<<1),
28         group_c = (1<<2),
29         group_d = (1<<3),
30         group_e = (1<<4),
31         group_f = (1<<5)
32 };
33
34 struct watcher
35 {
36         void (*notify)(const unsigned int gpio_in_available,
37                        const unsigned int gpio_out_available,
38                        const unsigned char pa_available,
39                        const unsigned char pb_available);
40         struct watcher *next;
41 };
42
43
44 struct if_group
45 {
46         enum io_if_group        group;
47         /* name - the name of the group 'A' to 'F' */
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;
53 };
54
55
56 struct interface
57 {
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. */
63         unsigned char            groups;
64         /* used - set when the interface is allocated. */
65         unsigned char            used;
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. */
80         unsigned int             gpio_g_in;
81         unsigned int             gpio_g_out;
82         unsigned char            gpio_b;
83 };
84
85 static struct if_group if_groups[6] = {
86         {
87                 .group = group_a,
88                 .name = "A",
89                 .used = 0,
90         },
91         {
92                 .group = group_b,
93                 .name = "B",
94                 .used = 0,
95         },
96         {
97                 .group = group_c,
98                 .name = "C",
99                 .used = 0,
100         },
101         {
102                 .group = group_d,
103                 .name = "D",
104                 .used = 0,
105         },
106         {
107                 .group = group_e,
108                 .name = "E",
109                 .used = 0,
110         },
111         {
112                 .group = group_f,
113                 .name = "F",
114                 .used = 0,
115         }
116 };
117
118 /* The order in the array must match the order of enum
119  * cris_io_interface in io_interface_mux.h */
120 static struct interface interfaces[] = {
121         /* Begin Non-multiplexed interfaces */
122         {
123                 .ioif = if_eth,
124                 .name = "ethernet",
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
134                 .gpio_g_in = 0,
135                 .gpio_g_out = 0,
136                 .gpio_b = 0
137         },
138         {
139                 .ioif = if_serial_0,
140                 .name = "serial_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
150                 .gpio_g_in = 0,
151                 .gpio_g_out = 0,
152                 .gpio_b = 0
153         },
154         /* End Non-multiplexed interfaces */
155         {
156                 .ioif = if_serial_1,
157                 .name = "serial_1",
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
167                 .gpio_g_in =  0x00000000,
168                 .gpio_g_out = 0x00000000,
169                 .gpio_b = 0x00
170         },
171         {
172                 .ioif = if_serial_2,
173                 .name = "serial_2",
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
183                 .gpio_g_in =  0x000000c0,
184                 .gpio_g_out = 0x000000c0,
185                 .gpio_b = 0x00
186         },
187         {
188                 .ioif = if_serial_3,
189                 .name = "serial_3",
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
199                 .gpio_g_in =  0xc0000000,
200                 .gpio_g_out = 0xc0000000,
201                 .gpio_b = 0x00
202         },
203         {
204                 .ioif = if_sync_serial_1,
205                 .name = "sync_serial_1",
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
215                 .gpio_g_in =  0x00000000,
216                 .gpio_g_out = 0x00000000,
217                 .gpio_b = 0x10
218         },
219         {
220                 .ioif = if_sync_serial_3,
221                 .name = "sync_serial_3",
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
231                 .gpio_g_in =  0xc0000000,
232                 .gpio_g_out = 0xc0000000,
233                 .gpio_b = 0x80
234         },
235         {
236                 .ioif = if_shared_ram,
237                 .name = "shared_ram",
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
247                 .gpio_g_in =  0x0000ff3e,
248                 .gpio_g_out = 0x0000ff38,
249                 .gpio_b = 0x00
250         },
251         {
252                 .ioif = if_shared_ram_w,
253                 .name = "shared_ram_w",
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
263                 .gpio_g_in =  0x00ffff3e,
264                 .gpio_g_out = 0x00ffff38,
265                 .gpio_b = 0x00
266         },
267         {
268                 .ioif = if_par_0,
269                 .name = "par_0",
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
279                 .gpio_g_in =  0x0000ff3e,
280                 .gpio_g_out = 0x0000ff3e,
281                 .gpio_b = 0x00
282         },
283         {
284                 .ioif = if_par_1,
285                 .name = "par_1",
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
295                 .gpio_g_in =  0x3eff0000,
296                 .gpio_g_out = 0x3eff0000,
297                 .gpio_b = 0x00
298         },
299         {
300                 .ioif = if_par_w,
301                 .name = "par_w",
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
311                 .gpio_g_in =  0x00ffff3e,
312                 .gpio_g_out = 0x00ffff3e,
313                 .gpio_b = 0x00
314         },
315         {
316                 .ioif = if_scsi8_0,
317                 .name = "scsi8_0",
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
327                 .gpio_g_in =  0x0000ffff,
328                 .gpio_g_out = 0x0000ffff,
329                 .gpio_b = 0x10
330         },
331         {
332                 .ioif = if_scsi8_1,
333                 .name = "scsi8_1",
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
343                 .gpio_g_in =  0xffff0000,
344                 .gpio_g_out = 0xffff0000,
345                 .gpio_b = 0x80
346         },
347         {
348                 .ioif = if_scsi_w,
349                 .name = "scsi_w",
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
359                 .gpio_g_in =  0x01ffffff,
360                 .gpio_g_out = 0x07ffffff,
361                 .gpio_b = 0x80
362         },
363         {
364                 .ioif = if_ata,
365                 .name = "ata",
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
375                 .gpio_g_in =  0xf9ffffff,
376                 .gpio_g_out = 0xffffffff,
377                 .gpio_b = 0x80
378         },
379         {
380                 .ioif = if_csp,
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
391                 .gpio_g_in =  0x00000000,
392                 .gpio_g_out = 0x00000000,
393                 .gpio_b = 0xfc
394         },
395         {
396                 .ioif = if_i2c,
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
407                 .gpio_g_in =  0x00000000,
408                 .gpio_g_out = 0x00000000,
409                 .gpio_b = 0x03
410         },
411         {
412                 .ioif = if_usb_1,
413                 .name = "usb_1",
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
423                 .gpio_g_in =  0x00000000,
424                 .gpio_g_out = 0x00000000,
425                 .gpio_b = 0x2c
426         },
427         {
428                 .ioif = if_usb_2,
429                 .name = "usb_2",
430                 .groups = group_d,
431
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,
441                 .gpio_b = 0x00
442         },
443         /* GPIO pins */
444         {
445                 .ioif = if_gpio_grp_a,
446                 .name = "gpio_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
456                 .gpio_g_in =  0x0000ff3f,
457                 .gpio_g_out = 0x0000ff3f,
458                 .gpio_b = 0x00
459         },
460         {
461                 .ioif = if_gpio_grp_b,
462                 .name = "gpio_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
472                 .gpio_g_in =  0x000000c0,
473                 .gpio_g_out = 0x000000c0,
474                 .gpio_b = 0x00
475         },
476         {
477                 .ioif = if_gpio_grp_c,
478                 .name = "gpio_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
488                 .gpio_g_in =  0xc0000000,
489                 .gpio_g_out = 0xc0000000,
490                 .gpio_b = 0x00
491         },
492         {
493                 .ioif = if_gpio_grp_d,
494                 .name = "gpio_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
504                 .gpio_g_in =  0x3fff0000,
505                 .gpio_g_out = 0x3fff0000,
506                 .gpio_b = 0x00
507         },
508         {
509                 .ioif = if_gpio_grp_e,
510                 .name = "gpio_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
520                 .gpio_g_in =  0x00000000,
521                 .gpio_g_out = 0x00000000,
522                 .gpio_b = 0x00
523         },
524         {
525                 .ioif = if_gpio_grp_f,
526                 .name = "gpio_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
536                 .gpio_g_in =  0x00000000,
537                 .gpio_g_out = 0x00000000,
538                 .gpio_b = 0xff
539         }
540         /* Array end */
541 };
542
543 static struct watcher *watchers = NULL;
544
545 /* The pins that are free to use in the GPIO ports. */
546 static unsigned int gpio_in_pins =  0xffffffff;
547 static unsigned int gpio_out_pins = 0xffffffff;
548 static unsigned char gpio_pb_pins = 0xff;
549 static unsigned char gpio_pa_pins = 0xff;
550
551 /* Identifiers for the owners of the GPIO pins. */
552 static enum cris_io_interface gpio_pa_owners[8];
553 static enum cris_io_interface gpio_pb_owners[8];
554 static enum cris_io_interface gpio_pg_owners[32];
555
556 static int cris_io_interface_init(void);
557
558 static unsigned char clear_group_from_set(const unsigned char groups, struct if_group *group)
559 {
560         return (groups & ~group->group);
561 }
562
563
564 static struct if_group *get_group(const unsigned char groups)
565 {
566         int i;
567         for (i = 0; i < ARRAY_SIZE(if_groups); i++) {
568                 if (groups & if_groups[i].group) {
569                         return &if_groups[i];
570                 }
571         }
572         return NULL;
573 }
574
575
576 static void notify_watchers(void)
577 {
578         struct watcher *w = watchers;
579
580         DBG(printk("io_interface_mux: notifying watchers\n"));
581
582         while (NULL != w) {
583                 w->notify((const unsigned int)gpio_in_pins,
584                           (const unsigned int)gpio_out_pins,
585                           (const unsigned char)gpio_pa_pins,
586                           (const unsigned char)gpio_pb_pins);
587                 w = w->next;
588         }
589 }
590
591
592 int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id)
593 {
594         int set_gen_config = 0;
595         int set_gen_config_ii = 0;
596         unsigned long int gens;
597         unsigned long int gens_ii;
598         struct if_group *grp;
599         unsigned char group_set;
600         unsigned long flags;
601         int res = 0;
602
603         (void)cris_io_interface_init();
604
605         DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id));
606
607         if ((ioif >= if_max_interfaces) || (ioif < 0)) {
608                 printk(KERN_CRIT "cris_request_io_interface: Bad interface "
609                         "%u submitted for %s\n",
610                        ioif,
611                        device_id);
612                 return -EINVAL;
613         }
614
615         local_irq_save(flags);
616
617         if (interfaces[ioif].used) {
618                 printk(KERN_CRIT "cris_io_interface: Cannot allocate interface "
619                         "%s for %s, in use by %s\n",
620                        interfaces[ioif].name,
621                        device_id,
622                        interfaces[ioif].owner);
623                 res = -EBUSY;
624                 goto exit;
625         }
626
627         /* Check that all required pins in the used groups are free
628          * before allocating. */
629         group_set = interfaces[ioif].groups;
630         while (NULL != (grp = get_group(group_set))) {
631                 unsigned int if_group_use = 0;
632
633                 switch (grp->group) {
634                 case group_a:
635                         if_group_use = interfaces[ioif].group_a;
636                         break;
637                 case group_b:
638                         if_group_use = interfaces[ioif].group_b;
639                         break;
640                 case group_c:
641                         if_group_use = interfaces[ioif].group_c;
642                         break;
643                 case group_d:
644                         if_group_use = interfaces[ioif].group_d;
645                         break;
646                 case group_e:
647                         if_group_use = interfaces[ioif].group_e;
648                         break;
649                 case group_f:
650                         if_group_use = interfaces[ioif].group_f;
651                         break;
652                 default:
653                         BUG_ON(1);
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
664                 group_set = clear_group_from_set(group_set, grp);
665         }
666
667         /* Are the required GPIO pins available too? */
668         if (((interfaces[ioif].gpio_g_in & gpio_in_pins) !=
669                         interfaces[ioif].gpio_g_in) ||
670                 ((interfaces[ioif].gpio_g_out & gpio_out_pins) !=
671                         interfaces[ioif].gpio_g_out) ||
672                 ((interfaces[ioif].gpio_b & gpio_pb_pins) !=
673                         interfaces[ioif].gpio_b)) {
674                 printk(KERN_CRIT "cris_request_io_interface: Could not get "
675                         "required pins for interface %u\n", ioif);
676                 res = -EBUSY;
677                 goto exit;
678         }
679
680         /* Check which registers need to be reconfigured. */
681         gens = genconfig_shadow;
682         gens_ii = gen_config_ii_shadow;
683
684         set_gen_config = 1;
685         switch (ioif)
686         {
687         /* Begin Non-multiplexed interfaces */
688         case if_eth:
689                 /* fall through */
690         case if_serial_0:
691                 set_gen_config = 0;
692                 break;
693         /* End Non-multiplexed interfaces */
694         case if_serial_1:
695                 set_gen_config_ii = 1;
696                 SETS(gens_ii, R_GEN_CONFIG_II, sermode1, async);
697                 break;
698         case if_serial_2:
699                 SETS(gens, R_GEN_CONFIG, ser2, select);
700                 break;
701         case if_serial_3:
702                 SETS(gens, R_GEN_CONFIG, ser3, select);
703                 set_gen_config_ii = 1;
704                 SETS(gens_ii, R_GEN_CONFIG_II, sermode3, async);
705                 break;
706         case if_sync_serial_1:
707                 set_gen_config_ii = 1;
708                 SETS(gens_ii, R_GEN_CONFIG_II, sermode1, sync);
709                 break;
710         case if_sync_serial_3:
711                 SETS(gens, R_GEN_CONFIG, ser3, select);
712                 set_gen_config_ii = 1;
713                 SETS(gens_ii, R_GEN_CONFIG_II, sermode3, sync);
714                 break;
715         case if_shared_ram:
716                 SETS(gens, R_GEN_CONFIG, mio, select);
717                 break;
718         case if_shared_ram_w:
719                 SETS(gens, R_GEN_CONFIG, mio_w, select);
720                 break;
721         case if_par_0:
722                 SETS(gens, R_GEN_CONFIG, par0, select);
723                 break;
724         case if_par_1:
725                 SETS(gens, R_GEN_CONFIG, par1, select);
726                 break;
727         case if_par_w:
728                 SETS(gens, R_GEN_CONFIG, par0, select);
729                 SETS(gens, R_GEN_CONFIG, par_w, select);
730                 break;
731         case if_scsi8_0:
732                 SETS(gens, R_GEN_CONFIG, scsi0, select);
733                 break;
734         case if_scsi8_1:
735                 SETS(gens, R_GEN_CONFIG, scsi1, select);
736                 break;
737         case if_scsi_w:
738                 SETS(gens, R_GEN_CONFIG, scsi0, select);
739                 SETS(gens, R_GEN_CONFIG, scsi0w, select);
740                 break;
741         case if_ata:
742                 SETS(gens, R_GEN_CONFIG, ata, select);
743                 break;
744         case if_csp:
745                 /* fall through */
746         case if_i2c:
747                 set_gen_config = 0;
748                 break;
749         case if_usb_1:
750                 SETS(gens, R_GEN_CONFIG, usb1, select);
751                 break;
752         case if_usb_2:
753                 SETS(gens, R_GEN_CONFIG, usb2, select);
754                 break;
755         case if_gpio_grp_a:
756                 /* GPIO groups are only accounted, don't do configuration changes. */
757                 /* fall through */
758         case if_gpio_grp_b:
759                 /* fall through */
760         case if_gpio_grp_c:
761                 /* fall through */
762         case if_gpio_grp_d:
763                 /* fall through */
764         case if_gpio_grp_e:
765                 /* fall through */
766         case if_gpio_grp_f:
767                 set_gen_config = 0;
768                 break;
769         default:
770                 printk(KERN_INFO "cris_request_io_interface: Bad interface "
771                         "%u submitted for %s\n",
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);
807         }
808
809         interfaces[ioif].used = 1;
810         interfaces[ioif].owner = (char*)device_id;
811
812         if (set_gen_config) {
813                 volatile int i;
814                 genconfig_shadow = gens;
815                 *R_GEN_CONFIG = genconfig_shadow;
816                 /* Wait 12 cycles before doing any DMA command */
817                 for(i = 6; i > 0; i--)
818                         nop();
819         }
820         if (set_gen_config_ii) {
821                 gen_config_ii_shadow = gens_ii;
822                 *R_GEN_CONFIG_II = gen_config_ii_shadow;
823         }
824
825         DBG(printk(KERN_DEBUG "GPIO pins: available before: "
826                 "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
827                 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
828         DBG(printk(KERN_DEBUG
829                 "grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
830                 interfaces[ioif].gpio_g_in,
831                 interfaces[ioif].gpio_g_out,
832                 interfaces[ioif].gpio_b));
833
834         gpio_in_pins &= ~interfaces[ioif].gpio_g_in;
835         gpio_out_pins &= ~interfaces[ioif].gpio_g_out;
836         gpio_pb_pins &= ~interfaces[ioif].gpio_b;
837
838         DBG(printk(KERN_DEBUG "GPIO pins: available after: "
839                 "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
840                 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
841
842 exit:
843         local_irq_restore(flags);
844         if (res == 0)
845                 notify_watchers();
846         return res;
847 }
848
849
850 void cris_free_io_interface(enum cris_io_interface ioif)
851 {
852         struct if_group *grp;
853         unsigned char group_set;
854         unsigned long flags;
855
856         (void)cris_io_interface_init();
857
858         if ((ioif >= if_max_interfaces) || (ioif < 0)) {
859                 printk(KERN_CRIT "cris_free_io_interface: Bad interface %u\n",
860                        ioif);
861                 return;
862         }
863         local_irq_save(flags);
864         if (!interfaces[ioif].used) {
865                 printk(KERN_CRIT "cris_free_io_interface: Freeing free interface %u\n",
866                        ioif);
867                 local_irq_restore(flags);
868                 return;
869         }
870         group_set = interfaces[ioif].groups;
871         while (NULL != (grp = get_group(group_set))) {
872                 unsigned int if_group_use = 0;
873
874                 switch (grp->group) {
875                 case group_a:
876                         if_group_use = interfaces[ioif].group_a;
877                         break;
878                 case group_b:
879                         if_group_use = interfaces[ioif].group_b;
880                         break;
881                 case group_c:
882                         if_group_use = interfaces[ioif].group_c;
883                         break;
884                 case group_d:
885                         if_group_use = interfaces[ioif].group_d;
886                         break;
887                 case group_e:
888                         if_group_use = interfaces[ioif].group_e;
889                         break;
890                 case group_f:
891                         if_group_use = interfaces[ioif].group_f;
892                         break;
893                 default:
894                         BUG_ON(1);
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
901                 group_set = clear_group_from_set(group_set, grp);
902         }
903         interfaces[ioif].used = 0;
904         interfaces[ioif].owner = NULL;
905
906         DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
907                    gpio_in_pins, gpio_out_pins, gpio_pb_pins));
908         DBG(printk("freeing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
909                    interfaces[ioif].gpio_g_in,
910                    interfaces[ioif].gpio_g_out,
911                    interfaces[ioif].gpio_b));
912
913         gpio_in_pins |= interfaces[ioif].gpio_g_in;
914         gpio_out_pins |= interfaces[ioif].gpio_g_out;
915         gpio_pb_pins |= interfaces[ioif].gpio_b;
916
917         DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
918                    gpio_in_pins, gpio_out_pins, gpio_pb_pins));
919
920         local_irq_restore(flags);
921
922         notify_watchers();
923 }
924
925 /* Create a bitmask from bit 0 (inclusive) to bit stop_bit
926    (non-inclusive).  stop_bit == 0 returns 0x0 */
927 static inline unsigned int create_mask(const unsigned stop_bit)
928 {
929         /* Avoid overflow */
930         if (stop_bit >= 32) {
931                 return 0xffffffff;
932         }
933         return (1<<stop_bit)-1;
934 }
935
936
937 /* port can be 'a', 'b' or 'g' */
938 int cris_io_interface_allocate_pins(const enum cris_io_interface ioif,
939                                     const char port,
940                                     const unsigned start_bit,
941                                     const unsigned stop_bit)
942 {
943         unsigned int i;
944         unsigned int mask = 0;
945         unsigned int tmp_mask;
946         unsigned long int flags;
947         enum cris_io_interface *owners;
948
949         (void)cris_io_interface_init();
950
951         DBG(printk("cris_io_interface_allocate_pins: if=%d port=%c start=%u stop=%u\n",
952                    ioif, port, start_bit, stop_bit));
953
954         if (!((start_bit <= stop_bit) &&
955               ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
956                ((port == 'g') && (stop_bit < 32))))) {
957                 return -EINVAL;
958         }
959
960         mask = create_mask(stop_bit + 1);
961         tmp_mask = create_mask(start_bit);
962         mask &= ~tmp_mask;
963
964         DBG(printk("cris_io_interface_allocate_pins: port=%c start=%u stop=%u mask=0x%08x\n",
965                    port, start_bit, stop_bit, mask));
966
967         local_irq_save(flags);
968
969         switch (port) {
970         case 'a':
971                 if ((gpio_pa_pins & mask) != mask) {
972                         local_irq_restore(flags);
973                         return -EBUSY;
974                 }
975                 owners = gpio_pa_owners;
976                 gpio_pa_pins &= ~mask;
977                 break;
978         case 'b':
979                 if ((gpio_pb_pins & mask) != mask) {
980                         local_irq_restore(flags);
981                         return -EBUSY;
982                 }
983                 owners = gpio_pb_owners;
984                 gpio_pb_pins &= ~mask;
985                 break;
986         case 'g':
987                 if (((gpio_in_pins & mask) != mask) ||
988                     ((gpio_out_pins & mask) != mask)) {
989                         local_irq_restore(flags);
990                         return -EBUSY;
991                 }
992                 owners = gpio_pg_owners;
993                 gpio_in_pins &= ~mask;
994                 gpio_out_pins &= ~mask;
995                 break;
996         default:
997                 local_irq_restore(flags);
998                 return -EINVAL;
999         }
1000
1001         for (i = start_bit; i <= stop_bit; i++) {
1002                 owners[i] = ioif;
1003         }
1004         local_irq_restore(flags);
1005
1006         notify_watchers();
1007         return 0;
1008 }
1009
1010
1011 /* port can be 'a', 'b' or 'g' */
1012 int cris_io_interface_free_pins(const enum cris_io_interface ioif,
1013                                 const char port,
1014                                 const unsigned start_bit,
1015                                 const unsigned stop_bit)
1016 {
1017         unsigned int i;
1018         unsigned int mask = 0;
1019         unsigned int tmp_mask;
1020         unsigned long int flags;
1021         enum cris_io_interface *owners;
1022
1023         (void)cris_io_interface_init();
1024
1025         if (!((start_bit <= stop_bit) &&
1026               ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
1027                ((port == 'g') && (stop_bit < 32))))) {
1028                 return -EINVAL;
1029         }
1030
1031         mask = create_mask(stop_bit + 1);
1032         tmp_mask = create_mask(start_bit);
1033         mask &= ~tmp_mask;
1034
1035         DBG(printk("cris_io_interface_free_pins: port=%c start=%u stop=%u mask=0x%08x\n",
1036                    port, start_bit, stop_bit, mask));
1037
1038         local_irq_save(flags);
1039
1040         switch (port) {
1041         case 'a':
1042                 if ((~gpio_pa_pins & mask) != mask) {
1043                         local_irq_restore(flags);
1044                         printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
1045                 }
1046                 owners = gpio_pa_owners;
1047                 break;
1048         case 'b':
1049                 if ((~gpio_pb_pins & mask) != mask) {
1050                         local_irq_restore(flags);
1051                         printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
1052                 }
1053                 owners = gpio_pb_owners;
1054                 break;
1055         case 'g':
1056                 if (((~gpio_in_pins & mask) != mask) ||
1057                     ((~gpio_out_pins & mask) != mask)) {
1058                         local_irq_restore(flags);
1059                         printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
1060                 }
1061                 owners = gpio_pg_owners;
1062                 break;
1063         default:
1064                 owners = NULL; /* Cannot happen. Shut up, gcc! */
1065         }
1066
1067         for (i = start_bit; i <= stop_bit; i++) {
1068                 if (owners[i] != ioif) {
1069                         printk(KERN_CRIT "cris_io_interface_free_pins: Freeing unowned pins");
1070                 }
1071         }
1072
1073         /* All was ok, change data. */
1074         switch (port) {
1075         case 'a':
1076                 gpio_pa_pins |= mask;
1077                 break;
1078         case 'b':
1079                 gpio_pb_pins |= mask;
1080                 break;
1081         case 'g':
1082                 gpio_in_pins |= mask;
1083                 gpio_out_pins |= mask;
1084                 break;
1085         }
1086
1087         for (i = start_bit; i <= stop_bit; i++) {
1088                 owners[i] = if_unclaimed;
1089         }
1090         local_irq_restore(flags);
1091         notify_watchers();
1092
1093         return 0;
1094 }
1095
1096
1097 int cris_io_interface_register_watcher(void (*notify)(const unsigned int gpio_in_available,
1098                                                       const unsigned int gpio_out_available,
1099                                                       const unsigned char pa_available,
1100                                                       const unsigned char pb_available))
1101 {
1102         struct watcher *w;
1103
1104         (void)cris_io_interface_init();
1105
1106         if (NULL == notify) {
1107                 return -EINVAL;
1108         }
1109         w = kmalloc(sizeof(*w), GFP_KERNEL);
1110         if (!w) {
1111                 return -ENOMEM;
1112         }
1113         w->notify = notify;
1114         w->next = watchers;
1115         watchers = w;
1116
1117         w->notify((const unsigned int)gpio_in_pins,
1118                   (const unsigned int)gpio_out_pins,
1119                   (const unsigned char)gpio_pa_pins,
1120                   (const unsigned char)gpio_pb_pins);
1121
1122         return 0;
1123 }
1124
1125 void cris_io_interface_delete_watcher(void (*notify)(const unsigned int gpio_in_available,
1126                                                      const unsigned int gpio_out_available,
1127                                                      const unsigned char pa_available,
1128                                                      const unsigned char pb_available))
1129 {
1130         struct watcher *w = watchers, *prev = NULL;
1131
1132         (void)cris_io_interface_init();
1133
1134         while ((NULL != w) && (w->notify != notify)){
1135                 prev = w;
1136                 w = w->next;
1137         }
1138         if (NULL != w) {
1139                 if (NULL != prev) {
1140                         prev->next = w->next;
1141                 } else {
1142                         watchers = w->next;
1143                 }
1144                 kfree(w);
1145                 return;
1146         }
1147         printk(KERN_WARNING "cris_io_interface_delete_watcher: Deleting unknown watcher 0x%p\n", notify);
1148 }
1149
1150
1151 static int cris_io_interface_init(void)
1152 {
1153         static int first = 1;
1154         int i;
1155
1156         if (!first) {
1157                 return 0;
1158         }
1159         first = 0;
1160
1161         for (i = 0; i<8; i++) {
1162                 gpio_pa_owners[i] = if_unclaimed;
1163                 gpio_pb_owners[i] = if_unclaimed;
1164                 gpio_pg_owners[i] = if_unclaimed;
1165         }
1166         for (; i<32; i++) {
1167                 gpio_pg_owners[i] = if_unclaimed;
1168         }
1169         return 0;
1170 }
1171
1172
1173 module_init(cris_io_interface_init);
1174
1175
1176 EXPORT_SYMBOL(cris_request_io_interface);
1177 EXPORT_SYMBOL(cris_free_io_interface);
1178 EXPORT_SYMBOL(cris_io_interface_allocate_pins);
1179 EXPORT_SYMBOL(cris_io_interface_free_pins);
1180 EXPORT_SYMBOL(cris_io_interface_register_watcher);
1181 EXPORT_SYMBOL(cris_io_interface_delete_watcher);