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