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