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