Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/cris/arch-v10/kernel/io_interface_mux.c
15125 views
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);
1182
1183