Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
io_interface_mux.c
Go to the documentation of this file.
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 
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 {
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 {
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 
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 
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 
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 
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));
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 
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 */
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' */
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' */
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 
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 
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 
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