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)
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>
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>
28 #include <asm/system.h>
30 #include <arch/io_interface_mux.h>
32 #define GPIO_MAJOR 120 /* experimental MAJOR number */
38 #define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0)
43 static char gpio_name
[] = "etrax gpio";
46 static wait_queue_head_t
*gpio_wq
;
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 */
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
;
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
] = {
92 static volatile unsigned char *shads
[NUM_PORTS
] = {
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
101 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_DIR
102 #define CONFIG_ETRAX_PB_CHANGEABLE_DIR 0x00
105 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_BITS
106 #define CONFIG_ETRAX_PA_CHANGEABLE_BITS 0xFF
108 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_BITS
109 #define CONFIG_ETRAX_PB_CHANGEABLE_BITS 0xFF
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
] = {
127 static volatile unsigned char *dir_shadow
[NUM_PORTS
] = {
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
;
153 spin_lock_irqsave(&gpio_lock
, flags
);
155 poll_wait(file
, &priv
->alarm_wq
, wait
);
156 if (priv
->minor
== GPIO_MINOR_A
) {
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
;
176 if ((data
& priv
->highalarm
) ||
177 (~data
& priv
->lowalarm
)) {
178 mask
= POLLIN
|POLLRDNORM
;
182 spin_unlock_irqrestore(&gpio_lock
, flags
);
183 DP(printk("gpio_poll ready: mask 0x%08X\n", mask
));
188 int etrax_gpio_wake_up_check(void)
190 struct gpio_private
*priv
;
191 unsigned long data
= 0;
195 spin_lock_irqsave(&gpio_lock
, flags
);
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
);
211 spin_unlock_irqrestore(&gpio_lock
, flags
);
216 gpio_poll_timer_interrupt(int irq
, void *dev_id
)
218 if (gpio_some_alarms
) {
219 etrax_gpio_wake_up_check();
226 gpio_interrupt(int irq
, void *dev_id
)
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
;
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());
251 static void gpio_write_bit(struct gpio_private
*priv
,
252 unsigned char data
, int bit
)
254 *priv
->port
= *priv
->shadow
&= ~(priv
->clk_mask
);
256 *priv
->port
= *priv
->shadow
|= priv
->data_mask
;
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
)
269 for (i
= 7; i
>= 0; i
--)
270 gpio_write_bit(priv
, data
, i
);
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
;
281 ssize_t retval
= count
;
283 if (priv
->minor
!= GPIO_MINOR_A
&& priv
->minor
!= GPIO_MINOR_B
)
286 if (!access_ok(VERIFY_READ
, buf
, count
))
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) {
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
));
303 gpio_write_byte(priv
, *buf
++);
306 spin_unlock_irqrestore(&gpio_lock
, flags
);
313 gpio_open(struct inode
*inode
, struct file
*filp
)
315 struct gpio_private
*priv
;
316 int p
= iminor(inode
);
319 if (p
> GPIO_MINOR_LAST
)
322 priv
= kzalloc(sizeof(struct gpio_private
), GFP_KERNEL
);
330 /* initialize the io/alarm struct */
332 if (USE_PORTS(priv
)) { /* A and B */
333 priv
->port
= ports
[p
];
334 priv
->shadow
= shads
[p
];
336 priv
->dir_shadow
= dir_shadow
[p
];
337 priv
->changeable_dir
= changeable_dir
[p
];
338 priv
->changeable_bits
= changeable_bits
[p
];
343 priv
->dir_shadow
= NULL
;
344 priv
->changeable_dir
= 0;
345 priv
->changeable_bits
= 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
;
360 spin_unlock_irqrestore(&gpio_lock
, flags
);
367 gpio_release(struct inode
*inode
, struct file
*filp
)
369 struct gpio_private
*p
;
370 struct gpio_private
*todel
;
373 spin_lock_irqsave(&gpio_lock
, flags
);
376 todel
= filp
->private_data
;
378 /* unlink from alarmlist and free the private structure */
381 alarmlist
= todel
->next
;
383 while (p
->next
!= todel
)
385 p
->next
= todel
->next
;
389 /* Check if there are still any alarms set */
392 if (p
->highalarm
| p
->lowalarm
) {
393 gpio_some_alarms
= 1;
398 gpio_some_alarms
= 0;
400 spin_unlock_irqrestore(&gpio_lock
, flags
);
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
)
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 */
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;
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 "
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
;
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
)
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 */
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;
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 "
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 */
505 gpio_leds_ioctl(unsigned int cmd
, unsigned long arg
);
508 gpio_ioctl(struct inode
*inode
, struct file
*file
,
509 unsigned int cmd
, unsigned long arg
)
515 struct gpio_private
*priv
= file
->private_data
;
516 if (_IOC_TYPE(cmd
) != ETRAXGPIO_IOCTYPE
)
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 */
524 if (USE_PORTS(priv
)) {
526 } else if (priv
->minor
== GPIO_MINOR_G
) {
527 ret
= (*R_PORT_G_DATA
) & 0x7FFFFFFF;
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
);
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
);
549 // set alarm when bits with 1 in arg go high
550 priv
->highalarm
|= arg
;
551 gpio_some_alarms
= 1;
554 // set alarm when bits with 1 in arg go low
555 priv
->lowalarm
|= arg
;
556 gpio_some_alarms
= 1;
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
;
566 spin_lock_irq(&gpio_lock
);
570 if (p
->highalarm
| p
->lowalarm
) {
576 gpio_some_alarms
= some_alarms
;
577 spin_unlock_irq(&gpio_lock
);
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;
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;
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;
607 #if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
608 ret
= (*R_PORT_G_DATA
& ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT
));
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
)))
631 /* *arg is result of reading the input pins */
632 if (USE_PORTS(priv
)) {
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
)))
640 case IO_READ_OUTBITS
:
641 /* *arg is result of reading the output shadow */
642 if (USE_PORTS(priv
)) {
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
)))
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
)))
659 val
= setget_input(priv
, val
);
660 if (copy_to_user((void __user
*)arg
, &val
, sizeof(val
)))
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
))) {
671 val
= setget_output(priv
, val
);
672 if (copy_to_user((void __user
*)arg
, &val
, sizeof(val
)))
676 if (priv
->minor
== GPIO_MINOR_LEDS
)
677 ret
= gpio_leds_ioctl(cmd
, arg
);
682 spin_unlock_irqrestore(&gpio_lock
, flags
);
687 gpio_leds_ioctl(unsigned int cmd
, unsigned long arg
)
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
);
701 CRIS_LED_BIT_SET(arg
);
705 CRIS_LED_BIT_CLR(arg
);
715 static const struct file_operations gpio_fops
= {
716 .owner
= THIS_MODULE
,
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 "
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)
777 #if defined (CONFIG_ETRAX_CSP0_LEDS)
781 res
= register_chrdev(GPIO_MAJOR
, gpio_name
, &gpio_fops
);
783 printk(KERN_ERR
"gpio: couldn't get a major number.\n");
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
++)
800 /* The I/O interface allocation watcher will be called when
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
814 res
= request_irq(TIMER0_IRQ_NBR
, gpio_poll_timer_interrupt
,
815 IRQF_SHARED
| IRQF_DISABLED
, "gpio poll", gpio_name
);
817 printk(KERN_CRIT
"err: timer0 irq for gpio\n");
820 res
= request_irq(PA_IRQ_NBR
, gpio_interrupt
,
821 IRQF_SHARED
| IRQF_DISABLED
, "gpio PA", gpio_name
);
823 printk(KERN_CRIT
"err: PA irq for gpio\n");
828 /* this makes sure that gpio_init is called during kernel boot */
829 module_init(gpio_init
);