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