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