linux/drivers/gpio/gpio-samsung.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
   3 *              http://www.samsung.com/
   4 *
   5 * Copyright 2008 Openmoko, Inc.
   6 * Copyright 2008 Simtec Electronics
   7 *      Ben Dooks <ben@simtec.co.uk>
   8 *      http://armlinux.simtec.co.uk/
   9 *
  10 * SAMSUNG - GPIOlib support
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of the GNU General Public License version 2 as
  14 * published by the Free Software Foundation.
  15 */
  16
  17#include <linux/kernel.h>
  18#include <linux/irq.h>
  19#include <linux/io.h>
  20#include <linux/gpio.h>
  21#include <linux/init.h>
  22#include <linux/spinlock.h>
  23#include <linux/module.h>
  24#include <linux/interrupt.h>
  25#include <linux/device.h>
  26#include <linux/ioport.h>
  27#include <linux/of.h>
  28#include <linux/slab.h>
  29#include <linux/of_address.h>
  30
  31#include <asm/irq.h>
  32
  33#include <mach/hardware.h>
  34#include <mach/map.h>
  35#include <mach/regs-clock.h>
  36#include <mach/regs-gpio.h>
  37
  38#include <plat/cpu.h>
  39#include <plat/gpio-core.h>
  40#include <plat/gpio-cfg.h>
  41#include <plat/gpio-cfg-helpers.h>
  42#include <plat/gpio-fns.h>
  43#include <plat/pm.h>
  44
  45#ifndef DEBUG_GPIO
  46#define gpio_dbg(x...) do { } while (0)
  47#else
  48#define gpio_dbg(x...) printk(KERN_DEBUG x)
  49#endif
  50
  51int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
  52                                unsigned int off, samsung_gpio_pull_t pull)
  53{
  54        void __iomem *reg = chip->base + 0x08;
  55        int shift = off * 2;
  56        u32 pup;
  57
  58        pup = __raw_readl(reg);
  59        pup &= ~(3 << shift);
  60        pup |= pull << shift;
  61        __raw_writel(pup, reg);
  62
  63        return 0;
  64}
  65
  66samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
  67                                                unsigned int off)
  68{
  69        void __iomem *reg = chip->base + 0x08;
  70        int shift = off * 2;
  71        u32 pup = __raw_readl(reg);
  72
  73        pup >>= shift;
  74        pup &= 0x3;
  75
  76        return (__force samsung_gpio_pull_t)pup;
  77}
  78
  79int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
  80                         unsigned int off, samsung_gpio_pull_t pull)
  81{
  82        switch (pull) {
  83        case S3C_GPIO_PULL_NONE:
  84                pull = 0x01;
  85                break;
  86        case S3C_GPIO_PULL_UP:
  87                pull = 0x00;
  88                break;
  89        case S3C_GPIO_PULL_DOWN:
  90                pull = 0x02;
  91                break;
  92        }
  93        return samsung_gpio_setpull_updown(chip, off, pull);
  94}
  95
  96samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip,
  97                                         unsigned int off)
  98{
  99        samsung_gpio_pull_t pull;
 100
 101        pull = samsung_gpio_getpull_updown(chip, off);
 102
 103        switch (pull) {
 104        case 0x00:
 105                pull = S3C_GPIO_PULL_UP;
 106                break;
 107        case 0x01:
 108        case 0x03:
 109                pull = S3C_GPIO_PULL_NONE;
 110                break;
 111        case 0x02:
 112                pull = S3C_GPIO_PULL_DOWN;
 113                break;
 114        }
 115
 116        return pull;
 117}
 118
 119static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip,
 120                                  unsigned int off, samsung_gpio_pull_t pull,
 121                                  samsung_gpio_pull_t updown)
 122{
 123        void __iomem *reg = chip->base + 0x08;
 124        u32 pup = __raw_readl(reg);
 125
 126        if (pull == updown)
 127                pup &= ~(1 << off);
 128        else if (pull == S3C_GPIO_PULL_NONE)
 129                pup |= (1 << off);
 130        else
 131                return -EINVAL;
 132
 133        __raw_writel(pup, reg);
 134        return 0;
 135}
 136
 137static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip,
 138                                                  unsigned int off,
 139                                                  samsung_gpio_pull_t updown)
 140{
 141        void __iomem *reg = chip->base + 0x08;
 142        u32 pup = __raw_readl(reg);
 143
 144        pup &= (1 << off);
 145        return pup ? S3C_GPIO_PULL_NONE : updown;
 146}
 147
 148samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
 149                                             unsigned int off)
 150{
 151        return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
 152}
 153
 154int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
 155                             unsigned int off, samsung_gpio_pull_t pull)
 156{
 157        return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
 158}
 159
 160samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
 161                                               unsigned int off)
 162{
 163        return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
 164}
 165
 166int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
 167                               unsigned int off, samsung_gpio_pull_t pull)
 168{
 169        return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
 170}
 171
 172static int exynos_gpio_setpull(struct samsung_gpio_chip *chip,
 173                                unsigned int off, samsung_gpio_pull_t pull)
 174{
 175        if (pull == S3C_GPIO_PULL_UP)
 176                pull = 3;
 177
 178        return samsung_gpio_setpull_updown(chip, off, pull);
 179}
 180
 181static samsung_gpio_pull_t exynos_gpio_getpull(struct samsung_gpio_chip *chip,
 182                                                unsigned int off)
 183{
 184        samsung_gpio_pull_t pull;
 185
 186        pull = samsung_gpio_getpull_updown(chip, off);
 187
 188        if (pull == 3)
 189                pull = S3C_GPIO_PULL_UP;
 190
 191        return pull;
 192}
 193
 194/*
 195 * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration.
 196 * @chip: The gpio chip that is being configured.
 197 * @off: The offset for the GPIO being configured.
 198 * @cfg: The configuration value to set.
 199 *
 200 * This helper deal with the GPIO cases where the control register
 201 * has two bits of configuration per gpio, which have the following
 202 * functions:
 203 *      00 = input
 204 *      01 = output
 205 *      1x = special function
 206 */
 207
 208static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
 209                                    unsigned int off, unsigned int cfg)
 210{
 211        void __iomem *reg = chip->base;
 212        unsigned int shift = off * 2;
 213        u32 con;
 214
 215        if (samsung_gpio_is_cfg_special(cfg)) {
 216                cfg &= 0xf;
 217                if (cfg > 3)
 218                        return -EINVAL;
 219
 220                cfg <<= shift;
 221        }
 222
 223        con = __raw_readl(reg);
 224        con &= ~(0x3 << shift);
 225        con |= cfg;
 226        __raw_writel(con, reg);
 227
 228        return 0;
 229}
 230
 231/*
 232 * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
 233 * @chip: The gpio chip that is being configured.
 234 * @off: The offset for the GPIO being configured.
 235 *
 236 * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which
 237 * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
 238 * S3C_GPIO_SPECIAL() macro.
 239 */
 240
 241static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
 242                                             unsigned int off)
 243{
 244        u32 con;
 245
 246        con = __raw_readl(chip->base);
 247        con >>= off * 2;
 248        con &= 3;
 249
 250        /* this conversion works for IN and OUT as well as special mode */
 251        return S3C_GPIO_SPECIAL(con);
 252}
 253
 254/*
 255 * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
 256 * @chip: The gpio chip that is being configured.
 257 * @off: The offset for the GPIO being configured.
 258 * @cfg: The configuration value to set.
 259 *
 260 * This helper deal with the GPIO cases where the control register has 4 bits
 261 * of control per GPIO, generally in the form of:
 262 *      0000 = Input
 263 *      0001 = Output
 264 *      others = Special functions (dependent on bank)
 265 *
 266 * Note, since the code to deal with the case where there are two control
 267 * registers instead of one, we do not have a separate set of functions for
 268 * each case.
 269 */
 270
 271static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
 272                                    unsigned int off, unsigned int cfg)
 273{
 274        void __iomem *reg = chip->base;
 275        unsigned int shift = (off & 7) * 4;
 276        u32 con;
 277
 278        if (off < 8 && chip->chip.ngpio > 8)
 279                reg -= 4;
 280
 281        if (samsung_gpio_is_cfg_special(cfg)) {
 282                cfg &= 0xf;
 283                cfg <<= shift;
 284        }
 285
 286        con = __raw_readl(reg);
 287        con &= ~(0xf << shift);
 288        con |= cfg;
 289        __raw_writel(con, reg);
 290
 291        return 0;
 292}
 293
 294/*
 295 * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
 296 * @chip: The gpio chip that is being configured.
 297 * @off: The offset for the GPIO being configured.
 298 *
 299 * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
 300 * register setting into a value the software can use, such as could be passed
 301 * to samsung_gpio_setcfg_4bit().
 302 *
 303 * @sa samsung_gpio_getcfg_2bit
 304 */
 305
 306static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
 307                                         unsigned int off)
 308{
 309        void __iomem *reg = chip->base;
 310        unsigned int shift = (off & 7) * 4;
 311        u32 con;
 312
 313        if (off < 8 && chip->chip.ngpio > 8)
 314                reg -= 4;
 315
 316        con = __raw_readl(reg);
 317        con >>= shift;
 318        con &= 0xf;
 319
 320        /* this conversion works for IN and OUT as well as special mode */
 321        return S3C_GPIO_SPECIAL(con);
 322}
 323
 324#ifdef CONFIG_PLAT_S3C24XX
 325/*
 326 * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A)
 327 * @chip: The gpio chip that is being configured.
 328 * @off: The offset for the GPIO being configured.
 329 * @cfg: The configuration value to set.
 330 *
 331 * This helper deal with the GPIO cases where the control register
 332 * has one bit of configuration for the gpio, where setting the bit
 333 * means the pin is in special function mode and unset means output.
 334 */
 335
 336static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip,
 337                                     unsigned int off, unsigned int cfg)
 338{
 339        void __iomem *reg = chip->base;
 340        unsigned int shift = off;
 341        u32 con;
 342
 343        if (samsung_gpio_is_cfg_special(cfg)) {
 344                cfg &= 0xf;
 345
 346                /* Map output to 0, and SFN2 to 1 */
 347                cfg -= 1;
 348                if (cfg > 1)
 349                        return -EINVAL;
 350
 351                cfg <<= shift;
 352        }
 353
 354        con = __raw_readl(reg);
 355        con &= ~(0x1 << shift);
 356        con |= cfg;
 357        __raw_writel(con, reg);
 358
 359        return 0;
 360}
 361
 362/*
 363 * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A)
 364 * @chip: The gpio chip that is being configured.
 365 * @off: The offset for the GPIO being configured.
 366 *
 367 * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable
 368 * GPIO configuration value.
 369 *
 370 * @sa samsung_gpio_getcfg_2bit
 371 * @sa samsung_gpio_getcfg_4bit
 372 */
 373
 374static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip,
 375                                          unsigned int off)
 376{
 377        u32 con;
 378
 379        con = __raw_readl(chip->base);
 380        con >>= off;
 381        con &= 1;
 382        con++;
 383
 384        return S3C_GPIO_SFN(con);
 385}
 386#endif
 387
 388#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
 389static int s5p64x0_gpio_setcfg_rbank(struct samsung_gpio_chip *chip,
 390                                     unsigned int off, unsigned int cfg)
 391{
 392        void __iomem *reg = chip->base;
 393        unsigned int shift;
 394        u32 con;
 395
 396        switch (off) {
 397        case 0:
 398        case 1:
 399        case 2:
 400        case 3:
 401        case 4:
 402        case 5:
 403                shift = (off & 7) * 4;
 404                reg -= 4;
 405                break;
 406        case 6:
 407                shift = ((off + 1) & 7) * 4;
 408                reg -= 4;
 409        default:
 410                shift = ((off + 1) & 7) * 4;
 411                break;
 412        }
 413
 414        if (samsung_gpio_is_cfg_special(cfg)) {
 415                cfg &= 0xf;
 416                cfg <<= shift;
 417        }
 418
 419        con = __raw_readl(reg);
 420        con &= ~(0xf << shift);
 421        con |= cfg;
 422        __raw_writel(con, reg);
 423
 424        return 0;
 425}
 426#endif
 427
 428static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
 429                                           int nr_chips)
 430{
 431        for (; nr_chips > 0; nr_chips--, chipcfg++) {
 432                if (!chipcfg->set_config)
 433                        chipcfg->set_config = samsung_gpio_setcfg_4bit;
 434                if (!chipcfg->get_config)
 435                        chipcfg->get_config = samsung_gpio_getcfg_4bit;
 436                if (!chipcfg->set_pull)
 437                        chipcfg->set_pull = samsung_gpio_setpull_updown;
 438                if (!chipcfg->get_pull)
 439                        chipcfg->get_pull = samsung_gpio_getpull_updown;
 440        }
 441}
 442
 443struct samsung_gpio_cfg s3c24xx_gpiocfg_default = {
 444        .set_config     = samsung_gpio_setcfg_2bit,
 445        .get_config     = samsung_gpio_getcfg_2bit,
 446};
 447
 448#ifdef CONFIG_PLAT_S3C24XX
 449static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
 450        .set_config     = s3c24xx_gpio_setcfg_abank,
 451        .get_config     = s3c24xx_gpio_getcfg_abank,
 452};
 453#endif
 454
 455#if defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5)
 456static struct samsung_gpio_cfg exynos_gpio_cfg = {
 457        .set_pull       = exynos_gpio_setpull,
 458        .get_pull       = exynos_gpio_getpull,
 459        .set_config     = samsung_gpio_setcfg_4bit,
 460        .get_config     = samsung_gpio_getcfg_4bit,
 461};
 462#endif
 463
 464#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
 465static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = {
 466        .cfg_eint       = 0x3,
 467        .set_config     = s5p64x0_gpio_setcfg_rbank,
 468        .get_config     = samsung_gpio_getcfg_4bit,
 469        .set_pull       = samsung_gpio_setpull_updown,
 470        .get_pull       = samsung_gpio_getpull_updown,
 471};
 472#endif
 473
 474static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
 475        [0] = {
 476                .cfg_eint       = 0x0,
 477        },
 478        [1] = {
 479                .cfg_eint       = 0x3,
 480        },
 481        [2] = {
 482                .cfg_eint       = 0x7,
 483        },
 484        [3] = {
 485                .cfg_eint       = 0xF,
 486        },
 487        [4] = {
 488                .cfg_eint       = 0x0,
 489                .set_config     = samsung_gpio_setcfg_2bit,
 490                .get_config     = samsung_gpio_getcfg_2bit,
 491        },
 492        [5] = {
 493                .cfg_eint       = 0x2,
 494                .set_config     = samsung_gpio_setcfg_2bit,
 495                .get_config     = samsung_gpio_getcfg_2bit,
 496        },
 497        [6] = {
 498                .cfg_eint       = 0x3,
 499                .set_config     = samsung_gpio_setcfg_2bit,
 500                .get_config     = samsung_gpio_getcfg_2bit,
 501        },
 502        [7] = {
 503                .set_config     = samsung_gpio_setcfg_2bit,
 504                .get_config     = samsung_gpio_getcfg_2bit,
 505        },
 506        [8] = {
 507                .set_pull       = exynos_gpio_setpull,
 508                .get_pull       = exynos_gpio_getpull,
 509        },
 510        [9] = {
 511                .cfg_eint       = 0x3,
 512                .set_pull       = exynos_gpio_setpull,
 513                .get_pull       = exynos_gpio_getpull,
 514        }
 515};
 516
 517/*
 518 * Default routines for controlling GPIO, based on the original S3C24XX
 519 * GPIO functions which deal with the case where each gpio bank of the
 520 * chip is as following:
 521 *
 522 * base + 0x00: Control register, 2 bits per gpio
 523 *              gpio n: 2 bits starting at (2*n)
 524 *              00 = input, 01 = output, others mean special-function
 525 * base + 0x04: Data register, 1 bit per gpio
 526 *              bit n: data bit n
 527*/
 528
 529static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
 530{
 531        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 532        void __iomem *base = ourchip->base;
 533        unsigned long flags;
 534        unsigned long con;
 535
 536        samsung_gpio_lock(ourchip, flags);
 537
 538        con = __raw_readl(base + 0x00);
 539        con &= ~(3 << (offset * 2));
 540
 541        __raw_writel(con, base + 0x00);
 542
 543        samsung_gpio_unlock(ourchip, flags);
 544        return 0;
 545}
 546
 547static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
 548                                       unsigned offset, int value)
 549{
 550        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 551        void __iomem *base = ourchip->base;
 552        unsigned long flags;
 553        unsigned long dat;
 554        unsigned long con;
 555
 556        samsung_gpio_lock(ourchip, flags);
 557
 558        dat = __raw_readl(base + 0x04);
 559        dat &= ~(1 << offset);
 560        if (value)
 561                dat |= 1 << offset;
 562        __raw_writel(dat, base + 0x04);
 563
 564        con = __raw_readl(base + 0x00);
 565        con &= ~(3 << (offset * 2));
 566        con |= 1 << (offset * 2);
 567
 568        __raw_writel(con, base + 0x00);
 569        __raw_writel(dat, base + 0x04);
 570
 571        samsung_gpio_unlock(ourchip, flags);
 572        return 0;
 573}
 574
 575/*
 576 * The samsung_gpiolib_4bit routines are to control the gpio banks where
 577 * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
 578 * following example:
 579 *
 580 * base + 0x00: Control register, 4 bits per gpio
 581 *              gpio n: 4 bits starting at (4*n)
 582 *              0000 = input, 0001 = output, others mean special-function
 583 * base + 0x04: Data register, 1 bit per gpio
 584 *              bit n: data bit n
 585 *
 586 * Note, since the data register is one bit per gpio and is at base + 0x4
 587 * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
 588 * state of the output.
 589 */
 590
 591static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
 592                                      unsigned int offset)
 593{
 594        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 595        void __iomem *base = ourchip->base;
 596        unsigned long con;
 597
 598        con = __raw_readl(base + GPIOCON_OFF);
 599        con &= ~(0xf << con_4bit_shift(offset));
 600        __raw_writel(con, base + GPIOCON_OFF);
 601
 602        gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
 603
 604        return 0;
 605}
 606
 607static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
 608                                       unsigned int offset, int value)
 609{
 610        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 611        void __iomem *base = ourchip->base;
 612        unsigned long con;
 613        unsigned long dat;
 614
 615        con = __raw_readl(base + GPIOCON_OFF);
 616        con &= ~(0xf << con_4bit_shift(offset));
 617        con |= 0x1 << con_4bit_shift(offset);
 618
 619        dat = __raw_readl(base + GPIODAT_OFF);
 620
 621        if (value)
 622                dat |= 1 << offset;
 623        else
 624                dat &= ~(1 << offset);
 625
 626        __raw_writel(dat, base + GPIODAT_OFF);
 627        __raw_writel(con, base + GPIOCON_OFF);
 628        __raw_writel(dat, base + GPIODAT_OFF);
 629
 630        gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
 631
 632        return 0;
 633}
 634
 635/*
 636 * The next set of routines are for the case where the GPIO configuration
 637 * registers are 4 bits per GPIO but there is more than one register (the
 638 * bank has more than 8 GPIOs.
 639 *
 640 * This case is the similar to the 4 bit case, but the registers are as
 641 * follows:
 642 *
 643 * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
 644 *              gpio n: 4 bits starting at (4*n)
 645 *              0000 = input, 0001 = output, others mean special-function
 646 * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
 647 *              gpio n: 4 bits starting at (4*n)
 648 *              0000 = input, 0001 = output, others mean special-function
 649 * base + 0x08: Data register, 1 bit per gpio
 650 *              bit n: data bit n
 651 *
 652 * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
 653 * routines we store the 'base + 0x4' address so that these routines see
 654 * the data register at ourchip->base + 0x04.
 655 */
 656
 657static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
 658                                       unsigned int offset)
 659{
 660        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 661        void __iomem *base = ourchip->base;
 662        void __iomem *regcon = base;
 663        unsigned long con;
 664
 665        if (offset > 7)
 666                offset -= 8;
 667        else
 668                regcon -= 4;
 669
 670        con = __raw_readl(regcon);
 671        con &= ~(0xf << con_4bit_shift(offset));
 672        __raw_writel(con, regcon);
 673
 674        gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
 675
 676        return 0;
 677}
 678
 679static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
 680                                        unsigned int offset, int value)
 681{
 682        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 683        void __iomem *base = ourchip->base;
 684        void __iomem *regcon = base;
 685        unsigned long con;
 686        unsigned long dat;
 687        unsigned con_offset = offset;
 688
 689        if (con_offset > 7)
 690                con_offset -= 8;
 691        else
 692                regcon -= 4;
 693
 694        con = __raw_readl(regcon);
 695        con &= ~(0xf << con_4bit_shift(con_offset));
 696        con |= 0x1 << con_4bit_shift(con_offset);
 697
 698        dat = __raw_readl(base + GPIODAT_OFF);
 699
 700        if (value)
 701                dat |= 1 << offset;
 702        else
 703                dat &= ~(1 << offset);
 704
 705        __raw_writel(dat, base + GPIODAT_OFF);
 706        __raw_writel(con, regcon);
 707        __raw_writel(dat, base + GPIODAT_OFF);
 708
 709        gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
 710
 711        return 0;
 712}
 713
 714#ifdef CONFIG_PLAT_S3C24XX
 715/* The next set of routines are for the case of s3c24xx bank a */
 716
 717static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
 718{
 719        return -EINVAL;
 720}
 721
 722static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
 723                                        unsigned offset, int value)
 724{
 725        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 726        void __iomem *base = ourchip->base;
 727        unsigned long flags;
 728        unsigned long dat;
 729        unsigned long con;
 730
 731        local_irq_save(flags);
 732
 733        con = __raw_readl(base + 0x00);
 734        dat = __raw_readl(base + 0x04);
 735
 736        dat &= ~(1 << offset);
 737        if (value)
 738                dat |= 1 << offset;
 739
 740        __raw_writel(dat, base + 0x04);
 741
 742        con &= ~(1 << offset);
 743
 744        __raw_writel(con, base + 0x00);
 745        __raw_writel(dat, base + 0x04);
 746
 747        local_irq_restore(flags);
 748        return 0;
 749}
 750#endif
 751
 752/* The next set of routines are for the case of s5p64x0 bank r */
 753
 754static int s5p64x0_gpiolib_rbank_input(struct gpio_chip *chip,
 755                                       unsigned int offset)
 756{
 757        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 758        void __iomem *base = ourchip->base;
 759        void __iomem *regcon = base;
 760        unsigned long con;
 761        unsigned long flags;
 762
 763        switch (offset) {
 764        case 6:
 765                offset += 1;
 766        case 0:
 767        case 1:
 768        case 2:
 769        case 3:
 770        case 4:
 771        case 5:
 772                regcon -= 4;
 773                break;
 774        default:
 775                offset -= 7;
 776                break;
 777        }
 778
 779        samsung_gpio_lock(ourchip, flags);
 780
 781        con = __raw_readl(regcon);
 782        con &= ~(0xf << con_4bit_shift(offset));
 783        __raw_writel(con, regcon);
 784
 785        samsung_gpio_unlock(ourchip, flags);
 786
 787        return 0;
 788}
 789
 790static int s5p64x0_gpiolib_rbank_output(struct gpio_chip *chip,
 791                                        unsigned int offset, int value)
 792{
 793        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 794        void __iomem *base = ourchip->base;
 795        void __iomem *regcon = base;
 796        unsigned long con;
 797        unsigned long dat;
 798        unsigned long flags;
 799        unsigned con_offset  = offset;
 800
 801        switch (con_offset) {
 802        case 6:
 803                con_offset += 1;
 804        case 0:
 805        case 1:
 806        case 2:
 807        case 3:
 808        case 4:
 809        case 5:
 810                regcon -= 4;
 811                break;
 812        default:
 813                con_offset -= 7;
 814                break;
 815        }
 816
 817        samsung_gpio_lock(ourchip, flags);
 818
 819        con = __raw_readl(regcon);
 820        con &= ~(0xf << con_4bit_shift(con_offset));
 821        con |= 0x1 << con_4bit_shift(con_offset);
 822
 823        dat = __raw_readl(base + GPIODAT_OFF);
 824        if (value)
 825                dat |= 1 << offset;
 826        else
 827                dat &= ~(1 << offset);
 828
 829        __raw_writel(con, regcon);
 830        __raw_writel(dat, base + GPIODAT_OFF);
 831
 832        samsung_gpio_unlock(ourchip, flags);
 833
 834        return 0;
 835}
 836
 837static void samsung_gpiolib_set(struct gpio_chip *chip,
 838                                unsigned offset, int value)
 839{
 840        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 841        void __iomem *base = ourchip->base;
 842        unsigned long flags;
 843        unsigned long dat;
 844
 845        samsung_gpio_lock(ourchip, flags);
 846
 847        dat = __raw_readl(base + 0x04);
 848        dat &= ~(1 << offset);
 849        if (value)
 850                dat |= 1 << offset;
 851        __raw_writel(dat, base + 0x04);
 852
 853        samsung_gpio_unlock(ourchip, flags);
 854}
 855
 856static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
 857{
 858        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 859        unsigned long val;
 860
 861        val = __raw_readl(ourchip->base + 0x04);
 862        val >>= offset;
 863        val &= 1;
 864
 865        return val;
 866}
 867
 868/*
 869 * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
 870 * for use with the configuration calls, and other parts of the s3c gpiolib
 871 * support code.
 872 *
 873 * Not all s3c support code will need this, as some configurations of cpu
 874 * may only support one or two different configuration options and have an
 875 * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
 876 * the machine support file should provide its own samsung_gpiolib_getchip()
 877 * and any other necessary functions.
 878 */
 879
 880#ifdef CONFIG_S3C_GPIO_TRACK
 881struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
 882
 883static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
 884{
 885        unsigned int gpn;
 886        int i;
 887
 888        gpn = chip->chip.base;
 889        for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
 890                BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
 891                s3c_gpios[gpn] = chip;
 892        }
 893}
 894#endif /* CONFIG_S3C_GPIO_TRACK */
 895
 896/*
 897 * samsung_gpiolib_add() - add the Samsung gpio_chip.
 898 * @chip: The chip to register
 899 *
 900 * This is a wrapper to gpiochip_add() that takes our specific gpio chip
 901 * information and makes the necessary alterations for the platform and
 902 * notes the information for use with the configuration systems and any
 903 * other parts of the system.
 904 */
 905
 906static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
 907{
 908        struct gpio_chip *gc = &chip->chip;
 909        int ret;
 910
 911        BUG_ON(!chip->base);
 912        BUG_ON(!gc->label);
 913        BUG_ON(!gc->ngpio);
 914
 915        spin_lock_init(&chip->lock);
 916
 917        if (!gc->direction_input)
 918                gc->direction_input = samsung_gpiolib_2bit_input;
 919        if (!gc->direction_output)
 920                gc->direction_output = samsung_gpiolib_2bit_output;
 921        if (!gc->set)
 922                gc->set = samsung_gpiolib_set;
 923        if (!gc->get)
 924                gc->get = samsung_gpiolib_get;
 925
 926#ifdef CONFIG_PM
 927        if (chip->pm != NULL) {
 928                if (!chip->pm->save || !chip->pm->resume)
 929                        printk(KERN_ERR "gpio: %s has missing PM functions\n",
 930                               gc->label);
 931        } else
 932                printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
 933#endif
 934
 935        /* gpiochip_add() prints own failure message on error. */
 936        ret = gpiochip_add(gc);
 937        if (ret >= 0)
 938                s3c_gpiolib_track(chip);
 939}
 940
 941static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
 942                                             int nr_chips, void __iomem *base)
 943{
 944        int i;
 945        struct gpio_chip *gc = &chip->chip;
 946
 947        for (i = 0 ; i < nr_chips; i++, chip++) {
 948                /* skip banks not present on SoC */
 949                if (chip->chip.base >= S3C_GPIO_END)
 950                        continue;
 951
 952                if (!chip->config)
 953                        chip->config = &s3c24xx_gpiocfg_default;
 954                if (!chip->pm)
 955                        chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
 956                if ((base != NULL) && (chip->base == NULL))
 957                        chip->base = base + ((i) * 0x10);
 958
 959                if (!gc->direction_input)
 960                        gc->direction_input = samsung_gpiolib_2bit_input;
 961                if (!gc->direction_output)
 962                        gc->direction_output = samsung_gpiolib_2bit_output;
 963
 964                samsung_gpiolib_add(chip);
 965        }
 966}
 967
 968static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
 969                                                  int nr_chips, void __iomem *base,
 970                                                  unsigned int offset)
 971{
 972        int i;
 973
 974        for (i = 0 ; i < nr_chips; i++, chip++) {
 975                chip->chip.direction_input = samsung_gpiolib_2bit_input;
 976                chip->chip.direction_output = samsung_gpiolib_2bit_output;
 977
 978                if (!chip->config)
 979                        chip->config = &samsung_gpio_cfgs[7];
 980                if (!chip->pm)
 981                        chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
 982                if ((base != NULL) && (chip->base == NULL))
 983                        chip->base = base + ((i) * offset);
 984
 985                samsung_gpiolib_add(chip);
 986        }
 987}
 988
 989/*
 990 * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
 991 * @chip: The gpio chip that is being configured.
 992 * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
 993 *
 994 * This helper deal with the GPIO cases where the control register has 4 bits
 995 * of control per GPIO, generally in the form of:
 996 * 0000 = Input
 997 * 0001 = Output
 998 * others = Special functions (dependent on bank)
 999 *
1000 * Note, since the code to deal with the case where there are two control
1001 * registers instead of one, we do not have a separate set of function
1002 * (samsung_gpiolib_add_4bit2_chips)for each case.
1003 */
1004
1005static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
1006                                                  int nr_chips, void __iomem *base)
1007{
1008        int i;
1009
1010        for (i = 0 ; i < nr_chips; i++, chip++) {
1011                chip->chip.direction_input = samsung_gpiolib_4bit_input;
1012                chip->chip.direction_output = samsung_gpiolib_4bit_output;
1013
1014                if (!chip->config)
1015                        chip->config = &samsung_gpio_cfgs[2];
1016                if (!chip->pm)
1017                        chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1018                if ((base != NULL) && (chip->base == NULL))
1019                        chip->base = base + ((i) * 0x20);
1020
1021                samsung_gpiolib_add(chip);
1022        }
1023}
1024
1025static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
1026                                                   int nr_chips)
1027{
1028        for (; nr_chips > 0; nr_chips--, chip++) {
1029                chip->chip.direction_input = samsung_gpiolib_4bit2_input;
1030                chip->chip.direction_output = samsung_gpiolib_4bit2_output;
1031
1032                if (!chip->config)
1033                        chip->config = &samsung_gpio_cfgs[2];
1034                if (!chip->pm)
1035                        chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1036
1037                samsung_gpiolib_add(chip);
1038        }
1039}
1040
1041static void __init s5p64x0_gpiolib_add_rbank(struct samsung_gpio_chip *chip,
1042                                             int nr_chips)
1043{
1044        for (; nr_chips > 0; nr_chips--, chip++) {
1045                chip->chip.direction_input = s5p64x0_gpiolib_rbank_input;
1046                chip->chip.direction_output = s5p64x0_gpiolib_rbank_output;
1047
1048                if (!chip->pm)
1049                        chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1050
1051                samsung_gpiolib_add(chip);
1052        }
1053}
1054
1055int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
1056{
1057        struct samsung_gpio_chip *samsung_chip = container_of(chip, struct samsung_gpio_chip, chip);
1058
1059        return samsung_chip->irq_base + offset;
1060}
1061
1062#ifdef CONFIG_PLAT_S3C24XX
1063static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
1064{
1065        if (offset < 4)
1066                return IRQ_EINT0 + offset;
1067
1068        if (offset < 8)
1069                return IRQ_EINT4 + offset - 4;
1070
1071        return -EINVAL;
1072}
1073#endif
1074
1075#ifdef CONFIG_PLAT_S3C64XX
1076static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
1077{
1078        return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
1079}
1080
1081static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
1082{
1083        return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
1084}
1085#endif
1086
1087struct samsung_gpio_chip s3c24xx_gpios[] = {
1088#ifdef CONFIG_PLAT_S3C24XX
1089        {
1090                .config = &s3c24xx_gpiocfg_banka,
1091                .chip   = {
1092                        .base                   = S3C2410_GPA(0),
1093                        .owner                  = THIS_MODULE,
1094                        .label                  = "GPIOA",
1095                        .ngpio                  = 24,
1096                        .direction_input        = s3c24xx_gpiolib_banka_input,
1097                        .direction_output       = s3c24xx_gpiolib_banka_output,
1098                },
1099        }, {
1100                .chip   = {
1101                        .base   = S3C2410_GPB(0),
1102                        .owner  = THIS_MODULE,
1103                        .label  = "GPIOB",
1104                        .ngpio  = 16,
1105                },
1106        }, {
1107                .chip   = {
1108                        .base   = S3C2410_GPC(0),
1109                        .owner  = THIS_MODULE,
1110                        .label  = "GPIOC",
1111                        .ngpio  = 16,
1112                },
1113        }, {
1114                .chip   = {
1115                        .base   = S3C2410_GPD(0),
1116                        .owner  = THIS_MODULE,
1117                        .label  = "GPIOD",
1118                        .ngpio  = 16,
1119                },
1120        }, {
1121                .chip   = {
1122                        .base   = S3C2410_GPE(0),
1123                        .label  = "GPIOE",
1124                        .owner  = THIS_MODULE,
1125                        .ngpio  = 16,
1126                },
1127        }, {
1128                .chip   = {
1129                        .base   = S3C2410_GPF(0),
1130                        .owner  = THIS_MODULE,
1131                        .label  = "GPIOF",
1132                        .ngpio  = 8,
1133                        .to_irq = s3c24xx_gpiolib_fbank_to_irq,
1134                },
1135        }, {
1136                .irq_base = IRQ_EINT8,
1137                .chip   = {
1138                        .base   = S3C2410_GPG(0),
1139                        .owner  = THIS_MODULE,
1140                        .label  = "GPIOG",
1141                        .ngpio  = 16,
1142                        .to_irq = samsung_gpiolib_to_irq,
1143                },
1144        }, {
1145                .chip   = {
1146                        .base   = S3C2410_GPH(0),
1147                        .owner  = THIS_MODULE,
1148                        .label  = "GPIOH",
1149                        .ngpio  = 11,
1150                },
1151        },
1152                /* GPIOS for the S3C2443 and later devices. */
1153        {
1154                .base   = S3C2440_GPJCON,
1155                .chip   = {
1156                        .base   = S3C2410_GPJ(0),
1157                        .owner  = THIS_MODULE,
1158                        .label  = "GPIOJ",
1159                        .ngpio  = 16,
1160                },
1161        }, {
1162                .base   = S3C2443_GPKCON,
1163                .chip   = {
1164                        .base   = S3C2410_GPK(0),
1165                        .owner  = THIS_MODULE,
1166                        .label  = "GPIOK",
1167                        .ngpio  = 16,
1168                },
1169        }, {
1170                .base   = S3C2443_GPLCON,
1171                .chip   = {
1172                        .base   = S3C2410_GPL(0),
1173                        .owner  = THIS_MODULE,
1174                        .label  = "GPIOL",
1175                        .ngpio  = 15,
1176                },
1177        }, {
1178                .base   = S3C2443_GPMCON,
1179                .chip   = {
1180                        .base   = S3C2410_GPM(0),
1181                        .owner  = THIS_MODULE,
1182                        .label  = "GPIOM",
1183                        .ngpio  = 2,
1184                },
1185        },
1186#endif
1187};
1188
1189/*
1190 * GPIO bank summary:
1191 *
1192 * Bank GPIOs   Style   SlpCon  ExtInt Group
1193 * A    8       4Bit    Yes     1
1194 * B    7       4Bit    Yes     1
1195 * C    8       4Bit    Yes     2
1196 * D    5       4Bit    Yes     3
1197 * E    5       4Bit    Yes     None
1198 * F    16      2Bit    Yes     4 [1]
1199 * G    7       4Bit    Yes     5
1200 * H    10      4Bit[2] Yes     6
1201 * I    16      2Bit    Yes     None
1202 * J    12      2Bit    Yes     None
1203 * K    16      4Bit[2] No      None
1204 * L    15      4Bit[2] No      None
1205 * M    6       4Bit    No      IRQ_EINT
1206 * N    16      2Bit    No      IRQ_EINT
1207 * O    16      2Bit    Yes     7
1208 * P    15      2Bit    Yes     8
1209 * Q    9       2Bit    Yes     9
1210 *
1211 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
1212 * [2] BANK has two control registers, GPxCON0 and GPxCON1
1213 */
1214
1215static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
1216#ifdef CONFIG_PLAT_S3C64XX
1217        {
1218                .chip   = {
1219                        .base   = S3C64XX_GPA(0),
1220                        .ngpio  = S3C64XX_GPIO_A_NR,
1221                        .label  = "GPA",
1222                },
1223        }, {
1224                .chip   = {
1225                        .base   = S3C64XX_GPB(0),
1226                        .ngpio  = S3C64XX_GPIO_B_NR,
1227                        .label  = "GPB",
1228                },
1229        }, {
1230                .chip   = {
1231                        .base   = S3C64XX_GPC(0),
1232                        .ngpio  = S3C64XX_GPIO_C_NR,
1233                        .label  = "GPC",
1234                },
1235        }, {
1236                .chip   = {
1237                        .base   = S3C64XX_GPD(0),
1238                        .ngpio  = S3C64XX_GPIO_D_NR,
1239                        .label  = "GPD",
1240                },
1241        }, {
1242                .config = &samsung_gpio_cfgs[0],
1243                .chip   = {
1244                        .base   = S3C64XX_GPE(0),
1245                        .ngpio  = S3C64XX_GPIO_E_NR,
1246                        .label  = "GPE",
1247                },
1248        }, {
1249                .base   = S3C64XX_GPG_BASE,
1250                .chip   = {
1251                        .base   = S3C64XX_GPG(0),
1252                        .ngpio  = S3C64XX_GPIO_G_NR,
1253                        .label  = "GPG",
1254                },
1255        }, {
1256                .base   = S3C64XX_GPM_BASE,
1257                .config = &samsung_gpio_cfgs[1],
1258                .chip   = {
1259                        .base   = S3C64XX_GPM(0),
1260                        .ngpio  = S3C64XX_GPIO_M_NR,
1261                        .label  = "GPM",
1262                        .to_irq = s3c64xx_gpiolib_mbank_to_irq,
1263                },
1264        },
1265#endif
1266};
1267
1268static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
1269#ifdef CONFIG_PLAT_S3C64XX
1270        {
1271                .base   = S3C64XX_GPH_BASE + 0x4,
1272                .chip   = {
1273                        .base   = S3C64XX_GPH(0),
1274                        .ngpio  = S3C64XX_GPIO_H_NR,
1275                        .label  = "GPH",
1276                },
1277        }, {
1278                .base   = S3C64XX_GPK_BASE + 0x4,
1279                .config = &samsung_gpio_cfgs[0],
1280                .chip   = {
1281                        .base   = S3C64XX_GPK(0),
1282                        .ngpio  = S3C64XX_GPIO_K_NR,
1283                        .label  = "GPK",
1284                },
1285        }, {
1286                .base   = S3C64XX_GPL_BASE + 0x4,
1287                .config = &samsung_gpio_cfgs[1],
1288                .chip   = {
1289                        .base   = S3C64XX_GPL(0),
1290                        .ngpio  = S3C64XX_GPIO_L_NR,
1291                        .label  = "GPL",
1292                        .to_irq = s3c64xx_gpiolib_lbank_to_irq,
1293                },
1294        },
1295#endif
1296};
1297
1298static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
1299#ifdef CONFIG_PLAT_S3C64XX
1300        {
1301                .base   = S3C64XX_GPF_BASE,
1302                .config = &samsung_gpio_cfgs[6],
1303                .chip   = {
1304                        .base   = S3C64XX_GPF(0),
1305                        .ngpio  = S3C64XX_GPIO_F_NR,
1306                        .label  = "GPF",
1307                },
1308        }, {
1309                .config = &samsung_gpio_cfgs[7],
1310                .chip   = {
1311                        .base   = S3C64XX_GPI(0),
1312                        .ngpio  = S3C64XX_GPIO_I_NR,
1313                        .label  = "GPI",
1314                },
1315        }, {
1316                .config = &samsung_gpio_cfgs[7],
1317                .chip   = {
1318                        .base   = S3C64XX_GPJ(0),
1319                        .ngpio  = S3C64XX_GPIO_J_NR,
1320                        .label  = "GPJ",
1321                },
1322        }, {
1323                .config = &samsung_gpio_cfgs[6],
1324                .chip   = {
1325                        .base   = S3C64XX_GPO(0),
1326                        .ngpio  = S3C64XX_GPIO_O_NR,
1327                        .label  = "GPO",
1328                },
1329        }, {
1330                .config = &samsung_gpio_cfgs[6],
1331                .chip   = {
1332                        .base   = S3C64XX_GPP(0),
1333                        .ngpio  = S3C64XX_GPIO_P_NR,
1334                        .label  = "GPP",
1335                },
1336        }, {
1337                .config = &samsung_gpio_cfgs[6],
1338                .chip   = {
1339                        .base   = S3C64XX_GPQ(0),
1340                        .ngpio  = S3C64XX_GPIO_Q_NR,
1341                        .label  = "GPQ",
1342                },
1343        }, {
1344                .base   = S3C64XX_GPN_BASE,
1345                .irq_base = IRQ_EINT(0),
1346                .config = &samsung_gpio_cfgs[5],
1347                .chip   = {
1348                        .base   = S3C64XX_GPN(0),
1349                        .ngpio  = S3C64XX_GPIO_N_NR,
1350                        .label  = "GPN",
1351                        .to_irq = samsung_gpiolib_to_irq,
1352                },
1353        },
1354#endif
1355};
1356
1357/*
1358 * S5P6440 GPIO bank summary:
1359 *
1360 * Bank GPIOs   Style   SlpCon  ExtInt Group
1361 * A    6       4Bit    Yes     1
1362 * B    7       4Bit    Yes     1
1363 * C    8       4Bit    Yes     2
1364 * F    2       2Bit    Yes     4 [1]
1365 * G    7       4Bit    Yes     5
1366 * H    10      4Bit[2] Yes     6
1367 * I    16      2Bit    Yes     None
1368 * J    12      2Bit    Yes     None
1369 * N    16      2Bit    No      IRQ_EINT
1370 * P    8       2Bit    Yes     8
1371 * R    15      4Bit[2] Yes     8
1372 */
1373
1374static struct samsung_gpio_chip s5p6440_gpios_4bit[] = {
1375#ifdef CONFIG_CPU_S5P6440
1376        {
1377                .chip   = {
1378                        .base   = S5P6440_GPA(0),
1379                        .ngpio  = S5P6440_GPIO_A_NR,
1380                        .label  = "GPA",
1381                },
1382        }, {
1383                .chip   = {
1384                        .base   = S5P6440_GPB(0),
1385                        .ngpio  = S5P6440_GPIO_B_NR,
1386                        .label  = "GPB",
1387                },
1388        }, {
1389                .chip   = {
1390                        .base   = S5P6440_GPC(0),
1391                        .ngpio  = S5P6440_GPIO_C_NR,
1392                        .label  = "GPC",
1393                },
1394        }, {
1395                .base   = S5P64X0_GPG_BASE,
1396                .chip   = {
1397                        .base   = S5P6440_GPG(0),
1398                        .ngpio  = S5P6440_GPIO_G_NR,
1399                        .label  = "GPG",
1400                },
1401        },
1402#endif
1403};
1404
1405static struct samsung_gpio_chip s5p6440_gpios_4bit2[] = {
1406#ifdef CONFIG_CPU_S5P6440
1407        {
1408                .base   = S5P64X0_GPH_BASE + 0x4,
1409                .chip   = {
1410                        .base   = S5P6440_GPH(0),
1411                        .ngpio  = S5P6440_GPIO_H_NR,
1412                        .label  = "GPH",
1413                },
1414        },
1415#endif
1416};
1417
1418static struct samsung_gpio_chip s5p6440_gpios_rbank[] = {
1419#ifdef CONFIG_CPU_S5P6440
1420        {
1421                .base   = S5P64X0_GPR_BASE + 0x4,
1422                .config = &s5p64x0_gpio_cfg_rbank,
1423                .chip   = {
1424                        .base   = S5P6440_GPR(0),
1425                        .ngpio  = S5P6440_GPIO_R_NR,
1426                        .label  = "GPR",
1427                },
1428        },
1429#endif
1430};
1431
1432static struct samsung_gpio_chip s5p6440_gpios_2bit[] = {
1433#ifdef CONFIG_CPU_S5P6440
1434        {
1435                .base   = S5P64X0_GPF_BASE,
1436                .config = &samsung_gpio_cfgs[6],
1437                .chip   = {
1438                        .base   = S5P6440_GPF(0),
1439                        .ngpio  = S5P6440_GPIO_F_NR,
1440                        .label  = "GPF",
1441                },
1442        }, {
1443                .base   = S5P64X0_GPI_BASE,
1444                .config = &samsung_gpio_cfgs[4],
1445                .chip   = {
1446                        .base   = S5P6440_GPI(0),
1447                        .ngpio  = S5P6440_GPIO_I_NR,
1448                        .label  = "GPI",
1449                },
1450        }, {
1451                .base   = S5P64X0_GPJ_BASE,
1452                .config = &samsung_gpio_cfgs[4],
1453                .chip   = {
1454                        .base   = S5P6440_GPJ(0),
1455                        .ngpio  = S5P6440_GPIO_J_NR,
1456                        .label  = "GPJ",
1457                },
1458        }, {
1459                .base   = S5P64X0_GPN_BASE,
1460                .config = &samsung_gpio_cfgs[5],
1461                .chip   = {
1462                        .base   = S5P6440_GPN(0),
1463                        .ngpio  = S5P6440_GPIO_N_NR,
1464                        .label  = "GPN",
1465                },
1466        }, {
1467                .base   = S5P64X0_GPP_BASE,
1468                .config = &samsung_gpio_cfgs[6],
1469                .chip   = {
1470                        .base   = S5P6440_GPP(0),
1471                        .ngpio  = S5P6440_GPIO_P_NR,
1472                        .label  = "GPP",
1473                },
1474        },
1475#endif
1476};
1477
1478/*
1479 * S5P6450 GPIO bank summary:
1480 *
1481 * Bank GPIOs   Style   SlpCon  ExtInt Group
1482 * A    6       4Bit    Yes     1
1483 * B    7       4Bit    Yes     1
1484 * C    8       4Bit    Yes     2
1485 * D    8       4Bit    Yes     None
1486 * F    2       2Bit    Yes     None
1487 * G    14      4Bit[2] Yes     5
1488 * H    10      4Bit[2] Yes     6
1489 * I    16      2Bit    Yes     None
1490 * J    12      2Bit    Yes     None
1491 * K    5       4Bit    Yes     None
1492 * N    16      2Bit    No      IRQ_EINT
1493 * P    11      2Bit    Yes     8
1494 * Q    14      2Bit    Yes     None
1495 * R    15      4Bit[2] Yes     None
1496 * S    8       2Bit    Yes     None
1497 *
1498 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
1499 * [2] BANK has two control registers, GPxCON0 and GPxCON1
1500 */
1501
1502static struct samsung_gpio_chip s5p6450_gpios_4bit[] = {
1503#ifdef CONFIG_CPU_S5P6450
1504        {
1505                .chip   = {
1506                        .base   = S5P6450_GPA(0),
1507                        .ngpio  = S5P6450_GPIO_A_NR,
1508                        .label  = "GPA",
1509                },
1510        }, {
1511                .chip   = {
1512                        .base   = S5P6450_GPB(0),
1513                        .ngpio  = S5P6450_GPIO_B_NR,
1514                        .label  = "GPB",
1515                },
1516        }, {
1517                .chip   = {
1518                        .base   = S5P6450_GPC(0),
1519                        .ngpio  = S5P6450_GPIO_C_NR,
1520                        .label  = "GPC",
1521                },
1522        }, {
1523                .chip   = {
1524                        .base   = S5P6450_GPD(0),
1525                        .ngpio  = S5P6450_GPIO_D_NR,
1526                        .label  = "GPD",
1527                },
1528        }, {
1529                .base   = S5P6450_GPK_BASE,
1530                .chip   = {
1531                        .base   = S5P6450_GPK(0),
1532                        .ngpio  = S5P6450_GPIO_K_NR,
1533                        .label  = "GPK",
1534                },
1535        },
1536#endif
1537};
1538
1539static struct samsung_gpio_chip s5p6450_gpios_4bit2[] = {
1540#ifdef CONFIG_CPU_S5P6450
1541        {
1542                .base   = S5P64X0_GPG_BASE + 0x4,
1543                .chip   = {
1544                        .base   = S5P6450_GPG(0),
1545                        .ngpio  = S5P6450_GPIO_G_NR,
1546                        .label  = "GPG",
1547                },
1548        }, {
1549                .base   = S5P64X0_GPH_BASE + 0x4,
1550                .chip   = {
1551                        .base   = S5P6450_GPH(0),
1552                        .ngpio  = S5P6450_GPIO_H_NR,
1553                        .label  = "GPH",
1554                },
1555        },
1556#endif
1557};
1558
1559static struct samsung_gpio_chip s5p6450_gpios_rbank[] = {
1560#ifdef CONFIG_CPU_S5P6450
1561        {
1562                .base   = S5P64X0_GPR_BASE + 0x4,
1563                .config = &s5p64x0_gpio_cfg_rbank,
1564                .chip   = {
1565                        .base   = S5P6450_GPR(0),
1566                        .ngpio  = S5P6450_GPIO_R_NR,
1567                        .label  = "GPR",
1568                },
1569        },
1570#endif
1571};
1572
1573static struct samsung_gpio_chip s5p6450_gpios_2bit[] = {
1574#ifdef CONFIG_CPU_S5P6450
1575        {
1576                .base   = S5P64X0_GPF_BASE,
1577                .config = &samsung_gpio_cfgs[6],
1578                .chip   = {
1579                        .base   = S5P6450_GPF(0),
1580                        .ngpio  = S5P6450_GPIO_F_NR,
1581                        .label  = "GPF",
1582                },
1583        }, {
1584                .base   = S5P64X0_GPI_BASE,
1585                .config = &samsung_gpio_cfgs[4],
1586                .chip   = {
1587                        .base   = S5P6450_GPI(0),
1588                        .ngpio  = S5P6450_GPIO_I_NR,
1589                        .label  = "GPI",
1590                },
1591        }, {
1592                .base   = S5P64X0_GPJ_BASE,
1593                .config = &samsung_gpio_cfgs[4],
1594                .chip   = {
1595                        .base   = S5P6450_GPJ(0),
1596                        .ngpio  = S5P6450_GPIO_J_NR,
1597                        .label  = "GPJ",
1598                },
1599        }, {
1600                .base   = S5P64X0_GPN_BASE,
1601                .config = &samsung_gpio_cfgs[5],
1602                .chip   = {
1603                        .base   = S5P6450_GPN(0),
1604                        .ngpio  = S5P6450_GPIO_N_NR,
1605                        .label  = "GPN",
1606                },
1607        }, {
1608                .base   = S5P64X0_GPP_BASE,
1609                .config = &samsung_gpio_cfgs[6],
1610                .chip   = {
1611                        .base   = S5P6450_GPP(0),
1612                        .ngpio  = S5P6450_GPIO_P_NR,
1613                        .label  = "GPP",
1614                },
1615        }, {
1616                .base   = S5P6450_GPQ_BASE,
1617                .config = &samsung_gpio_cfgs[5],
1618                .chip   = {
1619                        .base   = S5P6450_GPQ(0),
1620                        .ngpio  = S5P6450_GPIO_Q_NR,
1621                        .label  = "GPQ",
1622                },
1623        }, {
1624                .base   = S5P6450_GPS_BASE,
1625                .config = &samsung_gpio_cfgs[6],
1626                .chip   = {
1627                        .base   = S5P6450_GPS(0),
1628                        .ngpio  = S5P6450_GPIO_S_NR,
1629                        .label  = "GPS",
1630                },
1631        },
1632#endif
1633};
1634
1635/*
1636 * S5PC100 GPIO bank summary:
1637 *
1638 * Bank GPIOs   Style   INT Type
1639 * A0   8       4Bit    GPIO_INT0
1640 * A1   5       4Bit    GPIO_INT1
1641 * B    8       4Bit    GPIO_INT2
1642 * C    5       4Bit    GPIO_INT3
1643 * D    7       4Bit    GPIO_INT4
1644 * E0   8       4Bit    GPIO_INT5
1645 * E1   6       4Bit    GPIO_INT6
1646 * F0   8       4Bit    GPIO_INT7
1647 * F1   8       4Bit    GPIO_INT8
1648 * F2   8       4Bit    GPIO_INT9
1649 * F3   4       4Bit    GPIO_INT10
1650 * G0   8       4Bit    GPIO_INT11
1651 * G1   3       4Bit    GPIO_INT12
1652 * G2   7       4Bit    GPIO_INT13
1653 * G3   7       4Bit    GPIO_INT14
1654 * H0   8       4Bit    WKUP_INT
1655 * H1   8       4Bit    WKUP_INT
1656 * H2   8       4Bit    WKUP_INT
1657 * H3   8       4Bit    WKUP_INT
1658 * I    8       4Bit    GPIO_INT15
1659 * J0   8       4Bit    GPIO_INT16
1660 * J1   5       4Bit    GPIO_INT17
1661 * J2   8       4Bit    GPIO_INT18
1662 * J3   8       4Bit    GPIO_INT19
1663 * J4   4       4Bit    GPIO_INT20
1664 * K0   8       4Bit    None
1665 * K1   6       4Bit    None
1666 * K2   8       4Bit    None
1667 * K3   8       4Bit    None
1668 * L0   8       4Bit    None
1669 * L1   8       4Bit    None
1670 * L2   8       4Bit    None
1671 * L3   8       4Bit    None
1672 */
1673
1674static struct samsung_gpio_chip s5pc100_gpios_4bit[] = {
1675#ifdef CONFIG_CPU_S5PC100
1676        {
1677                .chip   = {
1678                        .base   = S5PC100_GPA0(0),
1679                        .ngpio  = S5PC100_GPIO_A0_NR,
1680                        .label  = "GPA0",
1681                },
1682        }, {
1683                .chip   = {
1684                        .base   = S5PC100_GPA1(0),
1685                        .ngpio  = S5PC100_GPIO_A1_NR,
1686                        .label  = "GPA1",
1687                },
1688        }, {
1689                .chip   = {
1690                        .base   = S5PC100_GPB(0),
1691                        .ngpio  = S5PC100_GPIO_B_NR,
1692                        .label  = "GPB",
1693                },
1694        }, {
1695                .chip   = {
1696                        .base   = S5PC100_GPC(0),
1697                        .ngpio  = S5PC100_GPIO_C_NR,
1698                        .label  = "GPC",
1699                },
1700        }, {
1701                .chip   = {
1702                        .base   = S5PC100_GPD(0),
1703                        .ngpio  = S5PC100_GPIO_D_NR,
1704                        .label  = "GPD",
1705                },
1706        }, {
1707                .chip   = {
1708                        .base   = S5PC100_GPE0(0),
1709                        .ngpio  = S5PC100_GPIO_E0_NR,
1710                        .label  = "GPE0",
1711                },
1712        }, {
1713                .chip   = {
1714                        .base   = S5PC100_GPE1(0),
1715                        .ngpio  = S5PC100_GPIO_E1_NR,
1716                        .label  = "GPE1",
1717                },
1718        }, {
1719                .chip   = {
1720                        .base   = S5PC100_GPF0(0),
1721                        .ngpio  = S5PC100_GPIO_F0_NR,
1722                        .label  = "GPF0",
1723                },
1724        }, {
1725                .chip   = {
1726                        .base   = S5PC100_GPF1(0),
1727                        .ngpio  = S5PC100_GPIO_F1_NR,
1728                        .label  = "GPF1",
1729                },
1730        }, {
1731                .chip   = {
1732                        .base   = S5PC100_GPF2(0),
1733                        .ngpio  = S5PC100_GPIO_F2_NR,
1734                        .label  = "GPF2",
1735                },
1736        }, {
1737                .chip   = {
1738                        .base   = S5PC100_GPF3(0),
1739                        .ngpio  = S5PC100_GPIO_F3_NR,
1740                        .label  = "GPF3",
1741                },
1742        }, {
1743                .chip   = {
1744                        .base   = S5PC100_GPG0(0),
1745                        .ngpio  = S5PC100_GPIO_G0_NR,
1746                        .label  = "GPG0",
1747                },
1748        }, {
1749                .chip   = {
1750                        .base   = S5PC100_GPG1(0),
1751                        .ngpio  = S5PC100_GPIO_G1_NR,
1752                        .label  = "GPG1",
1753                },
1754        }, {
1755                .chip   = {
1756                        .base   = S5PC100_GPG2(0),
1757                        .ngpio  = S5PC100_GPIO_G2_NR,
1758                        .label  = "GPG2",
1759                },
1760        }, {
1761                .chip   = {
1762                        .base   = S5PC100_GPG3(0),
1763                        .ngpio  = S5PC100_GPIO_G3_NR,
1764                        .label  = "GPG3",
1765                },
1766        }, {
1767                .chip   = {
1768                        .base   = S5PC100_GPI(0),
1769                        .ngpio  = S5PC100_GPIO_I_NR,
1770                        .label  = "GPI",
1771                },
1772        }, {
1773                .chip   = {
1774                        .base   = S5PC100_GPJ0(0),
1775                        .ngpio  = S5PC100_GPIO_J0_NR,
1776                        .label  = "GPJ0",
1777                },
1778        }, {
1779                .chip   = {
1780                        .base   = S5PC100_GPJ1(0),
1781                        .ngpio  = S5PC100_GPIO_J1_NR,
1782                        .label  = "GPJ1",
1783                },
1784        }, {
1785                .chip   = {
1786                        .base   = S5PC100_GPJ2(0),
1787                        .ngpio  = S5PC100_GPIO_J2_NR,
1788                        .label  = "GPJ2",
1789                },
1790        }, {
1791                .chip   = {
1792                        .base   = S5PC100_GPJ3(0),
1793                        .ngpio  = S5PC100_GPIO_J3_NR,
1794                        .label  = "GPJ3",
1795                },
1796        }, {
1797                .chip   = {
1798                        .base   = S5PC100_GPJ4(0),
1799                        .ngpio  = S5PC100_GPIO_J4_NR,
1800                        .label  = "GPJ4",
1801                },
1802        }, {
1803                .chip   = {
1804                        .base   = S5PC100_GPK0(0),
1805                        .ngpio  = S5PC100_GPIO_K0_NR,
1806                        .label  = "GPK0",
1807                },
1808        }, {
1809                .chip   = {
1810                        .base   = S5PC100_GPK1(0),
1811                        .ngpio  = S5PC100_GPIO_K1_NR,
1812                        .label  = "GPK1",
1813                },
1814        }, {
1815                .chip   = {
1816                        .base   = S5PC100_GPK2(0),
1817                        .ngpio  = S5PC100_GPIO_K2_NR,
1818                        .label  = "GPK2",
1819                },
1820        }, {
1821                .chip   = {
1822                        .base   = S5PC100_GPK3(0),
1823                        .ngpio  = S5PC100_GPIO_K3_NR,
1824                        .label  = "GPK3",
1825                },
1826        }, {
1827                .chip   = {
1828                        .base   = S5PC100_GPL0(0),
1829                        .ngpio  = S5PC100_GPIO_L0_NR,
1830                        .label  = "GPL0",
1831                },
1832        }, {
1833                .chip   = {
1834                        .base   = S5PC100_GPL1(0),
1835                        .ngpio  = S5PC100_GPIO_L1_NR,
1836                        .label  = "GPL1",
1837                },
1838        }, {
1839                .chip   = {
1840                        .base   = S5PC100_GPL2(0),
1841                        .ngpio  = S5PC100_GPIO_L2_NR,
1842                        .label  = "GPL2",
1843                },
1844        }, {
1845                .chip   = {
1846                        .base   = S5PC100_GPL3(0),
1847                        .ngpio  = S5PC100_GPIO_L3_NR,
1848                        .label  = "GPL3",
1849                },
1850        }, {
1851                .chip   = {
1852                        .base   = S5PC100_GPL4(0),
1853                        .ngpio  = S5PC100_GPIO_L4_NR,
1854                        .label  = "GPL4",
1855                },
1856        }, {
1857                .base   = (S5P_VA_GPIO + 0xC00),
1858                .irq_base = IRQ_EINT(0),
1859                .chip   = {
1860                        .base   = S5PC100_GPH0(0),
1861                        .ngpio  = S5PC100_GPIO_H0_NR,
1862                        .label  = "GPH0",
1863                        .to_irq = samsung_gpiolib_to_irq,
1864                },
1865        }, {
1866                .base   = (S5P_VA_GPIO + 0xC20),
1867                .irq_base = IRQ_EINT(8),
1868                .chip   = {
1869                        .base   = S5PC100_GPH1(0),
1870                        .ngpio  = S5PC100_GPIO_H1_NR,
1871                        .label  = "GPH1",
1872                        .to_irq = samsung_gpiolib_to_irq,
1873                },
1874        }, {
1875                .base   = (S5P_VA_GPIO + 0xC40),
1876                .irq_base = IRQ_EINT(16),
1877                .chip   = {
1878                        .base   = S5PC100_GPH2(0),
1879                        .ngpio  = S5PC100_GPIO_H2_NR,
1880                        .label  = "GPH2",
1881                        .to_irq = samsung_gpiolib_to_irq,
1882                },
1883        }, {
1884                .base   = (S5P_VA_GPIO + 0xC60),
1885                .irq_base = IRQ_EINT(24),
1886                .chip   = {
1887                        .base   = S5PC100_GPH3(0),
1888                        .ngpio  = S5PC100_GPIO_H3_NR,
1889                        .label  = "GPH3",
1890                        .to_irq = samsung_gpiolib_to_irq,
1891                },
1892        },
1893#endif
1894};
1895
1896/*
1897 * Followings are the gpio banks in S5PV210/S5PC110
1898 *
1899 * The 'config' member when left to NULL, is initialized to the default
1900 * structure samsung_gpio_cfgs[3] in the init function below.
1901 *
1902 * The 'base' member is also initialized in the init function below.
1903 * Note: The initialization of 'base' member of samsung_gpio_chip structure
1904 * uses the above macro and depends on the banks being listed in order here.
1905 */
1906
1907static struct samsung_gpio_chip s5pv210_gpios_4bit[] = {
1908#ifdef CONFIG_CPU_S5PV210
1909        {
1910                .chip   = {
1911                        .base   = S5PV210_GPA0(0),
1912                        .ngpio  = S5PV210_GPIO_A0_NR,
1913                        .label  = "GPA0",
1914                },
1915        }, {
1916                .chip   = {
1917                        .base   = S5PV210_GPA1(0),
1918                        .ngpio  = S5PV210_GPIO_A1_NR,
1919                        .label  = "GPA1",
1920                },
1921        }, {
1922                .chip   = {
1923                        .base   = S5PV210_GPB(0),
1924                        .ngpio  = S5PV210_GPIO_B_NR,
1925                        .label  = "GPB",
1926                },
1927        }, {
1928                .chip   = {
1929                        .base   = S5PV210_GPC0(0),
1930                        .ngpio  = S5PV210_GPIO_C0_NR,
1931                        .label  = "GPC0",
1932                },
1933        }, {
1934                .chip   = {
1935                        .base   = S5PV210_GPC1(0),
1936                        .ngpio  = S5PV210_GPIO_C1_NR,
1937                        .label  = "GPC1",
1938                },
1939        }, {
1940                .chip   = {
1941                        .base   = S5PV210_GPD0(0),
1942                        .ngpio  = S5PV210_GPIO_D0_NR,
1943                        .label  = "GPD0",
1944                },
1945        }, {
1946                .chip   = {
1947                        .base   = S5PV210_GPD1(0),
1948                        .ngpio  = S5PV210_GPIO_D1_NR,
1949                        .label  = "GPD1",
1950                },
1951        }, {
1952                .chip   = {
1953                        .base   = S5PV210_GPE0(0),
1954                        .ngpio  = S5PV210_GPIO_E0_NR,
1955                        .label  = "GPE0",
1956                },
1957        }, {
1958                .chip   = {
1959                        .base   = S5PV210_GPE1(0),
1960                        .ngpio  = S5PV210_GPIO_E1_NR,
1961                        .label  = "GPE1",
1962                },
1963        }, {
1964                .chip   = {
1965                        .base   = S5PV210_GPF0(0),
1966                        .ngpio  = S5PV210_GPIO_F0_NR,
1967                        .label  = "GPF0",
1968                },
1969        }, {
1970                .chip   = {
1971                        .base   = S5PV210_GPF1(0),
1972                        .ngpio  = S5PV210_GPIO_F1_NR,
1973                        .label  = "GPF1",
1974                },
1975        }, {
1976                .chip   = {
1977                        .base   = S5PV210_GPF2(0),
1978                        .ngpio  = S5PV210_GPIO_F2_NR,
1979                        .label  = "GPF2",
1980                },
1981        }, {
1982                .chip   = {
1983                        .base   = S5PV210_GPF3(0),
1984                        .ngpio  = S5PV210_GPIO_F3_NR,
1985                        .label  = "GPF3",
1986                },
1987        }, {
1988                .chip   = {
1989                        .base   = S5PV210_GPG0(0),
1990                        .ngpio  = S5PV210_GPIO_G0_NR,
1991                        .label  = "GPG0",
1992                },
1993        }, {
1994                .chip   = {
1995                        .base   = S5PV210_GPG1(0),
1996                        .ngpio  = S5PV210_GPIO_G1_NR,
1997                        .label  = "GPG1",
1998                },
1999        }, {
2000                .chip   = {
2001                        .base   = S5PV210_GPG2(0),
2002                        .ngpio  = S5PV210_GPIO_G2_NR,
2003                        .label  = "GPG2",
2004                },
2005        }, {
2006                .chip   = {
2007                        .base   = S5PV210_GPG3(0),
2008                        .ngpio  = S5PV210_GPIO_G3_NR,
2009                        .label  = "GPG3",
2010                },
2011        }, {
2012                .chip   = {
2013                        .base   = S5PV210_GPI(0),
2014                        .ngpio  = S5PV210_GPIO_I_NR,
2015                        .label  = "GPI",
2016                },
2017        }, {
2018                .chip   = {
2019                        .base   = S5PV210_GPJ0(0),
2020                        .ngpio  = S5PV210_GPIO_J0_NR,
2021                        .label  = "GPJ0",
2022                },
2023        }, {
2024                .chip   = {
2025                        .base   = S5PV210_GPJ1(0),
2026                        .ngpio  = S5PV210_GPIO_J1_NR,
2027                        .label  = "GPJ1",
2028                },
2029        }, {
2030                .chip   = {
2031                        .base   = S5PV210_GPJ2(0),
2032                        .ngpio  = S5PV210_GPIO_J2_NR,
2033                        .label  = "GPJ2",
2034                },
2035        }, {
2036                .chip   = {
2037                        .base   = S5PV210_GPJ3(0),
2038                        .ngpio  = S5PV210_GPIO_J3_NR,
2039                        .label  = "GPJ3",
2040                },
2041        }, {
2042                .chip   = {
2043                        .base   = S5PV210_GPJ4(0),
2044                        .ngpio  = S5PV210_GPIO_J4_NR,
2045                        .label  = "GPJ4",
2046                },
2047        }, {
2048                .chip   = {
2049                        .base   = S5PV210_MP01(0),
2050                        .ngpio  = S5PV210_GPIO_MP01_NR,
2051                        .label  = "MP01",
2052                },
2053        }, {
2054                .chip   = {
2055                        .base   = S5PV210_MP02(0),
2056                        .ngpio  = S5PV210_GPIO_MP02_NR,
2057                        .label  = "MP02",
2058                },
2059        }, {
2060                .chip   = {
2061                        .base   = S5PV210_MP03(0),
2062                        .ngpio  = S5PV210_GPIO_MP03_NR,
2063                        .label  = "MP03",
2064                },
2065        }, {
2066                .chip   = {
2067                        .base   = S5PV210_MP04(0),
2068                        .ngpio  = S5PV210_GPIO_MP04_NR,
2069                        .label  = "MP04",
2070                },
2071        }, {
2072                .chip   = {
2073                        .base   = S5PV210_MP05(0),
2074                        .ngpio  = S5PV210_GPIO_MP05_NR,
2075                        .label  = "MP05",
2076                },
2077        }, {
2078                .base   = (S5P_VA_GPIO + 0xC00),
2079                .irq_base = IRQ_EINT(0),
2080                .chip   = {
2081                        .base   = S5PV210_GPH0(0),
2082                        .ngpio  = S5PV210_GPIO_H0_NR,
2083                        .label  = "GPH0",
2084                        .to_irq = samsung_gpiolib_to_irq,
2085                },
2086        }, {
2087                .base   = (S5P_VA_GPIO + 0xC20),
2088                .irq_base = IRQ_EINT(8),
2089                .chip   = {
2090                        .base   = S5PV210_GPH1(0),
2091                        .ngpio  = S5PV210_GPIO_H1_NR,
2092                        .label  = "GPH1",
2093                        .to_irq = samsung_gpiolib_to_irq,
2094                },
2095        }, {
2096                .base   = (S5P_VA_GPIO + 0xC40),
2097                .irq_base = IRQ_EINT(16),
2098                .chip   = {
2099                        .base   = S5PV210_GPH2(0),
2100                        .ngpio  = S5PV210_GPIO_H2_NR,
2101                        .label  = "GPH2",
2102                        .to_irq = samsung_gpiolib_to_irq,
2103                },
2104        }, {
2105                .base   = (S5P_VA_GPIO + 0xC60),
2106                .irq_base = IRQ_EINT(24),
2107                .chip   = {
2108                        .base   = S5PV210_GPH3(0),
2109                        .ngpio  = S5PV210_GPIO_H3_NR,
2110                        .label  = "GPH3",
2111                        .to_irq = samsung_gpiolib_to_irq,
2112                },
2113        },
2114#endif
2115};
2116
2117/*
2118 * Followings are the gpio banks in EXYNOS SoCs
2119 *
2120 * The 'config' member when left to NULL, is initialized to the default
2121 * structure exynos_gpio_cfg in the init function below.
2122 *
2123 * The 'base' member is also initialized in the init function below.
2124 * Note: The initialization of 'base' member of samsung_gpio_chip structure
2125 * uses the above macro and depends on the banks being listed in order here.
2126 */
2127
2128#ifdef CONFIG_ARCH_EXYNOS4
2129static struct samsung_gpio_chip exynos4_gpios_1[] = {
2130        {
2131                .chip   = {
2132                        .base   = EXYNOS4_GPA0(0),
2133                        .ngpio  = EXYNOS4_GPIO_A0_NR,
2134                        .label  = "GPA0",
2135                },
2136        }, {
2137                .chip   = {
2138                        .base   = EXYNOS4_GPA1(0),
2139                        .ngpio  = EXYNOS4_GPIO_A1_NR,
2140                        .label  = "GPA1",
2141                },
2142        }, {
2143                .chip   = {
2144                        .base   = EXYNOS4_GPB(0),
2145                        .ngpio  = EXYNOS4_GPIO_B_NR,
2146                        .label  = "GPB",
2147                },
2148        }, {
2149                .chip   = {
2150                        .base   = EXYNOS4_GPC0(0),
2151                        .ngpio  = EXYNOS4_GPIO_C0_NR,
2152                        .label  = "GPC0",
2153                },
2154        }, {
2155                .chip   = {
2156                        .base   = EXYNOS4_GPC1(0),
2157                        .ngpio  = EXYNOS4_GPIO_C1_NR,
2158                        .label  = "GPC1",
2159                },
2160        }, {
2161                .chip   = {
2162                        .base   = EXYNOS4_GPD0(0),
2163                        .ngpio  = EXYNOS4_GPIO_D0_NR,
2164                        .label  = "GPD0",
2165                },
2166        }, {
2167                .chip   = {
2168                        .base   = EXYNOS4_GPD1(0),
2169                        .ngpio  = EXYNOS4_GPIO_D1_NR,
2170                        .label  = "GPD1",
2171                },
2172        }, {
2173                .chip   = {
2174                        .base   = EXYNOS4_GPE0(0),
2175                        .ngpio  = EXYNOS4_GPIO_E0_NR,
2176                        .label  = "GPE0",
2177                },
2178        }, {
2179                .chip   = {
2180                        .base   = EXYNOS4_GPE1(0),
2181                        .ngpio  = EXYNOS4_GPIO_E1_NR,
2182                        .label  = "GPE1",
2183                },
2184        }, {
2185                .chip   = {
2186                        .base   = EXYNOS4_GPE2(0),
2187                        .ngpio  = EXYNOS4_GPIO_E2_NR,
2188                        .label  = "GPE2",
2189                },
2190        }, {
2191                .chip   = {
2192                        .base   = EXYNOS4_GPE3(0),
2193                        .ngpio  = EXYNOS4_GPIO_E3_NR,
2194                        .label  = "GPE3",
2195                },
2196        }, {
2197                .chip   = {
2198                        .base   = EXYNOS4_GPE4(0),
2199                        .ngpio  = EXYNOS4_GPIO_E4_NR,
2200                        .label  = "GPE4",
2201                },
2202        }, {
2203                .chip   = {
2204                        .base   = EXYNOS4_GPF0(0),
2205                        .ngpio  = EXYNOS4_GPIO_F0_NR,
2206                        .label  = "GPF0",
2207                },
2208        }, {
2209                .chip   = {
2210                        .base   = EXYNOS4_GPF1(0),
2211                        .ngpio  = EXYNOS4_GPIO_F1_NR,
2212                        .label  = "GPF1",
2213                },
2214        }, {
2215                .chip   = {
2216                        .base   = EXYNOS4_GPF2(0),
2217                        .ngpio  = EXYNOS4_GPIO_F2_NR,
2218                        .label  = "GPF2",
2219                },
2220        }, {
2221                .chip   = {
2222                        .base   = EXYNOS4_GPF3(0),
2223                        .ngpio  = EXYNOS4_GPIO_F3_NR,
2224                        .label  = "GPF3",
2225                },
2226        },
2227};
2228#endif
2229
2230#ifdef CONFIG_ARCH_EXYNOS4
2231static struct samsung_gpio_chip exynos4_gpios_2[] = {
2232        {
2233                .chip   = {
2234                        .base   = EXYNOS4_GPJ0(0),
2235                        .ngpio  = EXYNOS4_GPIO_J0_NR,
2236                        .label  = "GPJ0",
2237                },
2238        }, {
2239                .chip   = {
2240                        .base   = EXYNOS4_GPJ1(0),
2241                        .ngpio  = EXYNOS4_GPIO_J1_NR,
2242                        .label  = "GPJ1",
2243                },
2244        }, {
2245                .chip   = {
2246                        .base   = EXYNOS4_GPK0(0),
2247                        .ngpio  = EXYNOS4_GPIO_K0_NR,
2248                        .label  = "GPK0",
2249                },
2250        }, {
2251                .chip   = {
2252                        .base   = EXYNOS4_GPK1(0),
2253                        .ngpio  = EXYNOS4_GPIO_K1_NR,
2254                        .label  = "GPK1",
2255                },
2256        }, {
2257                .chip   = {
2258                        .base   = EXYNOS4_GPK2(0),
2259                        .ngpio  = EXYNOS4_GPIO_K2_NR,
2260                        .label  = "GPK2",
2261                },
2262        }, {
2263                .chip   = {
2264                        .base   = EXYNOS4_GPK3(0),
2265                        .ngpio  = EXYNOS4_GPIO_K3_NR,
2266                        .label  = "GPK3",
2267                },
2268        }, {
2269                .chip   = {
2270                        .base   = EXYNOS4_GPL0(0),
2271                        .ngpio  = EXYNOS4_GPIO_L0_NR,
2272                        .label  = "GPL0",
2273                },
2274        }, {
2275                .chip   = {
2276                        .base   = EXYNOS4_GPL1(0),
2277                        .ngpio  = EXYNOS4_GPIO_L1_NR,
2278                        .label  = "GPL1",
2279                },
2280        }, {
2281                .chip   = {
2282                        .base   = EXYNOS4_GPL2(0),
2283                        .ngpio  = EXYNOS4_GPIO_L2_NR,
2284                        .label  = "GPL2",
2285                },
2286        }, {
2287                .config = &samsung_gpio_cfgs[8],
2288                .chip   = {
2289                        .base   = EXYNOS4_GPY0(0),
2290                        .ngpio  = EXYNOS4_GPIO_Y0_NR,
2291                        .label  = "GPY0",
2292                },
2293        }, {
2294                .config = &samsung_gpio_cfgs[8],
2295                .chip   = {
2296                        .base   = EXYNOS4_GPY1(0),
2297                        .ngpio  = EXYNOS4_GPIO_Y1_NR,
2298                        .label  = "GPY1",
2299                },
2300        }, {
2301                .config = &samsung_gpio_cfgs[8],
2302                .chip   = {
2303                        .base   = EXYNOS4_GPY2(0),
2304                        .ngpio  = EXYNOS4_GPIO_Y2_NR,
2305                        .label  = "GPY2",
2306                },
2307        }, {
2308                .config = &samsung_gpio_cfgs[8],
2309                .chip   = {
2310                        .base   = EXYNOS4_GPY3(0),
2311                        .ngpio  = EXYNOS4_GPIO_Y3_NR,
2312                        .label  = "GPY3",
2313                },
2314        }, {
2315                .config = &samsung_gpio_cfgs[8],
2316                .chip   = {
2317                        .base   = EXYNOS4_GPY4(0),
2318                        .ngpio  = EXYNOS4_GPIO_Y4_NR,
2319                        .label  = "GPY4",
2320                },
2321        }, {
2322                .config = &samsung_gpio_cfgs[8],
2323                .chip   = {
2324                        .base   = EXYNOS4_GPY5(0),
2325                        .ngpio  = EXYNOS4_GPIO_Y5_NR,
2326                        .label  = "GPY5",
2327                },
2328        }, {
2329                .config = &samsung_gpio_cfgs[8],
2330                .chip   = {
2331                        .base   = EXYNOS4_GPY6(0),
2332                        .ngpio  = EXYNOS4_GPIO_Y6_NR,
2333                        .label  = "GPY6",
2334                },
2335        }, {
2336                .config = &samsung_gpio_cfgs[9],
2337                .irq_base = IRQ_EINT(0),
2338                .chip   = {
2339                        .base   = EXYNOS4_GPX0(0),
2340                        .ngpio  = EXYNOS4_GPIO_X0_NR,
2341                        .label  = "GPX0",
2342                        .to_irq = samsung_gpiolib_to_irq,
2343                },
2344        }, {
2345                .config = &samsung_gpio_cfgs[9],
2346                .irq_base = IRQ_EINT(8),
2347                .chip   = {
2348                        .base   = EXYNOS4_GPX1(0),
2349                        .ngpio  = EXYNOS4_GPIO_X1_NR,
2350                        .label  = "GPX1",
2351                        .to_irq = samsung_gpiolib_to_irq,
2352                },
2353        }, {
2354                .config = &samsung_gpio_cfgs[9],
2355                .irq_base = IRQ_EINT(16),
2356                .chip   = {
2357                        .base   = EXYNOS4_GPX2(0),
2358                        .ngpio  = EXYNOS4_GPIO_X2_NR,
2359                        .label  = "GPX2",
2360                        .to_irq = samsung_gpiolib_to_irq,
2361                },
2362        }, {
2363                .config = &samsung_gpio_cfgs[9],
2364                .irq_base = IRQ_EINT(24),
2365                .chip   = {
2366                        .base   = EXYNOS4_GPX3(0),
2367                        .ngpio  = EXYNOS4_GPIO_X3_NR,
2368                        .label  = "GPX3",
2369                        .to_irq = samsung_gpiolib_to_irq,
2370                },
2371        },
2372};
2373#endif
2374
2375#ifdef CONFIG_ARCH_EXYNOS4
2376static struct samsung_gpio_chip exynos4_gpios_3[] = {
2377        {
2378                .chip   = {
2379                        .base   = EXYNOS4_GPZ(0),
2380                        .ngpio  = EXYNOS4_GPIO_Z_NR,
2381                        .label  = "GPZ",
2382                },
2383        },
2384};
2385#endif
2386
2387#ifdef CONFIG_ARCH_EXYNOS5
2388static struct samsung_gpio_chip exynos5_gpios_1[] = {
2389        {
2390                .chip   = {
2391                        .base   = EXYNOS5_GPA0(0),
2392                        .ngpio  = EXYNOS5_GPIO_A0_NR,
2393                        .label  = "GPA0",
2394                },
2395        }, {
2396                .chip   = {
2397                        .base   = EXYNOS5_GPA1(0),
2398                        .ngpio  = EXYNOS5_GPIO_A1_NR,
2399                        .label  = "GPA1",
2400                },
2401        }, {
2402                .chip   = {
2403                        .base   = EXYNOS5_GPA2(0),
2404                        .ngpio  = EXYNOS5_GPIO_A2_NR,
2405                        .label  = "GPA2",
2406                },
2407        }, {
2408                .chip   = {
2409                        .base   = EXYNOS5_GPB0(0),
2410                        .ngpio  = EXYNOS5_GPIO_B0_NR,
2411                        .label  = "GPB0",
2412                },
2413        }, {
2414                .chip   = {
2415                        .base   = EXYNOS5_GPB1(0),
2416                        .ngpio  = EXYNOS5_GPIO_B1_NR,
2417                        .label  = "GPB1",
2418                },
2419        }, {
2420                .chip   = {
2421                        .base   = EXYNOS5_GPB2(0),
2422                        .ngpio  = EXYNOS5_GPIO_B2_NR,
2423                        .label  = "GPB2",
2424                },
2425        }, {
2426                .chip   = {
2427                        .base   = EXYNOS5_GPB3(0),
2428                        .ngpio  = EXYNOS5_GPIO_B3_NR,
2429                        .label  = "GPB3",
2430                },
2431        }, {
2432                .chip   = {
2433                        .base   = EXYNOS5_GPC0(0),
2434                        .ngpio  = EXYNOS5_GPIO_C0_NR,
2435                        .label  = "GPC0",
2436                },
2437        }, {
2438                .chip   = {
2439                        .base   = EXYNOS5_GPC1(0),
2440                        .ngpio  = EXYNOS5_GPIO_C1_NR,
2441                        .label  = "GPC1",
2442                },
2443        }, {
2444                .chip   = {
2445                        .base   = EXYNOS5_GPC2(0),
2446                        .ngpio  = EXYNOS5_GPIO_C2_NR,
2447                        .label  = "GPC2",
2448                },
2449        }, {
2450                .chip   = {
2451                        .base   = EXYNOS5_GPC3(0),
2452                        .ngpio  = EXYNOS5_GPIO_C3_NR,
2453                        .label  = "GPC3",
2454                },
2455        }, {
2456                .chip   = {
2457                        .base   = EXYNOS5_GPD0(0),
2458                        .ngpio  = EXYNOS5_GPIO_D0_NR,
2459                        .label  = "GPD0",
2460                },
2461        }, {
2462                .chip   = {
2463                        .base   = EXYNOS5_GPD1(0),
2464                        .ngpio  = EXYNOS5_GPIO_D1_NR,
2465                        .label  = "GPD1",
2466                },
2467        }, {
2468                .chip   = {
2469                        .base   = EXYNOS5_GPY0(0),
2470                        .ngpio  = EXYNOS5_GPIO_Y0_NR,
2471                        .label  = "GPY0",
2472                },
2473        }, {
2474                .chip   = {
2475                        .base   = EXYNOS5_GPY1(0),
2476                        .ngpio  = EXYNOS5_GPIO_Y1_NR,
2477                        .label  = "GPY1",
2478                },
2479        }, {
2480                .chip   = {
2481                        .base   = EXYNOS5_GPY2(0),
2482                        .ngpio  = EXYNOS5_GPIO_Y2_NR,
2483                        .label  = "GPY2",
2484                },
2485        }, {
2486                .chip   = {
2487                        .base   = EXYNOS5_GPY3(0),
2488                        .ngpio  = EXYNOS5_GPIO_Y3_NR,
2489                        .label  = "GPY3",
2490                },
2491        }, {
2492                .chip   = {
2493                        .base   = EXYNOS5_GPY4(0),
2494                        .ngpio  = EXYNOS5_GPIO_Y4_NR,
2495                        .label  = "GPY4",
2496                },
2497        }, {
2498                .chip   = {
2499                        .base   = EXYNOS5_GPY5(0),
2500                        .ngpio  = EXYNOS5_GPIO_Y5_NR,
2501                        .label  = "GPY5",
2502                },
2503        }, {
2504                .chip   = {
2505                        .base   = EXYNOS5_GPY6(0),
2506                        .ngpio  = EXYNOS5_GPIO_Y6_NR,
2507                        .label  = "GPY6",
2508                },
2509        }, {
2510                .chip   = {
2511                        .base   = EXYNOS5_GPC4(0),
2512                        .ngpio  = EXYNOS5_GPIO_C4_NR,
2513                        .label  = "GPC4",
2514                },
2515        }, {
2516                .config = &samsung_gpio_cfgs[9],
2517                .irq_base = IRQ_EINT(0),
2518                .chip   = {
2519                        .base   = EXYNOS5_GPX0(0),
2520                        .ngpio  = EXYNOS5_GPIO_X0_NR,
2521                        .label  = "GPX0",
2522                        .to_irq = samsung_gpiolib_to_irq,
2523                },
2524        }, {
2525                .config = &samsung_gpio_cfgs[9],
2526                .irq_base = IRQ_EINT(8),
2527                .chip   = {
2528                        .base   = EXYNOS5_GPX1(0),
2529                        .ngpio  = EXYNOS5_GPIO_X1_NR,
2530                        .label  = "GPX1",
2531                        .to_irq = samsung_gpiolib_to_irq,
2532                },
2533        }, {
2534                .config = &samsung_gpio_cfgs[9],
2535                .irq_base = IRQ_EINT(16),
2536                .chip   = {
2537                        .base   = EXYNOS5_GPX2(0),
2538                        .ngpio  = EXYNOS5_GPIO_X2_NR,
2539                        .label  = "GPX2",
2540                        .to_irq = samsung_gpiolib_to_irq,
2541                },
2542        }, {
2543                .config = &samsung_gpio_cfgs[9],
2544                .irq_base = IRQ_EINT(24),
2545                .chip   = {
2546                        .base   = EXYNOS5_GPX3(0),
2547                        .ngpio  = EXYNOS5_GPIO_X3_NR,
2548                        .label  = "GPX3",
2549                        .to_irq = samsung_gpiolib_to_irq,
2550                },
2551        },
2552};
2553#endif
2554
2555#ifdef CONFIG_ARCH_EXYNOS5
2556static struct samsung_gpio_chip exynos5_gpios_2[] = {
2557        {
2558                .chip   = {
2559                        .base   = EXYNOS5_GPE0(0),
2560                        .ngpio  = EXYNOS5_GPIO_E0_NR,
2561                        .label  = "GPE0",
2562                },
2563        }, {
2564                .chip   = {
2565                        .base   = EXYNOS5_GPE1(0),
2566                        .ngpio  = EXYNOS5_GPIO_E1_NR,
2567                        .label  = "GPE1",
2568                },
2569        }, {
2570                .chip   = {
2571                        .base   = EXYNOS5_GPF0(0),
2572                        .ngpio  = EXYNOS5_GPIO_F0_NR,
2573                        .label  = "GPF0",
2574                },
2575        }, {
2576                .chip   = {
2577                        .base   = EXYNOS5_GPF1(0),
2578                        .ngpio  = EXYNOS5_GPIO_F1_NR,
2579                        .label  = "GPF1",
2580                },
2581        }, {
2582                .chip   = {
2583                        .base   = EXYNOS5_GPG0(0),
2584                        .ngpio  = EXYNOS5_GPIO_G0_NR,
2585                        .label  = "GPG0",
2586                },
2587        }, {
2588                .chip   = {
2589                        .base   = EXYNOS5_GPG1(0),
2590                        .ngpio  = EXYNOS5_GPIO_G1_NR,
2591                        .label  = "GPG1",
2592                },
2593        }, {
2594                .chip   = {
2595                        .base   = EXYNOS5_GPG2(0),
2596                        .ngpio  = EXYNOS5_GPIO_G2_NR,
2597                        .label  = "GPG2",
2598                },
2599        }, {
2600                .chip   = {
2601                        .base   = EXYNOS5_GPH0(0),
2602                        .ngpio  = EXYNOS5_GPIO_H0_NR,
2603                        .label  = "GPH0",
2604                },
2605        }, {
2606                .chip   = {
2607                        .base   = EXYNOS5_GPH1(0),
2608                        .ngpio  = EXYNOS5_GPIO_H1_NR,
2609                        .label  = "GPH1",
2610
2611                },
2612        },
2613};
2614#endif
2615
2616#ifdef CONFIG_ARCH_EXYNOS5
2617static struct samsung_gpio_chip exynos5_gpios_3[] = {
2618        {
2619                .chip   = {
2620                        .base   = EXYNOS5_GPV0(0),
2621                        .ngpio  = EXYNOS5_GPIO_V0_NR,
2622                        .label  = "GPV0",
2623                },
2624        }, {
2625                .chip   = {
2626                        .base   = EXYNOS5_GPV1(0),
2627                        .ngpio  = EXYNOS5_GPIO_V1_NR,
2628                        .label  = "GPV1",
2629                },
2630        }, {
2631                .chip   = {
2632                        .base   = EXYNOS5_GPV2(0),
2633                        .ngpio  = EXYNOS5_GPIO_V2_NR,
2634                        .label  = "GPV2",
2635                },
2636        }, {
2637                .chip   = {
2638                        .base   = EXYNOS5_GPV3(0),
2639                        .ngpio  = EXYNOS5_GPIO_V3_NR,
2640                        .label  = "GPV3",
2641                },
2642        }, {
2643                .chip   = {
2644                        .base   = EXYNOS5_GPV4(0),
2645                        .ngpio  = EXYNOS5_GPIO_V4_NR,
2646                        .label  = "GPV4",
2647                },
2648        },
2649};
2650#endif
2651
2652#ifdef CONFIG_ARCH_EXYNOS5
2653static struct samsung_gpio_chip exynos5_gpios_4[] = {
2654        {
2655                .chip   = {
2656                        .base   = EXYNOS5_GPZ(0),
2657                        .ngpio  = EXYNOS5_GPIO_Z_NR,
2658                        .label  = "GPZ",
2659                },
2660        },
2661};
2662#endif
2663
2664
2665#if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF)
2666static int exynos_gpio_xlate(struct gpio_chip *gc,
2667                        const struct of_phandle_args *gpiospec, u32 *flags)
2668{
2669        unsigned int pin;
2670
2671        if (WARN_ON(gc->of_gpio_n_cells < 4))
2672                return -EINVAL;
2673
2674        if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
2675                return -EINVAL;
2676
2677        if (gpiospec->args[0] > gc->ngpio)
2678                return -EINVAL;
2679
2680        pin = gc->base + gpiospec->args[0];
2681
2682        if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
2683                pr_warn("gpio_xlate: failed to set pin function\n");
2684        if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff))
2685                pr_warn("gpio_xlate: failed to set pin pull up/down\n");
2686        if (s5p_gpio_set_drvstr(pin, gpiospec->args[3]))
2687                pr_warn("gpio_xlate: failed to set pin drive strength\n");
2688
2689        if (flags)
2690                *flags = gpiospec->args[2] >> 16;
2691
2692        return gpiospec->args[0];
2693}
2694
2695static const struct of_device_id exynos_gpio_dt_match[] __initdata = {
2696        { .compatible = "samsung,exynos4-gpio", },
2697        {}
2698};
2699
2700static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
2701                                                u64 base, u64 offset)
2702{
2703        struct gpio_chip *gc =  &chip->chip;
2704        u64 address;
2705
2706        if (!of_have_populated_dt())
2707                return;
2708
2709        address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
2710        gc->of_node = of_find_matching_node_by_address(NULL,
2711                        exynos_gpio_dt_match, address);
2712        if (!gc->of_node) {
2713                pr_info("gpio: device tree node not found for gpio controller"
2714                        " with base address %08llx\n", address);
2715                return;
2716        }
2717        gc->of_gpio_n_cells = 4;
2718        gc->of_xlate = exynos_gpio_xlate;
2719}
2720#elif defined(CONFIG_ARCH_EXYNOS)
2721static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
2722                                                u64 base, u64 offset)
2723{
2724        return;
2725}
2726#endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */
2727
2728static __init void exynos4_gpiolib_init(void)
2729{
2730#ifdef CONFIG_CPU_EXYNOS4210
2731        struct samsung_gpio_chip *chip;
2732        int i, nr_chips;
2733        void __iomem *gpio_base1, *gpio_base2, *gpio_base3;
2734        int group = 0;
2735        void __iomem *gpx_base;
2736
2737        /* gpio part1 */
2738        gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K);
2739        if (gpio_base1 == NULL) {
2740                pr_err("unable to ioremap for gpio_base1\n");
2741                goto err_ioremap1;
2742        }
2743
2744        chip = exynos4_gpios_1;
2745        nr_chips = ARRAY_SIZE(exynos4_gpios_1);
2746
2747        for (i = 0; i < nr_chips; i++, chip++) {
2748                if (!chip->config) {
2749                        chip->config = &exynos_gpio_cfg;
2750                        chip->group = group++;
2751                }
2752                exynos_gpiolib_attach_ofnode(chip,
2753                                EXYNOS4_PA_GPIO1, i * 0x20);
2754        }
2755        samsung_gpiolib_add_4bit_chips(exynos4_gpios_1,
2756                                       nr_chips, gpio_base1);
2757
2758        /* gpio part2 */
2759        gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
2760        if (gpio_base2 == NULL) {
2761                pr_err("unable to ioremap for gpio_base2\n");
2762                goto err_ioremap2;
2763        }
2764
2765        /* need to set base address for gpx */
2766        chip = &exynos4_gpios_2[16];
2767        gpx_base = gpio_base2 + 0xC00;
2768        for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
2769                chip->base = gpx_base;
2770
2771        chip = exynos4_gpios_2;
2772        nr_chips = ARRAY_SIZE(exynos4_gpios_2);
2773
2774        for (i = 0; i < nr_chips; i++, chip++) {
2775                if (!chip->config) {
2776                        chip->config = &exynos_gpio_cfg;
2777                        chip->group = group++;
2778                }
2779                exynos_gpiolib_attach_ofnode(chip,
2780                                EXYNOS4_PA_GPIO2, i * 0x20);
2781        }
2782        samsung_gpiolib_add_4bit_chips(exynos4_gpios_2,
2783                                       nr_chips, gpio_base2);
2784
2785        /* gpio part3 */
2786        gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256);
2787        if (gpio_base3 == NULL) {
2788                pr_err("unable to ioremap for gpio_base3\n");
2789                goto err_ioremap3;
2790        }
2791
2792        chip = exynos4_gpios_3;
2793        nr_chips = ARRAY_SIZE(exynos4_gpios_3);
2794
2795        for (i = 0; i < nr_chips; i++, chip++) {
2796                if (!chip->config) {
2797                        chip->config = &exynos_gpio_cfg;
2798                        chip->group = group++;
2799                }
2800                exynos_gpiolib_attach_ofnode(chip,
2801                                EXYNOS4_PA_GPIO3, i * 0x20);
2802        }
2803        samsung_gpiolib_add_4bit_chips(exynos4_gpios_3,
2804                                       nr_chips, gpio_base3);
2805
2806#if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT)
2807        s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
2808        s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
2809#endif
2810
2811        return;
2812
2813err_ioremap3:
2814        iounmap(gpio_base2);
2815err_ioremap2:
2816        iounmap(gpio_base1);
2817err_ioremap1:
2818        return;
2819#endif  /* CONFIG_CPU_EXYNOS4210 */
2820}
2821
2822static __init void exynos5_gpiolib_init(void)
2823{
2824#ifdef CONFIG_SOC_EXYNOS5250
2825        struct samsung_gpio_chip *chip;
2826        int i, nr_chips;
2827        void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4;
2828        int group = 0;
2829        void __iomem *gpx_base;
2830
2831        /* gpio part1 */
2832        gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
2833        if (gpio_base1 == NULL) {
2834                pr_err("unable to ioremap for gpio_base1\n");
2835                goto err_ioremap1;
2836        }
2837
2838        /* need to set base address for gpc4 */
2839        exynos5_gpios_1[20].base = gpio_base1 + 0x2E0;
2840
2841        /* need to set base address for gpx */
2842        chip = &exynos5_gpios_1[21];
2843        gpx_base = gpio_base1 + 0xC00;
2844        for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
2845                chip->base = gpx_base;
2846
2847        chip = exynos5_gpios_1;
2848        nr_chips = ARRAY_SIZE(exynos5_gpios_1);
2849
2850        for (i = 0; i < nr_chips; i++, chip++) {
2851                if (!chip->config) {
2852                        chip->config = &exynos_gpio_cfg;
2853                        chip->group = group++;
2854                }
2855                exynos_gpiolib_attach_ofnode(chip,
2856                                EXYNOS5_PA_GPIO1, i * 0x20);
2857        }
2858        samsung_gpiolib_add_4bit_chips(exynos5_gpios_1,
2859                                       nr_chips, gpio_base1);
2860
2861        /* gpio part2 */
2862        gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K);
2863        if (gpio_base2 == NULL) {
2864                pr_err("unable to ioremap for gpio_base2\n");
2865                goto err_ioremap2;
2866        }
2867
2868        chip = exynos5_gpios_2;
2869        nr_chips = ARRAY_SIZE(exynos5_gpios_2);
2870
2871        for (i = 0; i < nr_chips; i++, chip++) {
2872                if (!chip->config) {
2873                        chip->config = &exynos_gpio_cfg;
2874                        chip->group = group++;
2875                }
2876                exynos_gpiolib_attach_ofnode(chip,
2877                                EXYNOS5_PA_GPIO2, i * 0x20);
2878        }
2879        samsung_gpiolib_add_4bit_chips(exynos5_gpios_2,
2880                                       nr_chips, gpio_base2);
2881
2882        /* gpio part3 */
2883        gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K);
2884        if (gpio_base3 == NULL) {
2885                pr_err("unable to ioremap for gpio_base3\n");
2886                goto err_ioremap3;
2887        }
2888
2889        /* need to set base address for gpv */
2890        exynos5_gpios_3[0].base = gpio_base3;
2891        exynos5_gpios_3[1].base = gpio_base3 + 0x20;
2892        exynos5_gpios_3[2].base = gpio_base3 + 0x60;
2893        exynos5_gpios_3[3].base = gpio_base3 + 0x80;
2894        exynos5_gpios_3[4].base = gpio_base3 + 0xC0;
2895
2896        chip = exynos5_gpios_3;
2897        nr_chips = ARRAY_SIZE(exynos5_gpios_3);
2898
2899        for (i = 0; i < nr_chips; i++, chip++) {
2900                if (!chip->config) {
2901                        chip->config = &exynos_gpio_cfg;
2902                        chip->group = group++;
2903                }
2904                exynos_gpiolib_attach_ofnode(chip,
2905                                EXYNOS5_PA_GPIO3, i * 0x20);
2906        }
2907        samsung_gpiolib_add_4bit_chips(exynos5_gpios_3,
2908                                       nr_chips, gpio_base3);
2909
2910        /* gpio part4 */
2911        gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K);
2912        if (gpio_base4 == NULL) {
2913                pr_err("unable to ioremap for gpio_base4\n");
2914                goto err_ioremap4;
2915        }
2916
2917        chip = exynos5_gpios_4;
2918        nr_chips = ARRAY_SIZE(exynos5_gpios_4);
2919
2920        for (i = 0; i < nr_chips; i++, chip++) {
2921                if (!chip->config) {
2922                        chip->config = &exynos_gpio_cfg;
2923                        chip->group = group++;
2924                }
2925                exynos_gpiolib_attach_ofnode(chip,
2926                                EXYNOS5_PA_GPIO4, i * 0x20);
2927        }
2928        samsung_gpiolib_add_4bit_chips(exynos5_gpios_4,
2929                                       nr_chips, gpio_base4);
2930        return;
2931
2932err_ioremap4:
2933        iounmap(gpio_base3);
2934err_ioremap3:
2935        iounmap(gpio_base2);
2936err_ioremap2:
2937        iounmap(gpio_base1);
2938err_ioremap1:
2939        return;
2940
2941#endif  /* CONFIG_SOC_EXYNOS5250 */
2942}
2943
2944/* TODO: cleanup soc_is_* */
2945static __init int samsung_gpiolib_init(void)
2946{
2947        struct samsung_gpio_chip *chip;
2948        int i, nr_chips;
2949        int group = 0;
2950
2951        samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
2952
2953        if (soc_is_s3c24xx()) {
2954                s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
2955                                ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
2956        } else if (soc_is_s3c64xx()) {
2957                samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
2958                                ARRAY_SIZE(s3c64xx_gpios_2bit),
2959                                S3C64XX_VA_GPIO + 0xE0, 0x20);
2960                samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
2961                                ARRAY_SIZE(s3c64xx_gpios_4bit),
2962                                S3C64XX_VA_GPIO);
2963                samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
2964                                ARRAY_SIZE(s3c64xx_gpios_4bit2));
2965        } else if (soc_is_s5p6440()) {
2966                samsung_gpiolib_add_2bit_chips(s5p6440_gpios_2bit,
2967                                ARRAY_SIZE(s5p6440_gpios_2bit), NULL, 0x0);
2968                samsung_gpiolib_add_4bit_chips(s5p6440_gpios_4bit,
2969                                ARRAY_SIZE(s5p6440_gpios_4bit), S5P_VA_GPIO);
2970                samsung_gpiolib_add_4bit2_chips(s5p6440_gpios_4bit2,
2971                                ARRAY_SIZE(s5p6440_gpios_4bit2));
2972                s5p64x0_gpiolib_add_rbank(s5p6440_gpios_rbank,
2973                                ARRAY_SIZE(s5p6440_gpios_rbank));
2974        } else if (soc_is_s5p6450()) {
2975                samsung_gpiolib_add_2bit_chips(s5p6450_gpios_2bit,
2976                                ARRAY_SIZE(s5p6450_gpios_2bit), NULL, 0x0);
2977                samsung_gpiolib_add_4bit_chips(s5p6450_gpios_4bit,
2978                                ARRAY_SIZE(s5p6450_gpios_4bit), S5P_VA_GPIO);
2979                samsung_gpiolib_add_4bit2_chips(s5p6450_gpios_4bit2,
2980                                ARRAY_SIZE(s5p6450_gpios_4bit2));
2981                s5p64x0_gpiolib_add_rbank(s5p6450_gpios_rbank,
2982                                ARRAY_SIZE(s5p6450_gpios_rbank));
2983        } else if (soc_is_s5pc100()) {
2984                group = 0;
2985                chip = s5pc100_gpios_4bit;
2986                nr_chips = ARRAY_SIZE(s5pc100_gpios_4bit);
2987
2988                for (i = 0; i < nr_chips; i++, chip++) {
2989                        if (!chip->config) {
2990                                chip->config = &samsung_gpio_cfgs[3];
2991                                chip->group = group++;
2992                        }
2993                }
2994                samsung_gpiolib_add_4bit_chips(s5pc100_gpios_4bit, nr_chips, S5P_VA_GPIO);
2995#if defined(CONFIG_CPU_S5PC100) && defined(CONFIG_S5P_GPIO_INT)
2996                s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
2997#endif
2998        } else if (soc_is_s5pv210()) {
2999                group = 0;
3000                chip = s5pv210_gpios_4bit;
3001                nr_chips = ARRAY_SIZE(s5pv210_gpios_4bit);
3002
3003                for (i = 0; i < nr_chips; i++, chip++) {
3004                        if (!chip->config) {
3005                                chip->config = &samsung_gpio_cfgs[3];
3006                                chip->group = group++;
3007                        }
3008                }
3009                samsung_gpiolib_add_4bit_chips(s5pv210_gpios_4bit, nr_chips, S5P_VA_GPIO);
3010#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_S5P_GPIO_INT)
3011                s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
3012#endif
3013        } else if (soc_is_exynos4210()) {
3014                exynos4_gpiolib_init();
3015        } else if (soc_is_exynos5250()) {
3016                exynos5_gpiolib_init();
3017        } else {
3018                WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
3019                return -ENODEV;
3020        }
3021
3022        return 0;
3023}
3024core_initcall(samsung_gpiolib_init);
3025
3026int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
3027{
3028        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3029        unsigned long flags;
3030        int offset;
3031        int ret;
3032
3033        if (!chip)
3034                return -EINVAL;
3035
3036        offset = pin - chip->chip.base;
3037
3038        samsung_gpio_lock(chip, flags);
3039        ret = samsung_gpio_do_setcfg(chip, offset, config);
3040        samsung_gpio_unlock(chip, flags);
3041
3042        return ret;
3043}
3044EXPORT_SYMBOL(s3c_gpio_cfgpin);
3045
3046int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
3047                          unsigned int cfg)
3048{
3049        int ret;
3050
3051        for (; nr > 0; nr--, start++) {
3052                ret = s3c_gpio_cfgpin(start, cfg);
3053                if (ret != 0)
3054                        return ret;
3055        }
3056
3057        return 0;
3058}
3059EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
3060
3061int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
3062                          unsigned int cfg, samsung_gpio_pull_t pull)
3063{
3064        int ret;
3065
3066        for (; nr > 0; nr--, start++) {
3067                s3c_gpio_setpull(start, pull);
3068                ret = s3c_gpio_cfgpin(start, cfg);
3069                if (ret != 0)
3070                        return ret;
3071        }
3072
3073        return 0;
3074}
3075EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
3076
3077unsigned s3c_gpio_getcfg(unsigned int pin)
3078{
3079        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3080        unsigned long flags;
3081        unsigned ret = 0;
3082        int offset;
3083
3084        if (chip) {
3085                offset = pin - chip->chip.base;
3086
3087                samsung_gpio_lock(chip, flags);
3088                ret = samsung_gpio_do_getcfg(chip, offset);
3089                samsung_gpio_unlock(chip, flags);
3090        }
3091
3092        return ret;
3093}
3094EXPORT_SYMBOL(s3c_gpio_getcfg);
3095
3096int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
3097{
3098        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3099        unsigned long flags;
3100        int offset, ret;
3101
3102        if (!chip)
3103                return -EINVAL;
3104
3105        offset = pin - chip->chip.base;
3106
3107        samsung_gpio_lock(chip, flags);
3108        ret = samsung_gpio_do_setpull(chip, offset, pull);
3109        samsung_gpio_unlock(chip, flags);
3110
3111        return ret;
3112}
3113EXPORT_SYMBOL(s3c_gpio_setpull);
3114
3115samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
3116{
3117        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3118        unsigned long flags;
3119        int offset;
3120        u32 pup = 0;
3121
3122        if (chip) {
3123                offset = pin - chip->chip.base;
3124
3125                samsung_gpio_lock(chip, flags);
3126                pup = samsung_gpio_do_getpull(chip, offset);
3127                samsung_gpio_unlock(chip, flags);
3128        }
3129
3130        return (__force samsung_gpio_pull_t)pup;
3131}
3132EXPORT_SYMBOL(s3c_gpio_getpull);
3133
3134/* gpiolib wrappers until these are totally eliminated */
3135
3136void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
3137{
3138        int ret;
3139
3140        WARN_ON(to);    /* should be none of these left */
3141
3142        if (!to) {
3143                /* if pull is enabled, try first with up, and if that
3144                 * fails, try using down */
3145
3146                ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
3147                if (ret)
3148                        s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
3149        } else {
3150                s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
3151        }
3152}
3153EXPORT_SYMBOL(s3c2410_gpio_pullup);
3154
3155void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
3156{
3157        /* do this via gpiolib until all users removed */
3158
3159        gpio_request(pin, "temporary");
3160        gpio_set_value(pin, to);
3161        gpio_free(pin);
3162}
3163EXPORT_SYMBOL(s3c2410_gpio_setpin);
3164
3165unsigned int s3c2410_gpio_getpin(unsigned int pin)
3166{
3167        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3168        unsigned long offs = pin - chip->chip.base;
3169
3170        return __raw_readl(chip->base + 0x04) & (1 << offs);
3171}
3172EXPORT_SYMBOL(s3c2410_gpio_getpin);
3173
3174#ifdef CONFIG_S5P_GPIO_DRVSTR
3175s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
3176{
3177        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3178        unsigned int off;
3179        void __iomem *reg;
3180        int shift;
3181        u32 drvstr;
3182
3183        if (!chip)
3184                return -EINVAL;
3185
3186        off = pin - chip->chip.base;
3187        shift = off * 2;
3188        reg = chip->base + 0x0C;
3189
3190        drvstr = __raw_readl(reg);
3191        drvstr = drvstr >> shift;
3192        drvstr &= 0x3;
3193
3194        return (__force s5p_gpio_drvstr_t)drvstr;
3195}
3196EXPORT_SYMBOL(s5p_gpio_get_drvstr);
3197
3198int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
3199{
3200        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3201        unsigned int off;
3202        void __iomem *reg;
3203        int shift;
3204        u32 tmp;
3205
3206        if (!chip)
3207                return -EINVAL;
3208
3209        off = pin - chip->chip.base;
3210        shift = off * 2;
3211        reg = chip->base + 0x0C;
3212
3213        tmp = __raw_readl(reg);
3214        tmp &= ~(0x3 << shift);
3215        tmp |= drvstr << shift;
3216
3217        __raw_writel(tmp, reg);
3218
3219        return 0;
3220}
3221EXPORT_SYMBOL(s5p_gpio_set_drvstr);
3222#endif  /* CONFIG_S5P_GPIO_DRVSTR */
3223
3224#ifdef CONFIG_PLAT_S3C24XX
3225unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
3226{
3227        unsigned long flags;
3228        unsigned long misccr;
3229
3230        local_irq_save(flags);
3231        misccr = __raw_readl(S3C24XX_MISCCR);
3232        misccr &= ~clear;
3233        misccr ^= change;
3234        __raw_writel(misccr, S3C24XX_MISCCR);
3235        local_irq_restore(flags);
3236
3237        return misccr;
3238}
3239EXPORT_SYMBOL(s3c2410_modify_misccr);
3240#endif
3241
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.