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
 164/*
 165 * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration.
 166 * @chip: The gpio chip that is being configured.
 167 * @off: The offset for the GPIO being configured.
 168 * @cfg: The configuration value to set.
 169 *
 170 * This helper deal with the GPIO cases where the control register
 171 * has two bits of configuration per gpio, which have the following
 172 * functions:
 173 *      00 = input
 174 *      01 = output
 175 *      1x = special function
 176 */
 177
 178static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
 179                                    unsigned int off, unsigned int cfg)
 180{
 181        void __iomem *reg = chip->base;
 182        unsigned int shift = off * 2;
 183        u32 con;
 184
 185        if (samsung_gpio_is_cfg_special(cfg)) {
 186                cfg &= 0xf;
 187                if (cfg > 3)
 188                        return -EINVAL;
 189
 190                cfg <<= shift;
 191        }
 192
 193        con = __raw_readl(reg);
 194        con &= ~(0x3 << shift);
 195        con |= cfg;
 196        __raw_writel(con, reg);
 197
 198        return 0;
 199}
 200
 201/*
 202 * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
 203 * @chip: The gpio chip that is being configured.
 204 * @off: The offset for the GPIO being configured.
 205 *
 206 * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which
 207 * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
 208 * S3C_GPIO_SPECIAL() macro.
 209 */
 210
 211static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
 212                                             unsigned int off)
 213{
 214        u32 con;
 215
 216        con = __raw_readl(chip->base);
 217        con >>= off * 2;
 218        con &= 3;
 219
 220        /* this conversion works for IN and OUT as well as special mode */
 221        return S3C_GPIO_SPECIAL(con);
 222}
 223
 224/*
 225 * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
 226 * @chip: The gpio chip that is being configured.
 227 * @off: The offset for the GPIO being configured.
 228 * @cfg: The configuration value to set.
 229 *
 230 * This helper deal with the GPIO cases where the control register has 4 bits
 231 * of control per GPIO, generally in the form of:
 232 *      0000 = Input
 233 *      0001 = Output
 234 *      others = Special functions (dependent on bank)
 235 *
 236 * Note, since the code to deal with the case where there are two control
 237 * registers instead of one, we do not have a separate set of functions for
 238 * each case.
 239 */
 240
 241static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
 242                                    unsigned int off, unsigned int cfg)
 243{
 244        void __iomem *reg = chip->base;
 245        unsigned int shift = (off & 7) * 4;
 246        u32 con;
 247
 248        if (off < 8 && chip->chip.ngpio > 8)
 249                reg -= 4;
 250
 251        if (samsung_gpio_is_cfg_special(cfg)) {
 252                cfg &= 0xf;
 253                cfg <<= shift;
 254        }
 255
 256        con = __raw_readl(reg);
 257        con &= ~(0xf << shift);
 258        con |= cfg;
 259        __raw_writel(con, reg);
 260
 261        return 0;
 262}
 263
 264/*
 265 * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
 266 * @chip: The gpio chip that is being configured.
 267 * @off: The offset for the GPIO being configured.
 268 *
 269 * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
 270 * register setting into a value the software can use, such as could be passed
 271 * to samsung_gpio_setcfg_4bit().
 272 *
 273 * @sa samsung_gpio_getcfg_2bit
 274 */
 275
 276static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
 277                                         unsigned int off)
 278{
 279        void __iomem *reg = chip->base;
 280        unsigned int shift = (off & 7) * 4;
 281        u32 con;
 282
 283        if (off < 8 && chip->chip.ngpio > 8)
 284                reg -= 4;
 285
 286        con = __raw_readl(reg);
 287        con >>= shift;
 288        con &= 0xf;
 289
 290        /* this conversion works for IN and OUT as well as special mode */
 291        return S3C_GPIO_SPECIAL(con);
 292}
 293
 294#ifdef CONFIG_PLAT_S3C24XX
 295/*
 296 * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A)
 297 * @chip: The gpio chip that is being configured.
 298 * @off: The offset for the GPIO being configured.
 299 * @cfg: The configuration value to set.
 300 *
 301 * This helper deal with the GPIO cases where the control register
 302 * has one bit of configuration for the gpio, where setting the bit
 303 * means the pin is in special function mode and unset means output.
 304 */
 305
 306static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip,
 307                                     unsigned int off, unsigned int cfg)
 308{
 309        void __iomem *reg = chip->base;
 310        unsigned int shift = off;
 311        u32 con;
 312
 313        if (samsung_gpio_is_cfg_special(cfg)) {
 314                cfg &= 0xf;
 315
 316                /* Map output to 0, and SFN2 to 1 */
 317                cfg -= 1;
 318                if (cfg > 1)
 319                        return -EINVAL;
 320
 321                cfg <<= shift;
 322        }
 323
 324        con = __raw_readl(reg);
 325        con &= ~(0x1 << shift);
 326        con |= cfg;
 327        __raw_writel(con, reg);
 328
 329        return 0;
 330}
 331
 332/*
 333 * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A)
 334 * @chip: The gpio chip that is being configured.
 335 * @off: The offset for the GPIO being configured.
 336 *
 337 * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable
 338 * GPIO configuration value.
 339 *
 340 * @sa samsung_gpio_getcfg_2bit
 341 * @sa samsung_gpio_getcfg_4bit
 342 */
 343
 344static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip,
 345                                          unsigned int off)
 346{
 347        u32 con;
 348
 349        con = __raw_readl(chip->base);
 350        con >>= off;
 351        con &= 1;
 352        con++;
 353
 354        return S3C_GPIO_SFN(con);
 355}
 356#endif
 357
 358#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
 359static int s5p64x0_gpio_setcfg_rbank(struct samsung_gpio_chip *chip,
 360                                     unsigned int off, unsigned int cfg)
 361{
 362        void __iomem *reg = chip->base;
 363        unsigned int shift;
 364        u32 con;
 365
 366        switch (off) {
 367        case 0:
 368        case 1:
 369        case 2:
 370        case 3:
 371        case 4:
 372        case 5:
 373                shift = (off & 7) * 4;
 374                reg -= 4;
 375                break;
 376        case 6:
 377                shift = ((off + 1) & 7) * 4;
 378                reg -= 4;
 379        default:
 380                shift = ((off + 1) & 7) * 4;
 381                break;
 382        }
 383
 384        if (samsung_gpio_is_cfg_special(cfg)) {
 385                cfg &= 0xf;
 386                cfg <<= shift;
 387        }
 388
 389        con = __raw_readl(reg);
 390        con &= ~(0xf << shift);
 391        con |= cfg;
 392        __raw_writel(con, reg);
 393
 394        return 0;
 395}
 396#endif
 397
 398static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
 399                                           int nr_chips)
 400{
 401        for (; nr_chips > 0; nr_chips--, chipcfg++) {
 402                if (!chipcfg->set_config)
 403                        chipcfg->set_config = samsung_gpio_setcfg_4bit;
 404                if (!chipcfg->get_config)
 405                        chipcfg->get_config = samsung_gpio_getcfg_4bit;
 406                if (!chipcfg->set_pull)
 407                        chipcfg->set_pull = samsung_gpio_setpull_updown;
 408                if (!chipcfg->get_pull)
 409                        chipcfg->get_pull = samsung_gpio_getpull_updown;
 410        }
 411}
 412
 413struct samsung_gpio_cfg s3c24xx_gpiocfg_default = {
 414        .set_config     = samsung_gpio_setcfg_2bit,
 415        .get_config     = samsung_gpio_getcfg_2bit,
 416};
 417
 418#ifdef CONFIG_PLAT_S3C24XX
 419static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
 420        .set_config     = s3c24xx_gpio_setcfg_abank,
 421        .get_config     = s3c24xx_gpio_getcfg_abank,
 422};
 423#endif
 424
 425#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
 426static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = {
 427        .cfg_eint       = 0x3,
 428        .set_config     = s5p64x0_gpio_setcfg_rbank,
 429        .get_config     = samsung_gpio_getcfg_4bit,
 430        .set_pull       = samsung_gpio_setpull_updown,
 431        .get_pull       = samsung_gpio_getpull_updown,
 432};
 433#endif
 434
 435static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
 436        [0] = {
 437                .cfg_eint       = 0x0,
 438        },
 439        [1] = {
 440                .cfg_eint       = 0x3,
 441        },
 442        [2] = {
 443                .cfg_eint       = 0x7,
 444        },
 445        [3] = {
 446                .cfg_eint       = 0xF,
 447        },
 448        [4] = {
 449                .cfg_eint       = 0x0,
 450                .set_config     = samsung_gpio_setcfg_2bit,
 451                .get_config     = samsung_gpio_getcfg_2bit,
 452        },
 453        [5] = {
 454                .cfg_eint       = 0x2,
 455                .set_config     = samsung_gpio_setcfg_2bit,
 456                .get_config     = samsung_gpio_getcfg_2bit,
 457        },
 458        [6] = {
 459                .cfg_eint       = 0x3,
 460                .set_config     = samsung_gpio_setcfg_2bit,
 461                .get_config     = samsung_gpio_getcfg_2bit,
 462        },
 463        [7] = {
 464                .set_config     = samsung_gpio_setcfg_2bit,
 465                .get_config     = samsung_gpio_getcfg_2bit,
 466        },
 467};
 468
 469/*
 470 * Default routines for controlling GPIO, based on the original S3C24XX
 471 * GPIO functions which deal with the case where each gpio bank of the
 472 * chip is as following:
 473 *
 474 * base + 0x00: Control register, 2 bits per gpio
 475 *              gpio n: 2 bits starting at (2*n)
 476 *              00 = input, 01 = output, others mean special-function
 477 * base + 0x04: Data register, 1 bit per gpio
 478 *              bit n: data bit n
 479*/
 480
 481static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
 482{
 483        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 484        void __iomem *base = ourchip->base;
 485        unsigned long flags;
 486        unsigned long con;
 487
 488        samsung_gpio_lock(ourchip, flags);
 489
 490        con = __raw_readl(base + 0x00);
 491        con &= ~(3 << (offset * 2));
 492
 493        __raw_writel(con, base + 0x00);
 494
 495        samsung_gpio_unlock(ourchip, flags);
 496        return 0;
 497}
 498
 499static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
 500                                       unsigned offset, int value)
 501{
 502        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 503        void __iomem *base = ourchip->base;
 504        unsigned long flags;
 505        unsigned long dat;
 506        unsigned long con;
 507
 508        samsung_gpio_lock(ourchip, flags);
 509
 510        dat = __raw_readl(base + 0x04);
 511        dat &= ~(1 << offset);
 512        if (value)
 513                dat |= 1 << offset;
 514        __raw_writel(dat, base + 0x04);
 515
 516        con = __raw_readl(base + 0x00);
 517        con &= ~(3 << (offset * 2));
 518        con |= 1 << (offset * 2);
 519
 520        __raw_writel(con, base + 0x00);
 521        __raw_writel(dat, base + 0x04);
 522
 523        samsung_gpio_unlock(ourchip, flags);
 524        return 0;
 525}
 526
 527/*
 528 * The samsung_gpiolib_4bit routines are to control the gpio banks where
 529 * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
 530 * following example:
 531 *
 532 * base + 0x00: Control register, 4 bits per gpio
 533 *              gpio n: 4 bits starting at (4*n)
 534 *              0000 = input, 0001 = output, others mean special-function
 535 * base + 0x04: Data register, 1 bit per gpio
 536 *              bit n: data bit n
 537 *
 538 * Note, since the data register is one bit per gpio and is at base + 0x4
 539 * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
 540 * state of the output.
 541 */
 542
 543static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
 544                                      unsigned int offset)
 545{
 546        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 547        void __iomem *base = ourchip->base;
 548        unsigned long con;
 549
 550        con = __raw_readl(base + GPIOCON_OFF);
 551        if (ourchip->bitmap_gpio_int & BIT(offset))
 552                con |= 0xf << con_4bit_shift(offset);
 553        else
 554                con &= ~(0xf << con_4bit_shift(offset));
 555        __raw_writel(con, base + GPIOCON_OFF);
 556
 557        pr_debug("%s: %p: CON now %08lx\n", __func__, base, con);
 558
 559        return 0;
 560}
 561
 562static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
 563                                       unsigned int offset, int value)
 564{
 565        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 566        void __iomem *base = ourchip->base;
 567        unsigned long con;
 568        unsigned long dat;
 569
 570        con = __raw_readl(base + GPIOCON_OFF);
 571        con &= ~(0xf << con_4bit_shift(offset));
 572        con |= 0x1 << con_4bit_shift(offset);
 573
 574        dat = __raw_readl(base + GPIODAT_OFF);
 575
 576        if (value)
 577                dat |= 1 << offset;
 578        else
 579                dat &= ~(1 << offset);
 580
 581        __raw_writel(dat, base + GPIODAT_OFF);
 582        __raw_writel(con, base + GPIOCON_OFF);
 583        __raw_writel(dat, base + GPIODAT_OFF);
 584
 585        pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
 586
 587        return 0;
 588}
 589
 590/*
 591 * The next set of routines are for the case where the GPIO configuration
 592 * registers are 4 bits per GPIO but there is more than one register (the
 593 * bank has more than 8 GPIOs.
 594 *
 595 * This case is the similar to the 4 bit case, but the registers are as
 596 * follows:
 597 *
 598 * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
 599 *              gpio n: 4 bits starting at (4*n)
 600 *              0000 = input, 0001 = output, others mean special-function
 601 * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
 602 *              gpio n: 4 bits starting at (4*n)
 603 *              0000 = input, 0001 = output, others mean special-function
 604 * base + 0x08: Data register, 1 bit per gpio
 605 *              bit n: data bit n
 606 *
 607 * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
 608 * routines we store the 'base + 0x4' address so that these routines see
 609 * the data register at ourchip->base + 0x04.
 610 */
 611
 612static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
 613                                       unsigned int offset)
 614{
 615        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 616        void __iomem *base = ourchip->base;
 617        void __iomem *regcon = base;
 618        unsigned long con;
 619
 620        if (offset > 7)
 621                offset -= 8;
 622        else
 623                regcon -= 4;
 624
 625        con = __raw_readl(regcon);
 626        con &= ~(0xf << con_4bit_shift(offset));
 627        __raw_writel(con, regcon);
 628
 629        pr_debug("%s: %p: CON %08lx\n", __func__, base, con);
 630
 631        return 0;
 632}
 633
 634static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
 635                                        unsigned int offset, int value)
 636{
 637        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 638        void __iomem *base = ourchip->base;
 639        void __iomem *regcon = base;
 640        unsigned long con;
 641        unsigned long dat;
 642        unsigned con_offset = offset;
 643
 644        if (con_offset > 7)
 645                con_offset -= 8;
 646        else
 647                regcon -= 4;
 648
 649        con = __raw_readl(regcon);
 650        con &= ~(0xf << con_4bit_shift(con_offset));
 651        con |= 0x1 << con_4bit_shift(con_offset);
 652
 653        dat = __raw_readl(base + GPIODAT_OFF);
 654
 655        if (value)
 656                dat |= 1 << offset;
 657        else
 658                dat &= ~(1 << offset);
 659
 660        __raw_writel(dat, base + GPIODAT_OFF);
 661        __raw_writel(con, regcon);
 662        __raw_writel(dat, base + GPIODAT_OFF);
 663
 664        pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
 665
 666        return 0;
 667}
 668
 669#ifdef CONFIG_PLAT_S3C24XX
 670/* The next set of routines are for the case of s3c24xx bank a */
 671
 672static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
 673{
 674        return -EINVAL;
 675}
 676
 677static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
 678                                        unsigned offset, int value)
 679{
 680        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 681        void __iomem *base = ourchip->base;
 682        unsigned long flags;
 683        unsigned long dat;
 684        unsigned long con;
 685
 686        local_irq_save(flags);
 687
 688        con = __raw_readl(base + 0x00);
 689        dat = __raw_readl(base + 0x04);
 690
 691        dat &= ~(1 << offset);
 692        if (value)
 693                dat |= 1 << offset;
 694
 695        __raw_writel(dat, base + 0x04);
 696
 697        con &= ~(1 << offset);
 698
 699        __raw_writel(con, base + 0x00);
 700        __raw_writel(dat, base + 0x04);
 701
 702        local_irq_restore(flags);
 703        return 0;
 704}
 705#endif
 706
 707/* The next set of routines are for the case of s5p64x0 bank r */
 708
 709static int s5p64x0_gpiolib_rbank_input(struct gpio_chip *chip,
 710                                       unsigned int offset)
 711{
 712        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 713        void __iomem *base = ourchip->base;
 714        void __iomem *regcon = base;
 715        unsigned long con;
 716        unsigned long flags;
 717
 718        switch (offset) {
 719        case 6:
 720                offset += 1;
 721        case 0:
 722        case 1:
 723        case 2:
 724        case 3:
 725        case 4:
 726        case 5:
 727                regcon -= 4;
 728                break;
 729        default:
 730                offset -= 7;
 731                break;
 732        }
 733
 734        samsung_gpio_lock(ourchip, flags);
 735
 736        con = __raw_readl(regcon);
 737        con &= ~(0xf << con_4bit_shift(offset));
 738        __raw_writel(con, regcon);
 739
 740        samsung_gpio_unlock(ourchip, flags);
 741
 742        return 0;
 743}
 744
 745static int s5p64x0_gpiolib_rbank_output(struct gpio_chip *chip,
 746                                        unsigned int offset, int value)
 747{
 748        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 749        void __iomem *base = ourchip->base;
 750        void __iomem *regcon = base;
 751        unsigned long con;
 752        unsigned long dat;
 753        unsigned long flags;
 754        unsigned con_offset  = offset;
 755
 756        switch (con_offset) {
 757        case 6:
 758                con_offset += 1;
 759        case 0:
 760        case 1:
 761        case 2:
 762        case 3:
 763        case 4:
 764        case 5:
 765                regcon -= 4;
 766                break;
 767        default:
 768                con_offset -= 7;
 769                break;
 770        }
 771
 772        samsung_gpio_lock(ourchip, flags);
 773
 774        con = __raw_readl(regcon);
 775        con &= ~(0xf << con_4bit_shift(con_offset));
 776        con |= 0x1 << con_4bit_shift(con_offset);
 777
 778        dat = __raw_readl(base + GPIODAT_OFF);
 779        if (value)
 780                dat |= 1 << offset;
 781        else
 782                dat &= ~(1 << offset);
 783
 784        __raw_writel(con, regcon);
 785        __raw_writel(dat, base + GPIODAT_OFF);
 786
 787        samsung_gpio_unlock(ourchip, flags);
 788
 789        return 0;
 790}
 791
 792static void samsung_gpiolib_set(struct gpio_chip *chip,
 793                                unsigned offset, int value)
 794{
 795        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 796        void __iomem *base = ourchip->base;
 797        unsigned long flags;
 798        unsigned long dat;
 799
 800        samsung_gpio_lock(ourchip, flags);
 801
 802        dat = __raw_readl(base + 0x04);
 803        dat &= ~(1 << offset);
 804        if (value)
 805                dat |= 1 << offset;
 806        __raw_writel(dat, base + 0x04);
 807
 808        samsung_gpio_unlock(ourchip, flags);
 809}
 810
 811static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
 812{
 813        struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
 814        unsigned long val;
 815
 816        val = __raw_readl(ourchip->base + 0x04);
 817        val >>= offset;
 818        val &= 1;
 819
 820        return val;
 821}
 822
 823/*
 824 * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
 825 * for use with the configuration calls, and other parts of the s3c gpiolib
 826 * support code.
 827 *
 828 * Not all s3c support code will need this, as some configurations of cpu
 829 * may only support one or two different configuration options and have an
 830 * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
 831 * the machine support file should provide its own samsung_gpiolib_getchip()
 832 * and any other necessary functions.
 833 */
 834
 835#ifdef CONFIG_S3C_GPIO_TRACK
 836struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
 837
 838static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
 839{
 840        unsigned int gpn;
 841        int i;
 842
 843        gpn = chip->chip.base;
 844        for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
 845                BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
 846                s3c_gpios[gpn] = chip;
 847        }
 848}
 849#endif /* CONFIG_S3C_GPIO_TRACK */
 850
 851/*
 852 * samsung_gpiolib_add() - add the Samsung gpio_chip.
 853 * @chip: The chip to register
 854 *
 855 * This is a wrapper to gpiochip_add() that takes our specific gpio chip
 856 * information and makes the necessary alterations for the platform and
 857 * notes the information for use with the configuration systems and any
 858 * other parts of the system.
 859 */
 860
 861static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
 862{
 863        struct gpio_chip *gc = &chip->chip;
 864        int ret;
 865
 866        BUG_ON(!chip->base);
 867        BUG_ON(!gc->label);
 868        BUG_ON(!gc->ngpio);
 869
 870        spin_lock_init(&chip->lock);
 871
 872        if (!gc->direction_input)
 873                gc->direction_input = samsung_gpiolib_2bit_input;
 874        if (!gc->direction_output)
 875                gc->direction_output = samsung_gpiolib_2bit_output;
 876        if (!gc->set)
 877                gc->set = samsung_gpiolib_set;
 878        if (!gc->get)
 879                gc->get = samsung_gpiolib_get;
 880
 881#ifdef CONFIG_PM
 882        if (chip->pm != NULL) {
 883                if (!chip->pm->save || !chip->pm->resume)
 884                        pr_err("gpio: %s has missing PM functions\n",
 885                               gc->label);
 886        } else
 887                pr_err("gpio: %s has no PM function\n", gc->label);
 888#endif
 889
 890        /* gpiochip_add() prints own failure message on error. */
 891        ret = gpiochip_add(gc);
 892        if (ret >= 0)
 893                s3c_gpiolib_track(chip);
 894}
 895
 896#if defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF)
 897static int s3c24xx_gpio_xlate(struct gpio_chip *gc,
 898                        const struct of_phandle_args *gpiospec, u32 *flags)
 899{
 900        unsigned int pin;
 901
 902        if (WARN_ON(gc->of_gpio_n_cells < 3))
 903                return -EINVAL;
 904
 905        if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
 906                return -EINVAL;
 907
 908        if (gpiospec->args[0] > gc->ngpio)
 909                return -EINVAL;
 910
 911        pin = gc->base + gpiospec->args[0];
 912
 913        if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
 914                pr_warn("gpio_xlate: failed to set pin function\n");
 915        if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff))
 916                pr_warn("gpio_xlate: failed to set pin pull up/down\n");
 917
 918        if (flags)
 919                *flags = gpiospec->args[2] >> 16;
 920
 921        return gpiospec->args[0];
 922}
 923
 924static const struct of_device_id s3c24xx_gpio_dt_match[] __initdata = {
 925        { .compatible = "samsung,s3c24xx-gpio", },
 926        {}
 927};
 928
 929static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
 930                                                 u64 base, u64 offset)
 931{
 932        struct gpio_chip *gc =  &chip->chip;
 933        u64 address;
 934
 935        if (!of_have_populated_dt())
 936                return;
 937
 938        address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
 939        gc->of_node = of_find_matching_node_by_address(NULL,
 940                        s3c24xx_gpio_dt_match, address);
 941        if (!gc->of_node) {
 942                pr_info("gpio: device tree node not found for gpio controller"
 943                        " with base address %08llx\n", address);
 944                return;
 945        }
 946        gc->of_gpio_n_cells = 3;
 947        gc->of_xlate = s3c24xx_gpio_xlate;
 948}
 949#else
 950static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
 951                                                 u64 base, u64 offset)
 952{
 953        return;
 954}
 955#endif /* defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF) */
 956
 957static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
 958                                             int nr_chips, void __iomem *base)
 959{
 960        int i;
 961        struct gpio_chip *gc = &chip->chip;
 962
 963        for (i = 0 ; i < nr_chips; i++, chip++) {
 964                /* skip banks not present on SoC */
 965                if (chip->chip.base >= S3C_GPIO_END)
 966                        continue;
 967
 968                if (!chip->config)
 969                        chip->config = &s3c24xx_gpiocfg_default;
 970                if (!chip->pm)
 971                        chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
 972                if ((base != NULL) && (chip->base == NULL))
 973                        chip->base = base + ((i) * 0x10);
 974
 975                if (!gc->direction_input)
 976                        gc->direction_input = samsung_gpiolib_2bit_input;
 977                if (!gc->direction_output)
 978                        gc->direction_output = samsung_gpiolib_2bit_output;
 979
 980                samsung_gpiolib_add(chip);
 981
 982                s3c24xx_gpiolib_attach_ofnode(chip, S3C24XX_PA_GPIO, i * 0x10);
 983        }
 984}
 985
 986static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
 987                                                  int nr_chips, void __iomem *base,
 988                                                  unsigned int offset)
 989{
 990        int i;
 991
 992        for (i = 0 ; i < nr_chips; i++, chip++) {
 993                chip->chip.direction_input = samsung_gpiolib_2bit_input;
 994                chip->chip.direction_output = samsung_gpiolib_2bit_output;
 995
 996                if (!chip->config)
 997                        chip->config = &samsung_gpio_cfgs[7];
 998                if (!chip->pm)
 999                        chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
1000                if ((base != NULL) && (chip->base == NULL))
1001                        chip->base = base + ((i) * offset);
1002
1003                samsung_gpiolib_add(chip);
1004        }
1005}
1006
1007/*
1008 * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
1009 * @chip: The gpio chip that is being configured.
1010 * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
1011 *
1012 * This helper deal with the GPIO cases where the control register has 4 bits
1013 * of control per GPIO, generally in the form of:
1014 * 0000 = Input
1015 * 0001 = Output
1016 * others = Special functions (dependent on bank)
1017 *
1018 * Note, since the code to deal with the case where there are two control
1019 * registers instead of one, we do not have a separate set of function
1020 * (samsung_gpiolib_add_4bit2_chips)for each case.
1021 */
1022
1023static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
1024                                                  int nr_chips, void __iomem *base)
1025{
1026        int i;
1027
1028        for (i = 0 ; i < nr_chips; i++, chip++) {
1029                chip->chip.direction_input = samsung_gpiolib_4bit_input;
1030                chip->chip.direction_output = samsung_gpiolib_4bit_output;
1031
1032                if (!chip->config)
1033                        chip->config = &samsung_gpio_cfgs[2];
1034                if (!chip->pm)
1035                        chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1036                if ((base != NULL) && (chip->base == NULL))
1037                        chip->base = base + ((i) * 0x20);
1038
1039                chip->bitmap_gpio_int = 0;
1040
1041                samsung_gpiolib_add(chip);
1042        }
1043}
1044
1045static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
1046                                                   int nr_chips)
1047{
1048        for (; nr_chips > 0; nr_chips--, chip++) {
1049                chip->chip.direction_input = samsung_gpiolib_4bit2_input;
1050                chip->chip.direction_output = samsung_gpiolib_4bit2_output;
1051
1052                if (!chip->config)
1053                        chip->config = &samsung_gpio_cfgs[2];
1054                if (!chip->pm)
1055                        chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1056
1057                samsung_gpiolib_add(chip);
1058        }
1059}
1060
1061static void __init s5p64x0_gpiolib_add_rbank(struct samsung_gpio_chip *chip,
1062                                             int nr_chips)
1063{
1064        for (; nr_chips > 0; nr_chips--, chip++) {
1065                chip->chip.direction_input = s5p64x0_gpiolib_rbank_input;
1066                chip->chip.direction_output = s5p64x0_gpiolib_rbank_output;
1067
1068                if (!chip->pm)
1069                        chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1070
1071                samsung_gpiolib_add(chip);
1072        }
1073}
1074
1075int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
1076{
1077        struct samsung_gpio_chip *samsung_chip = container_of(chip, struct samsung_gpio_chip, chip);
1078
1079        return samsung_chip->irq_base + offset;
1080}
1081
1082#ifdef CONFIG_PLAT_S3C24XX
1083static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
1084{
1085        if (offset < 4) {
1086                if (soc_is_s3c2412())
1087                        return IRQ_EINT0_2412 + offset;
1088                else
1089                        return IRQ_EINT0 + offset;
1090        }
1091
1092        if (offset < 8)
1093                return IRQ_EINT4 + offset - 4;
1094
1095        return -EINVAL;
1096}
1097#endif
1098
1099#ifdef CONFIG_ARCH_S3C64XX
1100static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
1101{
1102        return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
1103}
1104
1105static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
1106{
1107        return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
1108}
1109#endif
1110
1111struct samsung_gpio_chip s3c24xx_gpios[] = {
1112#ifdef CONFIG_PLAT_S3C24XX
1113        {
1114                .config = &s3c24xx_gpiocfg_banka,
1115                .chip   = {
1116                        .base                   = S3C2410_GPA(0),
1117                        .owner                  = THIS_MODULE,
1118                        .label                  = "GPIOA",
1119                        .ngpio                  = 24,
1120                        .direction_input        = s3c24xx_gpiolib_banka_input,
1121                        .direction_output       = s3c24xx_gpiolib_banka_output,
1122                },
1123        }, {
1124                .chip   = {
1125                        .base   = S3C2410_GPB(0),
1126                        .owner  = THIS_MODULE,
1127                        .label  = "GPIOB",
1128                        .ngpio  = 16,
1129                },
1130        }, {
1131                .chip   = {
1132                        .base   = S3C2410_GPC(0),
1133                        .owner  = THIS_MODULE,
1134                        .label  = "GPIOC",
1135                        .ngpio  = 16,
1136                },
1137        }, {
1138                .chip   = {
1139                        .base   = S3C2410_GPD(0),
1140                        .owner  = THIS_MODULE,
1141                        .label  = "GPIOD",
1142                        .ngpio  = 16,
1143                },
1144        }, {
1145                .chip   = {
1146                        .base   = S3C2410_GPE(0),
1147                        .label  = "GPIOE",
1148                        .owner  = THIS_MODULE,
1149                        .ngpio  = 16,
1150                },
1151        }, {
1152                .chip   = {
1153                        .base   = S3C2410_GPF(0),
1154                        .owner  = THIS_MODULE,
1155                        .label  = "GPIOF",
1156                        .ngpio  = 8,
1157                        .to_irq = s3c24xx_gpiolib_fbank_to_irq,
1158                },
1159        }, {
1160                .irq_base = IRQ_EINT8,
1161                .chip   = {
1162                        .base   = S3C2410_GPG(0),
1163                        .owner  = THIS_MODULE,
1164                        .label  = "GPIOG",
1165                        .ngpio  = 16,
1166                        .to_irq = samsung_gpiolib_to_irq,
1167                },
1168        }, {
1169                .chip   = {
1170                        .base   = S3C2410_GPH(0),
1171                        .owner  = THIS_MODULE,
1172                        .label  = "GPIOH",
1173                        .ngpio  = 11,
1174                },
1175        },
1176                /* GPIOS for the S3C2443 and later devices. */
1177        {
1178                .base   = S3C2440_GPJCON,
1179                .chip   = {
1180                        .base   = S3C2410_GPJ(0),
1181                        .owner  = THIS_MODULE,
1182                        .label  = "GPIOJ",
1183                        .ngpio  = 16,
1184                },
1185        }, {
1186                .base   = S3C2443_GPKCON,
1187                .chip   = {
1188                        .base   = S3C2410_GPK(0),
1189                        .owner  = THIS_MODULE,
1190                        .label  = "GPIOK",
1191                        .ngpio  = 16,
1192                },
1193        }, {
1194                .base   = S3C2443_GPLCON,
1195                .chip   = {
1196                        .base   = S3C2410_GPL(0),
1197                        .owner  = THIS_MODULE,
1198                        .label  = "GPIOL",
1199                        .ngpio  = 15,
1200                },
1201        }, {
1202                .base   = S3C2443_GPMCON,
1203                .chip   = {
1204                        .base   = S3C2410_GPM(0),
1205                        .owner  = THIS_MODULE,
1206                        .label  = "GPIOM",
1207                        .ngpio  = 2,
1208                },
1209        },
1210#endif
1211};
1212
1213/*
1214 * GPIO bank summary:
1215 *
1216 * Bank GPIOs   Style   SlpCon  ExtInt Group
1217 * A    8       4Bit    Yes     1
1218 * B    7       4Bit    Yes     1
1219 * C    8       4Bit    Yes     2
1220 * D    5       4Bit    Yes     3
1221 * E    5       4Bit    Yes     None
1222 * F    16      2Bit    Yes     4 [1]
1223 * G    7       4Bit    Yes     5
1224 * H    10      4Bit[2] Yes     6
1225 * I    16      2Bit    Yes     None
1226 * J    12      2Bit    Yes     None
1227 * K    16      4Bit[2] No      None
1228 * L    15      4Bit[2] No      None
1229 * M    6       4Bit    No      IRQ_EINT
1230 * N    16      2Bit    No      IRQ_EINT
1231 * O    16      2Bit    Yes     7
1232 * P    15      2Bit    Yes     8
1233 * Q    9       2Bit    Yes     9
1234 *
1235 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
1236 * [2] BANK has two control registers, GPxCON0 and GPxCON1
1237 */
1238
1239static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
1240#ifdef CONFIG_ARCH_S3C64XX
1241        {
1242                .chip   = {
1243                        .base   = S3C64XX_GPA(0),
1244                        .ngpio  = S3C64XX_GPIO_A_NR,
1245                        .label  = "GPA",
1246                },
1247        }, {
1248                .chip   = {
1249                        .base   = S3C64XX_GPB(0),
1250                        .ngpio  = S3C64XX_GPIO_B_NR,
1251                        .label  = "GPB",
1252                },
1253        }, {
1254                .chip   = {
1255                        .base   = S3C64XX_GPC(0),
1256                        .ngpio  = S3C64XX_GPIO_C_NR,
1257                        .label  = "GPC",
1258                },
1259        }, {
1260                .chip   = {
1261                        .base   = S3C64XX_GPD(0),
1262                        .ngpio  = S3C64XX_GPIO_D_NR,
1263                        .label  = "GPD",
1264                },
1265        }, {
1266                .config = &samsung_gpio_cfgs[0],
1267                .chip   = {
1268                        .base   = S3C64XX_GPE(0),
1269                        .ngpio  = S3C64XX_GPIO_E_NR,
1270                        .label  = "GPE",
1271                },
1272        }, {
1273                .base   = S3C64XX_GPG_BASE,
1274                .chip   = {
1275                        .base   = S3C64XX_GPG(0),
1276                        .ngpio  = S3C64XX_GPIO_G_NR,
1277                        .label  = "GPG",
1278                },
1279        }, {
1280                .base   = S3C64XX_GPM_BASE,
1281                .config = &samsung_gpio_cfgs[1],
1282                .chip   = {
1283                        .base   = S3C64XX_GPM(0),
1284                        .ngpio  = S3C64XX_GPIO_M_NR,
1285                        .label  = "GPM",
1286                        .to_irq = s3c64xx_gpiolib_mbank_to_irq,
1287                },
1288        },
1289#endif
1290};
1291
1292static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
1293#ifdef CONFIG_ARCH_S3C64XX
1294        {
1295                .base   = S3C64XX_GPH_BASE + 0x4,
1296                .chip   = {
1297                        .base   = S3C64XX_GPH(0),
1298                        .ngpio  = S3C64XX_GPIO_H_NR,
1299                        .label  = "GPH",
1300                },
1301        }, {
1302                .base   = S3C64XX_GPK_BASE + 0x4,
1303                .config = &samsung_gpio_cfgs[0],
1304                .chip   = {
1305                        .base   = S3C64XX_GPK(0),
1306                        .ngpio  = S3C64XX_GPIO_K_NR,
1307                        .label  = "GPK",
1308                },
1309        }, {
1310                .base   = S3C64XX_GPL_BASE + 0x4,
1311                .config = &samsung_gpio_cfgs[1],
1312                .chip   = {
1313                        .base   = S3C64XX_GPL(0),
1314                        .ngpio  = S3C64XX_GPIO_L_NR,
1315                        .label  = "GPL",
1316                        .to_irq = s3c64xx_gpiolib_lbank_to_irq,
1317                },
1318        },
1319#endif
1320};
1321
1322static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
1323#ifdef CONFIG_ARCH_S3C64XX
1324        {
1325                .base   = S3C64XX_GPF_BASE,
1326                .config = &samsung_gpio_cfgs[6],
1327                .chip   = {
1328                        .base   = S3C64XX_GPF(0),
1329                        .ngpio  = S3C64XX_GPIO_F_NR,
1330                        .label  = "GPF",
1331                },
1332        }, {
1333                .config = &samsung_gpio_cfgs[7],
1334                .chip   = {
1335                        .base   = S3C64XX_GPI(0),
1336                        .ngpio  = S3C64XX_GPIO_I_NR,
1337                        .label  = "GPI",
1338                },
1339        }, {
1340                .config = &samsung_gpio_cfgs[7],
1341                .chip   = {
1342                        .base   = S3C64XX_GPJ(0),
1343                        .ngpio  = S3C64XX_GPIO_J_NR,
1344                        .label  = "GPJ",
1345                },
1346        }, {
1347                .config = &samsung_gpio_cfgs[6],
1348                .chip   = {
1349                        .base   = S3C64XX_GPO(0),
1350                        .ngpio  = S3C64XX_GPIO_O_NR,
1351                        .label  = "GPO",
1352                },
1353        }, {
1354                .config = &samsung_gpio_cfgs[6],
1355                .chip   = {
1356                        .base   = S3C64XX_GPP(0),
1357                        .ngpio  = S3C64XX_GPIO_P_NR,
1358                        .label  = "GPP",
1359                },
1360        }, {
1361                .config = &samsung_gpio_cfgs[6],
1362                .chip   = {
1363                        .base   = S3C64XX_GPQ(0),
1364                        .ngpio  = S3C64XX_GPIO_Q_NR,
1365                        .label  = "GPQ",
1366                },
1367        }, {
1368                .base   = S3C64XX_GPN_BASE,
1369                .irq_base = IRQ_EINT(0),
1370                .config = &samsung_gpio_cfgs[5],
1371                .chip   = {
1372                        .base   = S3C64XX_GPN(0),
1373                        .ngpio  = S3C64XX_GPIO_N_NR,
1374                        .label  = "GPN",
1375                        .to_irq = samsung_gpiolib_to_irq,
1376                },
1377        },
1378#endif
1379};
1380
1381/*
1382 * S5P6440 GPIO bank summary:
1383 *
1384 * Bank GPIOs   Style   SlpCon  ExtInt Group
1385 * A    6       4Bit    Yes     1
1386 * B    7       4Bit    Yes     1
1387 * C    8       4Bit    Yes     2
1388 * F    2       2Bit    Yes     4 [1]
1389 * G    7       4Bit    Yes     5
1390 * H    10      4Bit[2] Yes     6
1391 * I    16      2Bit    Yes     None
1392 * J    12      2Bit    Yes     None
1393 * N    16      2Bit    No      IRQ_EINT
1394 * P    8       2Bit    Yes     8
1395 * R    15      4Bit[2] Yes     8
1396 */
1397
1398static struct samsung_gpio_chip s5p6440_gpios_4bit[] = {
1399#ifdef CONFIG_CPU_S5P6440
1400        {
1401                .chip   = {
1402                        .base   = S5P6440_GPA(0),
1403                        .ngpio  = S5P6440_GPIO_A_NR,
1404                        .label  = "GPA",
1405                },
1406        }, {
1407                .chip   = {
1408                        .base   = S5P6440_GPB(0),
1409                        .ngpio  = S5P6440_GPIO_B_NR,
1410                        .label  = "GPB",
1411                },
1412        }, {
1413                .chip   = {
1414                        .base   = S5P6440_GPC(0),
1415                        .ngpio  = S5P6440_GPIO_C_NR,
1416                        .label  = "GPC",
1417                },
1418        }, {
1419                .base   = S5P64X0_GPG_BASE,
1420                .chip   = {
1421                        .base   = S5P6440_GPG(0),
1422                        .ngpio  = S5P6440_GPIO_G_NR,
1423                        .label  = "GPG",
1424                },
1425        },
1426#endif
1427};
1428
1429static struct samsung_gpio_chip s5p6440_gpios_4bit2[] = {
1430#ifdef CONFIG_CPU_S5P6440
1431        {
1432                .base   = S5P64X0_GPH_BASE + 0x4,
1433                .chip   = {
1434                        .base   = S5P6440_GPH(0),
1435                        .ngpio  = S5P6440_GPIO_H_NR,
1436                        .label  = "GPH",
1437                },
1438        },
1439#endif
1440};
1441
1442static struct samsung_gpio_chip s5p6440_gpios_rbank[] = {
1443#ifdef CONFIG_CPU_S5P6440
1444        {
1445                .base   = S5P64X0_GPR_BASE + 0x4,
1446                .config = &s5p64x0_gpio_cfg_rbank,
1447                .chip   = {
1448                        .base   = S5P6440_GPR(0),
1449                        .ngpio  = S5P6440_GPIO_R_NR,
1450                        .label  = "GPR",
1451                },
1452        },
1453#endif
1454};
1455
1456static struct samsung_gpio_chip s5p6440_gpios_2bit[] = {
1457#ifdef CONFIG_CPU_S5P6440
1458        {
1459                .base   = S5P64X0_GPF_BASE,
1460                .config = &samsung_gpio_cfgs[6],
1461                .chip   = {
1462                        .base   = S5P6440_GPF(0),
1463                        .ngpio  = S5P6440_GPIO_F_NR,
1464                        .label  = "GPF",
1465                },
1466        }, {
1467                .base   = S5P64X0_GPI_BASE,
1468                .config = &samsung_gpio_cfgs[4],
1469                .chip   = {
1470                        .base   = S5P6440_GPI(0),
1471                        .ngpio  = S5P6440_GPIO_I_NR,
1472                        .label  = "GPI",
1473                },
1474        }, {
1475                .base   = S5P64X0_GPJ_BASE,
1476                .config = &samsung_gpio_cfgs[4],
1477                .chip   = {
1478                        .base   = S5P6440_GPJ(0),
1479                        .ngpio  = S5P6440_GPIO_J_NR,
1480                        .label  = "GPJ",
1481                },
1482        }, {
1483                .base   = S5P64X0_GPN_BASE,
1484                .config = &samsung_gpio_cfgs[5],
1485                .chip   = {
1486                        .base   = S5P6440_GPN(0),
1487                        .ngpio  = S5P6440_GPIO_N_NR,
1488                        .label  = "GPN",
1489                },
1490        }, {
1491                .base   = S5P64X0_GPP_BASE,
1492                .config = &samsung_gpio_cfgs[6],
1493                .chip   = {
1494                        .base   = S5P6440_GPP(0),
1495                        .ngpio  = S5P6440_GPIO_P_NR,
1496                        .label  = "GPP",
1497                },
1498        },
1499#endif
1500};
1501
1502/*
1503 * S5P6450 GPIO bank summary:
1504 *
1505 * Bank GPIOs   Style   SlpCon  ExtInt Group
1506 * A    6       4Bit    Yes     1
1507 * B    7       4Bit    Yes     1
1508 * C    8       4Bit    Yes     2
1509 * D    8       4Bit    Yes     None
1510 * F    2       2Bit    Yes     None
1511 * G    14      4Bit[2] Yes     5
1512 * H    10      4Bit[2] Yes     6
1513 * I    16      2Bit    Yes     None
1514 * J    12      2Bit    Yes     None
1515 * K    5       4Bit    Yes     None
1516 * N    16      2Bit    No      IRQ_EINT
1517 * P    11      2Bit    Yes     8
1518 * Q    14      2Bit    Yes     None
1519 * R    15      4Bit[2] Yes     None
1520 * S    8       2Bit    Yes     None
1521 *
1522 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
1523 * [2] BANK has two control registers, GPxCON0 and GPxCON1
1524 */
1525
1526static struct samsung_gpio_chip s5p6450_gpios_4bit[] = {
1527#ifdef CONFIG_CPU_S5P6450
1528        {
1529                .chip   = {
1530                        .base   = S5P6450_GPA(0),
1531                        .ngpio  = S5P6450_GPIO_A_NR,
1532                        .label  = "GPA",
1533                },
1534        }, {
1535                .chip   = {
1536                        .base   = S5P6450_GPB(0),
1537                        .ngpio  = S5P6450_GPIO_B_NR,
1538                        .label  = "GPB",
1539                },
1540        }, {
1541                .chip   = {
1542                        .base   = S5P6450_GPC(0),
1543                        .ngpio  = S5P6450_GPIO_C_NR,
1544                        .label  = "GPC",
1545                },
1546        }, {
1547                .chip   = {
1548                        .base   = S5P6450_GPD(0),
1549                        .ngpio  = S5P6450_GPIO_D_NR,
1550                        .label  = "GPD",
1551                },
1552        }, {
1553                .base   = S5P6450_GPK_BASE,
1554                .chip   = {
1555                        .base   = S5P6450_GPK(0),
1556                        .ngpio  = S5P6450_GPIO_K_NR,
1557                        .label  = "GPK",
1558                },
1559        },
1560#endif
1561};
1562
1563static struct samsung_gpio_chip s5p6450_gpios_4bit2[] = {
1564#ifdef CONFIG_CPU_S5P6450
1565        {
1566                .base   = S5P64X0_GPG_BASE + 0x4,
1567                .chip   = {
1568                        .base   = S5P6450_GPG(0),
1569                        .ngpio  = S5P6450_GPIO_G_NR,
1570                        .label  = "GPG",
1571                },
1572        }, {
1573                .base   = S5P64X0_GPH_BASE + 0x4,
1574                .chip   = {
1575                        .base   = S5P6450_GPH(0),
1576                        .ngpio  = S5P6450_GPIO_H_NR,
1577                        .label  = "GPH",
1578                },
1579        },
1580#endif
1581};
1582
1583static struct samsung_gpio_chip s5p6450_gpios_rbank[] = {
1584#ifdef CONFIG_CPU_S5P6450
1585        {
1586                .base   = S5P64X0_GPR_BASE + 0x4,
1587                .config = &s5p64x0_gpio_cfg_rbank,
1588                .chip   = {
1589                        .base   = S5P6450_GPR(0),
1590                        .ngpio  = S5P6450_GPIO_R_NR,
1591                        .label  = "GPR",
1592                },
1593        },
1594#endif
1595};
1596
1597static struct samsung_gpio_chip s5p6450_gpios_2bit[] = {
1598#ifdef CONFIG_CPU_S5P6450
1599        {
1600                .base   = S5P64X0_GPF_BASE,
1601                .config = &samsung_gpio_cfgs[6],
1602                .chip   = {
1603                        .base   = S5P6450_GPF(0),
1604                        .ngpio  = S5P6450_GPIO_F_NR,
1605                        .label  = "GPF",
1606                },
1607        }, {
1608                .base   = S5P64X0_GPI_BASE,
1609                .config = &samsung_gpio_cfgs[4],
1610                .chip   = {
1611                        .base   = S5P6450_GPI(0),
1612                        .ngpio  = S5P6450_GPIO_I_NR,
1613                        .label  = "GPI",
1614                },
1615        }, {
1616                .base   = S5P64X0_GPJ_BASE,
1617                .config = &samsung_gpio_cfgs[4],
1618                .chip   = {
1619                        .base   = S5P6450_GPJ(0),
1620                        .ngpio  = S5P6450_GPIO_J_NR,
1621                        .label  = "GPJ",
1622                },
1623        }, {
1624                .base   = S5P64X0_GPN_BASE,
1625                .config = &samsung_gpio_cfgs[5],
1626                .chip   = {
1627                        .base   = S5P6450_GPN(0),
1628                        .ngpio  = S5P6450_GPIO_N_NR,
1629                        .label  = "GPN",
1630                },
1631        }, {
1632                .base   = S5P64X0_GPP_BASE,
1633                .config = &samsung_gpio_cfgs[6],
1634                .chip   = {
1635                        .base   = S5P6450_GPP(0),
1636                        .ngpio  = S5P6450_GPIO_P_NR,
1637                        .label  = "GPP",
1638                },
1639        }, {
1640                .base   = S5P6450_GPQ_BASE,
1641                .config = &samsung_gpio_cfgs[5],
1642                .chip   = {
1643                        .base   = S5P6450_GPQ(0),
1644                        .ngpio  = S5P6450_GPIO_Q_NR,
1645                        .label  = "GPQ",
1646                },
1647        }, {
1648                .base   = S5P6450_GPS_BASE,
1649                .config = &samsung_gpio_cfgs[6],
1650                .chip   = {
1651                        .base   = S5P6450_GPS(0),
1652                        .ngpio  = S5P6450_GPIO_S_NR,
1653                        .label  = "GPS",
1654                },
1655        },
1656#endif
1657};
1658
1659/*
1660 * S5PC100 GPIO bank summary:
1661 *
1662 * Bank GPIOs   Style   INT Type
1663 * A0   8       4Bit    GPIO_INT0
1664 * A1   5       4Bit    GPIO_INT1
1665 * B    8       4Bit    GPIO_INT2
1666 * C    5       4Bit    GPIO_INT3
1667 * D    7       4Bit    GPIO_INT4
1668 * E0   8       4Bit    GPIO_INT5
1669 * E1   6       4Bit    GPIO_INT6
1670 * F0   8       4Bit    GPIO_INT7
1671 * F1   8       4Bit    GPIO_INT8
1672 * F2   8       4Bit    GPIO_INT9
1673 * F3   4       4Bit    GPIO_INT10
1674 * G0   8       4Bit    GPIO_INT11
1675 * G1   3       4Bit    GPIO_INT12
1676 * G2   7       4Bit    GPIO_INT13
1677 * G3   7       4Bit    GPIO_INT14
1678 * H0   8       4Bit    WKUP_INT
1679 * H1   8       4Bit    WKUP_INT
1680 * H2   8       4Bit    WKUP_INT
1681 * H3   8       4Bit    WKUP_INT
1682 * I    8       4Bit    GPIO_INT15
1683 * J0   8       4Bit    GPIO_INT16
1684 * J1   5       4Bit    GPIO_INT17
1685 * J2   8       4Bit    GPIO_INT18
1686 * J3   8       4Bit    GPIO_INT19
1687 * J4   4       4Bit    GPIO_INT20
1688 * K0   8       4Bit    None
1689 * K1   6       4Bit    None
1690 * K2   8       4Bit    None
1691 * K3   8       4Bit    None
1692 * L0   8       4Bit    None
1693 * L1   8       4Bit    None
1694 * L2   8       4Bit    None
1695 * L3   8       4Bit    None
1696 */
1697
1698static struct samsung_gpio_chip s5pc100_gpios_4bit[] = {
1699#ifdef CONFIG_CPU_S5PC100
1700        {
1701                .chip   = {
1702                        .base   = S5PC100_GPA0(0),
1703                        .ngpio  = S5PC100_GPIO_A0_NR,
1704                        .label  = "GPA0",
1705                },
1706        }, {
1707                .chip   = {
1708                        .base   = S5PC100_GPA1(0),
1709                        .ngpio  = S5PC100_GPIO_A1_NR,
1710                        .label  = "GPA1",
1711                },
1712        }, {
1713                .chip   = {
1714                        .base   = S5PC100_GPB(0),
1715                        .ngpio  = S5PC100_GPIO_B_NR,
1716                        .label  = "GPB",
1717                },
1718        }, {
1719                .chip   = {
1720                        .base   = S5PC100_GPC(0),
1721                        .ngpio  = S5PC100_GPIO_C_NR,
1722                        .label  = "GPC",
1723                },
1724        }, {
1725                .chip   = {
1726                        .base   = S5PC100_GPD(0),
1727                        .ngpio  = S5PC100_GPIO_D_NR,
1728                        .label  = "GPD",
1729                },
1730        }, {
1731                .chip   = {
1732                        .base   = S5PC100_GPE0(0),
1733                        .ngpio  = S5PC100_GPIO_E0_NR,
1734                        .label  = "GPE0",
1735                },
1736        }, {
1737                .chip   = {
1738                        .base   = S5PC100_GPE1(0),
1739                        .ngpio  = S5PC100_GPIO_E1_NR,
1740                        .label  = "GPE1",
1741                },
1742        }, {
1743                .chip   = {
1744                        .base   = S5PC100_GPF0(0),
1745                        .ngpio  = S5PC100_GPIO_F0_NR,
1746                        .label  = "GPF0",
1747                },
1748        }, {
1749                .chip   = {
1750                        .base   = S5PC100_GPF1(0),
1751                        .ngpio  = S5PC100_GPIO_F1_NR,
1752                        .label  = "GPF1",
1753                },
1754        }, {
1755                .chip   = {
1756                        .base   = S5PC100_GPF2(0),
1757                        .ngpio  = S5PC100_GPIO_F2_NR,
1758                        .label  = "GPF2",
1759                },
1760        }, {
1761                .chip   = {
1762                        .base   = S5PC100_GPF3(0),
1763                        .ngpio  = S5PC100_GPIO_F3_NR,
1764                        .label  = "GPF3",
1765                },
1766        }, {
1767                .chip   = {
1768                        .base   = S5PC100_GPG0(0),
1769                        .ngpio  = S5PC100_GPIO_G0_NR,
1770                        .label  = "GPG0",
1771                },
1772        }, {
1773                .chip   = {
1774                        .base   = S5PC100_GPG1(0),
1775                        .ngpio  = S5PC100_GPIO_G1_NR,
1776                        .label  = "GPG1",
1777                },
1778        }, {
1779                .chip   = {
1780                        .base   = S5PC100_GPG2(0),
1781                        .ngpio  = S5PC100_GPIO_G2_NR,
1782                        .label  = "GPG2",
1783                },
1784        }, {
1785                .chip   = {
1786                        .base   = S5PC100_GPG3(0),
1787                        .ngpio  = S5PC100_GPIO_G3_NR,
1788                        .label  = "GPG3",
1789                },
1790        }, {
1791                .chip   = {
1792                        .base   = S5PC100_GPI(0),
1793                        .ngpio  = S5PC100_GPIO_I_NR,
1794                        .label  = "GPI",
1795                },
1796        }, {
1797                .chip   = {
1798                        .base   = S5PC100_GPJ0(0),
1799                        .ngpio  = S5PC100_GPIO_J0_NR,
1800                        .label  = "GPJ0",
1801                },
1802        }, {
1803                .chip   = {
1804                        .base   = S5PC100_GPJ1(0),
1805                        .ngpio  = S5PC100_GPIO_J1_NR,
1806                        .label  = "GPJ1",
1807                },
1808        }, {
1809                .chip   = {
1810                        .base   = S5PC100_GPJ2(0),
1811                        .ngpio  = S5PC100_GPIO_J2_NR,
1812                        .label  = "GPJ2",
1813                },
1814        }, {
1815                .chip   = {
1816                        .base   = S5PC100_GPJ3(0),
1817                        .ngpio  = S5PC100_GPIO_J3_NR,
1818                        .label  = "GPJ3",
1819                },
1820        }, {
1821                .chip   = {
1822                        .base   = S5PC100_GPJ4(0),
1823                        .ngpio  = S5PC100_GPIO_J4_NR,
1824                        .label  = "GPJ4",
1825                },
1826        }, {
1827                .chip   = {
1828                        .base   = S5PC100_GPK0(0),
1829                        .ngpio  = S5PC100_GPIO_K0_NR,
1830                        .label  = "GPK0",
1831                },
1832        }, {
1833                .chip   = {
1834                        .base   = S5PC100_GPK1(0),
1835                        .ngpio  = S5PC100_GPIO_K1_NR,
1836                        .label  = "GPK1",
1837                },
1838        }, {
1839                .chip   = {
1840                        .base   = S5PC100_GPK2(0),
1841                        .ngpio  = S5PC100_GPIO_K2_NR,
1842                        .label  = "GPK2",
1843                },
1844        }, {
1845                .chip   = {
1846                        .base   = S5PC100_GPK3(0),
1847                        .ngpio  = S5PC100_GPIO_K3_NR,
1848                        .label  = "GPK3",
1849                },
1850        }, {
1851                .chip   = {
1852                        .base   = S5PC100_GPL0(0),
1853                        .ngpio  = S5PC100_GPIO_L0_NR,
1854                        .label  = "GPL0",
1855                },
1856        }, {
1857                .chip   = {
1858                        .base   = S5PC100_GPL1(0),
1859                        .ngpio  = S5PC100_GPIO_L1_NR,
1860                        .label  = "GPL1",
1861                },
1862        }, {
1863                .chip   = {
1864                        .base   = S5PC100_GPL2(0),
1865                        .ngpio  = S5PC100_GPIO_L2_NR,
1866                        .label  = "GPL2",
1867                },
1868        }, {
1869                .chip   = {
1870                        .base   = S5PC100_GPL3(0),
1871                        .ngpio  = S5PC100_GPIO_L3_NR,
1872                        .label  = "GPL3",
1873                },
1874        }, {
1875                .chip   = {
1876                        .base   = S5PC100_GPL4(0),
1877                        .ngpio  = S5PC100_GPIO_L4_NR,
1878                        .label  = "GPL4",
1879                },
1880        }, {
1881                .base   = (S5P_VA_GPIO + 0xC00),
1882                .irq_base = IRQ_EINT(0),
1883                .chip   = {
1884                        .base   = S5PC100_GPH0(0),
1885                        .ngpio  = S5PC100_GPIO_H0_NR,
1886                        .label  = "GPH0",
1887                        .to_irq = samsung_gpiolib_to_irq,
1888                },
1889        }, {
1890                .base   = (S5P_VA_GPIO + 0xC20),
1891                .irq_base = IRQ_EINT(8),
1892                .chip   = {
1893                        .base   = S5PC100_GPH1(0),
1894                        .ngpio  = S5PC100_GPIO_H1_NR,
1895                        .label  = "GPH1",
1896                        .to_irq = samsung_gpiolib_to_irq,
1897                },
1898        }, {
1899                .base   = (S5P_VA_GPIO + 0xC40),
1900                .irq_base = IRQ_EINT(16),
1901                .chip   = {
1902                        .base   = S5PC100_GPH2(0),
1903                        .ngpio  = S5PC100_GPIO_H2_NR,
1904                        .label  = "GPH2",
1905                        .to_irq = samsung_gpiolib_to_irq,
1906                },
1907        }, {
1908                .base   = (S5P_VA_GPIO + 0xC60),
1909                .irq_base = IRQ_EINT(24),
1910                .chip   = {
1911                        .base   = S5PC100_GPH3(0),
1912                        .ngpio  = S5PC100_GPIO_H3_NR,
1913                        .label  = "GPH3",
1914                        .to_irq = samsung_gpiolib_to_irq,
1915                },
1916        },
1917#endif
1918};
1919
1920/*
1921 * Followings are the gpio banks in S5PV210/S5PC110
1922 *
1923 * The 'config' member when left to NULL, is initialized to the default
1924 * structure samsung_gpio_cfgs[3] in the init function below.
1925 *
1926 * The 'base' member is also initialized in the init function below.
1927 * Note: The initialization of 'base' member of samsung_gpio_chip structure
1928 * uses the above macro and depends on the banks being listed in order here.
1929 */
1930
1931static struct samsung_gpio_chip s5pv210_gpios_4bit[] = {
1932#ifdef CONFIG_CPU_S5PV210
1933        {
1934                .chip   = {
1935                        .base   = S5PV210_GPA0(0),
1936                        .ngpio  = S5PV210_GPIO_A0_NR,
1937                        .label  = "GPA0",
1938                },
1939        }, {
1940                .chip   = {
1941                        .base   = S5PV210_GPA1(0),
1942                        .ngpio  = S5PV210_GPIO_A1_NR,
1943                        .label  = "GPA1",
1944                },
1945        }, {
1946                .chip   = {
1947                        .base   = S5PV210_GPB(0),
1948                        .ngpio  = S5PV210_GPIO_B_NR,
1949                        .label  = "GPB",
1950                },
1951        }, {
1952                .chip   = {
1953                        .base   = S5PV210_GPC0(0),
1954                        .ngpio  = S5PV210_GPIO_C0_NR,
1955                        .label  = "GPC0",
1956                },
1957        }, {
1958                .chip   = {
1959                        .base   = S5PV210_GPC1(0),
1960                        .ngpio  = S5PV210_GPIO_C1_NR,
1961                        .label  = "GPC1",
1962                },
1963        }, {
1964                .chip   = {
1965                        .base   = S5PV210_GPD0(0),
1966                        .ngpio  = S5PV210_GPIO_D0_NR,
1967                        .label  = "GPD0",
1968                },
1969        }, {
1970                .chip   = {
1971                        .base   = S5PV210_GPD1(0),
1972                        .ngpio  = S5PV210_GPIO_D1_NR,
1973                        .label  = "GPD1",
1974                },
1975        }, {
1976                .chip   = {
1977                        .base   = S5PV210_GPE0(0),
1978                        .ngpio  = S5PV210_GPIO_E0_NR,
1979                        .label  = "GPE0",
1980                },
1981        }, {
1982                .chip   = {
1983                        .base   = S5PV210_GPE1(0),
1984                        .ngpio  = S5PV210_GPIO_E1_NR,
1985                        .label  = "GPE1",
1986                },
1987        }, {
1988                .chip   = {
1989                        .base   = S5PV210_GPF0(0),
1990                        .ngpio  = S5PV210_GPIO_F0_NR,
1991                        .label  = "GPF0",
1992                },
1993        }, {
1994                .chip   = {
1995                        .base   = S5PV210_GPF1(0),
1996                        .ngpio  = S5PV210_GPIO_F1_NR,
1997                        .label  = "GPF1",
1998                },
1999        }, {
2000                .chip   = {
2001                        .base   = S5PV210_GPF2(0),
2002                        .ngpio  = S5PV210_GPIO_F2_NR,
2003                        .label  = "GPF2",
2004                },
2005        }, {
2006                .chip   = {
2007                        .base   = S5PV210_GPF3(0),
2008                        .ngpio  = S5PV210_GPIO_F3_NR,
2009                        .label  = "GPF3",
2010                },
2011        }, {
2012                .chip   = {
2013                        .base   = S5PV210_GPG0(0),
2014                        .ngpio  = S5PV210_GPIO_G0_NR,
2015                        .label  = "GPG0",
2016                },
2017        }, {
2018                .chip   = {
2019                        .base   = S5PV210_GPG1(0),
2020                        .ngpio  = S5PV210_GPIO_G1_NR,
2021                        .label  = "GPG1",
2022                },
2023        }, {
2024                .chip   = {
2025                        .base   = S5PV210_GPG2(0),
2026                        .ngpio  = S5PV210_GPIO_G2_NR,
2027                        .label  = "GPG2",
2028                },
2029        }, {
2030                .chip   = {
2031                        .base   = S5PV210_GPG3(0),
2032                        .ngpio  = S5PV210_GPIO_G3_NR,
2033                        .label  = "GPG3",
2034                },
2035        }, {
2036                .chip   = {
2037                        .base   = S5PV210_GPI(0),
2038                        .ngpio  = S5PV210_GPIO_I_NR,
2039                        .label  = "GPI",
2040                },
2041        }, {
2042                .chip   = {
2043                        .base   = S5PV210_GPJ0(0),
2044                        .ngpio  = S5PV210_GPIO_J0_NR,
2045                        .label  = "GPJ0",
2046                },
2047        }, {
2048                .chip   = {
2049                        .base   = S5PV210_GPJ1(0),
2050                        .ngpio  = S5PV210_GPIO_J1_NR,
2051                        .label  = "GPJ1",
2052                },
2053        }, {
2054                .chip   = {
2055                        .base   = S5PV210_GPJ2(0),
2056                        .ngpio  = S5PV210_GPIO_J2_NR,
2057                        .label  = "GPJ2",
2058                },
2059        }, {
2060                .chip   = {
2061                        .base   = S5PV210_GPJ3(0),
2062                        .ngpio  = S5PV210_GPIO_J3_NR,
2063                        .label  = "GPJ3",
2064                },
2065        }, {
2066                .chip   = {
2067                        .base   = S5PV210_GPJ4(0),
2068                        .ngpio  = S5PV210_GPIO_J4_NR,
2069                        .label  = "GPJ4",
2070                },
2071        }, {
2072                .chip   = {
2073                        .base   = S5PV210_MP01(0),
2074                        .ngpio  = S5PV210_GPIO_MP01_NR,
2075                        .label  = "MP01",
2076                },
2077        }, {
2078                .chip   = {
2079                        .base   = S5PV210_MP02(0),
2080                        .ngpio  = S5PV210_GPIO_MP02_NR,
2081                        .label  = "MP02",
2082                },
2083        }, {
2084                .chip   = {
2085                        .base   = S5PV210_MP03(0),
2086                        .ngpio  = S5PV210_GPIO_MP03_NR,
2087                        .label  = "MP03",
2088                },
2089        }, {
2090                .chip   = {
2091                        .base   = S5PV210_MP04(0),
2092                        .ngpio  = S5PV210_GPIO_MP04_NR,
2093                        .label  = "MP04",
2094                },
2095        }, {
2096                .chip   = {
2097                        .base   = S5PV210_MP05(0),
2098                        .ngpio  = S5PV210_GPIO_MP05_NR,
2099                        .label  = "MP05",
2100                },
2101        }, {
2102                .base   = (S5P_VA_GPIO + 0xC00),
2103                .irq_base = IRQ_EINT(0),
2104                .chip   = {
2105                        .base   = S5PV210_GPH0(0),
2106                        .ngpio  = S5PV210_GPIO_H0_NR,
2107                        .label  = "GPH0",
2108                        .to_irq = samsung_gpiolib_to_irq,
2109                },
2110        }, {
2111                .base   = (S5P_VA_GPIO + 0xC20),
2112                .irq_base = IRQ_EINT(8),
2113                .chip   = {
2114                        .base   = S5PV210_GPH1(0),
2115                        .ngpio  = S5PV210_GPIO_H1_NR,
2116                        .label  = "GPH1",
2117                        .to_irq = samsung_gpiolib_to_irq,
2118                },
2119        }, {
2120                .base   = (S5P_VA_GPIO + 0xC40),
2121                .irq_base = IRQ_EINT(16),
2122                .chip   = {
2123                        .base   = S5PV210_GPH2(0),
2124                        .ngpio  = S5PV210_GPIO_H2_NR,
2125                        .label  = "GPH2",
2126                        .to_irq = samsung_gpiolib_to_irq,
2127                },
2128        }, {
2129                .base   = (S5P_VA_GPIO + 0xC60),
2130                .irq_base = IRQ_EINT(24),
2131                .chip   = {
2132                        .base   = S5PV210_GPH3(0),
2133                        .ngpio  = S5PV210_GPIO_H3_NR,
2134                        .label  = "GPH3",
2135                        .to_irq = samsung_gpiolib_to_irq,
2136                },
2137        },
2138#endif
2139};
2140
2141/* TODO: cleanup soc_is_* */
2142static __init int samsung_gpiolib_init(void)
2143{
2144        struct samsung_gpio_chip *chip;
2145        int i, nr_chips;
2146        int group = 0;
2147
2148#if defined(CONFIG_PINCTRL_EXYNOS) || defined(CONFIG_PINCTRL_EXYNOS5440)
2149        /*
2150        * This gpio driver includes support for device tree support and there
2151        * are platforms using it. In order to maintain compatibility with those
2152        * platforms, and to allow non-dt Exynos4210 platforms to use this
2153        * gpiolib support, a check is added to find out if there is a active
2154        * pin-controller driver support available. If it is available, this
2155        * gpiolib support is ignored and the gpiolib support available in
2156        * pin-controller driver is used. This is a temporary check and will go
2157        * away when all of the Exynos4210 platforms have switched to using
2158        * device tree and the pin-ctrl driver.
2159        */
2160        struct device_node *pctrl_np;
2161        static const struct of_device_id exynos_pinctrl_ids[] = {
2162                { .compatible = "samsung,exynos4210-pinctrl", },
2163                { .compatible = "samsung,exynos4x12-pinctrl", },
2164                { .compatible = "samsung,exynos5250-pinctrl", },
2165                { .compatible = "samsung,exynos5440-pinctrl", },
2166                { }
2167        };
2168        for_each_matching_node(pctrl_np, exynos_pinctrl_ids)
2169                if (pctrl_np && of_device_is_available(pctrl_np))
2170                        return -ENODEV;
2171#endif
2172
2173        samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
2174
2175        if (soc_is_s3c24xx()) {
2176                s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
2177                                ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
2178        } else if (soc_is_s3c64xx()) {
2179                samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
2180                                ARRAY_SIZE(s3c64xx_gpios_2bit),
2181                                S3C64XX_VA_GPIO + 0xE0, 0x20);
2182                samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
2183                                ARRAY_SIZE(s3c64xx_gpios_4bit),
2184                                S3C64XX_VA_GPIO);
2185                samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
2186                                ARRAY_SIZE(s3c64xx_gpios_4bit2));
2187        } else if (soc_is_s5p6440()) {
2188                samsung_gpiolib_add_2bit_chips(s5p6440_gpios_2bit,
2189                                ARRAY_SIZE(s5p6440_gpios_2bit), NULL, 0x0);
2190                samsung_gpiolib_add_4bit_chips(s5p6440_gpios_4bit,
2191                                ARRAY_SIZE(s5p6440_gpios_4bit), S5P_VA_GPIO);
2192                samsung_gpiolib_add_4bit2_chips(s5p6440_gpios_4bit2,
2193                                ARRAY_SIZE(s5p6440_gpios_4bit2));
2194                s5p64x0_gpiolib_add_rbank(s5p6440_gpios_rbank,
2195                                ARRAY_SIZE(s5p6440_gpios_rbank));
2196        } else if (soc_is_s5p6450()) {
2197                samsung_gpiolib_add_2bit_chips(s5p6450_gpios_2bit,
2198                                ARRAY_SIZE(s5p6450_gpios_2bit), NULL, 0x0);
2199                samsung_gpiolib_add_4bit_chips(s5p6450_gpios_4bit,
2200                                ARRAY_SIZE(s5p6450_gpios_4bit), S5P_VA_GPIO);
2201                samsung_gpiolib_add_4bit2_chips(s5p6450_gpios_4bit2,
2202                                ARRAY_SIZE(s5p6450_gpios_4bit2));
2203                s5p64x0_gpiolib_add_rbank(s5p6450_gpios_rbank,
2204                                ARRAY_SIZE(s5p6450_gpios_rbank));
2205        } else if (soc_is_s5pc100()) {
2206                group = 0;
2207                chip = s5pc100_gpios_4bit;
2208                nr_chips = ARRAY_SIZE(s5pc100_gpios_4bit);
2209
2210                for (i = 0; i < nr_chips; i++, chip++) {
2211                        if (!chip->config) {
2212                                chip->config = &samsung_gpio_cfgs[3];
2213                                chip->group = group++;
2214                        }
2215                }
2216                samsung_gpiolib_add_4bit_chips(s5pc100_gpios_4bit, nr_chips, S5P_VA_GPIO);
2217#if defined(CONFIG_CPU_S5PC100) && defined(CONFIG_S5P_GPIO_INT)
2218                s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
2219#endif
2220        } else if (soc_is_s5pv210()) {
2221                group = 0;
2222                chip = s5pv210_gpios_4bit;
2223                nr_chips = ARRAY_SIZE(s5pv210_gpios_4bit);
2224
2225                for (i = 0; i < nr_chips; i++, chip++) {
2226                        if (!chip->config) {
2227                                chip->config = &samsung_gpio_cfgs[3];
2228                                chip->group = group++;
2229                        }
2230                }
2231                samsung_gpiolib_add_4bit_chips(s5pv210_gpios_4bit, nr_chips, S5P_VA_GPIO);
2232#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_S5P_GPIO_INT)
2233                s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
2234#endif
2235        } else {
2236                WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
2237                return -ENODEV;
2238        }
2239
2240        return 0;
2241}
2242core_initcall(samsung_gpiolib_init);
2243
2244int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
2245{
2246        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2247        unsigned long flags;
2248        int offset;
2249        int ret;
2250
2251        if (!chip)
2252                return -EINVAL;
2253
2254        offset = pin - chip->chip.base;
2255
2256        samsung_gpio_lock(chip, flags);
2257        ret = samsung_gpio_do_setcfg(chip, offset, config);
2258        samsung_gpio_unlock(chip, flags);
2259
2260        return ret;
2261}
2262EXPORT_SYMBOL(s3c_gpio_cfgpin);
2263
2264int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
2265                          unsigned int cfg)
2266{
2267        int ret;
2268
2269        for (; nr > 0; nr--, start++) {
2270                ret = s3c_gpio_cfgpin(start, cfg);
2271                if (ret != 0)
2272                        return ret;
2273        }
2274
2275        return 0;
2276}
2277EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
2278
2279int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
2280                          unsigned int cfg, samsung_gpio_pull_t pull)
2281{
2282        int ret;
2283
2284        for (; nr > 0; nr--, start++) {
2285                s3c_gpio_setpull(start, pull);
2286                ret = s3c_gpio_cfgpin(start, cfg);
2287                if (ret != 0)
2288                        return ret;
2289        }
2290
2291        return 0;
2292}
2293EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
2294
2295unsigned s3c_gpio_getcfg(unsigned int pin)
2296{
2297        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2298        unsigned long flags;
2299        unsigned ret = 0;
2300        int offset;
2301
2302        if (chip) {
2303                offset = pin - chip->chip.base;
2304
2305                samsung_gpio_lock(chip, flags);
2306                ret = samsung_gpio_do_getcfg(chip, offset);
2307                samsung_gpio_unlock(chip, flags);
2308        }
2309
2310        return ret;
2311}
2312EXPORT_SYMBOL(s3c_gpio_getcfg);
2313
2314int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
2315{
2316        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2317        unsigned long flags;
2318        int offset, ret;
2319
2320        if (!chip)
2321                return -EINVAL;
2322
2323        offset = pin - chip->chip.base;
2324
2325        samsung_gpio_lock(chip, flags);
2326        ret = samsung_gpio_do_setpull(chip, offset, pull);
2327        samsung_gpio_unlock(chip, flags);
2328
2329        return ret;
2330}
2331EXPORT_SYMBOL(s3c_gpio_setpull);
2332
2333samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
2334{
2335        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2336        unsigned long flags;
2337        int offset;
2338        u32 pup = 0;
2339
2340        if (chip) {
2341                offset = pin - chip->chip.base;
2342
2343                samsung_gpio_lock(chip, flags);
2344                pup = samsung_gpio_do_getpull(chip, offset);
2345                samsung_gpio_unlock(chip, flags);
2346        }
2347
2348        return (__force samsung_gpio_pull_t)pup;
2349}
2350EXPORT_SYMBOL(s3c_gpio_getpull);
2351
2352#ifdef CONFIG_S5P_GPIO_DRVSTR
2353s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
2354{
2355        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2356        unsigned int off;
2357        void __iomem *reg;
2358        int shift;
2359        u32 drvstr;
2360
2361        if (!chip)
2362                return -EINVAL;
2363
2364        off = pin - chip->chip.base;
2365        shift = off * 2;
2366        reg = chip->base + 0x0C;
2367
2368        drvstr = __raw_readl(reg);
2369        drvstr = drvstr >> shift;
2370        drvstr &= 0x3;
2371
2372        return (__force s5p_gpio_drvstr_t)drvstr;
2373}
2374EXPORT_SYMBOL(s5p_gpio_get_drvstr);
2375
2376int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
2377{
2378        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2379        unsigned int off;
2380        void __iomem *reg;
2381        int shift;
2382        u32 tmp;
2383
2384        if (!chip)
2385                return -EINVAL;
2386
2387        off = pin - chip->chip.base;
2388        shift = off * 2;
2389        reg = chip->base + 0x0C;
2390
2391        tmp = __raw_readl(reg);
2392        tmp &= ~(0x3 << shift);
2393        tmp |= drvstr << shift;
2394
2395        __raw_writel(tmp, reg);
2396
2397        return 0;
2398}
2399EXPORT_SYMBOL(s5p_gpio_set_drvstr);
2400#endif  /* CONFIG_S5P_GPIO_DRVSTR */
2401
2402#ifdef CONFIG_PLAT_S3C24XX
2403unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
2404{
2405        unsigned long flags;
2406        unsigned long misccr;
2407
2408        local_irq_save(flags);
2409        misccr = __raw_readl(S3C24XX_MISCCR);
2410        misccr &= ~clear;
2411        misccr ^= change;
2412        __raw_writel(misccr, S3C24XX_MISCCR);
2413        local_irq_restore(flags);
2414
2415        return misccr;
2416}
2417EXPORT_SYMBOL(s3c2410_modify_misccr);
2418#endif
2419