Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/cris/arch-v10/drivers/gpio.c
15126 views
1
/*
2
* Etrax general port I/O device
3
*
4
* Copyright (c) 1999-2007 Axis Communications AB
5
*
6
* Authors: Bjorn Wesen (initial version)
7
* Ola Knutsson (LED handling)
8
* Johan Adolfsson (read/set directions, write, port G)
9
*/
10
11
12
#include <linux/module.h>
13
#include <linux/sched.h>
14
#include <linux/slab.h>
15
#include <linux/ioport.h>
16
#include <linux/errno.h>
17
#include <linux/kernel.h>
18
#include <linux/fs.h>
19
#include <linux/string.h>
20
#include <linux/poll.h>
21
#include <linux/init.h>
22
#include <linux/interrupt.h>
23
24
#include <asm/etraxgpio.h>
25
#include <arch/svinto.h>
26
#include <asm/io.h>
27
#include <asm/system.h>
28
#include <asm/irq.h>
29
#include <arch/io_interface_mux.h>
30
31
#define GPIO_MAJOR 120 /* experimental MAJOR number */
32
33
#define D(x)
34
35
#if 0
36
static int dp_cnt;
37
#define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0)
38
#else
39
#define DP(x)
40
#endif
41
42
static char gpio_name[] = "etrax gpio";
43
44
#if 0
45
static wait_queue_head_t *gpio_wq;
46
#endif
47
48
static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
49
static ssize_t gpio_write(struct file *file, const char __user *buf,
50
size_t count, loff_t *off);
51
static int gpio_open(struct inode *inode, struct file *filp);
52
static int gpio_release(struct inode *inode, struct file *filp);
53
static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
54
55
/* private data per open() of this driver */
56
57
struct gpio_private {
58
struct gpio_private *next;
59
/* These fields are for PA and PB only */
60
volatile unsigned char *port, *shadow;
61
volatile unsigned char *dir, *dir_shadow;
62
unsigned char changeable_dir;
63
unsigned char changeable_bits;
64
unsigned char clk_mask;
65
unsigned char data_mask;
66
unsigned char write_msb;
67
unsigned char pad1, pad2, pad3;
68
/* These fields are generic */
69
unsigned long highalarm, lowalarm;
70
wait_queue_head_t alarm_wq;
71
int minor;
72
};
73
74
/* linked list of alarms to check for */
75
76
static struct gpio_private *alarmlist;
77
78
static int gpio_some_alarms; /* Set if someone uses alarm */
79
static unsigned long gpio_pa_irq_enabled_mask;
80
81
static DEFINE_SPINLOCK(gpio_lock); /* Protect directions etc */
82
83
/* Port A and B use 8 bit access, but Port G is 32 bit */
84
#define NUM_PORTS (GPIO_MINOR_B+1)
85
86
static volatile unsigned char *ports[NUM_PORTS] = {
87
R_PORT_PA_DATA,
88
R_PORT_PB_DATA,
89
};
90
static volatile unsigned char *shads[NUM_PORTS] = {
91
&port_pa_data_shadow,
92
&port_pb_data_shadow
93
};
94
95
/* What direction bits that are user changeable 1=changeable*/
96
#ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR
97
#define CONFIG_ETRAX_PA_CHANGEABLE_DIR 0x00
98
#endif
99
#ifndef CONFIG_ETRAX_PB_CHANGEABLE_DIR
100
#define CONFIG_ETRAX_PB_CHANGEABLE_DIR 0x00
101
#endif
102
103
#ifndef CONFIG_ETRAX_PA_CHANGEABLE_BITS
104
#define CONFIG_ETRAX_PA_CHANGEABLE_BITS 0xFF
105
#endif
106
#ifndef CONFIG_ETRAX_PB_CHANGEABLE_BITS
107
#define CONFIG_ETRAX_PB_CHANGEABLE_BITS 0xFF
108
#endif
109
110
111
static unsigned char changeable_dir[NUM_PORTS] = {
112
CONFIG_ETRAX_PA_CHANGEABLE_DIR,
113
CONFIG_ETRAX_PB_CHANGEABLE_DIR
114
};
115
static unsigned char changeable_bits[NUM_PORTS] = {
116
CONFIG_ETRAX_PA_CHANGEABLE_BITS,
117
CONFIG_ETRAX_PB_CHANGEABLE_BITS
118
};
119
120
static volatile unsigned char *dir[NUM_PORTS] = {
121
R_PORT_PA_DIR,
122
R_PORT_PB_DIR
123
};
124
125
static volatile unsigned char *dir_shadow[NUM_PORTS] = {
126
&port_pa_dir_shadow,
127
&port_pb_dir_shadow
128
};
129
130
/* All bits in port g that can change dir. */
131
static const unsigned long int changeable_dir_g_mask = 0x01FFFF01;
132
133
/* Port G is 32 bit, handle it special, some bits are both inputs
134
and outputs at the same time, only some of the bits can change direction
135
and some of them in groups of 8 bit. */
136
static unsigned long changeable_dir_g;
137
static unsigned long dir_g_in_bits;
138
static unsigned long dir_g_out_bits;
139
static unsigned long dir_g_shadow; /* 1=output */
140
141
#define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
142
143
144
static unsigned int gpio_poll(struct file *file, poll_table *wait)
145
{
146
unsigned int mask = 0;
147
struct gpio_private *priv = file->private_data;
148
unsigned long data;
149
unsigned long flags;
150
151
spin_lock_irqsave(&gpio_lock, flags);
152
153
poll_wait(file, &priv->alarm_wq, wait);
154
if (priv->minor == GPIO_MINOR_A) {
155
unsigned long tmp;
156
data = *R_PORT_PA_DATA;
157
/* PA has support for high level interrupt -
158
* lets activate for those low and with highalarm set
159
*/
160
tmp = ~data & priv->highalarm & 0xFF;
161
tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
162
163
gpio_pa_irq_enabled_mask |= tmp;
164
*R_IRQ_MASK1_SET = tmp;
165
} else if (priv->minor == GPIO_MINOR_B)
166
data = *R_PORT_PB_DATA;
167
else if (priv->minor == GPIO_MINOR_G)
168
data = *R_PORT_G_DATA;
169
else {
170
mask = 0;
171
goto out;
172
}
173
174
if ((data & priv->highalarm) ||
175
(~data & priv->lowalarm)) {
176
mask = POLLIN|POLLRDNORM;
177
}
178
179
out:
180
spin_unlock_irqrestore(&gpio_lock, flags);
181
DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
182
183
return mask;
184
}
185
186
int etrax_gpio_wake_up_check(void)
187
{
188
struct gpio_private *priv;
189
unsigned long data = 0;
190
int ret = 0;
191
unsigned long flags;
192
193
spin_lock_irqsave(&gpio_lock, flags);
194
priv = alarmlist;
195
while (priv) {
196
if (USE_PORTS(priv))
197
data = *priv->port;
198
else if (priv->minor == GPIO_MINOR_G)
199
data = *R_PORT_G_DATA;
200
201
if ((data & priv->highalarm) ||
202
(~data & priv->lowalarm)) {
203
DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
204
wake_up_interruptible(&priv->alarm_wq);
205
ret = 1;
206
}
207
priv = priv->next;
208
}
209
spin_unlock_irqrestore(&gpio_lock, flags);
210
return ret;
211
}
212
213
static irqreturn_t
214
gpio_poll_timer_interrupt(int irq, void *dev_id)
215
{
216
if (gpio_some_alarms) {
217
etrax_gpio_wake_up_check();
218
return IRQ_HANDLED;
219
}
220
return IRQ_NONE;
221
}
222
223
static irqreturn_t
224
gpio_interrupt(int irq, void *dev_id)
225
{
226
unsigned long tmp;
227
unsigned long flags;
228
229
spin_lock_irqsave(&gpio_lock, flags);
230
231
/* Find what PA interrupts are active */
232
tmp = (*R_IRQ_READ1);
233
234
/* Find those that we have enabled */
235
tmp &= gpio_pa_irq_enabled_mask;
236
237
/* Clear them.. */
238
*R_IRQ_MASK1_CLR = tmp;
239
gpio_pa_irq_enabled_mask &= ~tmp;
240
241
spin_unlock_irqrestore(&gpio_lock, flags);
242
243
if (gpio_some_alarms)
244
return IRQ_RETVAL(etrax_gpio_wake_up_check());
245
246
return IRQ_NONE;
247
}
248
249
static void gpio_write_bit(struct gpio_private *priv,
250
unsigned char data, int bit)
251
{
252
*priv->port = *priv->shadow &= ~(priv->clk_mask);
253
if (data & 1 << bit)
254
*priv->port = *priv->shadow |= priv->data_mask;
255
else
256
*priv->port = *priv->shadow &= ~(priv->data_mask);
257
258
/* For FPGA: min 5.0ns (DCC) before CCLK high */
259
*priv->port = *priv->shadow |= priv->clk_mask;
260
}
261
262
static void gpio_write_byte(struct gpio_private *priv, unsigned char data)
263
{
264
int i;
265
266
if (priv->write_msb)
267
for (i = 7; i >= 0; i--)
268
gpio_write_bit(priv, data, i);
269
else
270
for (i = 0; i <= 7; i++)
271
gpio_write_bit(priv, data, i);
272
}
273
274
static ssize_t gpio_write(struct file *file, const char __user *buf,
275
size_t count, loff_t *off)
276
{
277
struct gpio_private *priv = file->private_data;
278
unsigned long flags;
279
ssize_t retval = count;
280
281
if (priv->minor != GPIO_MINOR_A && priv->minor != GPIO_MINOR_B)
282
return -EFAULT;
283
284
if (!access_ok(VERIFY_READ, buf, count))
285
return -EFAULT;
286
287
spin_lock_irqsave(&gpio_lock, flags);
288
289
/* It must have been configured using the IO_CFG_WRITE_MODE */
290
/* Perhaps a better error code? */
291
if (priv->clk_mask == 0 || priv->data_mask == 0) {
292
retval = -EPERM;
293
goto out;
294
}
295
296
D(printk(KERN_DEBUG "gpio_write: %02X to data 0x%02X "
297
"clk 0x%02X msb: %i\n",
298
count, priv->data_mask, priv->clk_mask, priv->write_msb));
299
300
while (count--)
301
gpio_write_byte(priv, *buf++);
302
303
out:
304
spin_unlock_irqrestore(&gpio_lock, flags);
305
return retval;
306
}
307
308
309
310
static int
311
gpio_open(struct inode *inode, struct file *filp)
312
{
313
struct gpio_private *priv;
314
int p = iminor(inode);
315
unsigned long flags;
316
317
if (p > GPIO_MINOR_LAST)
318
return -EINVAL;
319
320
priv = kzalloc(sizeof(struct gpio_private), GFP_KERNEL);
321
322
if (!priv)
323
return -ENOMEM;
324
325
priv->minor = p;
326
327
/* initialize the io/alarm struct */
328
329
if (USE_PORTS(priv)) { /* A and B */
330
priv->port = ports[p];
331
priv->shadow = shads[p];
332
priv->dir = dir[p];
333
priv->dir_shadow = dir_shadow[p];
334
priv->changeable_dir = changeable_dir[p];
335
priv->changeable_bits = changeable_bits[p];
336
} else {
337
priv->port = NULL;
338
priv->shadow = NULL;
339
priv->dir = NULL;
340
priv->dir_shadow = NULL;
341
priv->changeable_dir = 0;
342
priv->changeable_bits = 0;
343
}
344
345
priv->highalarm = 0;
346
priv->lowalarm = 0;
347
priv->clk_mask = 0;
348
priv->data_mask = 0;
349
init_waitqueue_head(&priv->alarm_wq);
350
351
filp->private_data = priv;
352
353
/* link it into our alarmlist */
354
spin_lock_irqsave(&gpio_lock, flags);
355
priv->next = alarmlist;
356
alarmlist = priv;
357
spin_unlock_irqrestore(&gpio_lock, flags);
358
359
return 0;
360
}
361
362
static int
363
gpio_release(struct inode *inode, struct file *filp)
364
{
365
struct gpio_private *p;
366
struct gpio_private *todel;
367
unsigned long flags;
368
369
spin_lock_irqsave(&gpio_lock, flags);
370
371
p = alarmlist;
372
todel = filp->private_data;
373
374
/* unlink from alarmlist and free the private structure */
375
376
if (p == todel) {
377
alarmlist = todel->next;
378
} else {
379
while (p->next != todel)
380
p = p->next;
381
p->next = todel->next;
382
}
383
384
kfree(todel);
385
/* Check if there are still any alarms set */
386
p = alarmlist;
387
while (p) {
388
if (p->highalarm | p->lowalarm) {
389
gpio_some_alarms = 1;
390
goto out;
391
}
392
p = p->next;
393
}
394
gpio_some_alarms = 0;
395
out:
396
spin_unlock_irqrestore(&gpio_lock, flags);
397
return 0;
398
}
399
400
/* Main device API. ioctl's to read/set/clear bits, as well as to
401
* set alarms to wait for using a subsequent select().
402
*/
403
unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
404
{
405
/* Set direction 0=unchanged 1=input,
406
* return mask with 1=input */
407
if (USE_PORTS(priv)) {
408
*priv->dir = *priv->dir_shadow &=
409
~((unsigned char)arg & priv->changeable_dir);
410
return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
411
}
412
413
if (priv->minor != GPIO_MINOR_G)
414
return 0;
415
416
/* We must fiddle with R_GEN_CONFIG to change dir */
417
if (((arg & dir_g_in_bits) != arg) &&
418
(arg & changeable_dir_g)) {
419
arg &= changeable_dir_g;
420
/* Clear bits in genconfig to set to input */
421
if (arg & (1<<0)) {
422
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g0dir);
423
dir_g_in_bits |= (1<<0);
424
dir_g_out_bits &= ~(1<<0);
425
}
426
if ((arg & 0x0000FF00) == 0x0000FF00) {
427
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g8_15dir);
428
dir_g_in_bits |= 0x0000FF00;
429
dir_g_out_bits &= ~0x0000FF00;
430
}
431
if ((arg & 0x00FF0000) == 0x00FF0000) {
432
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g16_23dir);
433
dir_g_in_bits |= 0x00FF0000;
434
dir_g_out_bits &= ~0x00FF0000;
435
}
436
if (arg & (1<<24)) {
437
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g24dir);
438
dir_g_in_bits |= (1<<24);
439
dir_g_out_bits &= ~(1<<24);
440
}
441
D(printk(KERN_DEBUG "gpio: SETINPUT on port G set "
442
"genconfig to 0x%08lX "
443
"in_bits: 0x%08lX "
444
"out_bits: 0x%08lX\n",
445
(unsigned long)genconfig_shadow,
446
dir_g_in_bits, dir_g_out_bits));
447
*R_GEN_CONFIG = genconfig_shadow;
448
/* Must be a >120 ns delay before writing this again */
449
450
}
451
return dir_g_in_bits;
452
} /* setget_input */
453
454
unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
455
{
456
if (USE_PORTS(priv)) {
457
*priv->dir = *priv->dir_shadow |=
458
((unsigned char)arg & priv->changeable_dir);
459
return *priv->dir_shadow;
460
}
461
if (priv->minor != GPIO_MINOR_G)
462
return 0;
463
464
/* We must fiddle with R_GEN_CONFIG to change dir */
465
if (((arg & dir_g_out_bits) != arg) &&
466
(arg & changeable_dir_g)) {
467
/* Set bits in genconfig to set to output */
468
if (arg & (1<<0)) {
469
genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g0dir);
470
dir_g_out_bits |= (1<<0);
471
dir_g_in_bits &= ~(1<<0);
472
}
473
if ((arg & 0x0000FF00) == 0x0000FF00) {
474
genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g8_15dir);
475
dir_g_out_bits |= 0x0000FF00;
476
dir_g_in_bits &= ~0x0000FF00;
477
}
478
if ((arg & 0x00FF0000) == 0x00FF0000) {
479
genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g16_23dir);
480
dir_g_out_bits |= 0x00FF0000;
481
dir_g_in_bits &= ~0x00FF0000;
482
}
483
if (arg & (1<<24)) {
484
genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g24dir);
485
dir_g_out_bits |= (1<<24);
486
dir_g_in_bits &= ~(1<<24);
487
}
488
D(printk(KERN_INFO "gpio: SETOUTPUT on port G set "
489
"genconfig to 0x%08lX "
490
"in_bits: 0x%08lX "
491
"out_bits: 0x%08lX\n",
492
(unsigned long)genconfig_shadow,
493
dir_g_in_bits, dir_g_out_bits));
494
*R_GEN_CONFIG = genconfig_shadow;
495
/* Must be a >120 ns delay before writing this again */
496
}
497
return dir_g_out_bits & 0x7FFFFFFF;
498
} /* setget_output */
499
500
static int
501
gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
502
503
static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
504
{
505
unsigned long flags;
506
unsigned long val;
507
int ret = 0;
508
509
struct gpio_private *priv = file->private_data;
510
if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
511
return -EINVAL;
512
513
switch (_IOC_NR(cmd)) {
514
case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
515
// read the port
516
spin_lock_irqsave(&gpio_lock, flags);
517
if (USE_PORTS(priv)) {
518
ret = *priv->port;
519
} else if (priv->minor == GPIO_MINOR_G) {
520
ret = (*R_PORT_G_DATA) & 0x7FFFFFFF;
521
}
522
spin_unlock_irqrestore(&gpio_lock, flags);
523
524
break;
525
case IO_SETBITS:
526
// set changeable bits with a 1 in arg
527
spin_lock_irqsave(&gpio_lock, flags);
528
529
if (USE_PORTS(priv)) {
530
*priv->port = *priv->shadow |=
531
((unsigned char)arg & priv->changeable_bits);
532
} else if (priv->minor == GPIO_MINOR_G) {
533
*R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
534
}
535
spin_unlock_irqrestore(&gpio_lock, flags);
536
537
break;
538
case IO_CLRBITS:
539
// clear changeable bits with a 1 in arg
540
spin_lock_irqsave(&gpio_lock, flags);
541
if (USE_PORTS(priv)) {
542
*priv->port = *priv->shadow &=
543
~((unsigned char)arg & priv->changeable_bits);
544
} else if (priv->minor == GPIO_MINOR_G) {
545
*R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits);
546
}
547
spin_unlock_irqrestore(&gpio_lock, flags);
548
break;
549
case IO_HIGHALARM:
550
// set alarm when bits with 1 in arg go high
551
spin_lock_irqsave(&gpio_lock, flags);
552
priv->highalarm |= arg;
553
gpio_some_alarms = 1;
554
spin_unlock_irqrestore(&gpio_lock, flags);
555
break;
556
case IO_LOWALARM:
557
// set alarm when bits with 1 in arg go low
558
spin_lock_irqsave(&gpio_lock, flags);
559
priv->lowalarm |= arg;
560
gpio_some_alarms = 1;
561
spin_unlock_irqrestore(&gpio_lock, flags);
562
break;
563
case IO_CLRALARM:
564
/* clear alarm for bits with 1 in arg */
565
spin_lock_irqsave(&gpio_lock, flags);
566
priv->highalarm &= ~arg;
567
priv->lowalarm &= ~arg;
568
{
569
/* Must update gpio_some_alarms */
570
struct gpio_private *p = alarmlist;
571
int some_alarms;
572
p = alarmlist;
573
some_alarms = 0;
574
while (p) {
575
if (p->highalarm | p->lowalarm) {
576
some_alarms = 1;
577
break;
578
}
579
p = p->next;
580
}
581
gpio_some_alarms = some_alarms;
582
}
583
spin_unlock_irqrestore(&gpio_lock, flags);
584
break;
585
case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
586
/* Read direction 0=input 1=output */
587
spin_lock_irqsave(&gpio_lock, flags);
588
if (USE_PORTS(priv)) {
589
ret = *priv->dir_shadow;
590
} else if (priv->minor == GPIO_MINOR_G) {
591
/* Note: Some bits are both in and out,
592
* Those that are dual is set here as well.
593
*/
594
ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
595
}
596
spin_unlock_irqrestore(&gpio_lock, flags);
597
break;
598
case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
599
/* Set direction 0=unchanged 1=input,
600
* return mask with 1=input
601
*/
602
spin_lock_irqsave(&gpio_lock, flags);
603
ret = setget_input(priv, arg) & 0x7FFFFFFF;
604
spin_unlock_irqrestore(&gpio_lock, flags);
605
break;
606
case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
607
/* Set direction 0=unchanged 1=output,
608
* return mask with 1=output
609
*/
610
spin_lock_irqsave(&gpio_lock, flags);
611
ret = setget_output(priv, arg) & 0x7FFFFFFF;
612
spin_unlock_irqrestore(&gpio_lock, flags);
613
break;
614
case IO_SHUTDOWN:
615
spin_lock_irqsave(&gpio_lock, flags);
616
SOFT_SHUTDOWN();
617
spin_unlock_irqrestore(&gpio_lock, flags);
618
break;
619
case IO_GET_PWR_BT:
620
spin_lock_irqsave(&gpio_lock, flags);
621
#if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
622
ret = (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
623
#else
624
ret = 0;
625
#endif
626
spin_unlock_irqrestore(&gpio_lock, flags);
627
break;
628
case IO_CFG_WRITE_MODE:
629
spin_lock_irqsave(&gpio_lock, flags);
630
priv->clk_mask = arg & 0xFF;
631
priv->data_mask = (arg >> 8) & 0xFF;
632
priv->write_msb = (arg >> 16) & 0x01;
633
/* Check if we're allowed to change the bits and
634
* the direction is correct
635
*/
636
if (!((priv->clk_mask & priv->changeable_bits) &&
637
(priv->data_mask & priv->changeable_bits) &&
638
(priv->clk_mask & *priv->dir_shadow) &&
639
(priv->data_mask & *priv->dir_shadow)))
640
{
641
priv->clk_mask = 0;
642
priv->data_mask = 0;
643
ret = -EPERM;
644
}
645
spin_unlock_irqrestore(&gpio_lock, flags);
646
break;
647
case IO_READ_INBITS:
648
/* *arg is result of reading the input pins */
649
spin_lock_irqsave(&gpio_lock, flags);
650
if (USE_PORTS(priv)) {
651
val = *priv->port;
652
} else if (priv->minor == GPIO_MINOR_G) {
653
val = *R_PORT_G_DATA;
654
}
655
spin_unlock_irqrestore(&gpio_lock, flags);
656
if (copy_to_user((void __user *)arg, &val, sizeof(val)))
657
ret = -EFAULT;
658
break;
659
case IO_READ_OUTBITS:
660
/* *arg is result of reading the output shadow */
661
spin_lock_irqsave(&gpio_lock, flags);
662
if (USE_PORTS(priv)) {
663
val = *priv->shadow;
664
} else if (priv->minor == GPIO_MINOR_G) {
665
val = port_g_data_shadow;
666
}
667
spin_unlock_irqrestore(&gpio_lock, flags);
668
if (copy_to_user((void __user *)arg, &val, sizeof(val)))
669
ret = -EFAULT;
670
break;
671
case IO_SETGET_INPUT:
672
/* bits set in *arg is set to input,
673
* *arg updated with current input pins.
674
*/
675
if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
676
{
677
ret = -EFAULT;
678
break;
679
}
680
spin_lock_irqsave(&gpio_lock, flags);
681
val = setget_input(priv, val);
682
spin_unlock_irqrestore(&gpio_lock, flags);
683
if (copy_to_user((void __user *)arg, &val, sizeof(val)))
684
ret = -EFAULT;
685
break;
686
case IO_SETGET_OUTPUT:
687
/* bits set in *arg is set to output,
688
* *arg updated with current output pins.
689
*/
690
if (copy_from_user(&val, (void __user *)arg, sizeof(val))) {
691
ret = -EFAULT;
692
break;
693
}
694
spin_lock_irqsave(&gpio_lock, flags);
695
val = setget_output(priv, val);
696
spin_unlock_irqrestore(&gpio_lock, flags);
697
if (copy_to_user((void __user *)arg, &val, sizeof(val)))
698
ret = -EFAULT;
699
break;
700
default:
701
spin_lock_irqsave(&gpio_lock, flags);
702
if (priv->minor == GPIO_MINOR_LEDS)
703
ret = gpio_leds_ioctl(cmd, arg);
704
else
705
ret = -EINVAL;
706
spin_unlock_irqrestore(&gpio_lock, flags);
707
} /* switch */
708
709
return ret;
710
}
711
712
static int
713
gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
714
{
715
unsigned char green;
716
unsigned char red;
717
718
switch (_IOC_NR(cmd)) {
719
case IO_LEDACTIVE_SET:
720
green = ((unsigned char)arg) & 1;
721
red = (((unsigned char)arg) >> 1) & 1;
722
CRIS_LED_ACTIVE_SET_G(green);
723
CRIS_LED_ACTIVE_SET_R(red);
724
break;
725
726
case IO_LED_SETBIT:
727
CRIS_LED_BIT_SET(arg);
728
break;
729
730
case IO_LED_CLRBIT:
731
CRIS_LED_BIT_CLR(arg);
732
break;
733
734
default:
735
return -EINVAL;
736
} /* switch */
737
738
return 0;
739
}
740
741
static const struct file_operations gpio_fops = {
742
.owner = THIS_MODULE,
743
.poll = gpio_poll,
744
.unlocked_ioctl = gpio_ioctl,
745
.write = gpio_write,
746
.open = gpio_open,
747
.release = gpio_release,
748
.llseek = noop_llseek,
749
};
750
751
static void ioif_watcher(const unsigned int gpio_in_available,
752
const unsigned int gpio_out_available,
753
const unsigned char pa_available,
754
const unsigned char pb_available)
755
{
756
unsigned long int flags;
757
758
D(printk(KERN_DEBUG "gpio.c: ioif_watcher called\n"));
759
D(printk(KERN_DEBUG "gpio.c: G in: 0x%08x G out: 0x%08x "
760
"PA: 0x%02x PB: 0x%02x\n",
761
gpio_in_available, gpio_out_available,
762
pa_available, pb_available));
763
764
spin_lock_irqsave(&gpio_lock, flags);
765
766
dir_g_in_bits = gpio_in_available;
767
dir_g_out_bits = gpio_out_available;
768
769
/* Initialise the dir_g_shadow etc. depending on genconfig */
770
/* 0=input 1=output */
771
if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out))
772
dir_g_shadow |= (1 << 0);
773
if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out))
774
dir_g_shadow |= 0x0000FF00;
775
if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g16_23dir, out))
776
dir_g_shadow |= 0x00FF0000;
777
if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out))
778
dir_g_shadow |= (1 << 24);
779
780
changeable_dir_g = changeable_dir_g_mask;
781
changeable_dir_g &= dir_g_out_bits;
782
changeable_dir_g &= dir_g_in_bits;
783
784
/* Correct the bits that can change direction */
785
dir_g_out_bits &= ~changeable_dir_g;
786
dir_g_out_bits |= dir_g_shadow;
787
dir_g_in_bits &= ~changeable_dir_g;
788
dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
789
790
spin_unlock_irqrestore(&gpio_lock, flags);
791
792
printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX "
793
"val: %08lX\n",
794
dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
795
printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n",
796
dir_g_shadow, changeable_dir_g);
797
}
798
799
/* main driver initialization routine, called from mem.c */
800
801
static int __init gpio_init(void)
802
{
803
int res;
804
#if defined (CONFIG_ETRAX_CSP0_LEDS)
805
int i;
806
#endif
807
808
res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
809
if (res < 0) {
810
printk(KERN_ERR "gpio: couldn't get a major number.\n");
811
return res;
812
}
813
814
/* Clear all leds */
815
#if defined (CONFIG_ETRAX_CSP0_LEDS) || defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS)
816
CRIS_LED_NETWORK_SET(0);
817
CRIS_LED_ACTIVE_SET(0);
818
CRIS_LED_DISK_READ(0);
819
CRIS_LED_DISK_WRITE(0);
820
821
#if defined (CONFIG_ETRAX_CSP0_LEDS)
822
for (i = 0; i < 32; i++)
823
CRIS_LED_BIT_SET(i);
824
#endif
825
826
#endif
827
/* The I/O interface allocation watcher will be called when
828
* registering it. */
829
if (cris_io_interface_register_watcher(ioif_watcher)){
830
printk(KERN_WARNING "gpio_init: Failed to install IO "
831
"if allocator watcher\n");
832
}
833
834
printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001-2008 "
835
"Axis Communications AB\n");
836
/* We call etrax_gpio_wake_up_check() from timer interrupt and
837
* from cpu_idle() in kernel/process.c
838
* The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
839
* in some tests.
840
*/
841
res = request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
842
IRQF_SHARED | IRQF_DISABLED, "gpio poll", gpio_name);
843
if (res) {
844
printk(KERN_CRIT "err: timer0 irq for gpio\n");
845
return res;
846
}
847
res = request_irq(PA_IRQ_NBR, gpio_interrupt,
848
IRQF_SHARED | IRQF_DISABLED, "gpio PA", gpio_name);
849
if (res)
850
printk(KERN_CRIT "err: PA irq for gpio\n");
851
852
return res;
853
}
854
855
/* this makes sure that gpio_init is called during kernel boot */
856
module_init(gpio_init);
857
858
859