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