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