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