• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/cris/arch-v32/drivers/mach-fs/
1/*
2 * ETRAX CRISv32 general port I/O device
3 *
4 * Copyright (c) 1999-2006 Axis Communications AB
5 *
6 * Authors:    Bjorn Wesen      (initial version)
7 *             Ola Knutsson     (LED handling)
8 *             Johan Adolfsson  (read/set directions, write, port G,
9 *                               port to ETRAX FS.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/sched.h>
15#include <linux/slab.h>
16#include <linux/ioport.h>
17#include <linux/errno.h>
18#include <linux/kernel.h>
19#include <linux/fs.h>
20#include <linux/string.h>
21#include <linux/poll.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/spinlock.h>
25#include <linux/smp_lock.h>
26
27#include <asm/etraxgpio.h>
28#include <hwregs/reg_map.h>
29#include <hwregs/reg_rdwr.h>
30#include <hwregs/gio_defs.h>
31#include <hwregs/intr_vect_defs.h>
32#include <asm/io.h>
33#include <asm/system.h>
34#include <asm/irq.h>
35
36#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
37#include "../i2c.h"
38
39#define VIRT_I2C_ADDR 0x40
40#endif
41
42/* The following gio ports on ETRAX FS is available:
43 * pa  8 bits, supports interrupts off, hi, low, set, posedge, negedge anyedge
44 * pb 18 bits
45 * pc 18 bits
46 * pd 18 bits
47 * pe 18 bits
48 * each port has a rw_px_dout, r_px_din and rw_px_oe register.
49 */
50
51#define GPIO_MAJOR 120  /* experimental MAJOR number */
52
53#define D(x)
54
55#define DP(x)
56
57static char gpio_name[] = "etrax gpio";
58
59
60#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
61static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
62	unsigned long arg);
63#endif
64static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
65static ssize_t gpio_write(struct file *file, const char *buf, size_t count,
66	loff_t *off);
67static int gpio_open(struct inode *inode, struct file *filp);
68static int gpio_release(struct inode *inode, struct file *filp);
69static unsigned int gpio_poll(struct file *filp,
70	struct poll_table_struct *wait);
71
72/* private data per open() of this driver */
73
74struct gpio_private {
75	struct gpio_private *next;
76	/* The IO_CFG_WRITE_MODE_VALUE only support 8 bits: */
77	unsigned char clk_mask;
78	unsigned char data_mask;
79	unsigned char write_msb;
80	unsigned char pad1;
81	/* These fields are generic */
82	unsigned long highalarm, lowalarm;
83	wait_queue_head_t alarm_wq;
84	int minor;
85};
86
87/* linked list of alarms to check for */
88
89static struct gpio_private *alarmlist;
90
91static int gpio_some_alarms; /* Set if someone uses alarm */
92static unsigned long gpio_pa_high_alarms;
93static unsigned long gpio_pa_low_alarms;
94
95static DEFINE_SPINLOCK(alarm_lock);
96
97#define NUM_PORTS (GPIO_MINOR_LAST+1)
98#define GIO_REG_RD_ADDR(reg) \
99	(volatile unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg)
100#define GIO_REG_WR_ADDR(reg) \
101	(volatile unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg)
102unsigned long led_dummy;
103#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
104static unsigned long virtual_dummy;
105static unsigned long virtual_rw_pv_oe = CONFIG_ETRAX_DEF_GIO_PV_OE;
106static unsigned short cached_virtual_gpio_read;
107#endif
108
109static volatile unsigned long *data_out[NUM_PORTS] = {
110	GIO_REG_WR_ADDR(rw_pa_dout),
111	GIO_REG_WR_ADDR(rw_pb_dout),
112	&led_dummy,
113	GIO_REG_WR_ADDR(rw_pc_dout),
114	GIO_REG_WR_ADDR(rw_pd_dout),
115	GIO_REG_WR_ADDR(rw_pe_dout),
116#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
117	&virtual_dummy,
118#endif
119};
120
121static volatile unsigned long *data_in[NUM_PORTS] = {
122	GIO_REG_RD_ADDR(r_pa_din),
123	GIO_REG_RD_ADDR(r_pb_din),
124	&led_dummy,
125	GIO_REG_RD_ADDR(r_pc_din),
126	GIO_REG_RD_ADDR(r_pd_din),
127	GIO_REG_RD_ADDR(r_pe_din),
128#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
129	&virtual_dummy,
130#endif
131};
132
133static unsigned long changeable_dir[NUM_PORTS] = {
134	CONFIG_ETRAX_PA_CHANGEABLE_DIR,
135	CONFIG_ETRAX_PB_CHANGEABLE_DIR,
136	0,
137	CONFIG_ETRAX_PC_CHANGEABLE_DIR,
138	CONFIG_ETRAX_PD_CHANGEABLE_DIR,
139	CONFIG_ETRAX_PE_CHANGEABLE_DIR,
140#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
141	CONFIG_ETRAX_PV_CHANGEABLE_DIR,
142#endif
143};
144
145static unsigned long changeable_bits[NUM_PORTS] = {
146	CONFIG_ETRAX_PA_CHANGEABLE_BITS,
147	CONFIG_ETRAX_PB_CHANGEABLE_BITS,
148	0,
149	CONFIG_ETRAX_PC_CHANGEABLE_BITS,
150	CONFIG_ETRAX_PD_CHANGEABLE_BITS,
151	CONFIG_ETRAX_PE_CHANGEABLE_BITS,
152#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
153	CONFIG_ETRAX_PV_CHANGEABLE_BITS,
154#endif
155};
156
157static volatile unsigned long *dir_oe[NUM_PORTS] = {
158	GIO_REG_WR_ADDR(rw_pa_oe),
159	GIO_REG_WR_ADDR(rw_pb_oe),
160	&led_dummy,
161	GIO_REG_WR_ADDR(rw_pc_oe),
162	GIO_REG_WR_ADDR(rw_pd_oe),
163	GIO_REG_WR_ADDR(rw_pe_oe),
164#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
165	&virtual_rw_pv_oe,
166#endif
167};
168
169
170
171static unsigned int gpio_poll(struct file *file, struct poll_table_struct *wait)
172{
173	unsigned int mask = 0;
174	struct gpio_private *priv = file->private_data;
175	unsigned long data;
176	poll_wait(file, &priv->alarm_wq, wait);
177	if (priv->minor == GPIO_MINOR_A) {
178		reg_gio_rw_intr_cfg intr_cfg;
179		unsigned long tmp;
180		unsigned long flags;
181
182		local_irq_save(flags);
183		data = REG_TYPE_CONV(unsigned long, reg_gio_r_pa_din,
184			REG_RD(gio, regi_gio, r_pa_din));
185		/* PA has support for interrupt
186		 * lets activate high for those low and with highalarm set
187		 */
188		intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
189
190		tmp = ~data & priv->highalarm & 0xFF;
191		if (tmp & (1 << 0))
192			intr_cfg.pa0 = regk_gio_hi;
193		if (tmp & (1 << 1))
194			intr_cfg.pa1 = regk_gio_hi;
195		if (tmp & (1 << 2))
196			intr_cfg.pa2 = regk_gio_hi;
197		if (tmp & (1 << 3))
198			intr_cfg.pa3 = regk_gio_hi;
199		if (tmp & (1 << 4))
200			intr_cfg.pa4 = regk_gio_hi;
201		if (tmp & (1 << 5))
202			intr_cfg.pa5 = regk_gio_hi;
203		if (tmp & (1 << 6))
204			intr_cfg.pa6 = regk_gio_hi;
205		if (tmp & (1 << 7))
206			intr_cfg.pa7 = regk_gio_hi;
207		/*
208		 * lets activate low for those high and with lowalarm set
209		 */
210		tmp = data & priv->lowalarm & 0xFF;
211		if (tmp & (1 << 0))
212			intr_cfg.pa0 = regk_gio_lo;
213		if (tmp & (1 << 1))
214			intr_cfg.pa1 = regk_gio_lo;
215		if (tmp & (1 << 2))
216			intr_cfg.pa2 = regk_gio_lo;
217		if (tmp & (1 << 3))
218			intr_cfg.pa3 = regk_gio_lo;
219		if (tmp & (1 << 4))
220			intr_cfg.pa4 = regk_gio_lo;
221		if (tmp & (1 << 5))
222			intr_cfg.pa5 = regk_gio_lo;
223		if (tmp & (1 << 6))
224			intr_cfg.pa6 = regk_gio_lo;
225		if (tmp & (1 << 7))
226			intr_cfg.pa7 = regk_gio_lo;
227
228		REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
229		local_irq_restore(flags);
230	} else if (priv->minor <= GPIO_MINOR_E)
231		data = *data_in[priv->minor];
232	else
233		return 0;
234
235	if ((data & priv->highalarm) || (~data & priv->lowalarm))
236		mask = POLLIN|POLLRDNORM;
237
238	DP(printk(KERN_DEBUG "gpio_poll ready: mask 0x%08X\n", mask));
239	return mask;
240}
241
242int etrax_gpio_wake_up_check(void)
243{
244	struct gpio_private *priv;
245	unsigned long data = 0;
246	unsigned long flags;
247	int ret = 0;
248	spin_lock_irqsave(&alarm_lock, flags);
249	priv = alarmlist;
250	while (priv) {
251#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
252		if (priv->minor == GPIO_MINOR_V)
253			data = (unsigned long)cached_virtual_gpio_read;
254		else {
255			data = *data_in[priv->minor];
256			if (priv->minor == GPIO_MINOR_A)
257				priv->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
258		}
259#else
260		data = *data_in[priv->minor];
261#endif
262		if ((data & priv->highalarm) ||
263		    (~data & priv->lowalarm)) {
264			DP(printk(KERN_DEBUG
265				"etrax_gpio_wake_up_check %i\n", priv->minor));
266			wake_up_interruptible(&priv->alarm_wq);
267			ret = 1;
268		}
269		priv = priv->next;
270	}
271	spin_unlock_irqrestore(&alarm_lock, flags);
272	return ret;
273}
274
275static irqreturn_t
276gpio_poll_timer_interrupt(int irq, void *dev_id)
277{
278	if (gpio_some_alarms)
279		return IRQ_RETVAL(etrax_gpio_wake_up_check());
280	return IRQ_NONE;
281}
282
283static irqreturn_t
284gpio_pa_interrupt(int irq, void *dev_id)
285{
286	reg_gio_rw_intr_mask intr_mask;
287	reg_gio_r_masked_intr masked_intr;
288	reg_gio_rw_ack_intr ack_intr;
289	unsigned long tmp;
290	unsigned long tmp2;
291#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
292	unsigned char enable_gpiov_ack = 0;
293#endif
294
295	/* Find what PA interrupts are active */
296	masked_intr = REG_RD(gio, regi_gio, r_masked_intr);
297	tmp = REG_TYPE_CONV(unsigned long, reg_gio_r_masked_intr, masked_intr);
298
299	/* Find those that we have enabled */
300	spin_lock(&alarm_lock);
301	tmp &= (gpio_pa_high_alarms | gpio_pa_low_alarms);
302	spin_unlock(&alarm_lock);
303
304#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
305	/* Something changed on virtual GPIO. Interrupt is acked by
306	 * reading the device.
307	 */
308	if (tmp & (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN)) {
309		i2c_read(VIRT_I2C_ADDR, (void *)&cached_virtual_gpio_read,
310			sizeof(cached_virtual_gpio_read));
311		enable_gpiov_ack = 1;
312	}
313#endif
314
315	/* Ack them */
316	ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp);
317	REG_WR(gio, regi_gio, rw_ack_intr, ack_intr);
318
319	/* Disable those interrupts.. */
320	intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
321	tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask);
322	tmp2 &= ~tmp;
323#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
324	/* Do not disable interrupt on virtual GPIO. Changes on virtual
325	 * pins are only noticed by an interrupt.
326	 */
327	if (enable_gpiov_ack)
328		tmp2 |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
329#endif
330	intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2);
331	REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
332
333	if (gpio_some_alarms)
334		return IRQ_RETVAL(etrax_gpio_wake_up_check());
335	return IRQ_NONE;
336}
337
338
339static ssize_t gpio_write(struct file *file, const char *buf, size_t count,
340	loff_t *off)
341{
342	struct gpio_private *priv = file->private_data;
343	unsigned char data, clk_mask, data_mask, write_msb;
344	unsigned long flags;
345	unsigned long shadow;
346	volatile unsigned long *port;
347	ssize_t retval = count;
348	/* Only bits 0-7 may be used for write operations but allow all
349	   devices except leds... */
350#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
351	if (priv->minor == GPIO_MINOR_V)
352		return -EFAULT;
353#endif
354	if (priv->minor == GPIO_MINOR_LEDS)
355		return -EFAULT;
356
357	if (!access_ok(VERIFY_READ, buf, count))
358		return -EFAULT;
359	clk_mask = priv->clk_mask;
360	data_mask = priv->data_mask;
361	/* It must have been configured using the IO_CFG_WRITE_MODE */
362	/* Perhaps a better error code? */
363	if (clk_mask == 0 || data_mask == 0)
364		return -EPERM;
365	write_msb = priv->write_msb;
366	D(printk(KERN_DEBUG "gpio_write: %lu to data 0x%02X clk 0x%02X "
367		"msb: %i\n", count, data_mask, clk_mask, write_msb));
368	port = data_out[priv->minor];
369
370	while (count--) {
371		int i;
372		data = *buf++;
373		if (priv->write_msb) {
374			for (i = 7; i >= 0; i--) {
375				local_irq_save(flags);
376				shadow = *port;
377				*port = shadow &= ~clk_mask;
378				if (data & 1<<i)
379					*port = shadow |= data_mask;
380				else
381					*port = shadow &= ~data_mask;
382			/* For FPGA: min 5.0ns (DCC) before CCLK high */
383				*port = shadow |= clk_mask;
384				local_irq_restore(flags);
385			}
386		} else {
387			for (i = 0; i <= 7; i++) {
388				local_irq_save(flags);
389				shadow = *port;
390				*port = shadow &= ~clk_mask;
391				if (data & 1<<i)
392					*port = shadow |= data_mask;
393				else
394					*port = shadow &= ~data_mask;
395			/* For FPGA: min 5.0ns (DCC) before CCLK high */
396				*port = shadow |= clk_mask;
397				local_irq_restore(flags);
398			}
399		}
400	}
401	return retval;
402}
403
404
405
406static int
407gpio_open(struct inode *inode, struct file *filp)
408{
409	struct gpio_private *priv;
410	int p = iminor(inode);
411
412	if (p > GPIO_MINOR_LAST)
413		return -EINVAL;
414
415	priv = kmalloc(sizeof(struct gpio_private), GFP_KERNEL);
416	if (!priv)
417		return -ENOMEM;
418
419	lock_kernel();
420	memset(priv, 0, sizeof(*priv));
421
422	priv->minor = p;
423
424	/* initialize the io/alarm struct */
425
426	priv->clk_mask = 0;
427	priv->data_mask = 0;
428	priv->highalarm = 0;
429	priv->lowalarm = 0;
430	init_waitqueue_head(&priv->alarm_wq);
431
432	filp->private_data = (void *)priv;
433
434	/* link it into our alarmlist */
435	spin_lock_irq(&alarm_lock);
436	priv->next = alarmlist;
437	alarmlist = priv;
438	spin_unlock_irq(&alarm_lock);
439
440	unlock_kernel();
441	return 0;
442}
443
444static int
445gpio_release(struct inode *inode, struct file *filp)
446{
447	struct gpio_private *p;
448	struct gpio_private *todel;
449	/* local copies while updating them: */
450	unsigned long a_high, a_low;
451	unsigned long some_alarms;
452
453	/* unlink from alarmlist and free the private structure */
454
455	spin_lock_irq(&alarm_lock);
456	p = alarmlist;
457	todel = filp->private_data;
458
459	if (p == todel) {
460		alarmlist = todel->next;
461	} else {
462		while (p->next != todel)
463			p = p->next;
464		p->next = todel->next;
465	}
466
467	kfree(todel);
468	/* Check if there are still any alarms set */
469	p = alarmlist;
470	some_alarms = 0;
471	a_high = 0;
472	a_low = 0;
473	while (p) {
474		if (p->minor == GPIO_MINOR_A) {
475#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
476			p->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
477#endif
478			a_high |= p->highalarm;
479			a_low |= p->lowalarm;
480		}
481
482		if (p->highalarm | p->lowalarm)
483			some_alarms = 1;
484		p = p->next;
485	}
486
487#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
488	/* Variables 'some_alarms' and 'a_low' needs to be set here again
489	 * to ensure that interrupt for virtual GPIO is handled.
490	 */
491	some_alarms = 1;
492	a_low |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
493#endif
494
495	gpio_some_alarms = some_alarms;
496	gpio_pa_high_alarms = a_high;
497	gpio_pa_low_alarms = a_low;
498	spin_unlock_irq(&alarm_lock);
499
500	return 0;
501}
502
503/* Main device API. ioctl's to read/set/clear bits, as well as to
504 * set alarms to wait for using a subsequent select().
505 */
506
507inline unsigned long setget_input(struct gpio_private *priv, unsigned long arg)
508{
509	/* Set direction 0=unchanged 1=input,
510	 * return mask with 1=input
511	 */
512	unsigned long flags;
513	unsigned long dir_shadow;
514
515	local_irq_save(flags);
516	dir_shadow = *dir_oe[priv->minor];
517	dir_shadow &= ~(arg & changeable_dir[priv->minor]);
518	*dir_oe[priv->minor] = dir_shadow;
519	local_irq_restore(flags);
520
521	if (priv->minor == GPIO_MINOR_A)
522		dir_shadow ^= 0xFF;    /* Only 8 bits */
523#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
524	else if (priv->minor == GPIO_MINOR_V)
525		dir_shadow ^= 0xFFFF;  /* Only 16 bits */
526#endif
527	else
528		dir_shadow ^= 0x3FFFF; /* Only 18 bits */
529	return dir_shadow;
530
531} /* setget_input */
532
533inline unsigned long setget_output(struct gpio_private *priv, unsigned long arg)
534{
535	unsigned long flags;
536	unsigned long dir_shadow;
537
538	local_irq_save(flags);
539	dir_shadow = *dir_oe[priv->minor];
540	dir_shadow |=  (arg & changeable_dir[priv->minor]);
541	*dir_oe[priv->minor] = dir_shadow;
542	local_irq_restore(flags);
543	return dir_shadow;
544} /* setget_output */
545
546static int gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
547
548static int
549gpio_ioctl_unlocked(struct file *file, unsigned int cmd, unsigned long arg)
550{
551	unsigned long flags;
552	unsigned long val;
553	unsigned long shadow;
554	struct gpio_private *priv = file->private_data;
555	if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
556		return -EINVAL;
557
558#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
559	if (priv->minor == GPIO_MINOR_V)
560		return virtual_gpio_ioctl(file, cmd, arg);
561#endif
562
563	switch (_IOC_NR(cmd)) {
564	case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
565		/* Read the port. */
566		return *data_in[priv->minor];
567		break;
568	case IO_SETBITS:
569		local_irq_save(flags);
570		/* Set changeable bits with a 1 in arg. */
571		shadow = *data_out[priv->minor];
572		shadow |=  (arg & changeable_bits[priv->minor]);
573		*data_out[priv->minor] = shadow;
574		local_irq_restore(flags);
575		break;
576	case IO_CLRBITS:
577		local_irq_save(flags);
578		/* Clear changeable bits with a 1 in arg. */
579		shadow = *data_out[priv->minor];
580		shadow &=  ~(arg & changeable_bits[priv->minor]);
581		*data_out[priv->minor] = shadow;
582		local_irq_restore(flags);
583		break;
584	case IO_HIGHALARM:
585		/* Set alarm when bits with 1 in arg go high. */
586		priv->highalarm |= arg;
587		spin_lock_irqsave(&alarm_lock, flags);
588		gpio_some_alarms = 1;
589		if (priv->minor == GPIO_MINOR_A)
590			gpio_pa_high_alarms |= arg;
591		spin_unlock_irqrestore(&alarm_lock, flags);
592		break;
593	case IO_LOWALARM:
594		/* Set alarm when bits with 1 in arg go low. */
595		priv->lowalarm |= arg;
596		spin_lock_irqsave(&alarm_lock, flags);
597		gpio_some_alarms = 1;
598		if (priv->minor == GPIO_MINOR_A)
599			gpio_pa_low_alarms |= arg;
600		spin_unlock_irqrestore(&alarm_lock, flags);
601		break;
602	case IO_CLRALARM:
603		/* Clear alarm for bits with 1 in arg. */
604		priv->highalarm &= ~arg;
605		priv->lowalarm  &= ~arg;
606		spin_lock_irqsave(&alarm_lock, flags);
607		if (priv->minor == GPIO_MINOR_A) {
608			if (gpio_pa_high_alarms & arg ||
609			    gpio_pa_low_alarms & arg)
610				/* Must update the gpio_pa_*alarms masks */
611				;
612		}
613		spin_unlock_irqrestore(&alarm_lock, flags);
614		break;
615	case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
616		/* Read direction 0=input 1=output */
617		return *dir_oe[priv->minor];
618	case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
619		/* Set direction 0=unchanged 1=input,
620		 * return mask with 1=input
621		 */
622		return setget_input(priv, arg);
623		break;
624	case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
625		/* Set direction 0=unchanged 1=output,
626		 * return mask with 1=output
627		 */
628		return setget_output(priv, arg);
629
630	case IO_CFG_WRITE_MODE:
631	{
632		unsigned long dir_shadow;
633		dir_shadow = *dir_oe[priv->minor];
634
635		priv->clk_mask = arg & 0xFF;
636		priv->data_mask = (arg >> 8) & 0xFF;
637		priv->write_msb = (arg >> 16) & 0x01;
638		/* Check if we're allowed to change the bits and
639		 * the direction is correct
640		 */
641		if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
642		      (priv->data_mask & changeable_bits[priv->minor]) &&
643		      (priv->clk_mask & dir_shadow) &&
644		      (priv->data_mask & dir_shadow))) {
645			priv->clk_mask = 0;
646			priv->data_mask = 0;
647			return -EPERM;
648		}
649		break;
650	}
651	case IO_READ_INBITS:
652		/* *arg is result of reading the input pins */
653		val = *data_in[priv->minor];
654		if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
655			return -EFAULT;
656		return 0;
657		break;
658	case IO_READ_OUTBITS:
659		 /* *arg is result of reading the output shadow */
660		val = *data_out[priv->minor];
661		if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
662			return -EFAULT;
663		break;
664	case IO_SETGET_INPUT:
665		/* bits set in *arg is set to input,
666		 * *arg updated with current input pins.
667		 */
668		if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
669			return -EFAULT;
670		val = setget_input(priv, val);
671		if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
672			return -EFAULT;
673		break;
674	case IO_SETGET_OUTPUT:
675		/* bits set in *arg is set to output,
676		 * *arg updated with current output pins.
677		 */
678		if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
679			return -EFAULT;
680		val = setget_output(priv, val);
681		if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
682			return -EFAULT;
683		break;
684	default:
685		if (priv->minor == GPIO_MINOR_LEDS)
686			return gpio_leds_ioctl(cmd, arg);
687		else
688			return -EINVAL;
689	} /* switch */
690
691	return 0;
692}
693
694static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
695{
696       long ret;
697
698       lock_kernel();
699       ret = gpio_ioctl_unlocked(file, cmd, arg);
700       unlock_kernel();
701
702       return ret;
703}
704
705#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
706static int
707virtual_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
708{
709	unsigned long flags;
710	unsigned short val;
711	unsigned short shadow;
712	struct gpio_private *priv = file->private_data;
713
714	switch (_IOC_NR(cmd)) {
715	case IO_SETBITS:
716		local_irq_save(flags);
717		/* Set changeable bits with a 1 in arg. */
718		i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
719		shadow |= ~*dir_oe[priv->minor];
720		shadow |= (arg & changeable_bits[priv->minor]);
721		i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
722		local_irq_restore(flags);
723		break;
724	case IO_CLRBITS:
725		local_irq_save(flags);
726		/* Clear changeable bits with a 1 in arg. */
727		i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
728		shadow |= ~*dir_oe[priv->minor];
729		shadow &= ~(arg & changeable_bits[priv->minor]);
730		i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
731		local_irq_restore(flags);
732		break;
733	case IO_HIGHALARM:
734		/* Set alarm when bits with 1 in arg go high. */
735		priv->highalarm |= arg;
736		spin_lock(&alarm_lock);
737		gpio_some_alarms = 1;
738		spin_unlock(&alarm_lock);
739		break;
740	case IO_LOWALARM:
741		/* Set alarm when bits with 1 in arg go low. */
742		priv->lowalarm |= arg;
743		spin_lock(&alarm_lock);
744		gpio_some_alarms = 1;
745		spin_unlock(&alarm_lock);
746		break;
747	case IO_CLRALARM:
748		/* Clear alarm for bits with 1 in arg. */
749		priv->highalarm &= ~arg;
750		priv->lowalarm  &= ~arg;
751		spin_lock(&alarm_lock);
752		spin_unlock(&alarm_lock);
753		break;
754	case IO_CFG_WRITE_MODE:
755	{
756		unsigned long dir_shadow;
757		dir_shadow = *dir_oe[priv->minor];
758
759		priv->clk_mask = arg & 0xFF;
760		priv->data_mask = (arg >> 8) & 0xFF;
761		priv->write_msb = (arg >> 16) & 0x01;
762		/* Check if we're allowed to change the bits and
763		 * the direction is correct
764		 */
765		if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
766		      (priv->data_mask & changeable_bits[priv->minor]) &&
767		      (priv->clk_mask & dir_shadow) &&
768		      (priv->data_mask & dir_shadow))) {
769			priv->clk_mask = 0;
770			priv->data_mask = 0;
771			return -EPERM;
772		}
773		break;
774	}
775	case IO_READ_INBITS:
776		/* *arg is result of reading the input pins */
777		val = cached_virtual_gpio_read;
778		val &= ~*dir_oe[priv->minor];
779		if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
780			return -EFAULT;
781		return 0;
782		break;
783	case IO_READ_OUTBITS:
784		 /* *arg is result of reading the output shadow */
785		i2c_read(VIRT_I2C_ADDR, (void *)&val, sizeof(val));
786		val &= *dir_oe[priv->minor];
787		if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
788			return -EFAULT;
789		break;
790	case IO_SETGET_INPUT:
791	{
792		/* bits set in *arg is set to input,
793		 * *arg updated with current input pins.
794		 */
795		unsigned short input_mask = ~*dir_oe[priv->minor];
796		if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
797			return -EFAULT;
798		val = setget_input(priv, val);
799		if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
800			return -EFAULT;
801		if ((input_mask & val) != input_mask) {
802			/* Input pins changed. All ports desired as input
803			 * should be set to logic 1.
804			 */
805			unsigned short change = input_mask ^ val;
806			i2c_read(VIRT_I2C_ADDR, (void *)&shadow,
807				sizeof(shadow));
808			shadow &= ~change;
809			shadow |= val;
810			i2c_write(VIRT_I2C_ADDR, (void *)&shadow,
811				sizeof(shadow));
812		}
813		break;
814	}
815	case IO_SETGET_OUTPUT:
816		/* bits set in *arg is set to output,
817		 * *arg updated with current output pins.
818		 */
819		if (copy_from_user(&val, (unsigned long *)arg, sizeof(val)))
820			return -EFAULT;
821		val = setget_output(priv, val);
822		if (copy_to_user((unsigned long *)arg, &val, sizeof(val)))
823			return -EFAULT;
824		break;
825	default:
826		return -EINVAL;
827	} /* switch */
828  return 0;
829}
830#endif /* CONFIG_ETRAX_VIRTUAL_GPIO */
831
832static int
833gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
834{
835	unsigned char green;
836	unsigned char red;
837
838	switch (_IOC_NR(cmd)) {
839	case IO_LEDACTIVE_SET:
840		green = ((unsigned char) arg) & 1;
841		red   = (((unsigned char) arg) >> 1) & 1;
842		CRIS_LED_ACTIVE_SET_G(green);
843		CRIS_LED_ACTIVE_SET_R(red);
844		break;
845
846	default:
847		return -EINVAL;
848	} /* switch */
849
850	return 0;
851}
852
853static const struct file_operations gpio_fops = {
854	.owner		= THIS_MODULE,
855	.poll		= gpio_poll,
856	.unlocked_ioctl	= gpio_ioctl,
857	.write		= gpio_write,
858	.open		= gpio_open,
859	.release	= gpio_release,
860};
861
862#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
863static void
864virtual_gpio_init(void)
865{
866	reg_gio_rw_intr_cfg intr_cfg;
867	reg_gio_rw_intr_mask intr_mask;
868	unsigned short shadow;
869
870	shadow = ~virtual_rw_pv_oe; /* Input ports should be set to logic 1 */
871	shadow |= CONFIG_ETRAX_DEF_GIO_PV_OUT;
872	i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
873
874	/* Set interrupt mask and on what state the interrupt shall trigger.
875	 * For virtual gpio the interrupt shall trigger on logic '0'.
876	 */
877	intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
878	intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
879
880	switch (CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN) {
881	case 0:
882		intr_cfg.pa0 = regk_gio_lo;
883		intr_mask.pa0 = regk_gio_yes;
884		break;
885	case 1:
886		intr_cfg.pa1 = regk_gio_lo;
887		intr_mask.pa1 = regk_gio_yes;
888		break;
889	case 2:
890		intr_cfg.pa2 = regk_gio_lo;
891		intr_mask.pa2 = regk_gio_yes;
892		break;
893	case 3:
894		intr_cfg.pa3 = regk_gio_lo;
895		intr_mask.pa3 = regk_gio_yes;
896		break;
897	case 4:
898		intr_cfg.pa4 = regk_gio_lo;
899		intr_mask.pa4 = regk_gio_yes;
900		break;
901	case 5:
902		intr_cfg.pa5 = regk_gio_lo;
903		intr_mask.pa5 = regk_gio_yes;
904		break;
905	case 6:
906		intr_cfg.pa6 = regk_gio_lo;
907		intr_mask.pa6 = regk_gio_yes;
908		break;
909	case 7:
910		intr_cfg.pa7 = regk_gio_lo;
911		intr_mask.pa7 = regk_gio_yes;
912	break;
913	}
914
915	REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
916	REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
917
918	gpio_pa_low_alarms |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN);
919	gpio_some_alarms = 1;
920}
921#endif
922
923/* main driver initialization routine, called from mem.c */
924
925static __init int
926gpio_init(void)
927{
928	int res;
929
930	/* do the formalities */
931
932	res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
933	if (res < 0) {
934		printk(KERN_ERR "gpio: couldn't get a major number.\n");
935		return res;
936	}
937
938	/* Clear all leds */
939	CRIS_LED_NETWORK_GRP0_SET(0);
940	CRIS_LED_NETWORK_GRP1_SET(0);
941	CRIS_LED_ACTIVE_SET(0);
942	CRIS_LED_DISK_READ(0);
943	CRIS_LED_DISK_WRITE(0);
944
945	printk(KERN_INFO "ETRAX FS GPIO driver v2.5, (c) 2003-2007 "
946		"Axis Communications AB\n");
947	/* We call etrax_gpio_wake_up_check() from timer interrupt and
948	 * from cpu_idle() in kernel/process.c
949	 * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
950	 * in some tests.
951	 */
952	if (request_irq(TIMER0_INTR_VECT, gpio_poll_timer_interrupt,
953			IRQF_SHARED | IRQF_DISABLED, "gpio poll", &alarmlist))
954		printk(KERN_ERR "timer0 irq for gpio\n");
955
956	if (request_irq(GIO_INTR_VECT, gpio_pa_interrupt,
957			IRQF_SHARED | IRQF_DISABLED, "gpio PA", &alarmlist))
958		printk(KERN_ERR "PA irq for gpio\n");
959
960#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
961	virtual_gpio_init();
962#endif
963
964	return res;
965}
966
967/* this makes sure that gpio_init is called during kernel boot */
968
969module_init(gpio_init);
970