CRIS: add missed local_irq_restore call
[deliverable/linux.git] / arch / cris / arch-v10 / kernel / io_interface_mux.c
CommitLineData
63245d2c
MS
1/* IO interface mux allocator for ETRAX100LX.
2 * Copyright 2004, Axis Communications AB
3 * $Id: io_interface_mux.c,v 1.2 2004/12/21 12:08:38 starvik Exp $
4 */
5
6
7/* C.f. ETRAX100LX Designer's Reference 20.9 */
8
9#include <linux/kernel.h>
10#include <linux/slab.h>
11#include <linux/errno.h>
12#include <linux/module.h>
13#include <linux/init.h>
14
15#include <asm/arch/svinto.h>
16#include <asm/io.h>
17#include <asm/arch/io_interface_mux.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
26enum 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
35struct 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
45struct if_group
46{
47 enum io_if_group group;
48 unsigned char used;
49 enum cris_io_interface owner;
50};
51
52
53struct interface
54{
55 enum cris_io_interface ioif;
56 unsigned char groups;
57 unsigned char used;
58 char *owner;
59 unsigned int gpio_g_in;
60 unsigned int gpio_g_out;
61 unsigned char gpio_b;
62};
63
64static struct if_group if_groups[6] = {
65 {
66 .group = group_a,
67 .used = 0,
68 },
69 {
70 .group = group_b,
71 .used = 0,
72 },
73 {
74 .group = group_c,
75 .used = 0,
76 },
77 {
78 .group = group_d,
79 .used = 0,
80 },
81 {
82 .group = group_e,
83 .used = 0,
84 },
85 {
86 .group = group_f,
87 .used = 0,
88 }
89};
90
91/* The order in the array must match the order of enum
92 * cris_io_interface in io_interface_mux.h */
93static struct interface interfaces[] = {
94 /* Begin Non-multiplexed interfaces */
95 {
96 .ioif = if_eth,
97 .groups = 0,
98 .gpio_g_in = 0,
99 .gpio_g_out = 0,
100 .gpio_b = 0
101 },
102 {
103 .ioif = if_serial_0,
104 .groups = 0,
105 .gpio_g_in = 0,
106 .gpio_g_out = 0,
107 .gpio_b = 0
108 },
109 /* End Non-multiplexed interfaces */
110 {
111 .ioif = if_serial_1,
112 .groups = group_e,
113 .gpio_g_in = 0x00000000,
114 .gpio_g_out = 0x00000000,
115 .gpio_b = 0x00
116 },
117 {
118 .ioif = if_serial_2,
119 .groups = group_b,
120 .gpio_g_in = 0x000000c0,
121 .gpio_g_out = 0x000000c0,
122 .gpio_b = 0x00
123 },
124 {
125 .ioif = if_serial_3,
126 .groups = group_c,
127 .gpio_g_in = 0xc0000000,
128 .gpio_g_out = 0xc0000000,
129 .gpio_b = 0x00
130 },
131 {
132 .ioif = if_sync_serial_1,
133 .groups = group_e | group_f, /* if_sync_serial_1 and if_sync_serial_3
134 can be used simultaneously */
135 .gpio_g_in = 0x00000000,
136 .gpio_g_out = 0x00000000,
137 .gpio_b = 0x10
138 },
139 {
140 .ioif = if_sync_serial_3,
141 .groups = group_c | group_f,
142 .gpio_g_in = 0xc0000000,
143 .gpio_g_out = 0xc0000000,
144 .gpio_b = 0x80
145 },
146 {
147 .ioif = if_shared_ram,
148 .groups = group_a,
149 .gpio_g_in = 0x0000ff3e,
150 .gpio_g_out = 0x0000ff38,
151 .gpio_b = 0x00
152 },
153 {
154 .ioif = if_shared_ram_w,
155 .groups = group_a | group_d,
156 .gpio_g_in = 0x00ffff3e,
157 .gpio_g_out = 0x00ffff38,
158 .gpio_b = 0x00
159 },
160 {
161 .ioif = if_par_0,
162 .groups = group_a,
163 .gpio_g_in = 0x0000ff3e,
164 .gpio_g_out = 0x0000ff3e,
165 .gpio_b = 0x00
166 },
167 {
168 .ioif = if_par_1,
169 .groups = group_d,
170 .gpio_g_in = 0x3eff0000,
171 .gpio_g_out = 0x3eff0000,
172 .gpio_b = 0x00
173 },
174 {
175 .ioif = if_par_w,
176 .groups = group_a | group_d,
177 .gpio_g_in = 0x00ffff3e,
178 .gpio_g_out = 0x00ffff3e,
179 .gpio_b = 0x00
180 },
181 {
182 .ioif = if_scsi8_0,
183 .groups = group_a | group_b | group_f, /* if_scsi8_0 and if_scsi8_1
184 can be used simultaneously */
185 .gpio_g_in = 0x0000ffff,
186 .gpio_g_out = 0x0000ffff,
187 .gpio_b = 0x10
188 },
189 {
190 .ioif = if_scsi8_1,
191 .groups = group_c | group_d | group_f, /* if_scsi8_0 and if_scsi8_1
192 can be used simultaneously */
193 .gpio_g_in = 0xffff0000,
194 .gpio_g_out = 0xffff0000,
195 .gpio_b = 0x80
196 },
197 {
198 .ioif = if_scsi_w,
199 .groups = group_a | group_b | group_d | group_f,
200 .gpio_g_in = 0x01ffffff,
201 .gpio_g_out = 0x07ffffff,
202 .gpio_b = 0x80
203 },
204 {
205 .ioif = if_ata,
206 .groups = group_a | group_b | group_c | group_d,
207 .gpio_g_in = 0xf9ffffff,
208 .gpio_g_out = 0xffffffff,
209 .gpio_b = 0x80
210 },
211 {
212 .ioif = if_csp,
213 .groups = group_f, /* if_csp and if_i2c can be used simultaneously */
214 .gpio_g_in = 0x00000000,
215 .gpio_g_out = 0x00000000,
216 .gpio_b = 0xfc
217 },
218 {
219 .ioif = if_i2c,
220 .groups = group_f, /* if_csp and if_i2c can be used simultaneously */
221 .gpio_g_in = 0x00000000,
222 .gpio_g_out = 0x00000000,
223 .gpio_b = 0x03
224 },
225 {
226 .ioif = if_usb_1,
227 .groups = group_e | group_f,
228 .gpio_g_in = 0x00000000,
229 .gpio_g_out = 0x00000000,
230 .gpio_b = 0x2c
231 },
232 {
233 .ioif = if_usb_2,
234 .groups = group_d,
235 .gpio_g_in = 0x0e000000,
236 .gpio_g_out = 0x3c000000,
237 .gpio_b = 0x00
238 },
239 /* GPIO pins */
240 {
241 .ioif = if_gpio_grp_a,
242 .groups = group_a,
243 .gpio_g_in = 0x0000ff3f,
244 .gpio_g_out = 0x0000ff3f,
245 .gpio_b = 0x00
246 },
247 {
248 .ioif = if_gpio_grp_b,
249 .groups = group_b,
250 .gpio_g_in = 0x000000c0,
251 .gpio_g_out = 0x000000c0,
252 .gpio_b = 0x00
253 },
254 {
255 .ioif = if_gpio_grp_c,
256 .groups = group_c,
257 .gpio_g_in = 0xc0000000,
258 .gpio_g_out = 0xc0000000,
259 .gpio_b = 0x00
260 },
261 {
262 .ioif = if_gpio_grp_d,
263 .groups = group_d,
264 .gpio_g_in = 0x3fff0000,
265 .gpio_g_out = 0x3fff0000,
266 .gpio_b = 0x00
267 },
268 {
269 .ioif = if_gpio_grp_e,
270 .groups = group_e,
271 .gpio_g_in = 0x00000000,
272 .gpio_g_out = 0x00000000,
273 .gpio_b = 0x00
274 },
275 {
276 .ioif = if_gpio_grp_f,
277 .groups = group_f,
278 .gpio_g_in = 0x00000000,
279 .gpio_g_out = 0x00000000,
280 .gpio_b = 0xff
281 }
282 /* Array end */
283};
284
285static struct watcher *watchers = NULL;
286
287static unsigned int gpio_in_pins = 0xffffffff;
288static unsigned int gpio_out_pins = 0xffffffff;
289static unsigned char gpio_pb_pins = 0xff;
290static unsigned char gpio_pa_pins = 0xff;
291
292static enum cris_io_interface gpio_pa_owners[8];
293static enum cris_io_interface gpio_pb_owners[8];
294static enum cris_io_interface gpio_pg_owners[32];
295
296static int cris_io_interface_init(void);
297
298static unsigned char clear_group_from_set(const unsigned char groups, struct if_group *group)
299{
300 return (groups & ~group->group);
301}
302
303
304static struct if_group *get_group(const unsigned char groups)
305{
306 int i;
16ad1b49 307 for (i = 0; i < ARRAY_SIZE(if_groups); i++) {
63245d2c
MS
308 if (groups & if_groups[i].group) {
309 return &if_groups[i];
310 }
311 }
312 return NULL;
313}
314
315
316static void notify_watchers(void)
317{
318 struct watcher *w = watchers;
319
320 DBG(printk("io_interface_mux: notifying watchers\n"));
321
322 while (NULL != w) {
323 w->notify((const unsigned int)gpio_in_pins,
324 (const unsigned int)gpio_out_pins,
325 (const unsigned char)gpio_pa_pins,
326 (const unsigned char)gpio_pb_pins);
327 w = w->next;
328 }
329}
330
331
332int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id)
333{
334 int set_gen_config = 0;
335 int set_gen_config_ii = 0;
336 unsigned long int gens;
337 unsigned long int gens_ii;
338 struct if_group *grp;
339 unsigned char group_set;
340 unsigned long flags;
341
342 (void)cris_io_interface_init();
343
344 DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id));
345
346 if ((ioif >= if_max_interfaces) || (ioif < 0)) {
347 printk(KERN_CRIT "cris_request_io_interface: Bad interface %u submitted for %s\n",
348 ioif,
349 device_id);
350 return -EINVAL;
351 }
352
353 local_irq_save(flags);
354
355 if (interfaces[ioif].used) {
356 local_irq_restore(flags);
357 printk(KERN_CRIT "cris_io_interface: Cannot allocate interface for %s, in use by %s\n",
358 device_id,
359 interfaces[ioif].owner);
360 return -EBUSY;
361 }
362
363 /* Check that all required groups are free before allocating, */
364 group_set = interfaces[ioif].groups;
365 while (NULL != (grp = get_group(group_set))) {
366 if (grp->used) {
367 if (grp->group == group_f) {
368 if ((if_sync_serial_1 == ioif) ||
369 (if_sync_serial_3 == ioif)) {
370 if ((grp->owner != if_sync_serial_1) &&
371 (grp->owner != if_sync_serial_3)) {
372 local_irq_restore(flags);
373 return -EBUSY;
374 }
375 } else if ((if_scsi8_0 == ioif) ||
376 (if_scsi8_1 == ioif)) {
377 if ((grp->owner != if_scsi8_0) &&
378 (grp->owner != if_scsi8_1)) {
379 local_irq_restore(flags);
380 return -EBUSY;
381 }
382 }
383 } else {
384 local_irq_restore(flags);
385 return -EBUSY;
386 }
387 }
388 group_set = clear_group_from_set(group_set, grp);
389 }
390
391 /* Are the required GPIO pins available too? */
392 if (((interfaces[ioif].gpio_g_in & gpio_in_pins) != interfaces[ioif].gpio_g_in) ||
393 ((interfaces[ioif].gpio_g_out & gpio_out_pins) != interfaces[ioif].gpio_g_out) ||
394 ((interfaces[ioif].gpio_b & gpio_pb_pins) != interfaces[ioif].gpio_b)) {
a56d00bb 395 local_irq_restore(flags);
63245d2c
MS
396 printk(KERN_CRIT "cris_request_io_interface: Could not get required pins for interface %u\n",
397 ioif);
398 return -EBUSY;
399 }
400
401 /* All needed I/O pins and pin groups are free, allocate. */
402 group_set = interfaces[ioif].groups;
403 while (NULL != (grp = get_group(group_set))) {
404 grp->used = 1;
405 grp->owner = ioif;
406 group_set = clear_group_from_set(group_set, grp);
407 }
408
409 gens = genconfig_shadow;
410 gens_ii = gen_config_ii_shadow;
411
412 set_gen_config = 1;
413 switch (ioif)
414 {
415 /* Begin Non-multiplexed interfaces */
416 case if_eth:
417 /* fall through */
418 case if_serial_0:
419 set_gen_config = 0;
420 break;
421 /* End Non-multiplexed interfaces */
422 case if_serial_1:
423 set_gen_config_ii = 1;
424 SETS(gens_ii, R_GEN_CONFIG_II, sermode1, async);
425 break;
426 case if_serial_2:
427 SETS(gens, R_GEN_CONFIG, ser2, select);
428 break;
429 case if_serial_3:
430 SETS(gens, R_GEN_CONFIG, ser3, select);
431 set_gen_config_ii = 1;
432 SETS(gens_ii, R_GEN_CONFIG_II, sermode3, async);
433 break;
434 case if_sync_serial_1:
435 set_gen_config_ii = 1;
436 SETS(gens_ii, R_GEN_CONFIG_II, sermode1, sync);
437 break;
438 case if_sync_serial_3:
439 SETS(gens, R_GEN_CONFIG, ser3, select);
440 set_gen_config_ii = 1;
441 SETS(gens_ii, R_GEN_CONFIG_II, sermode3, sync);
442 break;
443 case if_shared_ram:
444 SETS(gens, R_GEN_CONFIG, mio, select);
445 break;
446 case if_shared_ram_w:
447 SETS(gens, R_GEN_CONFIG, mio_w, select);
448 break;
449 case if_par_0:
450 SETS(gens, R_GEN_CONFIG, par0, select);
451 break;
452 case if_par_1:
453 SETS(gens, R_GEN_CONFIG, par1, select);
454 break;
455 case if_par_w:
456 SETS(gens, R_GEN_CONFIG, par0, select);
457 SETS(gens, R_GEN_CONFIG, par_w, select);
458 break;
459 case if_scsi8_0:
460 SETS(gens, R_GEN_CONFIG, scsi0, select);
461 break;
462 case if_scsi8_1:
463 SETS(gens, R_GEN_CONFIG, scsi1, select);
464 break;
465 case if_scsi_w:
466 SETS(gens, R_GEN_CONFIG, scsi0, select);
467 SETS(gens, R_GEN_CONFIG, scsi0w, select);
468 break;
469 case if_ata:
470 SETS(gens, R_GEN_CONFIG, ata, select);
471 break;
472 case if_csp:
473 /* fall through */
474 case if_i2c:
475 set_gen_config = 0;
476 break;
477 case if_usb_1:
478 SETS(gens, R_GEN_CONFIG, usb1, select);
479 break;
480 case if_usb_2:
481 SETS(gens, R_GEN_CONFIG, usb2, select);
482 break;
483 case if_gpio_grp_a:
484 /* GPIO groups are only accounted, don't do configuration changes. */
485 /* fall through */
486 case if_gpio_grp_b:
487 /* fall through */
488 case if_gpio_grp_c:
489 /* fall through */
490 case if_gpio_grp_d:
491 /* fall through */
492 case if_gpio_grp_e:
493 /* fall through */
494 case if_gpio_grp_f:
495 set_gen_config = 0;
496 break;
497 default:
498 panic("cris_request_io_interface: Bad interface %u submitted for %s\n",
499 ioif,
500 device_id);
501 }
502
503 interfaces[ioif].used = 1;
504 interfaces[ioif].owner = (char*)device_id;
505
506 if (set_gen_config) {
507 volatile int i;
508 genconfig_shadow = gens;
509 *R_GEN_CONFIG = genconfig_shadow;
510 /* Wait 12 cycles before doing any DMA command */
511 for(i = 6; i > 0; i--)
512 nop();
513 }
514 if (set_gen_config_ii) {
515 gen_config_ii_shadow = gens_ii;
516 *R_GEN_CONFIG_II = gen_config_ii_shadow;
517 }
518
519 DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
520 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
521 DBG(printk("grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
522 interfaces[ioif].gpio_g_in,
523 interfaces[ioif].gpio_g_out,
524 interfaces[ioif].gpio_b));
525
526 gpio_in_pins &= ~interfaces[ioif].gpio_g_in;
527 gpio_out_pins &= ~interfaces[ioif].gpio_g_out;
528 gpio_pb_pins &= ~interfaces[ioif].gpio_b;
529
530 DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
531 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
532
533 local_irq_restore(flags);
534
535 notify_watchers();
536
537 return 0;
538}
539
540
541void cris_free_io_interface(enum cris_io_interface ioif)
542{
543 struct if_group *grp;
544 unsigned char group_set;
545 unsigned long flags;
546
547 (void)cris_io_interface_init();
548
549 if ((ioif >= if_max_interfaces) || (ioif < 0)) {
550 printk(KERN_CRIT "cris_free_io_interface: Bad interface %u\n",
551 ioif);
552 return;
553 }
554 local_irq_save(flags);
555 if (!interfaces[ioif].used) {
556 printk(KERN_CRIT "cris_free_io_interface: Freeing free interface %u\n",
557 ioif);
558 local_irq_restore(flags);
559 return;
560 }
561 group_set = interfaces[ioif].groups;
562 while (NULL != (grp = get_group(group_set))) {
563 if (grp->group == group_f) {
564 switch (ioif)
565 {
566 case if_sync_serial_1:
567 if ((grp->owner == if_sync_serial_1) &&
568 interfaces[if_sync_serial_3].used) {
569 grp->owner = if_sync_serial_3;
570 } else
571 grp->used = 0;
572 break;
573 case if_sync_serial_3:
574 if ((grp->owner == if_sync_serial_3) &&
575 interfaces[if_sync_serial_1].used) {
576 grp->owner = if_sync_serial_1;
577 } else
578 grp->used = 0;
579 break;
580 case if_scsi8_0:
581 if ((grp->owner == if_scsi8_0) &&
582 interfaces[if_scsi8_1].used) {
583 grp->owner = if_scsi8_1;
584 } else
585 grp->used = 0;
586 break;
587 case if_scsi8_1:
588 if ((grp->owner == if_scsi8_1) &&
589 interfaces[if_scsi8_0].used) {
590 grp->owner = if_scsi8_0;
591 } else
592 grp->used = 0;
593 break;
594 default:
595 grp->used = 0;
596 }
597 } else {
598 grp->used = 0;
599 }
600 group_set = clear_group_from_set(group_set, grp);
601 }
602 interfaces[ioif].used = 0;
603 interfaces[ioif].owner = NULL;
604
605 DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
606 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
607 DBG(printk("freeing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
608 interfaces[ioif].gpio_g_in,
609 interfaces[ioif].gpio_g_out,
610 interfaces[ioif].gpio_b));
611
612 gpio_in_pins |= interfaces[ioif].gpio_g_in;
613 gpio_out_pins |= interfaces[ioif].gpio_g_out;
614 gpio_pb_pins |= interfaces[ioif].gpio_b;
615
616 DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
617 gpio_in_pins, gpio_out_pins, gpio_pb_pins));
618
619 local_irq_restore(flags);
620
621 notify_watchers();
622}
623
624/* Create a bitmask from bit 0 (inclusive) to bit stop_bit
625 (non-inclusive). stop_bit == 0 returns 0x0 */
626static inline unsigned int create_mask(const unsigned stop_bit)
627{
628 /* Avoid overflow */
629 if (stop_bit >= 32) {
630 return 0xffffffff;
631 }
632 return (1<<stop_bit)-1;
633}
634
635
636/* port can be 'a', 'b' or 'g' */
637int cris_io_interface_allocate_pins(const enum cris_io_interface ioif,
638 const char port,
639 const unsigned start_bit,
640 const unsigned stop_bit)
641{
642 unsigned int i;
643 unsigned int mask = 0;
644 unsigned int tmp_mask;
645 unsigned long int flags;
646 enum cris_io_interface *owners;
647
648 (void)cris_io_interface_init();
649
650 DBG(printk("cris_io_interface_allocate_pins: if=%d port=%c start=%u stop=%u\n",
651 ioif, port, start_bit, stop_bit));
652
653 if (!((start_bit <= stop_bit) &&
654 ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
655 ((port == 'g') && (stop_bit < 32))))) {
656 return -EINVAL;
657 }
658
659 mask = create_mask(stop_bit + 1);
660 tmp_mask = create_mask(start_bit);
661 mask &= ~tmp_mask;
662
663 DBG(printk("cris_io_interface_allocate_pins: port=%c start=%u stop=%u mask=0x%08x\n",
664 port, start_bit, stop_bit, mask));
665
666 local_irq_save(flags);
667
668 switch (port) {
669 case 'a':
670 if ((gpio_pa_pins & mask) != mask) {
671 local_irq_restore(flags);
672 return -EBUSY;
673 }
674 owners = gpio_pa_owners;
675 gpio_pa_pins &= ~mask;
676 break;
677 case 'b':
678 if ((gpio_pb_pins & mask) != mask) {
679 local_irq_restore(flags);
680 return -EBUSY;
681 }
682 owners = gpio_pb_owners;
683 gpio_pb_pins &= ~mask;
684 break;
685 case 'g':
686 if (((gpio_in_pins & mask) != mask) ||
687 ((gpio_out_pins & mask) != mask)) {
688 local_irq_restore(flags);
689 return -EBUSY;
690 }
691 owners = gpio_pg_owners;
692 gpio_in_pins &= ~mask;
693 gpio_out_pins &= ~mask;
694 break;
695 default:
696 local_irq_restore(flags);
697 return -EINVAL;
698 }
699
700 for (i = start_bit; i <= stop_bit; i++) {
701 owners[i] = ioif;
702 }
703 local_irq_restore(flags);
704
705 notify_watchers();
706 return 0;
707}
708
709
710/* port can be 'a', 'b' or 'g' */
711int cris_io_interface_free_pins(const enum cris_io_interface ioif,
712 const char port,
713 const unsigned start_bit,
714 const unsigned stop_bit)
715{
716 unsigned int i;
717 unsigned int mask = 0;
718 unsigned int tmp_mask;
719 unsigned long int flags;
720 enum cris_io_interface *owners;
721
722 (void)cris_io_interface_init();
723
724 if (!((start_bit <= stop_bit) &&
725 ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
726 ((port == 'g') && (stop_bit < 32))))) {
727 return -EINVAL;
728 }
729
730 mask = create_mask(stop_bit + 1);
731 tmp_mask = create_mask(start_bit);
732 mask &= ~tmp_mask;
733
734 DBG(printk("cris_io_interface_free_pins: port=%c start=%u stop=%u mask=0x%08x\n",
735 port, start_bit, stop_bit, mask));
736
737 local_irq_save(flags);
738
739 switch (port) {
740 case 'a':
741 if ((~gpio_pa_pins & mask) != mask) {
742 local_irq_restore(flags);
743 printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
744 }
745 owners = gpio_pa_owners;
746 break;
747 case 'b':
748 if ((~gpio_pb_pins & mask) != mask) {
749 local_irq_restore(flags);
750 printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
751 }
752 owners = gpio_pb_owners;
753 break;
754 case 'g':
755 if (((~gpio_in_pins & mask) != mask) ||
756 ((~gpio_out_pins & mask) != mask)) {
757 local_irq_restore(flags);
758 printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
759 }
760 owners = gpio_pg_owners;
761 break;
762 default:
763 owners = NULL; /* Cannot happen. Shut up, gcc! */
764 }
765
766 for (i = start_bit; i <= stop_bit; i++) {
767 if (owners[i] != ioif) {
768 printk(KERN_CRIT "cris_io_interface_free_pins: Freeing unowned pins");
769 }
770 }
771
772 /* All was ok, change data. */
773 switch (port) {
774 case 'a':
775 gpio_pa_pins |= mask;
776 break;
777 case 'b':
778 gpio_pb_pins |= mask;
779 break;
780 case 'g':
781 gpio_in_pins |= mask;
782 gpio_out_pins |= mask;
783 break;
784 }
785
786 for (i = start_bit; i <= stop_bit; i++) {
787 owners[i] = if_unclaimed;
788 }
789 local_irq_restore(flags);
790 notify_watchers();
791
792 return 0;
793}
794
795
796int cris_io_interface_register_watcher(void (*notify)(const unsigned int gpio_in_available,
797 const unsigned int gpio_out_available,
798 const unsigned char pa_available,
799 const unsigned char pb_available))
800{
801 struct watcher *w;
802
803 (void)cris_io_interface_init();
804
805 if (NULL == notify) {
806 return -EINVAL;
807 }
808 w = kmalloc(sizeof(*w), GFP_KERNEL);
809 if (!w) {
810 return -ENOMEM;
811 }
812 w->notify = notify;
813 w->next = watchers;
814 watchers = w;
815
816 w->notify((const unsigned int)gpio_in_pins,
817 (const unsigned int)gpio_out_pins,
818 (const unsigned char)gpio_pa_pins,
819 (const unsigned char)gpio_pb_pins);
820
821 return 0;
822}
823
824void cris_io_interface_delete_watcher(void (*notify)(const unsigned int gpio_in_available,
825 const unsigned int gpio_out_available,
826 const unsigned char pa_available,
827 const unsigned char pb_available))
828{
829 struct watcher *w = watchers, *prev = NULL;
830
831 (void)cris_io_interface_init();
832
833 while ((NULL != w) && (w->notify != notify)){
834 prev = w;
835 w = w->next;
836 }
837 if (NULL != w) {
838 if (NULL != prev) {
839 prev->next = w->next;
840 } else {
841 watchers = w->next;
842 }
843 kfree(w);
844 return;
845 }
846 printk(KERN_WARNING "cris_io_interface_delete_watcher: Deleting unknown watcher 0x%p\n", notify);
847}
848
849
850static int cris_io_interface_init(void)
851{
852 static int first = 1;
853 int i;
854
855 if (!first) {
856 return 0;
857 }
858 first = 0;
859
860 for (i = 0; i<8; i++) {
861 gpio_pa_owners[i] = if_unclaimed;
862 gpio_pb_owners[i] = if_unclaimed;
863 gpio_pg_owners[i] = if_unclaimed;
864 }
865 for (; i<32; i++) {
866 gpio_pg_owners[i] = if_unclaimed;
867 }
868 return 0;
869}
870
871
872module_init(cris_io_interface_init);
873
874
875EXPORT_SYMBOL(cris_request_io_interface);
876EXPORT_SYMBOL(cris_free_io_interface);
877EXPORT_SYMBOL(cris_io_interface_allocate_pins);
878EXPORT_SYMBOL(cris_io_interface_free_pins);
879EXPORT_SYMBOL(cris_io_interface_register_watcher);
880EXPORT_SYMBOL(cris_io_interface_delete_watcher);
This page took 0.26699 seconds and 5 git commands to generate.