Merge master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
[pandora-kernel.git] / arch / cris / arch-v32 / drivers / gpio.c
1 /* $Id: gpio.c,v 1.16 2005/06/19 17:06:49 starvik Exp $
2  *
3  * ETRAX CRISv32 general port I/O device
4  *
5  * Copyright (c) 1999, 2000, 2001, 2002, 2003 Axis Communications AB
6  *
7  * Authors:    Bjorn Wesen      (initial version)
8  *             Ola Knutsson     (LED handling)
9  *             Johan Adolfsson  (read/set directions, write, port G,
10  *                               port to ETRAX FS.
11  *
12  * $Log: gpio.c,v $
13  * Revision 1.16  2005/06/19 17:06:49  starvik
14  * Merge of Linux 2.6.12.
15  *
16  * Revision 1.15  2005/05/25 08:22:20  starvik
17  * Changed GPIO port order to fit packages/devices/axis-2.4.
18  *
19  * Revision 1.14  2005/04/24 18:35:08  starvik
20  * Updated with final register headers.
21  *
22  * Revision 1.13  2005/03/15 15:43:00  starvik
23  * dev_id needs to be supplied for shared IRQs.
24  *
25  * Revision 1.12  2005/03/10 17:12:00  starvik
26  * Protect alarm list with spinlock.
27  *
28  * Revision 1.11  2005/01/05 06:08:59  starvik
29  * No need to do local_irq_disable after local_irq_save.
30  *
31  * Revision 1.10  2004/11/19 08:38:31  starvik
32  * Removed old crap.
33  *
34  * Revision 1.9  2004/05/14 07:58:02  starvik
35  * Merge of changes from 2.4
36  *
37  * Revision 1.8  2003/09/11 07:29:50  starvik
38  * Merge of Linux 2.6.0-test5
39  *
40  * Revision 1.7  2003/07/10 13:25:46  starvik
41  * Compiles for 2.5.74
42  * Lindented ethernet.c
43  *
44  * Revision 1.6  2003/07/04 08:27:46  starvik
45  * Merge of Linux 2.5.74
46  *
47  * Revision 1.5  2003/06/10 08:26:37  johana
48  * Etrax -> ETRAX CRISv32
49  *
50  * Revision 1.4  2003/06/05 14:22:48  johana
51  * Initialise some_alarms.
52  *
53  * Revision 1.3  2003/06/05 10:15:46  johana
54  * New INTR_VECT macros.
55  * Enable interrupts in global config.
56  *
57  * Revision 1.2  2003/06/03 15:52:50  johana
58  * Initial CRIS v32 version.
59  *
60  * Revision 1.1  2003/06/03 08:53:15  johana
61  * Copy of os/lx25/arch/cris/arch-v10/drivers/gpio.c version 1.7.
62  *
63  */
64
65 #include <linux/config.h>
66
67 #include <linux/module.h>
68 #include <linux/sched.h>
69 #include <linux/slab.h>
70 #include <linux/ioport.h>
71 #include <linux/errno.h>
72 #include <linux/kernel.h>
73 #include <linux/fs.h>
74 #include <linux/string.h>
75 #include <linux/poll.h>
76 #include <linux/init.h>
77 #include <linux/interrupt.h>
78 #include <linux/spinlock.h>
79
80 #include <asm/etraxgpio.h>
81 #include <asm/arch/hwregs/reg_map.h>
82 #include <asm/arch/hwregs/reg_rdwr.h>
83 #include <asm/arch/hwregs/gio_defs.h>
84 #include <asm/arch/hwregs/intr_vect_defs.h>
85 #include <asm/io.h>
86 #include <asm/system.h>
87 #include <asm/irq.h>
88
89 /* The following gio ports on ETRAX FS is available:
90  * pa  8 bits, supports interrupts off, hi, low, set, posedge, negedge anyedge
91  * pb 18 bits
92  * pc 18 bits
93  * pd 18 bits
94  * pe 18 bits
95  * each port has a rw_px_dout, r_px_din and rw_px_oe register.
96  */
97
98 #define GPIO_MAJOR 120  /* experimental MAJOR number */
99
100 #define D(x)
101
102 #if 0
103 static int dp_cnt;
104 #define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0)
105 #else
106 #define DP(x)
107 #endif
108
109 static char gpio_name[] = "etrax gpio";
110
111 #if 0
112 static wait_queue_head_t *gpio_wq;
113 #endif
114
115 static int gpio_ioctl(struct inode *inode, struct file *file,
116                       unsigned int cmd, unsigned long arg);
117 static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
118                           loff_t *off);
119 static int gpio_open(struct inode *inode, struct file *filp);
120 static int gpio_release(struct inode *inode, struct file *filp);
121 static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
122
123 /* private data per open() of this driver */
124
125 struct gpio_private {
126         struct gpio_private *next;
127         /* The IO_CFG_WRITE_MODE_VALUE only support 8 bits: */
128         unsigned char clk_mask;
129         unsigned char data_mask;
130         unsigned char write_msb;
131         unsigned char pad1;
132         /* These fields are generic */
133         unsigned long highalarm, lowalarm;
134         wait_queue_head_t alarm_wq;
135         int minor;
136 };
137
138 /* linked list of alarms to check for */
139
140 static struct gpio_private *alarmlist = 0;
141
142 static int gpio_some_alarms = 0; /* Set if someone uses alarm */
143 static unsigned long gpio_pa_high_alarms = 0;
144 static unsigned long gpio_pa_low_alarms = 0;
145
146 static DEFINE_SPINLOCK(alarm_lock);
147
148 #define NUM_PORTS (GPIO_MINOR_LAST+1)
149 #define GIO_REG_RD_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg )
150 #define GIO_REG_WR_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg )
151 unsigned long led_dummy;
152
153 static volatile unsigned long *data_out[NUM_PORTS] = {
154         GIO_REG_WR_ADDR(rw_pa_dout),
155         GIO_REG_WR_ADDR(rw_pb_dout),
156         &led_dummy,
157         GIO_REG_WR_ADDR(rw_pc_dout),
158         GIO_REG_WR_ADDR(rw_pd_dout),
159         GIO_REG_WR_ADDR(rw_pe_dout),
160 };
161
162 static volatile unsigned long *data_in[NUM_PORTS] = {
163         GIO_REG_RD_ADDR(r_pa_din),
164         GIO_REG_RD_ADDR(r_pb_din),
165         &led_dummy,
166         GIO_REG_RD_ADDR(r_pc_din),
167         GIO_REG_RD_ADDR(r_pd_din),
168         GIO_REG_RD_ADDR(r_pe_din),
169 };
170
171 static unsigned long changeable_dir[NUM_PORTS] = {
172         CONFIG_ETRAX_PA_CHANGEABLE_DIR,
173         CONFIG_ETRAX_PB_CHANGEABLE_DIR,
174         0,
175         CONFIG_ETRAX_PC_CHANGEABLE_DIR,
176         CONFIG_ETRAX_PD_CHANGEABLE_DIR,
177         CONFIG_ETRAX_PE_CHANGEABLE_DIR,
178 };
179
180 static unsigned long changeable_bits[NUM_PORTS] = {
181         CONFIG_ETRAX_PA_CHANGEABLE_BITS,
182         CONFIG_ETRAX_PB_CHANGEABLE_BITS,
183         0,
184         CONFIG_ETRAX_PC_CHANGEABLE_BITS,
185         CONFIG_ETRAX_PD_CHANGEABLE_BITS,
186         CONFIG_ETRAX_PE_CHANGEABLE_BITS,
187 };
188
189 static volatile unsigned long *dir_oe[NUM_PORTS] = {
190         GIO_REG_WR_ADDR(rw_pa_oe),
191         GIO_REG_WR_ADDR(rw_pb_oe),
192         &led_dummy,
193         GIO_REG_WR_ADDR(rw_pc_oe),
194         GIO_REG_WR_ADDR(rw_pd_oe),
195         GIO_REG_WR_ADDR(rw_pe_oe),
196 };
197
198
199
200 static unsigned int
201 gpio_poll(struct file *file,
202           poll_table *wait)
203 {
204         unsigned int mask = 0;
205         struct gpio_private *priv = (struct gpio_private *)file->private_data;
206         unsigned long data;
207         poll_wait(file, &priv->alarm_wq, wait);
208         if (priv->minor == GPIO_MINOR_A) {
209                 reg_gio_rw_intr_cfg intr_cfg;
210                 unsigned long tmp;
211                 unsigned long flags;
212
213                 local_irq_save(flags);
214                 data = REG_TYPE_CONV(unsigned long, reg_gio_r_pa_din, REG_RD(gio, regi_gio, r_pa_din));
215                 /* PA has support for interrupt
216                  * lets activate high for those low and with highalarm set
217                  */
218                 intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
219
220                 tmp = ~data & priv->highalarm & 0xFF;
221                 if (tmp & (1 << 0)) {
222                         intr_cfg.pa0 = regk_gio_hi;
223                 }
224                 if (tmp & (1 << 1)) {
225                         intr_cfg.pa1 = regk_gio_hi;
226                 }
227                 if (tmp & (1 << 2)) {
228                         intr_cfg.pa2 = regk_gio_hi;
229                 }
230                 if (tmp & (1 << 3)) {
231                         intr_cfg.pa3 = regk_gio_hi;
232                 }
233                 if (tmp & (1 << 4)) {
234                         intr_cfg.pa4 = regk_gio_hi;
235                 }
236                 if (tmp & (1 << 5)) {
237                         intr_cfg.pa5 = regk_gio_hi;
238                 }
239                 if (tmp & (1 << 6)) {
240                         intr_cfg.pa6 = regk_gio_hi;
241                 }
242                 if (tmp & (1 << 7)) {
243                         intr_cfg.pa7 = regk_gio_hi;
244                 }
245                 /*
246                  * lets activate low for those high and with lowalarm set
247                  */
248                 tmp = data & priv->lowalarm & 0xFF;
249                 if (tmp & (1 << 0)) {
250                         intr_cfg.pa0 = regk_gio_lo;
251                 }
252                 if (tmp & (1 << 1)) {
253                         intr_cfg.pa1 = regk_gio_lo;
254                 }
255                 if (tmp & (1 << 2)) {
256                         intr_cfg.pa2 = regk_gio_lo;
257                 }
258                 if (tmp & (1 << 3)) {
259                         intr_cfg.pa3 = regk_gio_lo;
260                 }
261                 if (tmp & (1 << 4)) {
262                         intr_cfg.pa4 = regk_gio_lo;
263                 }
264                 if (tmp & (1 << 5)) {
265                         intr_cfg.pa5 = regk_gio_lo;
266                 }
267                 if (tmp & (1 << 6)) {
268                         intr_cfg.pa6 = regk_gio_lo;
269                 }
270                 if (tmp & (1 << 7)) {
271                         intr_cfg.pa7 = regk_gio_lo;
272                 }
273
274                 REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
275                 local_irq_restore(flags);
276         } else if (priv->minor <= GPIO_MINOR_E)
277                 data = *data_in[priv->minor];
278         else
279                 return 0;
280
281         if ((data & priv->highalarm) ||
282             (~data & priv->lowalarm)) {
283                 mask = POLLIN|POLLRDNORM;
284         }
285
286         DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
287         return mask;
288 }
289
290 int etrax_gpio_wake_up_check(void)
291 {
292         struct gpio_private *priv = alarmlist;
293         unsigned long data = 0;
294         int ret = 0;
295         while (priv) {
296                 data = *data_in[priv->minor];
297                 if ((data & priv->highalarm) ||
298                     (~data & priv->lowalarm)) {
299                         DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
300                         wake_up_interruptible(&priv->alarm_wq);
301                         ret = 1;
302                 }
303                 priv = priv->next;
304         }
305         return ret;
306 }
307
308 static irqreturn_t
309 gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
310 {
311         if (gpio_some_alarms) {
312                 return IRQ_RETVAL(etrax_gpio_wake_up_check());
313         }
314         return IRQ_NONE;
315 }
316
317 static irqreturn_t
318 gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
319 {
320         reg_gio_rw_intr_mask intr_mask;
321         reg_gio_r_masked_intr masked_intr;
322         reg_gio_rw_ack_intr ack_intr;
323         unsigned long tmp;
324         unsigned long tmp2;
325
326         /* Find what PA interrupts are active */
327         masked_intr = REG_RD(gio, regi_gio, r_masked_intr);
328         tmp = REG_TYPE_CONV(unsigned long, reg_gio_r_masked_intr, masked_intr);
329
330         /* Find those that we have enabled */
331         spin_lock(&alarm_lock);
332         tmp &= (gpio_pa_high_alarms | gpio_pa_low_alarms);
333         spin_unlock(&alarm_lock);
334
335         /* Ack them */
336         ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp);
337         REG_WR(gio, regi_gio, rw_ack_intr, ack_intr);
338
339         /* Disable those interrupts.. */
340         intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
341         tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask);
342         tmp2 &= ~tmp;
343         intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2);
344         REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
345
346         if (gpio_some_alarms) {
347                 return IRQ_RETVAL(etrax_gpio_wake_up_check());
348         }
349         return IRQ_NONE;
350 }
351
352
353 static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
354                           loff_t *off)
355 {
356         struct gpio_private *priv = (struct gpio_private *)file->private_data;
357         unsigned char data, clk_mask, data_mask, write_msb;
358         unsigned long flags;
359         unsigned long shadow;
360         volatile unsigned long *port;
361         ssize_t retval = count;
362         /* Only bits 0-7 may be used for write operations but allow all
363            devices except leds... */
364         if (priv->minor == GPIO_MINOR_LEDS) {
365                 return -EFAULT;
366         }
367
368         if (!access_ok(VERIFY_READ, buf, count)) {
369                 return -EFAULT;
370         }
371         clk_mask = priv->clk_mask;
372         data_mask = priv->data_mask;
373         /* It must have been configured using the IO_CFG_WRITE_MODE */
374         /* Perhaps a better error code? */
375         if (clk_mask == 0 || data_mask == 0) {
376                 return -EPERM;
377         }
378         write_msb = priv->write_msb;
379         D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb));
380         port = data_out[priv->minor];
381
382         while (count--) {
383                 int i;
384                 data = *buf++;
385                 if (priv->write_msb) {
386                         for (i = 7; i >= 0;i--) {
387                                 local_irq_save(flags);
388                                 shadow = *port;
389                                 *port = shadow &= ~clk_mask;
390                                 if (data & 1<<i)
391                                         *port = shadow |= data_mask;
392                                 else
393                                         *port = shadow &= ~data_mask;
394                         /* For FPGA: min 5.0ns (DCC) before CCLK high */
395                                 *port = shadow |= clk_mask;
396                                 local_irq_restore(flags);
397                         }
398                 } else {
399                         for (i = 0; i <= 7;i++) {
400                                 local_irq_save(flags);
401                                 shadow = *port;
402                                 *port = shadow &= ~clk_mask;
403                                 if (data & 1<<i)
404                                         *port = shadow |= data_mask;
405                                 else
406                                         *port = shadow &= ~data_mask;
407                         /* For FPGA: min 5.0ns (DCC) before CCLK high */
408                                 *port = shadow |= clk_mask;
409                                 local_irq_restore(flags);
410                         }
411                 }
412         }
413         return retval;
414 }
415
416
417
418 static int
419 gpio_open(struct inode *inode, struct file *filp)
420 {
421         struct gpio_private *priv;
422         int p = MINOR(inode->i_rdev);
423
424         if (p > GPIO_MINOR_LAST)
425                 return -EINVAL;
426
427         priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private),
428                                               GFP_KERNEL);
429
430         if (!priv)
431                 return -ENOMEM;
432
433         priv->minor = p;
434
435         /* initialize the io/alarm struct and link it into our alarmlist */
436
437         priv->next = alarmlist;
438         alarmlist = priv;
439         priv->clk_mask = 0;
440         priv->data_mask = 0;
441         priv->highalarm = 0;
442         priv->lowalarm = 0;
443         init_waitqueue_head(&priv->alarm_wq);
444
445         filp->private_data = (void *)priv;
446
447         return 0;
448 }
449
450 static int
451 gpio_release(struct inode *inode, struct file *filp)
452 {
453         struct gpio_private *p = alarmlist;
454         struct gpio_private *todel = (struct gpio_private *)filp->private_data;
455         /* local copies while updating them: */
456         unsigned long a_high, a_low;
457         unsigned long some_alarms;
458
459         /* unlink from alarmlist and free the private structure */
460
461         if (p == todel) {
462                 alarmlist = todel->next;
463         } else {
464                 while (p->next != todel)
465                         p = p->next;
466                 p->next = todel->next;
467         }
468
469         kfree(todel);
470         /* Check if there are still any alarms set */
471         p = alarmlist;
472         some_alarms = 0;
473         a_high = 0;
474         a_low = 0;
475         while (p) {
476                 if (p->minor == GPIO_MINOR_A) {
477                         a_high |= p->highalarm;
478                         a_low |= p->lowalarm;
479                 }
480
481                 if (p->highalarm | p->lowalarm) {
482                         some_alarms = 1;
483                 }
484                 p = p->next;
485         }
486
487         spin_lock(&alarm_lock);
488         gpio_some_alarms = some_alarms;
489         gpio_pa_high_alarms = a_high;
490         gpio_pa_low_alarms = a_low;
491         spin_unlock(&alarm_lock);
492
493         return 0;
494 }
495
496 /* Main device API. ioctl's to read/set/clear bits, as well as to
497  * set alarms to wait for using a subsequent select().
498  */
499
500 unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
501 {
502         /* Set direction 0=unchanged 1=input,
503          * return mask with 1=input
504          */
505         unsigned long flags;
506         unsigned long dir_shadow;
507
508         local_irq_save(flags);
509         dir_shadow = *dir_oe[priv->minor];
510         dir_shadow &= ~(arg & changeable_dir[priv->minor]);
511         *dir_oe[priv->minor] = dir_shadow;
512         local_irq_restore(flags);
513
514         if (priv->minor == GPIO_MINOR_A)
515                 dir_shadow ^= 0xFF;    /* Only 8 bits */
516         else
517                 dir_shadow ^= 0x3FFFF; /* Only 18 bits */
518         return dir_shadow;
519
520 } /* setget_input */
521
522 unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
523 {
524         unsigned long flags;
525         unsigned long dir_shadow;
526
527         local_irq_save(flags);
528         dir_shadow = *dir_oe[priv->minor];
529         dir_shadow |=  (arg & changeable_dir[priv->minor]);
530         *dir_oe[priv->minor] = dir_shadow;
531         local_irq_restore(flags);
532         return dir_shadow;
533 } /* setget_output */
534
535 static int
536 gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
537
538 static int
539 gpio_ioctl(struct inode *inode, struct file *file,
540            unsigned int cmd, unsigned long arg)
541 {
542         unsigned long flags;
543         unsigned long val;
544         unsigned long shadow;
545         struct gpio_private *priv = (struct gpio_private *)file->private_data;
546         if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
547                 return -EINVAL;
548         }
549
550         switch (_IOC_NR(cmd)) {
551         case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
552                 // read the port
553                 return *data_in[priv->minor];
554                 break;
555         case IO_SETBITS:
556                 local_irq_save(flags);
557                 if (arg & 0x04)
558                   printk("GPIO SET 2\n");
559                 // set changeable bits with a 1 in arg
560                 shadow = *data_out[priv->minor];
561                 shadow |=  (arg & changeable_bits[priv->minor]);
562                 *data_out[priv->minor] = shadow;
563                 local_irq_restore(flags);
564                 break;
565         case IO_CLRBITS:
566                 local_irq_save(flags);
567                 if (arg & 0x04)
568                   printk("GPIO CLR 2\n");
569                 // clear changeable bits with a 1 in arg
570                 shadow = *data_out[priv->minor];
571                 shadow &=  ~(arg & changeable_bits[priv->minor]);
572                 *data_out[priv->minor] = shadow;
573                 local_irq_restore(flags);
574                 break;
575         case IO_HIGHALARM:
576                 // set alarm when bits with 1 in arg go high
577                 priv->highalarm |= arg;
578                 spin_lock(&alarm_lock);
579                 gpio_some_alarms = 1;
580                 if (priv->minor == GPIO_MINOR_A) {
581                         gpio_pa_high_alarms |= arg;
582                 }
583                 spin_unlock(&alarm_lock);
584                 break;
585         case IO_LOWALARM:
586                 // set alarm when bits with 1 in arg go low
587                 priv->lowalarm |= arg;
588                 spin_lock(&alarm_lock);
589                 gpio_some_alarms = 1;
590                 if (priv->minor == GPIO_MINOR_A) {
591                         gpio_pa_low_alarms |= arg;
592                 }
593                 spin_unlock(&alarm_lock);
594                 break;
595         case IO_CLRALARM:
596                 // clear alarm for bits with 1 in arg
597                 priv->highalarm &= ~arg;
598                 priv->lowalarm  &= ~arg;
599                 spin_lock(&alarm_lock);
600                 if (priv->minor == GPIO_MINOR_A) {
601                         if (gpio_pa_high_alarms & arg ||
602                             gpio_pa_low_alarms & arg) {
603                                 /* Must update the gpio_pa_*alarms masks */
604                         }
605                 }
606                 spin_unlock(&alarm_lock);
607                 break;
608         case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
609                 /* Read direction 0=input 1=output */
610                 return *dir_oe[priv->minor];
611         case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
612                 /* Set direction 0=unchanged 1=input,
613                  * return mask with 1=input
614                  */
615                 return setget_input(priv, arg);
616                 break;
617         case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
618                 /* Set direction 0=unchanged 1=output,
619                  * return mask with 1=output
620                  */
621                 return setget_output(priv, arg);
622
623         case IO_CFG_WRITE_MODE:
624         {
625                 unsigned long dir_shadow;
626                 dir_shadow = *dir_oe[priv->minor];
627
628                 priv->clk_mask = arg & 0xFF;
629                 priv->data_mask = (arg >> 8) & 0xFF;
630                 priv->write_msb = (arg >> 16) & 0x01;
631                 /* Check if we're allowed to change the bits and
632                  * the direction is correct
633                  */
634                 if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
635                       (priv->data_mask & changeable_bits[priv->minor]) &&
636                       (priv->clk_mask & dir_shadow) &&
637                       (priv->data_mask & dir_shadow)))
638                 {
639                         priv->clk_mask = 0;
640                         priv->data_mask = 0;
641                         return -EPERM;
642                 }
643                 break;
644         }
645         case IO_READ_INBITS:
646                 /* *arg is result of reading the input pins */
647                 val = *data_in[priv->minor];
648                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
649                         return -EFAULT;
650                 return 0;
651                 break;
652         case IO_READ_OUTBITS:
653                  /* *arg is result of reading the output shadow */
654                 val = *data_out[priv->minor];
655                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
656                         return -EFAULT;
657                 break;
658         case IO_SETGET_INPUT:
659                 /* bits set in *arg is set to input,
660                  * *arg updated with current input pins.
661                  */
662                 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
663                         return -EFAULT;
664                 val = setget_input(priv, val);
665                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
666                         return -EFAULT;
667                 break;
668         case IO_SETGET_OUTPUT:
669                 /* bits set in *arg is set to output,
670                  * *arg updated with current output pins.
671                  */
672                 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
673                         return -EFAULT;
674                 val = setget_output(priv, val);
675                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
676                         return -EFAULT;
677                 break;
678         default:
679                 if (priv->minor == GPIO_MINOR_LEDS)
680                         return gpio_leds_ioctl(cmd, arg);
681                 else
682                         return -EINVAL;
683         } /* switch */
684
685         return 0;
686 }
687
688 static int
689 gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
690 {
691         unsigned char green;
692         unsigned char red;
693
694         switch (_IOC_NR(cmd)) {
695         case IO_LEDACTIVE_SET:
696                 green = ((unsigned char) arg) & 1;
697                 red   = (((unsigned char) arg) >> 1) & 1;
698                 LED_ACTIVE_SET_G(green);
699                 LED_ACTIVE_SET_R(red);
700                 break;
701
702         default:
703                 return -EINVAL;
704         } /* switch */
705
706         return 0;
707 }
708
709 struct file_operations gpio_fops = {
710         .owner       = THIS_MODULE,
711         .poll        = gpio_poll,
712         .ioctl       = gpio_ioctl,
713         .write       = gpio_write,
714         .open        = gpio_open,
715         .release     = gpio_release,
716 };
717
718
719 /* main driver initialization routine, called from mem.c */
720
721 static __init int
722 gpio_init(void)
723 {
724         int res;
725         reg_intr_vect_rw_mask intr_mask;
726
727         /* do the formalities */
728
729         res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
730         if (res < 0) {
731                 printk(KERN_ERR "gpio: couldn't get a major number.\n");
732                 return res;
733         }
734
735         /* Clear all leds */
736         LED_NETWORK_SET(0);
737         LED_ACTIVE_SET(0);
738         LED_DISK_READ(0);
739         LED_DISK_WRITE(0);
740
741         printk("ETRAX FS GPIO driver v2.5, (c) 2003-2005 Axis Communications AB\n");
742         /* We call etrax_gpio_wake_up_check() from timer interrupt and
743          * from cpu_idle() in kernel/process.c
744          * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
745          * in some tests.
746          */
747         if (request_irq(TIMER_INTR_VECT, gpio_poll_timer_interrupt,
748                         SA_SHIRQ | SA_INTERRUPT,"gpio poll", &alarmlist)) {
749                 printk("err: timer0 irq for gpio\n");
750         }
751         if (request_irq(GEN_IO_INTR_VECT, gpio_pa_interrupt,
752                         SA_SHIRQ | SA_INTERRUPT,"gpio PA", &alarmlist)) {
753                 printk("err: PA irq for gpio\n");
754         }
755         /* enable the gio and timer irq in global config */
756         intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
757         intr_mask.timer = 1;
758         intr_mask.gen_io = 1;
759         REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
760
761         return res;
762 }
763
764 /* this makes sure that gpio_init is called during kernel boot */
765
766 module_init(gpio_init);