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/string.h>
20#include <linux/poll.h>
21#include <linux/init.h>
22#include <linux/interrupt.h>
23
24#include <asm/etraxgpio.h>
25#include <arch/svinto.h>
26#include <asm/io.h>
27#include <asm/system.h>
28#include <asm/irq.h>
29#include <arch/io_interface_mux.h>
30
31#define GPIO_MAJOR 120
32
33#define D(x)
34
35#if 0
36static int dp_cnt;
37#define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0)
38#else
39#define DP(x)
40#endif
41
42static char gpio_name[] = "etrax gpio";
43
44#if 0
45static wait_queue_head_t *gpio_wq;
46#endif
47
48static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
49static ssize_t gpio_write(struct file *file, const char __user *buf,
50 size_t count, loff_t *off);
51static int gpio_open(struct inode *inode, struct file *filp);
52static int gpio_release(struct inode *inode, struct file *filp);
53static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
54
55
56
57struct gpio_private {
58 struct gpio_private *next;
59
60 volatile unsigned char *port, *shadow;
61 volatile unsigned char *dir, *dir_shadow;
62 unsigned char changeable_dir;
63 unsigned char changeable_bits;
64 unsigned char clk_mask;
65 unsigned char data_mask;
66 unsigned char write_msb;
67 unsigned char pad1, pad2, pad3;
68
69 unsigned long highalarm, lowalarm;
70 wait_queue_head_t alarm_wq;
71 int minor;
72};
73
74
75
76static struct gpio_private *alarmlist;
77
78static int gpio_some_alarms;
79static unsigned long gpio_pa_irq_enabled_mask;
80
81static DEFINE_SPINLOCK(gpio_lock);
82
83
84#define NUM_PORTS (GPIO_MINOR_B+1)
85
86static volatile unsigned char *ports[NUM_PORTS] = {
87 R_PORT_PA_DATA,
88 R_PORT_PB_DATA,
89};
90static volatile unsigned char *shads[NUM_PORTS] = {
91 &port_pa_data_shadow,
92 &port_pb_data_shadow
93};
94
95
96#ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR
97#define CONFIG_ETRAX_PA_CHANGEABLE_DIR 0x00
98#endif
99#ifndef CONFIG_ETRAX_PB_CHANGEABLE_DIR
100#define CONFIG_ETRAX_PB_CHANGEABLE_DIR 0x00
101#endif
102
103#ifndef CONFIG_ETRAX_PA_CHANGEABLE_BITS
104#define CONFIG_ETRAX_PA_CHANGEABLE_BITS 0xFF
105#endif
106#ifndef CONFIG_ETRAX_PB_CHANGEABLE_BITS
107#define CONFIG_ETRAX_PB_CHANGEABLE_BITS 0xFF
108#endif
109
110
111static unsigned char changeable_dir[NUM_PORTS] = {
112 CONFIG_ETRAX_PA_CHANGEABLE_DIR,
113 CONFIG_ETRAX_PB_CHANGEABLE_DIR
114};
115static unsigned char changeable_bits[NUM_PORTS] = {
116 CONFIG_ETRAX_PA_CHANGEABLE_BITS,
117 CONFIG_ETRAX_PB_CHANGEABLE_BITS
118};
119
120static volatile unsigned char *dir[NUM_PORTS] = {
121 R_PORT_PA_DIR,
122 R_PORT_PB_DIR
123};
124
125static volatile unsigned char *dir_shadow[NUM_PORTS] = {
126 &port_pa_dir_shadow,
127 &port_pb_dir_shadow
128};
129
130
131static const unsigned long int changeable_dir_g_mask = 0x01FFFF01;
132
133
134
135
136static unsigned long changeable_dir_g;
137static unsigned long dir_g_in_bits;
138static unsigned long dir_g_out_bits;
139static unsigned long dir_g_shadow;
140
141#define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
142
143
144static unsigned int gpio_poll(struct file *file, poll_table *wait)
145{
146 unsigned int mask = 0;
147 struct gpio_private *priv = file->private_data;
148 unsigned long data;
149 unsigned long flags;
150
151 spin_lock_irqsave(&gpio_lock, flags);
152
153 poll_wait(file, &priv->alarm_wq, wait);
154 if (priv->minor == GPIO_MINOR_A) {
155 unsigned long tmp;
156 data = *R_PORT_PA_DATA;
157
158
159
160 tmp = ~data & priv->highalarm & 0xFF;
161 tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
162
163 gpio_pa_irq_enabled_mask |= tmp;
164 *R_IRQ_MASK1_SET = tmp;
165 } else if (priv->minor == GPIO_MINOR_B)
166 data = *R_PORT_PB_DATA;
167 else if (priv->minor == GPIO_MINOR_G)
168 data = *R_PORT_G_DATA;
169 else {
170 mask = 0;
171 goto out;
172 }
173
174 if ((data & priv->highalarm) ||
175 (~data & priv->lowalarm)) {
176 mask = POLLIN|POLLRDNORM;
177 }
178
179out:
180 spin_unlock_irqrestore(&gpio_lock, flags);
181 DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
182
183 return mask;
184}
185
186int etrax_gpio_wake_up_check(void)
187{
188 struct gpio_private *priv;
189 unsigned long data = 0;
190 int ret = 0;
191 unsigned long flags;
192
193 spin_lock_irqsave(&gpio_lock, flags);
194 priv = alarmlist;
195 while (priv) {
196 if (USE_PORTS(priv))
197 data = *priv->port;
198 else if (priv->minor == GPIO_MINOR_G)
199 data = *R_PORT_G_DATA;
200
201 if ((data & priv->highalarm) ||
202 (~data & priv->lowalarm)) {
203 DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
204 wake_up_interruptible(&priv->alarm_wq);
205 ret = 1;
206 }
207 priv = priv->next;
208 }
209 spin_unlock_irqrestore(&gpio_lock, flags);
210 return ret;
211}
212
213static irqreturn_t
214gpio_poll_timer_interrupt(int irq, void *dev_id)
215{
216 if (gpio_some_alarms) {
217 etrax_gpio_wake_up_check();
218 return IRQ_HANDLED;
219 }
220 return IRQ_NONE;
221}
222
223static irqreturn_t
224gpio_interrupt(int irq, void *dev_id)
225{
226 unsigned long tmp;
227 unsigned long flags;
228
229 spin_lock_irqsave(&gpio_lock, flags);
230
231
232 tmp = (*R_IRQ_READ1);
233
234
235 tmp &= gpio_pa_irq_enabled_mask;
236
237
238 *R_IRQ_MASK1_CLR = tmp;
239 gpio_pa_irq_enabled_mask &= ~tmp;
240
241 spin_unlock_irqrestore(&gpio_lock, flags);
242
243 if (gpio_some_alarms)
244 return IRQ_RETVAL(etrax_gpio_wake_up_check());
245
246 return IRQ_NONE;
247}
248
249static void gpio_write_bit(struct gpio_private *priv,
250 unsigned char data, int bit)
251{
252 *priv->port = *priv->shadow &= ~(priv->clk_mask);
253 if (data & 1 << bit)
254 *priv->port = *priv->shadow |= priv->data_mask;
255 else
256 *priv->port = *priv->shadow &= ~(priv->data_mask);
257
258
259 *priv->port = *priv->shadow |= priv->clk_mask;
260}
261
262static void gpio_write_byte(struct gpio_private *priv, unsigned char data)
263{
264 int i;
265
266 if (priv->write_msb)
267 for (i = 7; i >= 0; i--)
268 gpio_write_bit(priv, data, i);
269 else
270 for (i = 0; i <= 7; i++)
271 gpio_write_bit(priv, data, i);
272}
273
274static ssize_t gpio_write(struct file *file, const char __user *buf,
275 size_t count, loff_t *off)
276{
277 struct gpio_private *priv = file->private_data;
278 unsigned long flags;
279 ssize_t retval = count;
280
281 if (priv->minor != GPIO_MINOR_A && priv->minor != GPIO_MINOR_B)
282 return -EFAULT;
283
284 if (!access_ok(VERIFY_READ, buf, count))
285 return -EFAULT;
286
287 spin_lock_irqsave(&gpio_lock, flags);
288
289
290
291 if (priv->clk_mask == 0 || priv->data_mask == 0) {
292 retval = -EPERM;
293 goto out;
294 }
295
296 D(printk(KERN_DEBUG "gpio_write: %02X to data 0x%02X "
297 "clk 0x%02X msb: %i\n",
298 count, priv->data_mask, priv->clk_mask, priv->write_msb));
299
300 while (count--)
301 gpio_write_byte(priv, *buf++);
302
303out:
304 spin_unlock_irqrestore(&gpio_lock, flags);
305 return retval;
306}
307
308
309
310static int
311gpio_open(struct inode *inode, struct file *filp)
312{
313 struct gpio_private *priv;
314 int p = iminor(inode);
315 unsigned long flags;
316
317 if (p > GPIO_MINOR_LAST)
318 return -EINVAL;
319
320 priv = kzalloc(sizeof(struct gpio_private), GFP_KERNEL);
321
322 if (!priv)
323 return -ENOMEM;
324
325 priv->minor = p;
326
327
328
329 if (USE_PORTS(priv)) {
330 priv->port = ports[p];
331 priv->shadow = shads[p];
332 priv->dir = dir[p];
333 priv->dir_shadow = dir_shadow[p];
334 priv->changeable_dir = changeable_dir[p];
335 priv->changeable_bits = changeable_bits[p];
336 } else {
337 priv->port = NULL;
338 priv->shadow = NULL;
339 priv->dir = NULL;
340 priv->dir_shadow = NULL;
341 priv->changeable_dir = 0;
342 priv->changeable_bits = 0;
343 }
344
345 priv->highalarm = 0;
346 priv->lowalarm = 0;
347 priv->clk_mask = 0;
348 priv->data_mask = 0;
349 init_waitqueue_head(&priv->alarm_wq);
350
351 filp->private_data = priv;
352
353
354 spin_lock_irqsave(&gpio_lock, flags);
355 priv->next = alarmlist;
356 alarmlist = priv;
357 spin_unlock_irqrestore(&gpio_lock, flags);
358
359 return 0;
360}
361
362static int
363gpio_release(struct inode *inode, struct file *filp)
364{
365 struct gpio_private *p;
366 struct gpio_private *todel;
367 unsigned long flags;
368
369 spin_lock_irqsave(&gpio_lock, flags);
370
371 p = alarmlist;
372 todel = filp->private_data;
373
374
375
376 if (p == todel) {
377 alarmlist = todel->next;
378 } else {
379 while (p->next != todel)
380 p = p->next;
381 p->next = todel->next;
382 }
383
384 kfree(todel);
385
386 p = alarmlist;
387 while (p) {
388 if (p->highalarm | p->lowalarm) {
389 gpio_some_alarms = 1;
390 goto out;
391 }
392 p = p->next;
393 }
394 gpio_some_alarms = 0;
395out:
396 spin_unlock_irqrestore(&gpio_lock, flags);
397 return 0;
398}
399
400
401
402
403unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
404{
405
406
407 if (USE_PORTS(priv)) {
408 *priv->dir = *priv->dir_shadow &=
409 ~((unsigned char)arg & priv->changeable_dir);
410 return ~(*priv->dir_shadow) & 0xFF;
411 }
412
413 if (priv->minor != GPIO_MINOR_G)
414 return 0;
415
416
417 if (((arg & dir_g_in_bits) != arg) &&
418 (arg & changeable_dir_g)) {
419 arg &= changeable_dir_g;
420
421 if (arg & (1<<0)) {
422 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g0dir);
423 dir_g_in_bits |= (1<<0);
424 dir_g_out_bits &= ~(1<<0);
425 }
426 if ((arg & 0x0000FF00) == 0x0000FF00) {
427 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g8_15dir);
428 dir_g_in_bits |= 0x0000FF00;
429 dir_g_out_bits &= ~0x0000FF00;
430 }
431 if ((arg & 0x00FF0000) == 0x00FF0000) {
432 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g16_23dir);
433 dir_g_in_bits |= 0x00FF0000;
434 dir_g_out_bits &= ~0x00FF0000;
435 }
436 if (arg & (1<<24)) {
437 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g24dir);
438 dir_g_in_bits |= (1<<24);
439 dir_g_out_bits &= ~(1<<24);
440 }
441 D(printk(KERN_DEBUG "gpio: SETINPUT on port G set "
442 "genconfig to 0x%08lX "
443 "in_bits: 0x%08lX "
444 "out_bits: 0x%08lX\n",
445 (unsigned long)genconfig_shadow,
446 dir_g_in_bits, dir_g_out_bits));
447 *R_GEN_CONFIG = genconfig_shadow;
448
449
450 }
451 return dir_g_in_bits;
452}
453
454unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
455{
456 if (USE_PORTS(priv)) {
457 *priv->dir = *priv->dir_shadow |=
458 ((unsigned char)arg & priv->changeable_dir);
459 return *priv->dir_shadow;
460 }
461 if (priv->minor != GPIO_MINOR_G)
462 return 0;
463
464
465 if (((arg & dir_g_out_bits) != arg) &&
466 (arg & changeable_dir_g)) {
467
468 if (arg & (1<<0)) {
469 genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g0dir);
470 dir_g_out_bits |= (1<<0);
471 dir_g_in_bits &= ~(1<<0);
472 }
473 if ((arg & 0x0000FF00) == 0x0000FF00) {
474 genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g8_15dir);
475 dir_g_out_bits |= 0x0000FF00;
476 dir_g_in_bits &= ~0x0000FF00;
477 }
478 if ((arg & 0x00FF0000) == 0x00FF0000) {
479 genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g16_23dir);
480 dir_g_out_bits |= 0x00FF0000;
481 dir_g_in_bits &= ~0x00FF0000;
482 }
483 if (arg & (1<<24)) {
484 genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g24dir);
485 dir_g_out_bits |= (1<<24);
486 dir_g_in_bits &= ~(1<<24);
487 }
488 D(printk(KERN_INFO "gpio: SETOUTPUT on port G set "
489 "genconfig to 0x%08lX "
490 "in_bits: 0x%08lX "
491 "out_bits: 0x%08lX\n",
492 (unsigned long)genconfig_shadow,
493 dir_g_in_bits, dir_g_out_bits));
494 *R_GEN_CONFIG = genconfig_shadow;
495
496 }
497 return dir_g_out_bits & 0x7FFFFFFF;
498}
499
500static int
501gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
502
503static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
504{
505 unsigned long flags;
506 unsigned long val;
507 int ret = 0;
508
509 struct gpio_private *priv = file->private_data;
510 if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
511 return -EINVAL;
512
513 switch (_IOC_NR(cmd)) {
514 case IO_READBITS:
515
516 spin_lock_irqsave(&gpio_lock, flags);
517 if (USE_PORTS(priv)) {
518 ret = *priv->port;
519 } else if (priv->minor == GPIO_MINOR_G) {
520 ret = (*R_PORT_G_DATA) & 0x7FFFFFFF;
521 }
522 spin_unlock_irqrestore(&gpio_lock, flags);
523
524 break;
525 case IO_SETBITS:
526
527 spin_lock_irqsave(&gpio_lock, flags);
528
529 if (USE_PORTS(priv)) {
530 *priv->port = *priv->shadow |=
531 ((unsigned char)arg & priv->changeable_bits);
532 } else if (priv->minor == GPIO_MINOR_G) {
533 *R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
534 }
535 spin_unlock_irqrestore(&gpio_lock, flags);
536
537 break;
538 case IO_CLRBITS:
539
540 spin_lock_irqsave(&gpio_lock, flags);
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 spin_unlock_irqrestore(&gpio_lock, flags);
548 break;
549 case IO_HIGHALARM:
550
551 spin_lock_irqsave(&gpio_lock, flags);
552 priv->highalarm |= arg;
553 gpio_some_alarms = 1;
554 spin_unlock_irqrestore(&gpio_lock, flags);
555 break;
556 case IO_LOWALARM:
557
558 spin_lock_irqsave(&gpio_lock, flags);
559 priv->lowalarm |= arg;
560 gpio_some_alarms = 1;
561 spin_unlock_irqrestore(&gpio_lock, flags);
562 break;
563 case IO_CLRALARM:
564
565 spin_lock_irqsave(&gpio_lock, flags);
566 priv->highalarm &= ~arg;
567 priv->lowalarm &= ~arg;
568 {
569
570 struct gpio_private *p = alarmlist;
571 int some_alarms;
572 p = alarmlist;
573 some_alarms = 0;
574 while (p) {
575 if (p->highalarm | p->lowalarm) {
576 some_alarms = 1;
577 break;
578 }
579 p = p->next;
580 }
581 gpio_some_alarms = some_alarms;
582 }
583 spin_unlock_irqrestore(&gpio_lock, flags);
584 break;
585 case IO_READDIR:
586
587 spin_lock_irqsave(&gpio_lock, flags);
588 if (USE_PORTS(priv)) {
589 ret = *priv->dir_shadow;
590 } else if (priv->minor == GPIO_MINOR_G) {
591
592
593
594 ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
595 }
596 spin_unlock_irqrestore(&gpio_lock, flags);
597 break;
598 case IO_SETINPUT:
599
600
601
602 spin_lock_irqsave(&gpio_lock, flags);
603 ret = setget_input(priv, arg) & 0x7FFFFFFF;
604 spin_unlock_irqrestore(&gpio_lock, flags);
605 break;
606 case IO_SETOUTPUT:
607
608
609
610 spin_lock_irqsave(&gpio_lock, flags);
611 ret = setget_output(priv, arg) & 0x7FFFFFFF;
612 spin_unlock_irqrestore(&gpio_lock, flags);
613 break;
614 case IO_SHUTDOWN:
615 spin_lock_irqsave(&gpio_lock, flags);
616 SOFT_SHUTDOWN();
617 spin_unlock_irqrestore(&gpio_lock, flags);
618 break;
619 case IO_GET_PWR_BT:
620 spin_lock_irqsave(&gpio_lock, flags);
621#if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
622 ret = (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
623#else
624 ret = 0;
625#endif
626 spin_unlock_irqrestore(&gpio_lock, flags);
627 break;
628 case IO_CFG_WRITE_MODE:
629 spin_lock_irqsave(&gpio_lock, flags);
630 priv->clk_mask = arg & 0xFF;
631 priv->data_mask = (arg >> 8) & 0xFF;
632 priv->write_msb = (arg >> 16) & 0x01;
633
634
635
636 if (!((priv->clk_mask & priv->changeable_bits) &&
637 (priv->data_mask & priv->changeable_bits) &&
638 (priv->clk_mask & *priv->dir_shadow) &&
639 (priv->data_mask & *priv->dir_shadow)))
640 {
641 priv->clk_mask = 0;
642 priv->data_mask = 0;
643 ret = -EPERM;
644 }
645 spin_unlock_irqrestore(&gpio_lock, flags);
646 break;
647 case IO_READ_INBITS:
648
649 spin_lock_irqsave(&gpio_lock, flags);
650 if (USE_PORTS(priv)) {
651 val = *priv->port;
652 } else if (priv->minor == GPIO_MINOR_G) {
653 val = *R_PORT_G_DATA;
654 }
655 spin_unlock_irqrestore(&gpio_lock, flags);
656 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
657 ret = -EFAULT;
658 break;
659 case IO_READ_OUTBITS:
660
661 spin_lock_irqsave(&gpio_lock, flags);
662 if (USE_PORTS(priv)) {
663 val = *priv->shadow;
664 } else if (priv->minor == GPIO_MINOR_G) {
665 val = port_g_data_shadow;
666 }
667 spin_unlock_irqrestore(&gpio_lock, flags);
668 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
669 ret = -EFAULT;
670 break;
671 case IO_SETGET_INPUT:
672
673
674
675 if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
676 {
677 ret = -EFAULT;
678 break;
679 }
680 spin_lock_irqsave(&gpio_lock, flags);
681 val = setget_input(priv, val);
682 spin_unlock_irqrestore(&gpio_lock, flags);
683 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
684 ret = -EFAULT;
685 break;
686 case IO_SETGET_OUTPUT:
687
688
689
690 if (copy_from_user(&val, (void __user *)arg, sizeof(val))) {
691 ret = -EFAULT;
692 break;
693 }
694 spin_lock_irqsave(&gpio_lock, flags);
695 val = setget_output(priv, val);
696 spin_unlock_irqrestore(&gpio_lock, flags);
697 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
698 ret = -EFAULT;
699 break;
700 default:
701 spin_lock_irqsave(&gpio_lock, flags);
702 if (priv->minor == GPIO_MINOR_LEDS)
703 ret = gpio_leds_ioctl(cmd, arg);
704 else
705 ret = -EINVAL;
706 spin_unlock_irqrestore(&gpio_lock, flags);
707 }
708
709 return ret;
710}
711
712static int
713gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
714{
715 unsigned char green;
716 unsigned char red;
717
718 switch (_IOC_NR(cmd)) {
719 case IO_LEDACTIVE_SET:
720 green = ((unsigned char)arg) & 1;
721 red = (((unsigned char)arg) >> 1) & 1;
722 CRIS_LED_ACTIVE_SET_G(green);
723 CRIS_LED_ACTIVE_SET_R(red);
724 break;
725
726 case IO_LED_SETBIT:
727 CRIS_LED_BIT_SET(arg);
728 break;
729
730 case IO_LED_CLRBIT:
731 CRIS_LED_BIT_CLR(arg);
732 break;
733
734 default:
735 return -EINVAL;
736 }
737
738 return 0;
739}
740
741static const struct file_operations gpio_fops = {
742 .owner = THIS_MODULE,
743 .poll = gpio_poll,
744 .unlocked_ioctl = gpio_ioctl,
745 .write = gpio_write,
746 .open = gpio_open,
747 .release = gpio_release,
748 .llseek = noop_llseek,
749};
750
751static void ioif_watcher(const unsigned int gpio_in_available,
752 const unsigned int gpio_out_available,
753 const unsigned char pa_available,
754 const unsigned char pb_available)
755{
756 unsigned long int flags;
757
758 D(printk(KERN_DEBUG "gpio.c: ioif_watcher called\n"));
759 D(printk(KERN_DEBUG "gpio.c: G in: 0x%08x G out: 0x%08x "
760 "PA: 0x%02x PB: 0x%02x\n",
761 gpio_in_available, gpio_out_available,
762 pa_available, pb_available));
763
764 spin_lock_irqsave(&gpio_lock, flags);
765
766 dir_g_in_bits = gpio_in_available;
767 dir_g_out_bits = gpio_out_available;
768
769
770
771 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out))
772 dir_g_shadow |= (1 << 0);
773 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out))
774 dir_g_shadow |= 0x0000FF00;
775 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g16_23dir, out))
776 dir_g_shadow |= 0x00FF0000;
777 if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out))
778 dir_g_shadow |= (1 << 24);
779
780 changeable_dir_g = changeable_dir_g_mask;
781 changeable_dir_g &= dir_g_out_bits;
782 changeable_dir_g &= dir_g_in_bits;
783
784
785 dir_g_out_bits &= ~changeable_dir_g;
786 dir_g_out_bits |= dir_g_shadow;
787 dir_g_in_bits &= ~changeable_dir_g;
788 dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
789
790 spin_unlock_irqrestore(&gpio_lock, flags);
791
792 printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX "
793 "val: %08lX\n",
794 dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
795 printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n",
796 dir_g_shadow, changeable_dir_g);
797}
798
799
800
801static int __init gpio_init(void)
802{
803 int res;
804#if defined (CONFIG_ETRAX_CSP0_LEDS)
805 int i;
806#endif
807
808 res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
809 if (res < 0) {
810 printk(KERN_ERR "gpio: couldn't get a major number.\n");
811 return res;
812 }
813
814
815#if defined (CONFIG_ETRAX_CSP0_LEDS) || defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS)
816 CRIS_LED_NETWORK_SET(0);
817 CRIS_LED_ACTIVE_SET(0);
818 CRIS_LED_DISK_READ(0);
819 CRIS_LED_DISK_WRITE(0);
820
821#if defined (CONFIG_ETRAX_CSP0_LEDS)
822 for (i = 0; i < 32; i++)
823 CRIS_LED_BIT_SET(i);
824#endif
825
826#endif
827
828
829 if (cris_io_interface_register_watcher(ioif_watcher)){
830 printk(KERN_WARNING "gpio_init: Failed to install IO "
831 "if allocator watcher\n");
832 }
833
834 printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001-2008 "
835 "Axis Communications AB\n");
836
837
838
839
840
841 res = request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
842 IRQF_SHARED | IRQF_DISABLED, "gpio poll", gpio_name);
843 if (res) {
844 printk(KERN_CRIT "err: timer0 irq for gpio\n");
845 return res;
846 }
847 res = request_irq(PA_IRQ_NBR, gpio_interrupt,
848 IRQF_SHARED | IRQF_DISABLED, "gpio PA", gpio_name);
849 if (res)
850 printk(KERN_CRIT "err: PA irq for gpio\n");
851
852 return res;
853}
854
855
856module_init(gpio_init);
857
858