patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / arch / cris / arch-v10 / drivers / gpio.c
1 /* $Id: gpio.c,v 1.11 2004/05/14 07:58:03 starvik Exp $
2  *
3  * Etrax general port I/O device
4  *
5  * Copyright (c) 1999, 2000, 2001, 2002 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  *
11  * $Log: gpio.c,v $
12  * Revision 1.11  2004/05/14 07:58:03  starvik
13  * Merge of changes from 2.4
14  *
15  * Revision 1.9  2003/09/11 07:29:48  starvik
16  * Merge of Linux 2.6.0-test5
17  *
18  * Revision 1.8  2003/07/04 08:27:37  starvik
19  * Merge of Linux 2.5.74
20  *
21  * Revision 1.7  2003/01/10 07:44:07  starvik
22  * init_ioremap is now called by kernel before drivers are initialized
23  *
24  * Revision 1.6  2002/12/11 13:13:57  starvik
25  * Added arch/ to v10 specific includes
26  * Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
27  *
28  * Revision 1.5  2002/11/20 11:56:11  starvik
29  * Merge of Linux 2.5.48
30  *
31  * Revision 1.4  2002/11/18 10:10:05  starvik
32  * Linux 2.5 port of latest gpio.c from Linux 2.4
33  *
34  * Revision 1.20  2002/10/16 21:16:24  johana
35  * Added support for PA high level interrupt.
36  * That gives 2ms response time with iodtest for high levels and 2-12 ms
37  * response time on low levels if the check is not made in
38  * process.c:cpu_idle() as well.
39  *
40  * Revision 1.19  2002/10/14 18:27:33  johana
41  * Implemented alarm handling so select() now works.
42  * Latency is around 6-9 ms with a etrax_gpio_wake_up_check() in
43  * cpu_idle().
44  * Otherwise I get 15-18 ms (same as doing the poll in userspace -
45  * but less overhead).
46  * TODO? Perhaps we should add the check in IMMEDIATE_BH (or whatever it
47  * is in 2.4) as well?
48  * TODO? Perhaps call request_irq()/free_irq() only when needed?
49  * Increased version to 2.5
50  *
51  * Revision 1.18  2002/10/11 15:02:00  johana
52  * Mask inverted 8 bit value in setget_input().
53  *
54  * Revision 1.17  2002/06/17 15:53:01  johana
55  * Added IO_READ_INBITS, IO_READ_OUTBITS, IO_SETGET_INPUT and IO_SETGET_OUTPUT
56  * that take a pointer as argument and thus can handle 32 bit ports (G)
57  * correctly.
58  * These should be used instead of IO_READBITS, IO_SETINPUT and IO_SETOUTPUT.
59  * (especially if Port G bit 31 is used)
60  *
61  * Revision 1.16  2002/06/17 09:59:51  johana
62  * Returning 32 bit values in the ioctl return value doesn't work if bit
63  * 31 is set (could happen for port G), so mask it of with 0x7FFFFFFF.
64  * A new set of ioctl's will be added.
65  *
66  * Revision 1.15  2002/05/06 13:19:13  johana
67  * IO_SETINPUT returns mask with bit set = inputs for PA and PB as well.
68  *
69  * Revision 1.14  2002/04/12 12:01:53  johana
70  * Use global r_port_g_data_shadow.
71  * Moved gpio_init_port_g() closer to gpio_init() and marked it __init.
72  *
73  * Revision 1.13  2002/04/10 12:03:55  johana
74  * Added support for port G /dev/gpiog (minor 3).
75  * Changed indentation on switch cases.
76  * Fixed other spaces to tabs.
77  *
78  * Revision 1.12  2001/11/12 19:42:15  pkj
79  * * Corrected return values from gpio_leds_ioctl().
80  * * Fixed compiler warnings.
81  *
82  * Revision 1.11  2001/10/30 14:39:12  johana
83  * Added D() around gpio_write printk.
84  *
85  * Revision 1.10  2001/10/25 10:24:42  johana
86  * Added IO_CFG_WRITE_MODE ioctl and write method that can do fast
87  * bittoggling in the kernel. (This speeds up programming an FPGA with 450kB
88  * from ~60 seconds to 4 seconds).
89  * Added save_flags/cli/restore_flags in ioctl.
90  *
91  * Revision 1.9  2001/05/04 14:16:07  matsfg
92  * Corrected spelling error
93  *
94  * Revision 1.8  2001/04/27 13:55:26  matsfg
95  * Moved initioremap.
96  * Turns off all LEDS on init.
97  * Added support for shutdown and powerbutton.
98  *
99  * Revision 1.7  2001/04/04 13:30:08  matsfg
100  * Added bitset and bitclear for leds. Calls init_ioremap to set up memmapping
101  *
102  * Revision 1.6  2001/03/26 16:03:06  bjornw
103  * Needs linux/config.h
104  *
105  * Revision 1.5  2001/03/26 14:22:03  bjornw
106  * Namechange of some config options
107  *
108  * Revision 1.4  2001/02/27 13:52:48  bjornw
109  * malloc.h -> slab.h
110  *
111  * Revision 1.3  2001/01/24 15:06:48  bjornw
112  * gpio_wq correct type
113  *
114  * Revision 1.2  2001/01/18 16:07:30  bjornw
115  * 2.4 port
116  *
117  * Revision 1.1  2001/01/18 15:55:16  bjornw
118  * Verbatim copy of etraxgpio.c from elinux 2.0 added
119  *
120  *
121  */
122
123 #include <linux/config.h>
124
125 #include <linux/module.h>
126 #include <linux/sched.h>
127 #include <linux/slab.h>
128 #include <linux/ioport.h>
129 #include <linux/errno.h>
130 #include <linux/kernel.h>
131 #include <linux/fs.h>
132 #include <linux/string.h>
133 #include <linux/poll.h>
134 #include <linux/init.h>
135 #include <linux/interrupt.h>
136
137 #include <asm/etraxgpio.h>
138 #include <asm/arch/svinto.h>
139 #include <asm/io.h>
140 #include <asm/system.h>
141 #include <asm/irq.h>
142
143 #define GPIO_MAJOR 120  /* experimental MAJOR number */
144
145 #define D(x)
146
147 #if 0
148 static int dp_cnt;
149 #define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0)
150 #else
151 #define DP(x)
152 #endif
153         
154 static char gpio_name[] = "etrax gpio";
155
156 #if 0
157 static wait_queue_head_t *gpio_wq;
158 #endif
159
160 static int gpio_ioctl(struct inode *inode, struct file *file,
161                       unsigned int cmd, unsigned long arg);
162 static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
163                           loff_t *off);
164 static int gpio_open(struct inode *inode, struct file *filp);
165 static int gpio_release(struct inode *inode, struct file *filp);
166 static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
167
168 /* private data per open() of this driver */
169
170 struct gpio_private {
171         struct gpio_private *next;
172         /* These fields are for PA and PB only */
173         volatile unsigned char *port, *shadow;
174         volatile unsigned char *dir, *dir_shadow;
175         unsigned char changeable_dir;
176         unsigned char changeable_bits;
177         unsigned char clk_mask;
178         unsigned char data_mask;
179         unsigned char write_msb;
180         unsigned char pad1, pad2, pad3;
181         /* These fields are generic */
182         unsigned long highalarm, lowalarm;
183         wait_queue_head_t alarm_wq;
184         int minor;
185 };
186
187 /* linked list of alarms to check for */
188
189 static struct gpio_private *alarmlist = 0;
190
191 static int gpio_some_alarms = 0; /* Set if someone uses alarm */
192 static unsigned long gpio_pa_irq_enabled_mask = 0;
193
194 /* Port A and B use 8 bit access, but Port G is 32 bit */
195 #define NUM_PORTS (GPIO_MINOR_B+1)
196
197 static volatile unsigned char *ports[NUM_PORTS] = { 
198         R_PORT_PA_DATA, 
199         R_PORT_PB_DATA,
200 };
201 static volatile unsigned char *shads[NUM_PORTS] = {
202         &port_pa_data_shadow, 
203         &port_pb_data_shadow
204 };
205
206 /* What direction bits that are user changeable 1=changeable*/
207 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR
208 #define CONFIG_ETRAX_PA_CHANGEABLE_DIR 0x00
209 #endif
210 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_DIR
211 #define CONFIG_ETRAX_PB_CHANGEABLE_DIR 0x00
212 #endif
213
214 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_BITS
215 #define CONFIG_ETRAX_PA_CHANGEABLE_BITS 0xFF
216 #endif
217 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_BITS
218 #define CONFIG_ETRAX_PB_CHANGEABLE_BITS 0xFF
219 #endif
220
221
222 static unsigned char changeable_dir[NUM_PORTS] = { 
223         CONFIG_ETRAX_PA_CHANGEABLE_DIR,
224         CONFIG_ETRAX_PB_CHANGEABLE_DIR 
225 };
226 static unsigned char changeable_bits[NUM_PORTS] = { 
227         CONFIG_ETRAX_PA_CHANGEABLE_BITS,
228         CONFIG_ETRAX_PB_CHANGEABLE_BITS 
229 };
230
231 static volatile unsigned char *dir[NUM_PORTS] = { 
232         R_PORT_PA_DIR, 
233         R_PORT_PB_DIR 
234 };
235
236 static volatile unsigned char *dir_shadow[NUM_PORTS] = {
237         &port_pa_dir_shadow, 
238         &port_pb_dir_shadow 
239 };
240
241 /* Port G is 32 bit, handle it special, some bits are both inputs 
242    and outputs at the same time, only some of the bits can change direction
243    and some of them in groups of 8 bit. */
244 static unsigned long changeable_dir_g;
245 static unsigned long dir_g_in_bits;
246 static unsigned long dir_g_out_bits;
247 static unsigned long dir_g_shadow; /* 1=output */
248
249 #define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
250
251
252
253 static unsigned int 
254 gpio_poll(struct file *file,
255           poll_table *wait)
256 {
257         unsigned int mask = 0;
258         struct gpio_private *priv = (struct gpio_private *)file->private_data;
259         unsigned long data;
260         poll_wait(file, &priv->alarm_wq, wait);
261         if (priv->minor == GPIO_MINOR_A) {
262                 unsigned long flags;
263                 unsigned long tmp;
264                 data = *R_PORT_PA_DATA;
265                 /* PA has support for high level interrupt -
266                  * lets activate for those low and with highalarm set
267                  */
268                 tmp = ~data & priv->highalarm & 0xFF;
269                 tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
270                 save_flags(flags); cli();
271                 gpio_pa_irq_enabled_mask |= tmp;
272                 *R_IRQ_MASK1_SET = tmp;
273                 restore_flags(flags);
274
275         } else if (priv->minor == GPIO_MINOR_B)
276                 data = *R_PORT_PB_DATA;
277         else if (priv->minor == GPIO_MINOR_G)
278                 data = *R_PORT_G_DATA;
279         else
280                 return 0;
281         
282         if ((data & priv->highalarm) ||
283             (~data & priv->lowalarm)) {
284                 mask = POLLIN|POLLRDNORM;
285         }
286         
287         DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
288         return mask;
289 }
290
291 int etrax_gpio_wake_up_check(void)
292 {
293         struct gpio_private *priv = alarmlist;
294         unsigned long data = 0;
295         int ret = 0;
296         while (priv) {
297                 if (USE_PORTS(priv)) {
298                         data = *priv->port;
299                 } else if (priv->minor == GPIO_MINOR_G) {
300                         data = *R_PORT_G_DATA;
301                 }
302                 if ((data & priv->highalarm) ||
303                     (~data & priv->lowalarm)) {
304                         DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
305                         wake_up_interruptible(&priv->alarm_wq);
306                         ret = 1;
307                 }
308                 priv = priv->next;
309         }
310         return ret;
311 }
312
313 static irqreturn_t
314 gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
315 {
316         if (gpio_some_alarms) {
317                 etrax_gpio_wake_up_check();
318                 return IRQ_HANDLED;
319         }
320         return IRQ_NONE;
321 }
322
323 static irqreturn_t
324 gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
325 {
326         unsigned long tmp;
327         /* Find what PA interrupts are active */
328         tmp = (*R_IRQ_READ1);
329
330         /* Find those that we have enabled */
331         tmp &= gpio_pa_irq_enabled_mask;
332
333         /* Clear them.. */
334         *R_IRQ_MASK1_CLR = tmp;
335         gpio_pa_irq_enabled_mask &= ~tmp;
336
337         if (gpio_some_alarms) {
338                 return IRQ_RETVAL(etrax_gpio_wake_up_check());
339         }
340         return IRQ_NONE;
341 }
342
343
344 static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
345                           loff_t *off)
346 {
347         struct gpio_private *priv = (struct gpio_private *)file->private_data;
348         unsigned char data, clk_mask, data_mask, write_msb;
349         unsigned long flags;
350         ssize_t retval = count;
351         if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) {
352                 return -EFAULT;
353         }
354     
355         if (verify_area(VERIFY_READ, buf, count)) {
356                 return -EFAULT;
357         }
358         clk_mask = priv->clk_mask;
359         data_mask = priv->data_mask;
360         /* It must have been configured using the IO_CFG_WRITE_MODE */
361         /* Perhaps a better error code? */
362         if (clk_mask == 0 || data_mask == 0) {
363                 return -EPERM;
364         }
365         write_msb = priv->write_msb;
366         D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb));
367         while (count--) {
368                 int i;
369                 data = *buf++;
370                 if (priv->write_msb) {
371                         for (i = 7; i >= 0;i--) {
372                                 local_irq_save(flags); local_irq_disable();
373                                 *priv->port = *priv->shadow &= ~clk_mask;
374                                 if (data & 1<<i)
375                                         *priv->port = *priv->shadow |= data_mask;
376                                 else
377                                         *priv->port = *priv->shadow &= ~data_mask;
378                         /* For FPGA: min 5.0ns (DCC) before CCLK high */
379                                 *priv->port = *priv->shadow |= clk_mask;
380                                 local_irq_restore(flags);
381                         }
382                 } else {
383                         for (i = 0; i <= 7;i++) {
384                                 local_irq_save(flags); local_irq_disable();
385                                 *priv->port = *priv->shadow &= ~clk_mask;
386                                 if (data & 1<<i)
387                                         *priv->port = *priv->shadow |= data_mask;
388                                 else
389                                         *priv->port = *priv->shadow &= ~data_mask;
390                         /* For FPGA: min 5.0ns (DCC) before CCLK high */
391                                 *priv->port = *priv->shadow |= clk_mask;
392                                 local_irq_restore(flags);
393                         }
394                 }
395         }
396         return retval;
397 }
398
399
400
401 static int
402 gpio_open(struct inode *inode, struct file *filp)
403 {
404         struct gpio_private *priv;
405         int p = MINOR(inode->i_rdev);
406
407         if (p > GPIO_MINOR_LAST)
408                 return -EINVAL;
409
410         priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private), 
411                                               GFP_KERNEL);
412
413         if (!priv)
414                 return -ENOMEM;
415
416         priv->minor = p;
417
418         /* initialize the io/alarm struct and link it into our alarmlist */
419
420         priv->next = alarmlist;
421         alarmlist = priv;
422         if (USE_PORTS(priv)) { /* A and B */
423                 priv->port = ports[p];
424                 priv->shadow = shads[p];
425                 priv->dir = dir[p];
426                 priv->dir_shadow = dir_shadow[p];
427                 priv->changeable_dir = changeable_dir[p];
428                 priv->changeable_bits = changeable_bits[p];
429         } else {
430                 priv->port = NULL;
431                 priv->shadow = NULL;
432                 priv->dir = NULL;
433                 priv->dir_shadow = NULL;
434                 priv->changeable_dir = 0;
435                 priv->changeable_bits = 0;
436         }
437
438         priv->highalarm = 0;
439         priv->lowalarm = 0;
440         priv->clk_mask = 0;
441         priv->data_mask = 0;
442         init_waitqueue_head(&priv->alarm_wq);
443
444         filp->private_data = (void *)priv;
445
446         return 0;
447 }
448
449 static int
450 gpio_release(struct inode *inode, struct file *filp)
451 {
452         struct gpio_private *p = alarmlist;
453         struct gpio_private *todel = (struct gpio_private *)filp->private_data;
454         
455         /* unlink from alarmlist and free the private structure */
456
457         if (p == todel) {
458                 alarmlist = todel->next;
459         } else {
460                 while (p->next != todel)
461                         p = p->next;
462                 p->next = todel->next;
463         }
464
465         kfree(todel);
466         /* Check if there are still any alarms set */
467         p = alarmlist;
468         while (p) {
469                 if (p->highalarm | p->lowalarm) {
470                         gpio_some_alarms = 1;
471                         return 0;
472                 }
473                 p = p->next;
474         }
475         gpio_some_alarms = 0;
476                 
477         return 0;
478 }
479
480 /* Main device API. ioctl's to read/set/clear bits, as well as to 
481  * set alarms to wait for using a subsequent select().
482  */
483
484 unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
485 {
486         /* Set direction 0=unchanged 1=input, 
487          * return mask with 1=input 
488          */
489         unsigned long flags;
490         if (USE_PORTS(priv)) {
491                 local_irq_save(flags); local_irq_disable();
492                 *priv->dir = *priv->dir_shadow &= 
493                 ~((unsigned char)arg & priv->changeable_dir);
494                 local_irq_restore(flags);
495                 return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
496         } else if (priv->minor == GPIO_MINOR_G) {
497                 /* We must fiddle with R_GEN_CONFIG to change dir */
498                 save_flags(flags); cli();
499                 if (((arg & dir_g_in_bits) != arg) && 
500                     (arg & changeable_dir_g)) {
501                         arg &= changeable_dir_g;
502                         /* Clear bits in genconfig to set to input */
503                         if (arg & (1<<0)) {
504                                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
505                                 dir_g_in_bits |= (1<<0);
506                                 dir_g_out_bits &= ~(1<<0);
507                         }
508                         if ((arg & 0x0000FF00) == 0x0000FF00) {
509                                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
510                                 dir_g_in_bits |= 0x0000FF00;
511                                 dir_g_out_bits &= ~0x0000FF00;
512                         }
513                         if ((arg & 0x00FF0000) == 0x00FF0000) {
514                                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
515                                 dir_g_in_bits |= 0x00FF0000;
516                                 dir_g_out_bits &= ~0x00FF0000;
517                         }
518                         if (arg & (1<<24)) {
519                                 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
520                                 dir_g_in_bits |= (1<<24);
521                                 dir_g_out_bits &= ~(1<<24);
522                         }
523                         D(printk(KERN_INFO "gpio: SETINPUT on port G set "
524                                  "genconfig to 0x%08lX "
525                                  "in_bits: 0x%08lX "
526                                  "out_bits: 0x%08lX\n",
527                                  (unsigned long)genconfig_shadow,
528                                  dir_g_in_bits, dir_g_out_bits));
529                         *R_GEN_CONFIG = genconfig_shadow;
530                         /* Must be a >120 ns delay before writing this again */
531                                 
532                 }
533                 restore_flags(flags);
534                 return dir_g_in_bits;
535         }
536         return 0;
537 } /* setget_input */
538
539 unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
540 {
541         unsigned long flags;
542         if (USE_PORTS(priv)) {
543                 local_irq_save(flags); local_irq_disable();
544                 *priv->dir = *priv->dir_shadow |= 
545                   ((unsigned char)arg & priv->changeable_dir);
546                 local_irq_restore(flags);
547                 return *priv->dir_shadow;
548         } else if (priv->minor == GPIO_MINOR_G) {
549                 /* We must fiddle with R_GEN_CONFIG to change dir */                    
550                 save_flags(flags); cli();
551                 if (((arg & dir_g_out_bits) != arg) &&
552                     (arg & changeable_dir_g)) {
553                         /* Set bits in genconfig to set to output */
554                         if (arg & (1<<0)) {
555                                 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
556                                 dir_g_out_bits |= (1<<0);
557                                 dir_g_in_bits &= ~(1<<0);
558                         }
559                         if ((arg & 0x0000FF00) == 0x0000FF00) {
560                                 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
561                                 dir_g_out_bits |= 0x0000FF00;
562                                 dir_g_in_bits &= ~0x0000FF00;
563                         }
564                         if ((arg & 0x00FF0000) == 0x00FF0000) {
565                                 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
566                                 dir_g_out_bits |= 0x00FF0000;
567                                 dir_g_in_bits &= ~0x00FF0000;
568                         }
569                         if (arg & (1<<24)) {
570                                 genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
571                                 dir_g_out_bits |= (1<<24);
572                                 dir_g_in_bits &= ~(1<<24);
573                         }
574                         D(printk(KERN_INFO "gpio: SETOUTPUT on port G set "
575                                  "genconfig to 0x%08lX "
576                                  "in_bits: 0x%08lX "
577                                  "out_bits: 0x%08lX\n",
578                                  (unsigned long)genconfig_shadow,
579                                  dir_g_in_bits, dir_g_out_bits));
580                         *R_GEN_CONFIG = genconfig_shadow;
581                         /* Must be a >120 ns delay before writing this again */
582                 }
583                 restore_flags(flags);
584                 return dir_g_out_bits & 0x7FFFFFFF;
585         }
586         return 0;
587 } /* setget_output */
588
589 static int
590 gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
591
592 static int
593 gpio_ioctl(struct inode *inode, struct file *file,
594            unsigned int cmd, unsigned long arg)
595 {
596         unsigned long flags;
597         unsigned long val;
598         struct gpio_private *priv = (struct gpio_private *)file->private_data;
599         if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
600                 return -EINVAL;
601         }
602
603         switch (_IOC_NR(cmd)) {
604         case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
605                 // read the port
606                 if (USE_PORTS(priv)) {
607                         return *priv->port;
608                 } else if (priv->minor == GPIO_MINOR_G) {
609                         return (*R_PORT_G_DATA) & 0x7FFFFFFF;
610                 }
611                 break;
612         case IO_SETBITS:
613                 local_irq_save(flags); local_irq_disable();
614                 // set changeable bits with a 1 in arg
615                 if (USE_PORTS(priv)) {
616                         *priv->port = *priv->shadow |= 
617                           ((unsigned char)arg & priv->changeable_bits);
618                 } else if (priv->minor == GPIO_MINOR_G) {
619                         *R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
620                 }
621                 local_irq_restore(flags);
622                 break;
623         case IO_CLRBITS:
624                 local_irq_save(flags); local_irq_disable();
625                 // clear changeable bits with a 1 in arg
626                 if (USE_PORTS(priv)) {
627                         *priv->port = *priv->shadow &= 
628                          ~((unsigned char)arg & priv->changeable_bits);
629                 } else if (priv->minor == GPIO_MINOR_G) {
630                         *R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits);
631                 }
632                 local_irq_restore(flags);
633                 break;
634         case IO_HIGHALARM:
635                 // set alarm when bits with 1 in arg go high
636                 priv->highalarm |= arg;
637                 gpio_some_alarms = 1;
638                 break;
639         case IO_LOWALARM:
640                 // set alarm when bits with 1 in arg go low
641                 priv->lowalarm |= arg;
642                 gpio_some_alarms = 1;
643                 break;
644         case IO_CLRALARM:
645                 // clear alarm for bits with 1 in arg
646                 priv->highalarm &= ~arg;
647                 priv->lowalarm  &= ~arg;
648                 {
649                         /* Must update gpio_some_alarms */
650                         struct gpio_private *p = alarmlist;
651                         int some_alarms;
652                         some_alarms = 0;
653                         while (p) {
654                                 if (p->highalarm | p->lowalarm) {
655                                         some_alarms = 1;
656                                         break;
657                                 }
658                                 p = p->next;
659                         }
660                         gpio_some_alarms = some_alarms;
661                 }
662                 break;
663         case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
664                 /* Read direction 0=input 1=output */
665                 if (USE_PORTS(priv)) {
666                         return *priv->dir_shadow;
667                 } else if (priv->minor == GPIO_MINOR_G) {
668                         /* Note: Some bits are both in and out,
669                          * Those that are dual is set here as well.
670                          */
671                         return (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
672                 }
673         case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
674                 /* Set direction 0=unchanged 1=input, 
675                  * return mask with 1=input 
676                  */
677                 return setget_input(priv, arg) & 0x7FFFFFFF;
678                 break;
679         case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
680                 /* Set direction 0=unchanged 1=output, 
681                  * return mask with 1=output 
682                  */
683                 return setget_output(priv, arg) & 0x7FFFFFFF;
684
685         case IO_SHUTDOWN:
686                 SOFT_SHUTDOWN();
687                 break;
688         case IO_GET_PWR_BT:
689 #if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
690                 return (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
691 #else
692                 return 0;
693 #endif
694                 break;
695         case IO_CFG_WRITE_MODE:
696                 priv->clk_mask = arg & 0xFF;
697                 priv->data_mask = (arg >> 8) & 0xFF;
698                 priv->write_msb = (arg >> 16) & 0x01;
699                 /* Check if we're allowed to change the bits and
700                  * the direction is correct
701                  */
702                 if (!((priv->clk_mask & priv->changeable_bits) &&
703                       (priv->data_mask & priv->changeable_bits) &&
704                       (priv->clk_mask & *priv->dir_shadow) &&
705                       (priv->data_mask & *priv->dir_shadow)))
706                 {
707                         priv->clk_mask = 0;
708                         priv->data_mask = 0;
709                         return -EPERM;
710                 }
711                 break;
712         case IO_READ_INBITS: 
713                 /* *arg is result of reading the input pins */
714                 if (USE_PORTS(priv)) {
715                         val = *priv->port;
716                 } else if (priv->minor == GPIO_MINOR_G) {
717                         val = *R_PORT_G_DATA;
718                 }
719                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
720                         return -EFAULT;
721                 return 0;
722                 break;
723         case IO_READ_OUTBITS:
724                  /* *arg is result of reading the output shadow */
725                 if (USE_PORTS(priv)) {
726                         val = *priv->shadow;
727                 } else if (priv->minor == GPIO_MINOR_G) {
728                         val = port_g_data_shadow;
729                 }
730                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
731                         return -EFAULT;
732                 break;
733         case IO_SETGET_INPUT: 
734                 /* bits set in *arg is set to input,
735                  * *arg updated with current input pins.
736                  */
737                 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
738                         return -EFAULT;
739                 val = setget_input(priv, val);
740                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
741                         return -EFAULT;
742                 break;
743         case IO_SETGET_OUTPUT:
744                 /* bits set in *arg is set to output,
745                  * *arg updated with current output pins.
746                  */
747                 if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
748                         return -EFAULT;
749                 val = setget_output(priv, val);
750                 if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
751                         return -EFAULT;
752                 break;
753         default:
754                 if (priv->minor == GPIO_MINOR_LEDS)
755                         return gpio_leds_ioctl(cmd, arg);
756                 else
757                         return -EINVAL;
758         } /* switch */
759         
760         return 0;
761 }
762
763 static int
764 gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
765 {
766         unsigned char green;
767         unsigned char red;
768
769         switch (_IOC_NR(cmd)) {
770         case IO_LEDACTIVE_SET:
771                 green = ((unsigned char) arg) & 1;
772                 red   = (((unsigned char) arg) >> 1) & 1;
773                 LED_ACTIVE_SET_G(green);
774                 LED_ACTIVE_SET_R(red);
775                 break;
776
777         case IO_LED_SETBIT:
778                 LED_BIT_SET(arg);
779                 break;
780
781         case IO_LED_CLRBIT:
782                 LED_BIT_CLR(arg);
783                 break;
784
785         default:
786                 return -EINVAL;
787         } /* switch */
788
789         return 0;
790 }
791
792 struct file_operations gpio_fops = {
793         .owner       = THIS_MODULE,
794         .poll        = gpio_poll,
795         .ioctl       = gpio_ioctl,
796         .write       = gpio_write,
797         .open        = gpio_open,
798         .release     = gpio_release,
799 };
800
801
802 static void __init gpio_init_port_g(void)
803 {
804 #define GROUPA (0x0000FF3F)
805 #define GROUPB (1<<6 | 1<<7)
806 #define GROUPC (1<<30 | 1<<31)
807 #define GROUPD (0x3FFF0000)
808 #define GROUPD_LOW (0x00FF0000)
809         unsigned long used_in_bits = 0;
810         unsigned long used_out_bits = 0;
811         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0, select)){
812                 used_in_bits  |= GROUPA | GROUPB | 0 | 0;
813                 used_out_bits |= GROUPA | GROUPB | 0 | 0;
814         }
815         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ata, select)) {
816                 used_in_bits  |= GROUPA | GROUPB | GROUPC | (GROUPD & ~(1<<25|1<<26));
817                 used_out_bits |= GROUPA | GROUPB | GROUPC | GROUPD;
818         }
819
820         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par0, select)) {
821                 used_in_bits  |= (GROUPA & ~(1<<0)) | 0 | 0 | 0;
822                 used_out_bits |= (GROUPA & ~(1<<0)) | 0 | 0 | 0;
823         }
824         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser2, select)) {
825                 used_in_bits  |= 0 | GROUPB | 0 | 0;
826                 used_out_bits |= 0 | GROUPB | 0 | 0;
827         }
828         /* mio same as shared RAM ? */
829         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio, select)) {
830                 used_in_bits  |= (GROUPA & ~(1<<0)) | 0 |0 |GROUPD_LOW;
831                 used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 |0 |GROUPD_LOW;
832         }
833         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi1, select)) {
834                 used_in_bits  |= 0 | 0 | GROUPC | GROUPD;
835                 used_out_bits |= 0 | 0 | GROUPC | GROUPD;
836         }
837         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0w, select)) {
838                 used_in_bits  |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24);
839                 used_out_bits |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24 | 1<<25|1<<26);
840         }
841
842         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par1, select)) {
843                 used_in_bits  |= 0 | 0 | 0 | (GROUPD & ~(1<<24));
844                 used_out_bits |= 0 | 0 | 0 | (GROUPD & ~(1<<24));
845         }
846         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser3, select)) {
847                 used_in_bits  |= 0 | 0 | GROUPC | 0;
848                 used_out_bits |= 0 | 0 | GROUPC | 0;
849         }
850         /* mio same as shared RAM-W? */
851         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio_w, select)) {
852                 used_in_bits  |= (GROUPA & ~(1<<0)) | 0 | 0 |GROUPD_LOW;
853                 used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 | 0 |GROUPD_LOW;
854         }
855         /* TODO: USB p2, parw, sync ser3? */
856
857         /* Initialise the dir_g_shadow etc. depending on genconfig */
858         /* 0=input 1=output */
859         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out)) 
860                 dir_g_shadow |= (1 << 0);
861         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out))
862                 dir_g_shadow |= 0x0000FF00;
863         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g16_23dir, out))
864                 dir_g_shadow |= 0x00FF0000;
865         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out))
866                 dir_g_shadow |= (1 << 24);
867
868         dir_g_in_bits = ~used_in_bits;
869         dir_g_out_bits = ~used_out_bits;
870
871         changeable_dir_g = 0x01FFFF01; /* all that can change dir */
872         changeable_dir_g &= dir_g_out_bits;
873         changeable_dir_g &= dir_g_in_bits;
874         /* Correct the bits that can change direction */ 
875         dir_g_out_bits &= ~changeable_dir_g;
876         dir_g_out_bits |= dir_g_shadow;
877         dir_g_in_bits &= ~changeable_dir_g;
878         dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
879
880
881         printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n",
882                dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
883         printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n",
884                dir_g_shadow, changeable_dir_g);
885 }
886
887 /* main driver initialization routine, called from mem.c */
888
889 static __init int
890 gpio_init(void)
891 {
892         int res;
893 #if defined (CONFIG_ETRAX_CSP0_LEDS)
894         int i;
895 #endif
896
897         /* do the formalities */
898
899         res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
900         if (res < 0) {
901                 printk(KERN_ERR "gpio: couldn't get a major number.\n");
902                 return res;
903         }
904
905         /* Clear all leds */
906 #if defined (CONFIG_ETRAX_CSP0_LEDS) ||  defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS)
907         LED_NETWORK_SET(0);
908         LED_ACTIVE_SET(0);
909         LED_DISK_READ(0);
910         LED_DISK_WRITE(0);
911
912 #if defined (CONFIG_ETRAX_CSP0_LEDS)
913         for (i = 0; i < 32; i++) {
914                 LED_BIT_SET(i);
915         }
916 #endif
917
918 #endif
919         gpio_init_port_g();
920         printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n");
921         /* We call etrax_gpio_wake_up_check() from timer interrupt and
922          * from cpu_idle() in kernel/process.c
923          * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
924          * in some tests.
925          */  
926         if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
927                         SA_SHIRQ | SA_INTERRUPT,"gpio poll", NULL)) {
928                 printk(KERN_CRIT "err: timer0 irq for gpio\n");
929         }
930         if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt,
931                         SA_SHIRQ | SA_INTERRUPT,"gpio PA", NULL)) {
932                 printk(KERN_CRIT "err: PA irq for gpio\n");
933         }
934         
935
936         return res;
937 }
938
939 /* this makes sure that gpio_init is called during kernel boot */
940
941 module_init(gpio_init);