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