1
2
3
4
5
6
7
8
9
10
11
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>
24
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>
31
32#define GPIO_MAJOR 120
33
34#define D(x)
35
36#if 0
37static 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
42
43static char gpio_name[] = "etrax gpio";
44
45#if 0
46static wait_queue_head_t *gpio_wq;
47#endif
48
49static int gpio_ioctl(struct inode *inode, struct file *file,
50 unsigned int cmd, unsigned long arg);
51static ssize_t gpio_write(struct file *file, const char __user *buf,
52 size_t count, loff_t *off);
53static int gpio_open(struct inode *inode, struct file *filp);
54static int gpio_release(struct inode *inode, struct file *filp);
55static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
56
57
58
59struct gpio_private {
60 struct gpio_private *next;
61
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
71 unsigned long highalarm, lowalarm;
72 wait_queue_head_t alarm_wq;
73 int minor;
74};
75
76
77
78static struct gpio_private *alarmlist;
79
80static int gpio_some_alarms;
81static unsigned long gpio_pa_irq_enabled_mask;
82
83static DEFINE_SPINLOCK(gpio_lock);
84
85
86#define NUM_PORTS (GPIO_MINOR_B+1)
87
88static volatile unsigned char *ports[NUM_PORTS] = {
89 R_PORT_PA_DATA,
90 R_PORT_PB_DATA,
91};
92static volatile unsigned char *shads[NUM_PORTS] = {
93 &port_pa_data_shadow,
94 &port_pb_data_shadow
95};
96
97
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
104
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
111
112
113static unsigned char changeable_dir[NUM_PORTS] = {
114 CONFIG_ETRAX_PA_CHANGEABLE_DIR,
115 CONFIG_ETRAX_PB_CHANGEABLE_DIR
116};
117static unsigned char changeable_bits[NUM_PORTS] = {
118 CONFIG_ETRAX_PA_CHANGEABLE_BITS,
119 CONFIG_ETRAX_PB_CHANGEABLE_BITS
120};
121
122static volatile unsigned char *dir[NUM_PORTS] = {
123 R_PORT_PA_DIR,
124 R_PORT_PB_DIR
125};
126
127static volatile unsigned char *dir_shadow[NUM_PORTS] = {
128 &port_pa_dir_shadow,
129 &port_pb_dir_shadow
130};
131
132
133static const unsigned long int changeable_dir_g_mask = 0x01FFFF01;
134
135
136
137
138static unsigned long changeable_dir_g;
139static unsigned long dir_g_in_bits;
140static unsigned long dir_g_out_bits;
141static unsigned long dir_g_shadow;
142
143#define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
144
145
146static unsigned int gpio_poll(struct file *file, poll_table *wait)
147{
148 unsigned int mask = 0;
149 struct gpio_private *priv = file->private_data;
150 unsigned long data;
151 unsigned long flags;
152
153 spin_lock_irqsave(&gpio_lock, flags);
154
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
160
161
162 tmp = ~data & priv->highalarm & 0xFF;
163 tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
164
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;
174 }
175
176 if ((data & priv->highalarm) ||
177 (~data & priv->lowalarm)) {
178 mask = POLLIN|POLLRDNORM;
179 }
180
181out:
182 spin_unlock_irqrestore(&gpio_lock, flags);
183 DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
184
185 return mask;
186}
187
188int etrax_gpio_wake_up_check(void)
189{
190 struct gpio_private *priv;
191 unsigned long data = 0;
192 int ret = 0;
193 unsigned long flags;
194
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;
202
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;
208 }
209 priv = priv->next;
210 }
211 spin_unlock_irqrestore(&gpio_lock, flags);
212 return ret;
213}
214
215static irqreturn_t
216gpio_poll_timer_interrupt(int irq, void *dev_id)
217{
218 if (gpio_some_alarms) {
219 etrax_gpio_wake_up_check();
220 return IRQ_HANDLED;
221 }
222 return IRQ_NONE;
223}
224
225static irqreturn_t
226gpio_interrupt(int irq, void *dev_id)
227{
228 unsigned long tmp;
229 unsigned long flags;
230
231 spin_lock_irqsave(&gpio_lock, flags);
232
233
234 tmp = (*R_IRQ_READ1);
235
236
237 tmp &= gpio_pa_irq_enabled_mask;
238
239
240 *R_IRQ_MASK1_CLR = tmp;
241 gpio_pa_irq_enabled_mask &= ~tmp;
242
243 spin_unlock_irqrestore(&gpio_lock, flags);
244
245 if (gpio_some_alarms)
246 return IRQ_RETVAL(etrax_gpio_wake_up_check());
247
248 return IRQ_NONE;
249}
250
251static void gpio_write_bit(struct gpio_private *priv,
252 unsigned char data, int bit)
253{
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);
259
260
261 *priv->port = *priv->shadow |= priv->clk_mask;
262}
263
264static void gpio_write_byte(struct gpio_private *priv, unsigned char data)
265{
266 int i;
267
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);
274}
275
276static ssize_t gpio_write(struct file *file, const char __user *buf,
277 size_t count, loff_t *off)
278{
279 struct gpio_private *priv = file->private_data;
280 unsigned long flags;
281 ssize_t retval = count;
282
283 if (priv->minor != GPIO_MINOR_A && priv->minor != GPIO_MINOR_B)
284 return -EFAULT;
285
286 if (!access_ok(VERIFY_READ, buf, count))
287 return -EFAULT;
288
289 spin_lock_irqsave(&gpio_lock, flags);
290
291
292
293 if (priv->clk_mask == 0 || priv->data_mask == 0) {
294 retval = -EPERM;
295 goto out;
296 }
297
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));
301
302 while (count--)
303 gpio_write_byte(priv, *buf++);
304
305out:
306 spin_unlock_irqrestore(&gpio_lock, flags);
307 return retval;
308}
309
310
311
312static int
313gpio_open(struct inode *inode, struct file *filp)
314{
315 struct gpio_private *priv;
316 int p = iminor(inode);
317 unsigned long flags;
318
319 if (p > GPIO_MINOR_LAST)
320 return -EINVAL;
321
322 priv = kzalloc(sizeof(struct gpio_private), GFP_KERNEL);
323
324 if (!priv)
325 return -ENOMEM;
326
327 lock_kernel();
328 priv->minor = p;
329
330
331
332 if (USE_PORTS(priv)) {
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;
346 }
347
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);
353
354 filp->private_data = priv;
355
356
357 spin_lock_irqsave(&gpio_lock, flags);
358 priv->next = alarmlist;
359 alarmlist = priv;
360 spin_unlock_irqrestore(&gpio_lock, flags);
361
362 unlock_kernel();
363 return 0;
364}
365
366static int
367gpio_release(struct inode *inode, struct file *filp)
368{
369 struct gpio_private *p;
370 struct gpio_private *todel;
371 unsigned long flags;
372
373 spin_lock_irqsave(&gpio_lock, flags);
374
375 p = alarmlist;
376 todel = filp->private_data;
377
378
379
380 if (p == todel) {
381 alarmlist = todel->next;
382 } else {
383 while (p->next != todel)
384 p = p->next;
385 p->next = todel->next;
386 }
387
388 kfree(todel);
389
390 p = alarmlist;
391 while (p) {
392 if (p->highalarm | p->lowalarm) {
393 gpio_some_alarms = 1;
394 goto out;
395 }
396 p = p->next;
397 }
398 gpio_some_alarms = 0;
399out:
400 spin_unlock_irqrestore(&gpio_lock, flags);
401 return 0;
402}
403
404
405
406
407unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
408{
409
410
411 if (USE_PORTS(priv)) {
412 *priv->dir = *priv->dir_shadow &=
413 ~((unsigned char)arg & priv->changeable_dir);
414 return ~(*priv->dir_shadow) & 0xFF;
415 }
416
417 if (priv->minor != GPIO_MINOR_G)
418 return 0;
419
420
421 if (((arg & dir_g_in_bits) != arg) &&
422 (arg & changeable_dir_g)) {
423 arg &= changeable_dir_g;
424
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);
429 }
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;
434 }
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;
439 }
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);
444 }
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
453
454 }
455 return dir_g_in_bits;
456}
457
458unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
459{
460 if (USE_PORTS(priv)) {
461 *priv->dir = *priv->dir_shadow |=
462 ((unsigned char)arg & priv->changeable_dir);
463 return *priv->dir_shadow;
464 }
465 if (priv->minor != GPIO_MINOR_G)
466 return 0;
467
468
469 if (((arg & dir_g_out_bits) != arg) &&
470 (arg & changeable_dir_g)) {
471
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);
476 }
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;
481 }
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;
486 }
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);
491 }
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
500 }
501 return dir_g_out_bits & 0x7FFFFFFF;
502}
503
504static int
505gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
506
507static int
508gpio_ioctl(struct inode *inode, struct file *file,
509 unsigned int cmd, unsigned long arg)
510{
511 unsigned long flags;
512 unsigned long val;
513 int ret = 0;
514
515 struct gpio_private *priv = file->private_data;
516 if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
517 return -EINVAL;
518
519 spin_lock_irqsave(&gpio_lock, flags);
520
521 switch (_IOC_NR(cmd)) {
522 case IO_READBITS:
523
524 if (USE_PORTS(priv)) {
525 ret = *priv->port;
526 } else if (priv->minor == GPIO_MINOR_G) {
527 ret = (*R_PORT_G_DATA) & 0x7FFFFFFF;
528 }
529 break;
530 case IO_SETBITS:
531
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);
537 }
538 break;
539 case IO_CLRBITS:
540
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);
546 }
547 break;
548 case IO_HIGHALARM:
549
550 priv->highalarm |= arg;
551 gpio_some_alarms = 1;
552 break;
553 case IO_LOWALARM:
554
555 priv->lowalarm |= arg;
556 gpio_some_alarms = 1;
557 break;
558 case IO_CLRALARM:
559
560 priv->highalarm &= ~arg;
561 priv->lowalarm &= ~arg;
562 {
563
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;
573 }
574 p = p->next;
575 }
576 gpio_some_alarms = some_alarms;
577 spin_unlock_irq(&gpio_lock);
578 }
579 break;
580 case IO_READDIR:
581
582 if (USE_PORTS(priv)) {
583 ret = *priv->dir_shadow;
584 } else if (priv->minor == GPIO_MINOR_G) {
585
586
587
588 ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
589 }
590 break;
591 case IO_SETINPUT:
592
593
594
595 ret = setget_input(priv, arg) & 0x7FFFFFFF;
596 break;
597 case IO_SETOUTPUT:
598
599
600
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
618
619
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)))
624 {
625 priv->clk_mask = 0;
626 priv->data_mask = 0;
627 ret = -EPERM;
628 }
629 break;
630 case IO_READ_INBITS:
631
632 if (USE_PORTS(priv)) {
633 val = *priv->port;
634 } else if (priv->minor == GPIO_MINOR_G) {
635 val = *R_PORT_G_DATA;
636 }
637 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
638 ret = -EFAULT;
639 break;
640 case IO_READ_OUTBITS:
641
642 if (USE_PORTS(priv)) {
643 val = *priv->shadow;
644 } else if (priv->minor == GPIO_MINOR_G) {
645 val = port_g_data_shadow;
646 }
647 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
648 ret = -EFAULT;
649 break;
650 case IO_SETGET_INPUT:
651
652
653
654 if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
655 {
656 ret = -EFAULT;
657 break;
658 }
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
665
666
667 if (copy_from_user(&val, (void __user *)arg, sizeof(val))) {
668 ret = -EFAULT;
669 break;
670 }
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 }
681
682 spin_unlock_irqrestore(&gpio_lock, flags);
683 return ret;
684}
685
686static int
687gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
688{
689 unsigned char green;
690 unsigned char red;
691
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;
699
700 case IO_LED_SETBIT:
701 CRIS_LED_BIT_SET(arg);
702 break;
703
704 case IO_LED_CLRBIT:
705 CRIS_LED_BIT_CLR(arg);
706 break;
707
708 default:
709 return -EINVAL;
710 }
711
712 return 0;
713}
714
715static 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,
722};
723
724static 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)
728{
729 unsigned long int flags;
730
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));
736
737 spin_lock_irqsave(&gpio_lock, flags);
738
739 dir_g_in_bits = gpio_in_available;
740 dir_g_out_bits = gpio_out_available;
741
742
743
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);
752
753 changeable_dir_g = changeable_dir_g_mask;
754 changeable_dir_g &= dir_g_out_bits;
755 changeable_dir_g &= dir_g_in_bits;
756
757
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);
762
763 spin_unlock_irqrestore(&gpio_lock, flags);
764
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);
770}
771
772
773
774static int __init gpio_init(void)
775{
776 int res;
777#if defined (CONFIG_ETRAX_CSP0_LEDS)
778 int i;
779#endif
780
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;
785 }
786
787
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);
793
794#if defined (CONFIG_ETRAX_CSP0_LEDS)
795 for (i = 0; i < 32; i++)
796 CRIS_LED_BIT_SET(i);
797#endif
798
799#endif
800
801
802 if (cris_io_interface_register_watcher(ioif_watcher)){
803 printk(KERN_WARNING "gpio_init: Failed to install IO "
804 "if allocator watcher\n");
805 }
806
807 printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001-2008 "
808 "Axis Communications AB\n");
809
810
811
812
813
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;
819 }
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");
824
825 return res;
826}
827
828
829module_init(gpio_init);
830
831