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