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
 936#if defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF)
 937static int s3c24xx_gpio_xlate(struct gpio_chip *gc,
 938                        const struct of_phandle_args *gpiospec, u32 *flags)
 939{
 940        unsigned int pin;
 941
 942        if (WARN_ON(gc->of_gpio_n_cells < 3))
 943                return -EINVAL;
 944
 945        if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
 946                return -EINVAL;
 947
 948        if (gpiospec->args[0] > gc->ngpio)
 949                return -EINVAL;
 950
 951        pin = gc->base + gpiospec->args[0];
 952
 953        if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
 954                pr_warn("gpio_xlate: failed to set pin function\n");
 955        if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff))
 956                pr_warn("gpio_xlate: failed to set pin pull up/down\n");
 957
 958        if (flags)
 959                *flags = gpiospec->args[2] >> 16;
 960
 961        return gpiospec->args[0];
 962}
 963
 964static const struct of_device_id s3c24xx_gpio_dt_match[] __initdata = {
 965        { .compatible = "samsung,s3c24xx-gpio", },
 966        {}
 967};
 968
 969static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
 970                                                 u64 base, u64 offset)
 971{
 972        struct gpio_chip *gc =  &chip->chip;
 973        u64 address;
 974
 975        if (!of_have_populated_dt())
 976                return;
 977
 978        address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
 979        gc->of_node = of_find_matching_node_by_address(NULL,
 980                        s3c24xx_gpio_dt_match, address);
 981        if (!gc->of_node) {
 982                pr_info("gpio: device tree node not found for gpio controller"
 983                        " with base address %08llx\n", address);
 984                return;
 985        }
 986        gc->of_gpio_n_cells = 3;
 987        gc->of_xlate = s3c24xx_gpio_xlate;
 988}
 989#else
 990static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
 991                                                 u64 base, u64 offset)
 992{
 993        return;
 994}
 995#endif /* defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF) */
 996
 997static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
 998                                             int nr_chips, void __iomem *base)
 999{
1000        int i;
1001        struct gpio_chip *gc = &chip->chip;
1002
1003        for (i = 0 ; i < nr_chips; i++, chip++) {
1004                /* skip banks not present on SoC */
1005                if (chip->chip.base >= S3C_GPIO_END)
1006                        continue;
1007
1008                if (!chip->config)
1009                        chip->config = &s3c24xx_gpiocfg_default;
1010                if (!chip->pm)
1011                        chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
1012                if ((base != NULL) && (chip->base == NULL))
1013                        chip->base = base + ((i) * 0x10);
1014
1015                if (!gc->direction_input)
1016                        gc->direction_input = samsung_gpiolib_2bit_input;
1017                if (!gc->direction_output)
1018                        gc->direction_output = samsung_gpiolib_2bit_output;
1019
1020                samsung_gpiolib_add(chip);
1021
1022                s3c24xx_gpiolib_attach_ofnode(chip, S3C24XX_PA_GPIO, i * 0x10);
1023        }
1024}
1025
1026static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
1027                                                  int nr_chips, void __iomem *base,
1028                                                  unsigned int offset)
1029{
1030        int i;
1031
1032        for (i = 0 ; i < nr_chips; i++, chip++) {
1033                chip->chip.direction_input = samsung_gpiolib_2bit_input;
1034                chip->chip.direction_output = samsung_gpiolib_2bit_output;
1035
1036                if (!chip->config)
1037                        chip->config = &samsung_gpio_cfgs[7];
1038                if (!chip->pm)
1039                        chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
1040                if ((base != NULL) && (chip->base == NULL))
1041                        chip->base = base + ((i) * offset);
1042
1043                samsung_gpiolib_add(chip);
1044        }
1045}
1046
1047/*
1048 * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
1049 * @chip: The gpio chip that is being configured.
1050 * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
1051 *
1052 * This helper deal with the GPIO cases where the control register has 4 bits
1053 * of control per GPIO, generally in the form of:
1054 * 0000 = Input
1055 * 0001 = Output
1056 * others = Special functions (dependent on bank)
1057 *
1058 * Note, since the code to deal with the case where there are two control
1059 * registers instead of one, we do not have a separate set of function
1060 * (samsung_gpiolib_add_4bit2_chips)for each case.
1061 */
1062
1063static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
1064                                                  int nr_chips, void __iomem *base)
1065{
1066        int i;
1067
1068        for (i = 0 ; i < nr_chips; i++, chip++) {
1069                chip->chip.direction_input = samsung_gpiolib_4bit_input;
1070                chip->chip.direction_output = samsung_gpiolib_4bit_output;
1071
1072                if (!chip->config)
1073                        chip->config = &samsung_gpio_cfgs[2];
1074                if (!chip->pm)
1075                        chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1076                if ((base != NULL) && (chip->base == NULL))
1077                        chip->base = base + ((i) * 0x20);
1078
1079                chip->bitmap_gpio_int = 0;
1080
1081                samsung_gpiolib_add(chip);
1082        }
1083}
1084
1085static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
1086                                                   int nr_chips)
1087{
1088        for (; nr_chips > 0; nr_chips--, chip++) {
1089                chip->chip.direction_input = samsung_gpiolib_4bit2_input;
1090                chip->chip.direction_output = samsung_gpiolib_4bit2_output;
1091
1092                if (!chip->config)
1093                        chip->config = &samsung_gpio_cfgs[2];
1094                if (!chip->pm)
1095                        chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1096
1097                samsung_gpiolib_add(chip);
1098        }
1099}
1100
1101static void __init s5p64x0_gpiolib_add_rbank(struct samsung_gpio_chip *chip,
1102                                             int nr_chips)
1103{
1104        for (; nr_chips > 0; nr_chips--, chip++) {
1105                chip->chip.direction_input = s5p64x0_gpiolib_rbank_input;
1106                chip->chip.direction_output = s5p64x0_gpiolib_rbank_output;
1107
1108                if (!chip->pm)
1109                        chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1110
1111                samsung_gpiolib_add(chip);
1112        }
1113}
1114
1115int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
1116{
1117        struct samsung_gpio_chip *samsung_chip = container_of(chip, struct samsung_gpio_chip, chip);
1118
1119        return samsung_chip->irq_base + offset;
1120}
1121
1122#ifdef CONFIG_PLAT_S3C24XX
1123static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
1124{
1125        if (offset < 4)
1126                return IRQ_EINT0 + offset;
1127
1128        if (offset < 8)
1129                return IRQ_EINT4 + offset - 4;
1130
1131        return -EINVAL;
1132}
1133#endif
1134
1135#ifdef CONFIG_PLAT_S3C64XX
1136static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
1137{
1138        return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
1139}
1140
1141static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
1142{
1143        return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
1144}
1145#endif
1146
1147struct samsung_gpio_chip s3c24xx_gpios[] = {
1148#ifdef CONFIG_PLAT_S3C24XX
1149        {
1150                .config = &s3c24xx_gpiocfg_banka,
1151                .chip   = {
1152                        .base                   = S3C2410_GPA(0),
1153                        .owner                  = THIS_MODULE,
1154                        .label                  = "GPIOA",
1155                        .ngpio                  = 24,
1156                        .direction_input        = s3c24xx_gpiolib_banka_input,
1157                        .direction_output       = s3c24xx_gpiolib_banka_output,
1158                },
1159        }, {
1160                .chip   = {
1161                        .base   = S3C2410_GPB(0),
1162                        .owner  = THIS_MODULE,
1163                        .label  = "GPIOB",
1164                        .ngpio  = 16,
1165                },
1166        }, {
1167                .chip   = {
1168                        .base   = S3C2410_GPC(0),
1169                        .owner  = THIS_MODULE,
1170                        .label  = "GPIOC",
1171                        .ngpio  = 16,
1172                },
1173        }, {
1174                .chip   = {
1175                        .base   = S3C2410_GPD(0),
1176                        .owner  = THIS_MODULE,
1177                        .label  = "GPIOD",
1178                        .ngpio  = 16,
1179                },
1180        }, {
1181                .chip   = {
1182                        .base   = S3C2410_GPE(0),
1183                        .label  = "GPIOE",
1184                        .owner  = THIS_MODULE,
1185                        .ngpio  = 16,
1186                },
1187        }, {
1188                .chip   = {
1189                        .base   = S3C2410_GPF(0),
1190                        .owner  = THIS_MODULE,
1191                        .label  = "GPIOF",
1192                        .ngpio  = 8,
1193                        .to_irq = s3c24xx_gpiolib_fbank_to_irq,
1194                },
1195        }, {
1196                .irq_base = IRQ_EINT8,
1197                .chip   = {
1198                        .base   = S3C2410_GPG(0),
1199                        .owner  = THIS_MODULE,
1200                        .label  = "GPIOG",
1201                        .ngpio  = 16,
1202                        .to_irq = samsung_gpiolib_to_irq,
1203                },
1204        }, {
1205                .chip   = {
1206                        .base   = S3C2410_GPH(0),
1207                        .owner  = THIS_MODULE,
1208                        .label  = "GPIOH",
1209                        .ngpio  = 11,
1210                },
1211        },
1212                /* GPIOS for the S3C2443 and later devices. */
1213        {
1214                .base   = S3C2440_GPJCON,
1215                .chip   = {
1216                        .base   = S3C2410_GPJ(0),
1217                        .owner  = THIS_MODULE,
1218                        .label  = "GPIOJ",
1219                        .ngpio  = 16,
1220                },
1221        }, {
1222                .base   = S3C2443_GPKCON,
1223                .chip   = {
1224                        .base   = S3C2410_GPK(0),
1225                        .owner  = THIS_MODULE,
1226                        .label  = "GPIOK",
1227                        .ngpio  = 16,
1228                },
1229        }, {
1230                .base   = S3C2443_GPLCON,
1231                .chip   = {
1232                        .base   = S3C2410_GPL(0),
1233                        .owner  = THIS_MODULE,
1234                        .label  = "GPIOL",
1235                        .ngpio  = 15,
1236                },
1237        }, {
1238                .base   = S3C2443_GPMCON,
1239                .chip   = {
1240                        .base   = S3C2410_GPM(0),
1241                        .owner  = THIS_MODULE,
1242                        .label  = "GPIOM",
1243                        .ngpio  = 2,
1244                },
1245        },
1246#endif
1247};
1248
1249/*
1250 * GPIO bank summary:
1251 *
1252 * Bank GPIOs   Style   SlpCon  ExtInt Group
1253 * A    8       4Bit    Yes     1
1254 * B    7       4Bit    Yes     1
1255 * C    8       4Bit    Yes     2
1256 * D    5       4Bit    Yes     3
1257 * E    5       4Bit    Yes     None
1258 * F    16      2Bit    Yes     4 [1]
1259 * G    7       4Bit    Yes     5
1260 * H    10      4Bit[2] Yes     6
1261 * I    16      2Bit    Yes     None
1262 * J    12      2Bit    Yes     None
1263 * K    16      4Bit[2] No      None
1264 * L    15      4Bit[2] No      None
1265 * M    6       4Bit    No      IRQ_EINT
1266 * N    16      2Bit    No      IRQ_EINT
1267 * O    16      2Bit    Yes     7
1268 * P    15      2Bit    Yes     8
1269 * Q    9       2Bit    Yes     9
1270 *
1271 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
1272 * [2] BANK has two control registers, GPxCON0 and GPxCON1
1273 */
1274
1275static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
1276#ifdef CONFIG_PLAT_S3C64XX
1277        {
1278                .chip   = {
1279                        .base   = S3C64XX_GPA(0),
1280                        .ngpio  = S3C64XX_GPIO_A_NR,
1281                        .label  = "GPA",
1282                },
1283        }, {
1284                .chip   = {
1285                        .base   = S3C64XX_GPB(0),
1286                        .ngpio  = S3C64XX_GPIO_B_NR,
1287                        .label  = "GPB",
1288                },
1289        }, {
1290                .chip   = {
1291                        .base   = S3C64XX_GPC(0),
1292                        .ngpio  = S3C64XX_GPIO_C_NR,
1293                        .label  = "GPC",
1294                },
1295        }, {
1296                .chip   = {
1297                        .base   = S3C64XX_GPD(0),
1298                        .ngpio  = S3C64XX_GPIO_D_NR,
1299                        .label  = "GPD",
1300                },
1301        }, {
1302                .config = &samsung_gpio_cfgs[0],
1303                .chip   = {
1304                        .base   = S3C64XX_GPE(0),
1305                        .ngpio  = S3C64XX_GPIO_E_NR,
1306                        .label  = "GPE",
1307                },
1308        }, {
1309                .base   = S3C64XX_GPG_BASE,
1310                .chip   = {
1311                        .base   = S3C64XX_GPG(0),
1312                        .ngpio  = S3C64XX_GPIO_G_NR,
1313                        .label  = "GPG",
1314                },
1315        }, {
1316                .base   = S3C64XX_GPM_BASE,
1317                .config = &samsung_gpio_cfgs[1],
1318                .chip   = {
1319                        .base   = S3C64XX_GPM(0),
1320                        .ngpio  = S3C64XX_GPIO_M_NR,
1321                        .label  = "GPM",
1322                        .to_irq = s3c64xx_gpiolib_mbank_to_irq,
1323                },
1324        },
1325#endif
1326};
1327
1328static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
1329#ifdef CONFIG_PLAT_S3C64XX
1330        {
1331                .base   = S3C64XX_GPH_BASE + 0x4,
1332                .chip   = {
1333                        .base   = S3C64XX_GPH(0),
1334                        .ngpio  = S3C64XX_GPIO_H_NR,
1335                        .label  = "GPH",
1336                },
1337        }, {
1338                .base   = S3C64XX_GPK_BASE + 0x4,
1339                .config = &samsung_gpio_cfgs[0],
1340                .chip   = {
1341                        .base   = S3C64XX_GPK(0),
1342                        .ngpio  = S3C64XX_GPIO_K_NR,
1343                        .label  = "GPK",
1344                },
1345        }, {
1346                .base   = S3C64XX_GPL_BASE + 0x4,
1347                .config = &samsung_gpio_cfgs[1],
1348                .chip   = {
1349                        .base   = S3C64XX_GPL(0),
1350                        .ngpio  = S3C64XX_GPIO_L_NR,
1351                        .label  = "GPL",
1352                        .to_irq = s3c64xx_gpiolib_lbank_to_irq,
1353                },
1354        },
1355#endif
1356};
1357
1358static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
1359#ifdef CONFIG_PLAT_S3C64XX
1360        {
1361                .base   = S3C64XX_GPF_BASE,
1362                .config = &samsung_gpio_cfgs[6],
1363                .chip   = {
1364                        .base   = S3C64XX_GPF(0),
1365                        .ngpio  = S3C64XX_GPIO_F_NR,
1366                        .label  = "GPF",
1367                },
1368        }, {
1369                .config = &samsung_gpio_cfgs[7],
1370                .chip   = {
1371                        .base   = S3C64XX_GPI(0),
1372                        .ngpio  = S3C64XX_GPIO_I_NR,
1373                        .label  = "GPI",
1374                },
1375        }, {
1376                .config = &samsung_gpio_cfgs[7],
1377                .chip   = {
1378                        .base   = S3C64XX_GPJ(0),
1379                        .ngpio  = S3C64XX_GPIO_J_NR,
1380                        .label  = "GPJ",
1381                },
1382        }, {
1383                .config = &samsung_gpio_cfgs[6],
1384                .chip   = {
1385                        .base   = S3C64XX_GPO(0),
1386                        .ngpio  = S3C64XX_GPIO_O_NR,
1387                        .label  = "GPO",
1388                },
1389        }, {
1390                .config = &samsung_gpio_cfgs[6],
1391                .chip   = {
1392                        .base   = S3C64XX_GPP(0),
1393                        .ngpio  = S3C64XX_GPIO_P_NR,
1394                        .label  = "GPP",
1395                },
1396        }, {
1397                .config = &samsung_gpio_cfgs[6],
1398                .chip   = {
1399                        .base   = S3C64XX_GPQ(0),
1400                        .ngpio  = S3C64XX_GPIO_Q_NR,
1401                        .label  = "GPQ",
1402                },
1403        }, {
1404                .base   = S3C64XX_GPN_BASE,
1405                .irq_base = IRQ_EINT(0),
1406                .config = &samsung_gpio_cfgs[5],
1407                .chip   = {
1408                        .base   = S3C64XX_GPN(0),
1409                        .ngpio  = S3C64XX_GPIO_N_NR,
1410                        .label  = "GPN",
1411                        .to_irq = samsung_gpiolib_to_irq,
1412                },
1413        },
1414#endif
1415};
1416
1417/*
1418 * S5P6440 GPIO bank summary:
1419 *
1420 * Bank GPIOs   Style   SlpCon  ExtInt Group
1421 * A    6       4Bit    Yes     1
1422 * B    7       4Bit    Yes     1
1423 * C    8       4Bit    Yes     2
1424 * F    2       2Bit    Yes     4 [1]
1425 * G    7       4Bit    Yes     5
1426 * H    10      4Bit[2] Yes     6
1427 * I    16      2Bit    Yes     None
1428 * J    12      2Bit    Yes     None
1429 * N    16      2Bit    No      IRQ_EINT
1430 * P    8       2Bit    Yes     8
1431 * R    15      4Bit[2] Yes     8
1432 */
1433
1434static struct samsung_gpio_chip s5p6440_gpios_4bit[] = {
1435#ifdef CONFIG_CPU_S5P6440
1436        {
1437                .chip   = {
1438                        .base   = S5P6440_GPA(0),
1439                        .ngpio  = S5P6440_GPIO_A_NR,
1440                        .label  = "GPA",
1441                },
1442        }, {
1443                .chip   = {
1444                        .base   = S5P6440_GPB(0),
1445                        .ngpio  = S5P6440_GPIO_B_NR,
1446                        .label  = "GPB",
1447                },
1448        }, {
1449                .chip   = {
1450                        .base   = S5P6440_GPC(0),
1451                        .ngpio  = S5P6440_GPIO_C_NR,
1452                        .label  = "GPC",
1453                },
1454        }, {
1455                .base   = S5P64X0_GPG_BASE,
1456                .chip   = {
1457                        .base   = S5P6440_GPG(0),
1458                        .ngpio  = S5P6440_GPIO_G_NR,
1459                        .label  = "GPG",
1460                },
1461        },
1462#endif
1463};
1464
1465static struct samsung_gpio_chip s5p6440_gpios_4bit2[] = {
1466#ifdef CONFIG_CPU_S5P6440
1467        {
1468                .base   = S5P64X0_GPH_BASE + 0x4,
1469                .chip   = {
1470                        .base   = S5P6440_GPH(0),
1471                        .ngpio  = S5P6440_GPIO_H_NR,
1472                        .label  = "GPH",
1473                },
1474        },
1475#endif
1476};
1477
1478static struct samsung_gpio_chip s5p6440_gpios_rbank[] = {
1479#ifdef CONFIG_CPU_S5P6440
1480        {
1481                .base   = S5P64X0_GPR_BASE + 0x4,
1482                .config = &s5p64x0_gpio_cfg_rbank,
1483                .chip   = {
1484                        .base   = S5P6440_GPR(0),
1485                        .ngpio  = S5P6440_GPIO_R_NR,
1486                        .label  = "GPR",
1487                },
1488        },
1489#endif
1490};
1491
1492static struct samsung_gpio_chip s5p6440_gpios_2bit[] = {
1493#ifdef CONFIG_CPU_S5P6440
1494        {
1495                .base   = S5P64X0_GPF_BASE,
1496                .config = &samsung_gpio_cfgs[6],
1497                .chip   = {
1498                        .base   = S5P6440_GPF(0),
1499                        .ngpio  = S5P6440_GPIO_F_NR,
1500                        .label  = "GPF",
1501                },
1502        }, {
1503                .base   = S5P64X0_GPI_BASE,
1504                .config = &samsung_gpio_cfgs[4],
1505                .chip   = {
1506                        .base   = S5P6440_GPI(0),
1507                        .ngpio  = S5P6440_GPIO_I_NR,
1508                        .label  = "GPI",
1509                },
1510        }, {
1511                .base   = S5P64X0_GPJ_BASE,
1512                .config = &samsung_gpio_cfgs[4],
1513                .chip   = {
1514                        .base   = S5P6440_GPJ(0),
1515                        .ngpio  = S5P6440_GPIO_J_NR,
1516                        .label  = "GPJ",
1517                },
1518        }, {
1519                .base   = S5P64X0_GPN_BASE,
1520                .config = &samsung_gpio_cfgs[5],
1521                .chip   = {
1522                        .base   = S5P6440_GPN(0),
1523                        .ngpio  = S5P6440_GPIO_N_NR,
1524                        .label  = "GPN",
1525                },
1526        }, {
1527                .base   = S5P64X0_GPP_BASE,
1528                .config = &samsung_gpio_cfgs[6],
1529                .chip   = {
1530                        .base   = S5P6440_GPP(0),
1531                        .ngpio  = S5P6440_GPIO_P_NR,
1532                        .label  = "GPP",
1533                },
1534        },
1535#endif
1536};
1537
1538/*
1539 * S5P6450 GPIO bank summary:
1540 *
1541 * Bank GPIOs   Style   SlpCon  ExtInt Group
1542 * A    6       4Bit    Yes     1
1543 * B    7       4Bit    Yes     1
1544 * C    8       4Bit    Yes     2
1545 * D    8       4Bit    Yes     None
1546 * F    2       2Bit    Yes     None
1547 * G    14      4Bit[2] Yes     5
1548 * H    10      4Bit[2] Yes     6
1549 * I    16      2Bit    Yes     None
1550 * J    12      2Bit    Yes     None
1551 * K    5       4Bit    Yes     None
1552 * N    16      2Bit    No      IRQ_EINT
1553 * P    11      2Bit    Yes     8
1554 * Q    14      2Bit    Yes     None
1555 * R    15      4Bit[2] Yes     None
1556 * S    8       2Bit    Yes     None
1557 *
1558 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
1559 * [2] BANK has two control registers, GPxCON0 and GPxCON1
1560 */
1561
1562static struct samsung_gpio_chip s5p6450_gpios_4bit[] = {
1563#ifdef CONFIG_CPU_S5P6450
1564        {
1565                .chip   = {
1566                        .base   = S5P6450_GPA(0),
1567                        .ngpio  = S5P6450_GPIO_A_NR,
1568                        .label  = "GPA",
1569                },
1570        }, {
1571                .chip   = {
1572                        .base   = S5P6450_GPB(0),
1573                        .ngpio  = S5P6450_GPIO_B_NR,
1574                        .label  = "GPB",
1575                },
1576        }, {
1577                .chip   = {
1578                        .base   = S5P6450_GPC(0),
1579                        .ngpio  = S5P6450_GPIO_C_NR,
1580                        .label  = "GPC",
1581                },
1582        }, {
1583                .chip   = {
1584                        .base   = S5P6450_GPD(0),
1585                        .ngpio  = S5P6450_GPIO_D_NR,
1586                        .label  = "GPD",
1587                },
1588        }, {
1589                .base   = S5P6450_GPK_BASE,
1590                .chip   = {
1591                        .base   = S5P6450_GPK(0),
1592                        .ngpio  = S5P6450_GPIO_K_NR,
1593                        .label  = "GPK",
1594                },
1595        },
1596#endif
1597};
1598
1599static struct samsung_gpio_chip s5p6450_gpios_4bit2[] = {
1600#ifdef CONFIG_CPU_S5P6450
1601        {
1602                .base   = S5P64X0_GPG_BASE + 0x4,
1603                .chip   = {
1604                        .base   = S5P6450_GPG(0),
1605                        .ngpio  = S5P6450_GPIO_G_NR,
1606                        .label  = "GPG",
1607                },
1608        }, {
1609                .base   = S5P64X0_GPH_BASE + 0x4,
1610                .chip   = {
1611                        .base   = S5P6450_GPH(0),
1612                        .ngpio  = S5P6450_GPIO_H_NR,
1613                        .label  = "GPH",
1614                },
1615        },
1616#endif
1617};
1618
1619static struct samsung_gpio_chip s5p6450_gpios_rbank[] = {
1620#ifdef CONFIG_CPU_S5P6450
1621        {
1622                .base   = S5P64X0_GPR_BASE + 0x4,
1623                .config = &s5p64x0_gpio_cfg_rbank,
1624                .chip   = {
1625                        .base   = S5P6450_GPR(0),
1626                        .ngpio  = S5P6450_GPIO_R_NR,
1627                        .label  = "GPR",
1628                },
1629        },
1630#endif
1631};
1632
1633static struct samsung_gpio_chip s5p6450_gpios_2bit[] = {
1634#ifdef CONFIG_CPU_S5P6450
1635        {
1636                .base   = S5P64X0_GPF_BASE,
1637                .config = &samsung_gpio_cfgs[6],
1638                .chip   = {
1639                        .base   = S5P6450_GPF(0),
1640                        .ngpio  = S5P6450_GPIO_F_NR,
1641                        .label  = "GPF",
1642                },
1643        }, {
1644                .base   = S5P64X0_GPI_BASE,
1645                .config = &samsung_gpio_cfgs[4],
1646                .chip   = {
1647                        .base   = S5P6450_GPI(0),
1648                        .ngpio  = S5P6450_GPIO_I_NR,
1649                        .label  = "GPI",
1650                },
1651        }, {
1652                .base   = S5P64X0_GPJ_BASE,
1653                .config = &samsung_gpio_cfgs[4],
1654                .chip   = {
1655                        .base   = S5P6450_GPJ(0),
1656                        .ngpio  = S5P6450_GPIO_J_NR,
1657                        .label  = "GPJ",
1658                },
1659        }, {
1660                .base   = S5P64X0_GPN_BASE,
1661                .config = &samsung_gpio_cfgs[5],
1662                .chip   = {
1663                        .base   = S5P6450_GPN(0),
1664                        .ngpio  = S5P6450_GPIO_N_NR,
1665                        .label  = "GPN",
1666                },
1667        }, {
1668                .base   = S5P64X0_GPP_BASE,
1669                .config = &samsung_gpio_cfgs[6],
1670                .chip   = {
1671                        .base   = S5P6450_GPP(0),
1672                        .ngpio  = S5P6450_GPIO_P_NR,
1673                        .label  = "GPP",
1674                },
1675        }, {
1676                .base   = S5P6450_GPQ_BASE,
1677                .config = &samsung_gpio_cfgs[5],
1678                .chip   = {
1679                        .base   = S5P6450_GPQ(0),
1680                        .ngpio  = S5P6450_GPIO_Q_NR,
1681                        .label  = "GPQ",
1682                },
1683        }, {
1684                .base   = S5P6450_GPS_BASE,
1685                .config = &samsung_gpio_cfgs[6],
1686                .chip   = {
1687                        .base   = S5P6450_GPS(0),
1688                        .ngpio  = S5P6450_GPIO_S_NR,
1689                        .label  = "GPS",
1690                },
1691        },
1692#endif
1693};
1694
1695/*
1696 * S5PC100 GPIO bank summary:
1697 *
1698 * Bank GPIOs   Style   INT Type
1699 * A0   8       4Bit    GPIO_INT0
1700 * A1   5       4Bit    GPIO_INT1
1701 * B    8       4Bit    GPIO_INT2
1702 * C    5       4Bit    GPIO_INT3
1703 * D    7       4Bit    GPIO_INT4
1704 * E0   8       4Bit    GPIO_INT5
1705 * E1   6       4Bit    GPIO_INT6
1706 * F0   8       4Bit    GPIO_INT7
1707 * F1   8       4Bit    GPIO_INT8
1708 * F2   8       4Bit    GPIO_INT9
1709 * F3   4       4Bit    GPIO_INT10
1710 * G0   8       4Bit    GPIO_INT11
1711 * G1   3       4Bit    GPIO_INT12
1712 * G2   7       4Bit    GPIO_INT13
1713 * G3   7       4Bit    GPIO_INT14
1714 * H0   8       4Bit    WKUP_INT
1715 * H1   8       4Bit    WKUP_INT
1716 * H2   8       4Bit    WKUP_INT
1717 * H3   8       4Bit    WKUP_INT
1718 * I    8       4Bit    GPIO_INT15
1719 * J0   8       4Bit    GPIO_INT16
1720 * J1   5       4Bit    GPIO_INT17
1721 * J2   8       4Bit    GPIO_INT18
1722 * J3   8       4Bit    GPIO_INT19
1723 * J4   4       4Bit    GPIO_INT20
1724 * K0   8       4Bit    None
1725 * K1   6       4Bit    None
1726 * K2   8       4Bit    None
1727 * K3   8       4Bit    None
1728 * L0   8       4Bit    None
1729 * L1   8       4Bit    None
1730 * L2   8       4Bit    None
1731 * L3   8       4Bit    None
1732 */
1733
1734static struct samsung_gpio_chip s5pc100_gpios_4bit[] = {
1735#ifdef CONFIG_CPU_S5PC100
1736        {
1737                .chip   = {
1738                        .base   = S5PC100_GPA0(0),
1739                        .ngpio  = S5PC100_GPIO_A0_NR,
1740                        .label  = "GPA0",
1741                },
1742        }, {
1743                .chip   = {
1744                        .base   = S5PC100_GPA1(0),
1745                        .ngpio  = S5PC100_GPIO_A1_NR,
1746                        .label  = "GPA1",
1747                },
1748        }, {
1749                .chip   = {
1750                        .base   = S5PC100_GPB(0),
1751                        .ngpio  = S5PC100_GPIO_B_NR,
1752                        .label  = "GPB",
1753                },
1754        }, {
1755                .chip   = {
1756                        .base   = S5PC100_GPC(0),
1757                        .ngpio  = S5PC100_GPIO_C_NR,
1758                        .label  = "GPC",
1759                },
1760        }, {
1761                .chip   = {
1762                        .base   = S5PC100_GPD(0),
1763                        .ngpio  = S5PC100_GPIO_D_NR,
1764                        .label  = "GPD",
1765                },
1766        }, {
1767                .chip   = {
1768                        .base   = S5PC100_GPE0(0),
1769                        .ngpio  = S5PC100_GPIO_E0_NR,
1770                        .label  = "GPE0",
1771                },
1772        }, {
1773                .chip   = {
1774                        .base   = S5PC100_GPE1(0),
1775                        .ngpio  = S5PC100_GPIO_E1_NR,
1776                        .label  = "GPE1",
1777                },
1778        }, {
1779                .chip   = {
1780                        .base   = S5PC100_GPF0(0),
1781                        .ngpio  = S5PC100_GPIO_F0_NR,
1782                        .label  = "GPF0",
1783                },
1784        }, {
1785                .chip   = {
1786                        .base   = S5PC100_GPF1(0),
1787                        .ngpio  = S5PC100_GPIO_F1_NR,
1788                        .label  = "GPF1",
1789                },
1790        }, {
1791                .chip   = {
1792                        .base   = S5PC100_GPF2(0),
1793                        .ngpio  = S5PC100_GPIO_F2_NR,
1794                        .label  = "GPF2",
1795                },
1796        }, {
1797                .chip   = {
1798                        .base   = S5PC100_GPF3(0),
1799                        .ngpio  = S5PC100_GPIO_F3_NR,
1800                        .label  = "GPF3",
1801                },
1802        }, {
1803                .chip   = {
1804                        .base   = S5PC100_GPG0(0),
1805                        .ngpio  = S5PC100_GPIO_G0_NR,
1806                        .label  = "GPG0",
1807                },
1808        }, {
1809                .chip   = {
1810                        .base   = S5PC100_GPG1(0),
1811                        .ngpio  = S5PC100_GPIO_G1_NR,
1812                        .label  = "GPG1",
1813                },
1814        }, {
1815                .chip   = {
1816                        .base   = S5PC100_GPG2(0),
1817                        .ngpio  = S5PC100_GPIO_G2_NR,
1818                        .label  = "GPG2",
1819                },
1820        }, {
1821                .chip   = {
1822                        .base   = S5PC100_GPG3(0),
1823                        .ngpio  = S5PC100_GPIO_G3_NR,
1824                        .label  = "GPG3",
1825                },
1826        }, {
1827                .chip   = {
1828                        .base   = S5PC100_GPI(0),
1829                        .ngpio  = S5PC100_GPIO_I_NR,
1830                        .label  = "GPI",
1831                },
1832        }, {
1833                .chip   = {
1834                        .base   = S5PC100_GPJ0(0),
1835                        .ngpio  = S5PC100_GPIO_J0_NR,
1836                        .label  = "GPJ0",
1837                },
1838        }, {
1839                .chip   = {
1840                        .base   = S5PC100_GPJ1(0),
1841                        .ngpio  = S5PC100_GPIO_J1_NR,
1842                        .label  = "GPJ1",
1843                },
1844        }, {
1845                .chip   = {
1846                        .base   = S5PC100_GPJ2(0),
1847                        .ngpio  = S5PC100_GPIO_J2_NR,
1848                        .label  = "GPJ2",
1849                },
1850        }, {
1851                .chip   = {
1852                        .base   = S5PC100_GPJ3(0),
1853                        .ngpio  = S5PC100_GPIO_J3_NR,
1854                        .label  = "GPJ3",
1855                },
1856        }, {
1857                .chip   = {
1858                        .base   = S5PC100_GPJ4(0),
1859                        .ngpio  = S5PC100_GPIO_J4_NR,
1860                        .label  = "GPJ4",
1861                },
1862        }, {
1863                .chip   = {
1864                        .base   = S5PC100_GPK0(0),
1865                        .ngpio  = S5PC100_GPIO_K0_NR,
1866                        .label  = "GPK0",
1867                },
1868        }, {
1869                .chip   = {
1870                        .base   = S5PC100_GPK1(0),
1871                        .ngpio  = S5PC100_GPIO_K1_NR,
1872                        .label  = "GPK1",
1873                },
1874        }, {
1875                .chip   = {
1876                        .base   = S5PC100_GPK2(0),
1877                        .ngpio  = S5PC100_GPIO_K2_NR,
1878                        .label  = "GPK2",
1879                },
1880        }, {
1881                .chip   = {
1882                        .base   = S5PC100_GPK3(0),
1883                        .ngpio  = S5PC100_GPIO_K3_NR,
1884                        .label  = "GPK3",
1885                },
1886        }, {
1887                .chip   = {
1888                        .base   = S5PC100_GPL0(0),
1889                        .ngpio  = S5PC100_GPIO_L0_NR,
1890                        .label  = "GPL0",
1891                },
1892        }, {
1893                .chip   = {
1894                        .base   = S5PC100_GPL1(0),
1895                        .ngpio  = S5PC100_GPIO_L1_NR,
1896                        .label  = "GPL1",
1897                },
1898        }, {
1899                .chip   = {
1900                        .base   = S5PC100_GPL2(0),
1901                        .ngpio  = S5PC100_GPIO_L2_NR,
1902                        .label  = "GPL2",
1903                },
1904        }, {
1905                .chip   = {
1906                        .base   = S5PC100_GPL3(0),
1907                        .ngpio  = S5PC100_GPIO_L3_NR,
1908                        .label  = "GPL3",
1909                },
1910        }, {
1911                .chip   = {
1912                        .base   = S5PC100_GPL4(0),
1913                        .ngpio  = S5PC100_GPIO_L4_NR,
1914                        .label  = "GPL4",
1915                },
1916        }, {
1917                .base   = (S5P_VA_GPIO + 0xC00),
1918                .irq_base = IRQ_EINT(0),
1919                .chip   = {
1920                        .base   = S5PC100_GPH0(0),
1921                        .ngpio  = S5PC100_GPIO_H0_NR,
1922                        .label  = "GPH0",
1923                        .to_irq = samsung_gpiolib_to_irq,
1924                },
1925        }, {
1926                .base   = (S5P_VA_GPIO + 0xC20),
1927                .irq_base = IRQ_EINT(8),
1928                .chip   = {
1929                        .base   = S5PC100_GPH1(0),
1930                        .ngpio  = S5PC100_GPIO_H1_NR,
1931                        .label  = "GPH1",
1932                        .to_irq = samsung_gpiolib_to_irq,
1933                },
1934        }, {
1935                .base   = (S5P_VA_GPIO + 0xC40),
1936                .irq_base = IRQ_EINT(16),
1937                .chip   = {
1938                        .base   = S5PC100_GPH2(0),
1939                        .ngpio  = S5PC100_GPIO_H2_NR,
1940                        .label  = "GPH2",
1941                        .to_irq = samsung_gpiolib_to_irq,
1942                },
1943        }, {
1944                .base   = (S5P_VA_GPIO + 0xC60),
1945                .irq_base = IRQ_EINT(24),
1946                .chip   = {
1947                        .base   = S5PC100_GPH3(0),
1948                        .ngpio  = S5PC100_GPIO_H3_NR,
1949                        .label  = "GPH3",
1950                        .to_irq = samsung_gpiolib_to_irq,
1951                },
1952        },
1953#endif
1954};
1955
1956/*
1957 * Followings are the gpio banks in S5PV210/S5PC110
1958 *
1959 * The 'config' member when left to NULL, is initialized to the default
1960 * structure samsung_gpio_cfgs[3] in the init function below.
1961 *
1962 * The 'base' member is also initialized in the init function below.
1963 * Note: The initialization of 'base' member of samsung_gpio_chip structure
1964 * uses the above macro and depends on the banks being listed in order here.
1965 */
1966
1967static struct samsung_gpio_chip s5pv210_gpios_4bit[] = {
1968#ifdef CONFIG_CPU_S5PV210
1969        {
1970                .chip   = {
1971                        .base   = S5PV210_GPA0(0),
1972                        .ngpio  = S5PV210_GPIO_A0_NR,
1973                        .label  = "GPA0",
1974                },
1975        }, {
1976                .chip   = {
1977                        .base   = S5PV210_GPA1(0),
1978                        .ngpio  = S5PV210_GPIO_A1_NR,
1979                        .label  = "GPA1",
1980                },
1981        }, {
1982                .chip   = {
1983                        .base   = S5PV210_GPB(0),
1984                        .ngpio  = S5PV210_GPIO_B_NR,
1985                        .label  = "GPB",
1986                },
1987        }, {
1988                .chip   = {
1989                        .base   = S5PV210_GPC0(0),
1990                        .ngpio  = S5PV210_GPIO_C0_NR,
1991                        .label  = "GPC0",
1992                },
1993        }, {
1994                .chip   = {
1995                        .base   = S5PV210_GPC1(0),
1996                        .ngpio  = S5PV210_GPIO_C1_NR,
1997                        .label  = "GPC1",
1998                },
1999        }, {
2000                .chip   = {
2001                        .base   = S5PV210_GPD0(0),
2002                        .ngpio  = S5PV210_GPIO_D0_NR,
2003                        .label  = "GPD0",
2004                },
2005        }, {
2006                .chip   = {
2007                        .base   = S5PV210_GPD1(0),
2008                        .ngpio  = S5PV210_GPIO_D1_NR,
2009                        .label  = "GPD1",
2010                },
2011        }, {
2012                .chip   = {
2013                        .base   = S5PV210_GPE0(0),
2014                        .ngpio  = S5PV210_GPIO_E0_NR,
2015                        .label  = "GPE0",
2016                },
2017        }, {
2018                .chip   = {
2019                        .base   = S5PV210_GPE1(0),
2020                        .ngpio  = S5PV210_GPIO_E1_NR,
2021                        .label  = "GPE1",
2022                },
2023        }, {
2024                .chip   = {
2025                        .base   = S5PV210_GPF0(0),
2026                        .ngpio  = S5PV210_GPIO_F0_NR,
2027                        .label  = "GPF0",
2028                },
2029        }, {
2030                .chip   = {
2031                        .base   = S5PV210_GPF1(0),
2032                        .ngpio  = S5PV210_GPIO_F1_NR,
2033                        .label  = "GPF1",
2034                },
2035        }, {
2036                .chip   = {
2037                        .base   = S5PV210_GPF2(0),
2038                        .ngpio  = S5PV210_GPIO_F2_NR,
2039                        .label  = "GPF2",
2040                },
2041        }, {
2042                .chip   = {
2043                        .base   = S5PV210_GPF3(0),
2044                        .ngpio  = S5PV210_GPIO_F3_NR,
2045                        .label  = "GPF3",
2046                },
2047        }, {
2048                .chip   = {
2049                        .base   = S5PV210_GPG0(0),
2050                        .ngpio  = S5PV210_GPIO_G0_NR,
2051                        .label  = "GPG0",
2052                },
2053        }, {
2054                .chip   = {
2055                        .base   = S5PV210_GPG1(0),
2056                        .ngpio  = S5PV210_GPIO_G1_NR,
2057                        .label  = "GPG1",
2058                },
2059        }, {
2060                .chip   = {
2061                        .base   = S5PV210_GPG2(0),
2062                        .ngpio  = S5PV210_GPIO_G2_NR,
2063                        .label  = "GPG2",
2064                },
2065        }, {
2066                .chip   = {
2067                        .base   = S5PV210_GPG3(0),
2068                        .ngpio  = S5PV210_GPIO_G3_NR,
2069                        .label  = "GPG3",
2070                },
2071        }, {
2072                .chip   = {
2073                        .base   = S5PV210_GPI(0),
2074                        .ngpio  = S5PV210_GPIO_I_NR,
2075                        .label  = "GPI",
2076                },
2077        }, {
2078                .chip   = {
2079                        .base   = S5PV210_GPJ0(0),
2080                        .ngpio  = S5PV210_GPIO_J0_NR,
2081                        .label  = "GPJ0",
2082                },
2083        }, {
2084                .chip   = {
2085                        .base   = S5PV210_GPJ1(0),
2086                        .ngpio  = S5PV210_GPIO_J1_NR,
2087                        .label  = "GPJ1",
2088                },
2089        }, {
2090                .chip   = {
2091                        .base   = S5PV210_GPJ2(0),
2092                        .ngpio  = S5PV210_GPIO_J2_NR,
2093                        .label  = "GPJ2",
2094                },
2095        }, {
2096                .chip   = {
2097                        .base   = S5PV210_GPJ3(0),
2098                        .ngpio  = S5PV210_GPIO_J3_NR,
2099                        .label  = "GPJ3",
2100                },
2101        }, {
2102                .chip   = {
2103                        .base   = S5PV210_GPJ4(0),
2104                        .ngpio  = S5PV210_GPIO_J4_NR,
2105                        .label  = "GPJ4",
2106                },
2107        }, {
2108                .chip   = {
2109                        .base   = S5PV210_MP01(0),
2110                        .ngpio  = S5PV210_GPIO_MP01_NR,
2111                        .label  = "MP01",
2112                },
2113        }, {
2114                .chip   = {
2115                        .base   = S5PV210_MP02(0),
2116                        .ngpio  = S5PV210_GPIO_MP02_NR,
2117                        .label  = "MP02",
2118                },
2119        }, {
2120                .chip   = {
2121                        .base   = S5PV210_MP03(0),
2122                        .ngpio  = S5PV210_GPIO_MP03_NR,
2123                        .label  = "MP03",
2124                },
2125        }, {
2126                .chip   = {
2127                        .base   = S5PV210_MP04(0),
2128                        .ngpio  = S5PV210_GPIO_MP04_NR,
2129                        .label  = "MP04",
2130                },
2131        }, {
2132                .chip   = {
2133                        .base   = S5PV210_MP05(0),
2134                        .ngpio  = S5PV210_GPIO_MP05_NR,
2135                        .label  = "MP05",
2136                },
2137        }, {
2138                .base   = (S5P_VA_GPIO + 0xC00),
2139                .irq_base = IRQ_EINT(0),
2140                .chip   = {
2141                        .base   = S5PV210_GPH0(0),
2142                        .ngpio  = S5PV210_GPIO_H0_NR,
2143                        .label  = "GPH0",
2144                        .to_irq = samsung_gpiolib_to_irq,
2145                },
2146        }, {
2147                .base   = (S5P_VA_GPIO + 0xC20),
2148                .irq_base = IRQ_EINT(8),
2149                .chip   = {
2150                        .base   = S5PV210_GPH1(0),
2151                        .ngpio  = S5PV210_GPIO_H1_NR,
2152                        .label  = "GPH1",
2153                        .to_irq = samsung_gpiolib_to_irq,
2154                },
2155        }, {
2156                .base   = (S5P_VA_GPIO + 0xC40),
2157                .irq_base = IRQ_EINT(16),
2158                .chip   = {
2159                        .base   = S5PV210_GPH2(0),
2160                        .ngpio  = S5PV210_GPIO_H2_NR,
2161                        .label  = "GPH2",
2162                        .to_irq = samsung_gpiolib_to_irq,
2163                },
2164        }, {
2165                .base   = (S5P_VA_GPIO + 0xC60),
2166                .irq_base = IRQ_EINT(24),
2167                .chip   = {
2168                        .base   = S5PV210_GPH3(0),
2169                        .ngpio  = S5PV210_GPIO_H3_NR,
2170                        .label  = "GPH3",
2171                        .to_irq = samsung_gpiolib_to_irq,
2172                },
2173        },
2174#endif
2175};
2176
2177/*
2178 * Followings are the gpio banks in EXYNOS SoCs
2179 *
2180 * The 'config' member when left to NULL, is initialized to the default
2181 * structure exynos_gpio_cfg in the init function below.
2182 *
2183 * The 'base' member is also initialized in the init function below.
2184 * Note: The initialization of 'base' member of samsung_gpio_chip structure
2185 * uses the above macro and depends on the banks being listed in order here.
2186 */
2187
2188#ifdef CONFIG_ARCH_EXYNOS4
2189static struct samsung_gpio_chip exynos4_gpios_1[] = {
2190        {
2191                .chip   = {
2192                        .base   = EXYNOS4_GPA0(0),
2193                        .ngpio  = EXYNOS4_GPIO_A0_NR,
2194                        .label  = "GPA0",
2195                },
2196        }, {
2197                .chip   = {
2198                        .base   = EXYNOS4_GPA1(0),
2199                        .ngpio  = EXYNOS4_GPIO_A1_NR,
2200                        .label  = "GPA1",
2201                },
2202        }, {
2203                .chip   = {
2204                        .base   = EXYNOS4_GPB(0),
2205                        .ngpio  = EXYNOS4_GPIO_B_NR,
2206                        .label  = "GPB",
2207                },
2208        }, {
2209                .chip   = {
2210                        .base   = EXYNOS4_GPC0(0),
2211                        .ngpio  = EXYNOS4_GPIO_C0_NR,
2212                        .label  = "GPC0",
2213                },
2214        }, {
2215                .chip   = {
2216                        .base   = EXYNOS4_GPC1(0),
2217                        .ngpio  = EXYNOS4_GPIO_C1_NR,
2218                        .label  = "GPC1",
2219                },
2220        }, {
2221                .chip   = {
2222                        .base   = EXYNOS4_GPD0(0),
2223                        .ngpio  = EXYNOS4_GPIO_D0_NR,
2224                        .label  = "GPD0",
2225                },
2226        }, {
2227                .chip   = {
2228                        .base   = EXYNOS4_GPD1(0),
2229                        .ngpio  = EXYNOS4_GPIO_D1_NR,
2230                        .label  = "GPD1",
2231                },
2232        }, {
2233                .chip   = {
2234                        .base   = EXYNOS4_GPE0(0),
2235                        .ngpio  = EXYNOS4_GPIO_E0_NR,
2236                        .label  = "GPE0",
2237                },
2238        }, {
2239                .chip   = {
2240                        .base   = EXYNOS4_GPE1(0),
2241                        .ngpio  = EXYNOS4_GPIO_E1_NR,
2242                        .label  = "GPE1",
2243                },
2244        }, {
2245                .chip   = {
2246                        .base   = EXYNOS4_GPE2(0),
2247                        .ngpio  = EXYNOS4_GPIO_E2_NR,
2248                        .label  = "GPE2",
2249                },
2250        }, {
2251                .chip   = {
2252                        .base   = EXYNOS4_GPE3(0),
2253                        .ngpio  = EXYNOS4_GPIO_E3_NR,
2254                        .label  = "GPE3",
2255                },
2256        }, {
2257                .chip   = {
2258                        .base   = EXYNOS4_GPE4(0),
2259                        .ngpio  = EXYNOS4_GPIO_E4_NR,
2260                        .label  = "GPE4",
2261                },
2262        }, {
2263                .chip   = {
2264                        .base   = EXYNOS4_GPF0(0),
2265                        .ngpio  = EXYNOS4_GPIO_F0_NR,
2266                        .label  = "GPF0",
2267                },
2268        }, {
2269                .chip   = {
2270                        .base   = EXYNOS4_GPF1(0),
2271                        .ngpio  = EXYNOS4_GPIO_F1_NR,
2272                        .label  = "GPF1",
2273                },
2274        }, {
2275                .chip   = {
2276                        .base   = EXYNOS4_GPF2(0),
2277                        .ngpio  = EXYNOS4_GPIO_F2_NR,
2278                        .label  = "GPF2",
2279                },
2280        }, {
2281                .chip   = {
2282                        .base   = EXYNOS4_GPF3(0),
2283                        .ngpio  = EXYNOS4_GPIO_F3_NR,
2284                        .label  = "GPF3",
2285                },
2286        },
2287};
2288#endif
2289
2290#ifdef CONFIG_ARCH_EXYNOS4
2291static struct samsung_gpio_chip exynos4_gpios_2[] = {
2292        {
2293                .chip   = {
2294                        .base   = EXYNOS4_GPJ0(0),
2295                        .ngpio  = EXYNOS4_GPIO_J0_NR,
2296                        .label  = "GPJ0",
2297                },
2298        }, {
2299                .chip   = {
2300                        .base   = EXYNOS4_GPJ1(0),
2301                        .ngpio  = EXYNOS4_GPIO_J1_NR,
2302                        .label  = "GPJ1",
2303                },
2304        }, {
2305                .chip   = {
2306                        .base   = EXYNOS4_GPK0(0),
2307                        .ngpio  = EXYNOS4_GPIO_K0_NR,
2308                        .label  = "GPK0",
2309                },
2310        }, {
2311                .chip   = {
2312                        .base   = EXYNOS4_GPK1(0),
2313                        .ngpio  = EXYNOS4_GPIO_K1_NR,
2314                        .label  = "GPK1",
2315                },
2316        }, {
2317                .chip   = {
2318                        .base   = EXYNOS4_GPK2(0),
2319                        .ngpio  = EXYNOS4_GPIO_K2_NR,
2320                        .label  = "GPK2",
2321                },
2322        }, {
2323                .chip   = {
2324                        .base   = EXYNOS4_GPK3(0),
2325                        .ngpio  = EXYNOS4_GPIO_K3_NR,
2326                        .label  = "GPK3",
2327                },
2328        }, {
2329                .chip   = {
2330                        .base   = EXYNOS4_GPL0(0),
2331                        .ngpio  = EXYNOS4_GPIO_L0_NR,
2332                        .label  = "GPL0",
2333                },
2334        }, {
2335                .chip   = {
2336                        .base   = EXYNOS4_GPL1(0),
2337                        .ngpio  = EXYNOS4_GPIO_L1_NR,
2338                        .label  = "GPL1",
2339                },
2340        }, {
2341                .chip   = {
2342                        .base   = EXYNOS4_GPL2(0),
2343                        .ngpio  = EXYNOS4_GPIO_L2_NR,
2344                        .label  = "GPL2",
2345                },
2346        }, {
2347                .config = &samsung_gpio_cfgs[8],
2348                .chip   = {
2349                        .base   = EXYNOS4_GPY0(0),
2350                        .ngpio  = EXYNOS4_GPIO_Y0_NR,
2351                        .label  = "GPY0",
2352                },
2353        }, {
2354                .config = &samsung_gpio_cfgs[8],
2355                .chip   = {
2356                        .base   = EXYNOS4_GPY1(0),
2357                        .ngpio  = EXYNOS4_GPIO_Y1_NR,
2358                        .label  = "GPY1",
2359                },
2360        }, {
2361                .config = &samsung_gpio_cfgs[8],
2362                .chip   = {
2363                        .base   = EXYNOS4_GPY2(0),
2364                        .ngpio  = EXYNOS4_GPIO_Y2_NR,
2365                        .label  = "GPY2",
2366                },
2367        }, {
2368                .config = &samsung_gpio_cfgs[8],
2369                .chip   = {
2370                        .base   = EXYNOS4_GPY3(0),
2371                        .ngpio  = EXYNOS4_GPIO_Y3_NR,
2372                        .label  = "GPY3",
2373                },
2374        }, {
2375                .config = &samsung_gpio_cfgs[8],
2376                .chip   = {
2377                        .base   = EXYNOS4_GPY4(0),
2378                        .ngpio  = EXYNOS4_GPIO_Y4_NR,
2379                        .label  = "GPY4",
2380                },
2381        }, {
2382                .config = &samsung_gpio_cfgs[8],
2383                .chip   = {
2384                        .base   = EXYNOS4_GPY5(0),
2385                        .ngpio  = EXYNOS4_GPIO_Y5_NR,
2386                        .label  = "GPY5",
2387                },
2388        }, {
2389                .config = &samsung_gpio_cfgs[8],
2390                .chip   = {
2391                        .base   = EXYNOS4_GPY6(0),
2392                        .ngpio  = EXYNOS4_GPIO_Y6_NR,
2393                        .label  = "GPY6",
2394                },
2395        }, {
2396                .config = &samsung_gpio_cfgs[9],
2397                .irq_base = IRQ_EINT(0),
2398                .chip   = {
2399                        .base   = EXYNOS4_GPX0(0),
2400                        .ngpio  = EXYNOS4_GPIO_X0_NR,
2401                        .label  = "GPX0",
2402                        .to_irq = samsung_gpiolib_to_irq,
2403                },
2404        }, {
2405                .config = &samsung_gpio_cfgs[9],
2406                .irq_base = IRQ_EINT(8),
2407                .chip   = {
2408                        .base   = EXYNOS4_GPX1(0),
2409                        .ngpio  = EXYNOS4_GPIO_X1_NR,
2410                        .label  = "GPX1",
2411                        .to_irq = samsung_gpiolib_to_irq,
2412                },
2413        }, {
2414                .config = &samsung_gpio_cfgs[9],
2415                .irq_base = IRQ_EINT(16),
2416                .chip   = {
2417                        .base   = EXYNOS4_GPX2(0),
2418                        .ngpio  = EXYNOS4_GPIO_X2_NR,
2419                        .label  = "GPX2",
2420                        .to_irq = samsung_gpiolib_to_irq,
2421                },
2422        }, {
2423                .config = &samsung_gpio_cfgs[9],
2424                .irq_base = IRQ_EINT(24),
2425                .chip   = {
2426                        .base   = EXYNOS4_GPX3(0),
2427                        .ngpio  = EXYNOS4_GPIO_X3_NR,
2428                        .label  = "GPX3",
2429                        .to_irq = samsung_gpiolib_to_irq,
2430                },
2431        },
2432};
2433#endif
2434
2435#ifdef CONFIG_ARCH_EXYNOS4
2436static struct samsung_gpio_chip exynos4_gpios_3[] = {
2437        {
2438                .chip   = {
2439                        .base   = EXYNOS4_GPZ(0),
2440                        .ngpio  = EXYNOS4_GPIO_Z_NR,
2441                        .label  = "GPZ",
2442                },
2443        },
2444};
2445#endif
2446
2447#ifdef CONFIG_SOC_EXYNOS5250
2448static struct samsung_gpio_chip exynos5_gpios_1[] = {
2449        {
2450                .chip   = {
2451                        .base   = EXYNOS5_GPA0(0),
2452                        .ngpio  = EXYNOS5_GPIO_A0_NR,
2453                        .label  = "GPA0",
2454                },
2455        }, {
2456                .chip   = {
2457                        .base   = EXYNOS5_GPA1(0),
2458                        .ngpio  = EXYNOS5_GPIO_A1_NR,
2459                        .label  = "GPA1",
2460                },
2461        }, {
2462                .chip   = {
2463                        .base   = EXYNOS5_GPA2(0),
2464                        .ngpio  = EXYNOS5_GPIO_A2_NR,
2465                        .label  = "GPA2",
2466                },
2467        }, {
2468                .chip   = {
2469                        .base   = EXYNOS5_GPB0(0),
2470                        .ngpio  = EXYNOS5_GPIO_B0_NR,
2471                        .label  = "GPB0",
2472                },
2473        }, {
2474                .chip   = {
2475                        .base   = EXYNOS5_GPB1(0),
2476                        .ngpio  = EXYNOS5_GPIO_B1_NR,
2477                        .label  = "GPB1",
2478                },
2479        }, {
2480                .chip   = {
2481                        .base   = EXYNOS5_GPB2(0),
2482                        .ngpio  = EXYNOS5_GPIO_B2_NR,
2483                        .label  = "GPB2",
2484                },
2485        }, {
2486                .chip   = {
2487                        .base   = EXYNOS5_GPB3(0),
2488                        .ngpio  = EXYNOS5_GPIO_B3_NR,
2489                        .label  = "GPB3",
2490                },
2491        }, {
2492                .chip   = {
2493                        .base   = EXYNOS5_GPC0(0),
2494                        .ngpio  = EXYNOS5_GPIO_C0_NR,
2495                        .label  = "GPC0",
2496                },
2497        }, {
2498                .chip   = {
2499                        .base   = EXYNOS5_GPC1(0),
2500                        .ngpio  = EXYNOS5_GPIO_C1_NR,
2501                        .label  = "GPC1",
2502                },
2503        }, {
2504                .chip   = {
2505                        .base   = EXYNOS5_GPC2(0),
2506                        .ngpio  = EXYNOS5_GPIO_C2_NR,
2507                        .label  = "GPC2",
2508                },
2509        }, {
2510                .chip   = {
2511                        .base   = EXYNOS5_GPC3(0),
2512                        .ngpio  = EXYNOS5_GPIO_C3_NR,
2513                        .label  = "GPC3",
2514                },
2515        }, {
2516                .chip   = {
2517                        .base   = EXYNOS5_GPD0(0),
2518                        .ngpio  = EXYNOS5_GPIO_D0_NR,
2519                        .label  = "GPD0",
2520                },
2521        }, {
2522                .chip   = {
2523                        .base   = EXYNOS5_GPD1(0),
2524                        .ngpio  = EXYNOS5_GPIO_D1_NR,
2525                        .label  = "GPD1",
2526                },
2527        }, {
2528                .chip   = {
2529                        .base   = EXYNOS5_GPY0(0),
2530                        .ngpio  = EXYNOS5_GPIO_Y0_NR,
2531                        .label  = "GPY0",
2532                },
2533        }, {
2534                .chip   = {
2535                        .base   = EXYNOS5_GPY1(0),
2536                        .ngpio  = EXYNOS5_GPIO_Y1_NR,
2537                        .label  = "GPY1",
2538                },
2539        }, {
2540                .chip   = {
2541                        .base   = EXYNOS5_GPY2(0),
2542                        .ngpio  = EXYNOS5_GPIO_Y2_NR,
2543                        .label  = "GPY2",
2544                },
2545        }, {
2546                .chip   = {
2547                        .base   = EXYNOS5_GPY3(0),
2548                        .ngpio  = EXYNOS5_GPIO_Y3_NR,
2549                        .label  = "GPY3",
2550                },
2551        }, {
2552                .chip   = {
2553                        .base   = EXYNOS5_GPY4(0),
2554                        .ngpio  = EXYNOS5_GPIO_Y4_NR,
2555                        .label  = "GPY4",
2556                },
2557        }, {
2558                .chip   = {
2559                        .base   = EXYNOS5_GPY5(0),
2560                        .ngpio  = EXYNOS5_GPIO_Y5_NR,
2561                        .label  = "GPY5",
2562                },
2563        }, {
2564                .chip   = {
2565                        .base   = EXYNOS5_GPY6(0),
2566                        .ngpio  = EXYNOS5_GPIO_Y6_NR,
2567                        .label  = "GPY6",
2568                },
2569        }, {
2570                .chip   = {
2571                        .base   = EXYNOS5_GPC4(0),
2572                        .ngpio  = EXYNOS5_GPIO_C4_NR,
2573                        .label  = "GPC4",
2574                },
2575        }, {
2576                .config = &samsung_gpio_cfgs[9],
2577                .irq_base = IRQ_EINT(0),
2578                .chip   = {
2579                        .base   = EXYNOS5_GPX0(0),
2580                        .ngpio  = EXYNOS5_GPIO_X0_NR,
2581                        .label  = "GPX0",
2582                        .to_irq = samsung_gpiolib_to_irq,
2583                },
2584        }, {
2585                .config = &samsung_gpio_cfgs[9],
2586                .irq_base = IRQ_EINT(8),
2587                .chip   = {
2588                        .base   = EXYNOS5_GPX1(0),
2589                        .ngpio  = EXYNOS5_GPIO_X1_NR,
2590                        .label  = "GPX1",
2591                        .to_irq = samsung_gpiolib_to_irq,
2592                },
2593        }, {
2594                .config = &samsung_gpio_cfgs[9],
2595                .irq_base = IRQ_EINT(16),
2596                .chip   = {
2597                        .base   = EXYNOS5_GPX2(0),
2598                        .ngpio  = EXYNOS5_GPIO_X2_NR,
2599                        .label  = "GPX2",
2600                        .to_irq = samsung_gpiolib_to_irq,
2601                },
2602        }, {
2603                .config = &samsung_gpio_cfgs[9],
2604                .irq_base = IRQ_EINT(24),
2605                .chip   = {
2606                        .base   = EXYNOS5_GPX3(0),
2607                        .ngpio  = EXYNOS5_GPIO_X3_NR,
2608                        .label  = "GPX3",
2609                        .to_irq = samsung_gpiolib_to_irq,
2610                },
2611        },
2612};
2613#endif
2614
2615#ifdef CONFIG_SOC_EXYNOS5250
2616static struct samsung_gpio_chip exynos5_gpios_2[] = {
2617        {
2618                .chip   = {
2619                        .base   = EXYNOS5_GPE0(0),
2620                        .ngpio  = EXYNOS5_GPIO_E0_NR,
2621                        .label  = "GPE0",
2622                },
2623        }, {
2624                .chip   = {
2625                        .base   = EXYNOS5_GPE1(0),
2626                        .ngpio  = EXYNOS5_GPIO_E1_NR,
2627                        .label  = "GPE1",
2628                },
2629        }, {
2630                .chip   = {
2631                        .base   = EXYNOS5_GPF0(0),
2632                        .ngpio  = EXYNOS5_GPIO_F0_NR,
2633                        .label  = "GPF0",
2634                },
2635        }, {
2636                .chip   = {
2637                        .base   = EXYNOS5_GPF1(0),
2638                        .ngpio  = EXYNOS5_GPIO_F1_NR,
2639                        .label  = "GPF1",
2640                },
2641        }, {
2642                .chip   = {
2643                        .base   = EXYNOS5_GPG0(0),
2644                        .ngpio  = EXYNOS5_GPIO_G0_NR,
2645                        .label  = "GPG0",
2646                },
2647        }, {
2648                .chip   = {
2649                        .base   = EXYNOS5_GPG1(0),
2650                        .ngpio  = EXYNOS5_GPIO_G1_NR,
2651                        .label  = "GPG1",
2652                },
2653        }, {
2654                .chip   = {
2655                        .base   = EXYNOS5_GPG2(0),
2656                        .ngpio  = EXYNOS5_GPIO_G2_NR,
2657                        .label  = "GPG2",
2658                },
2659        }, {
2660                .chip   = {
2661                        .base   = EXYNOS5_GPH0(0),
2662                        .ngpio  = EXYNOS5_GPIO_H0_NR,
2663                        .label  = "GPH0",
2664                },
2665        }, {
2666                .chip   = {
2667                        .base   = EXYNOS5_GPH1(0),
2668                        .ngpio  = EXYNOS5_GPIO_H1_NR,
2669                        .label  = "GPH1",
2670
2671                },
2672        },
2673};
2674#endif
2675
2676#ifdef CONFIG_SOC_EXYNOS5250
2677static struct samsung_gpio_chip exynos5_gpios_3[] = {
2678        {
2679                .chip   = {
2680                        .base   = EXYNOS5_GPV0(0),
2681                        .ngpio  = EXYNOS5_GPIO_V0_NR,
2682                        .label  = "GPV0",
2683                },
2684        }, {
2685                .chip   = {
2686                        .base   = EXYNOS5_GPV1(0),
2687                        .ngpio  = EXYNOS5_GPIO_V1_NR,
2688                        .label  = "GPV1",
2689                },
2690        }, {
2691                .chip   = {
2692                        .base   = EXYNOS5_GPV2(0),
2693                        .ngpio  = EXYNOS5_GPIO_V2_NR,
2694                        .label  = "GPV2",
2695                },
2696        }, {
2697                .chip   = {
2698                        .base   = EXYNOS5_GPV3(0),
2699                        .ngpio  = EXYNOS5_GPIO_V3_NR,
2700                        .label  = "GPV3",
2701                },
2702        }, {
2703                .chip   = {
2704                        .base   = EXYNOS5_GPV4(0),
2705                        .ngpio  = EXYNOS5_GPIO_V4_NR,
2706                        .label  = "GPV4",
2707                },
2708        },
2709};
2710#endif
2711
2712#ifdef CONFIG_SOC_EXYNOS5250
2713static struct samsung_gpio_chip exynos5_gpios_4[] = {
2714        {
2715                .chip   = {
2716                        .base   = EXYNOS5_GPZ(0),
2717                        .ngpio  = EXYNOS5_GPIO_Z_NR,
2718                        .label  = "GPZ",
2719                },
2720        },
2721};
2722#endif
2723
2724
2725#if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF)
2726static int exynos_gpio_xlate(struct gpio_chip *gc,
2727                        const struct of_phandle_args *gpiospec, u32 *flags)
2728{
2729        unsigned int pin;
2730
2731        if (WARN_ON(gc->of_gpio_n_cells < 4))
2732                return -EINVAL;
2733
2734        if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
2735                return -EINVAL;
2736
2737        if (gpiospec->args[0] > gc->ngpio)
2738                return -EINVAL;
2739
2740        pin = gc->base + gpiospec->args[0];
2741
2742        if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
2743                pr_warn("gpio_xlate: failed to set pin function\n");
2744        if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff))
2745                pr_warn("gpio_xlate: failed to set pin pull up/down\n");
2746        if (s5p_gpio_set_drvstr(pin, gpiospec->args[3]))
2747                pr_warn("gpio_xlate: failed to set pin drive strength\n");
2748
2749        if (flags)
2750                *flags = gpiospec->args[2] >> 16;
2751
2752        return gpiospec->args[0];
2753}
2754
2755static const struct of_device_id exynos_gpio_dt_match[] __initdata = {
2756        { .compatible = "samsung,exynos4-gpio", },
2757        {}
2758};
2759
2760static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
2761                                                u64 base, u64 offset)
2762{
2763        struct gpio_chip *gc =  &chip->chip;
2764        u64 address;
2765
2766        if (!of_have_populated_dt())
2767                return;
2768
2769        address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
2770        gc->of_node = of_find_matching_node_by_address(NULL,
2771                        exynos_gpio_dt_match, address);
2772        if (!gc->of_node) {
2773                pr_info("gpio: device tree node not found for gpio controller"
2774                        " with base address %08llx\n", address);
2775                return;
2776        }
2777        gc->of_gpio_n_cells = 4;
2778        gc->of_xlate = exynos_gpio_xlate;
2779}
2780#elif defined(CONFIG_ARCH_EXYNOS)
2781static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
2782                                                u64 base, u64 offset)
2783{
2784        return;
2785}
2786#endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */
2787
2788static __init void exynos4_gpiolib_init(void)
2789{
2790#ifdef CONFIG_CPU_EXYNOS4210
2791        struct samsung_gpio_chip *chip;
2792        int i, nr_chips;
2793        void __iomem *gpio_base1, *gpio_base2, *gpio_base3;
2794        int group = 0;
2795        void __iomem *gpx_base;
2796
2797        /* gpio part1 */
2798        gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K);
2799        if (gpio_base1 == NULL) {
2800                pr_err("unable to ioremap for gpio_base1\n");
2801                goto err_ioremap1;
2802        }
2803
2804        chip = exynos4_gpios_1;
2805        nr_chips = ARRAY_SIZE(exynos4_gpios_1);
2806
2807        for (i = 0; i < nr_chips; i++, chip++) {
2808                if (!chip->config) {
2809                        chip->config = &exynos_gpio_cfg;
2810                        chip->group = group++;
2811                }
2812                exynos_gpiolib_attach_ofnode(chip,
2813                                EXYNOS4_PA_GPIO1, i * 0x20);
2814        }
2815        samsung_gpiolib_add_4bit_chips(exynos4_gpios_1,
2816                                       nr_chips, gpio_base1);
2817
2818        /* gpio part2 */
2819        gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
2820        if (gpio_base2 == NULL) {
2821                pr_err("unable to ioremap for gpio_base2\n");
2822                goto err_ioremap2;
2823        }
2824
2825        /* need to set base address for gpx */
2826        chip = &exynos4_gpios_2[16];
2827        gpx_base = gpio_base2 + 0xC00;
2828        for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
2829                chip->base = gpx_base;
2830
2831        chip = exynos4_gpios_2;
2832        nr_chips = ARRAY_SIZE(exynos4_gpios_2);
2833
2834        for (i = 0; i < nr_chips; i++, chip++) {
2835                if (!chip->config) {
2836                        chip->config = &exynos_gpio_cfg;
2837                        chip->group = group++;
2838                }
2839                exynos_gpiolib_attach_ofnode(chip,
2840                                EXYNOS4_PA_GPIO2, i * 0x20);
2841        }
2842        samsung_gpiolib_add_4bit_chips(exynos4_gpios_2,
2843                                       nr_chips, gpio_base2);
2844
2845        /* gpio part3 */
2846        gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256);
2847        if (gpio_base3 == NULL) {
2848                pr_err("unable to ioremap for gpio_base3\n");
2849                goto err_ioremap3;
2850        }
2851
2852        chip = exynos4_gpios_3;
2853        nr_chips = ARRAY_SIZE(exynos4_gpios_3);
2854
2855        for (i = 0; i < nr_chips; i++, chip++) {
2856                if (!chip->config) {
2857                        chip->config = &exynos_gpio_cfg;
2858                        chip->group = group++;
2859                }
2860                exynos_gpiolib_attach_ofnode(chip,
2861                                EXYNOS4_PA_GPIO3, i * 0x20);
2862        }
2863        samsung_gpiolib_add_4bit_chips(exynos4_gpios_3,
2864                                       nr_chips, gpio_base3);
2865
2866#if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT)
2867        s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
2868        s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
2869#endif
2870
2871        return;
2872
2873err_ioremap3:
2874        iounmap(gpio_base2);
2875err_ioremap2:
2876        iounmap(gpio_base1);
2877err_ioremap1:
2878        return;
2879#endif  /* CONFIG_CPU_EXYNOS4210 */
2880}
2881
2882static __init void exynos5_gpiolib_init(void)
2883{
2884#ifdef CONFIG_SOC_EXYNOS5250
2885        struct samsung_gpio_chip *chip;
2886        int i, nr_chips;
2887        void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4;
2888        int group = 0;
2889        void __iomem *gpx_base;
2890
2891        /* gpio part1 */
2892        gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
2893        if (gpio_base1 == NULL) {
2894                pr_err("unable to ioremap for gpio_base1\n");
2895                goto err_ioremap1;
2896        }
2897
2898        /* need to set base address for gpc4 */
2899        exynos5_gpios_1[20].base = gpio_base1 + 0x2E0;
2900
2901        /* need to set base address for gpx */
2902        chip = &exynos5_gpios_1[21];
2903        gpx_base = gpio_base1 + 0xC00;
2904        for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
2905                chip->base = gpx_base;
2906
2907        chip = exynos5_gpios_1;
2908        nr_chips = ARRAY_SIZE(exynos5_gpios_1);
2909
2910        for (i = 0; i < nr_chips; i++, chip++) {
2911                if (!chip->config) {
2912                        chip->config = &exynos_gpio_cfg;
2913                        chip->group = group++;
2914                }
2915                exynos_gpiolib_attach_ofnode(chip,
2916                                EXYNOS5_PA_GPIO1, i * 0x20);
2917        }
2918        samsung_gpiolib_add_4bit_chips(exynos5_gpios_1,
2919                                       nr_chips, gpio_base1);
2920
2921        /* gpio part2 */
2922        gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K);
2923        if (gpio_base2 == NULL) {
2924                pr_err("unable to ioremap for gpio_base2\n");
2925                goto err_ioremap2;
2926        }
2927
2928        chip = exynos5_gpios_2;
2929        nr_chips = ARRAY_SIZE(exynos5_gpios_2);
2930
2931        for (i = 0; i < nr_chips; i++, chip++) {
2932                if (!chip->config) {
2933                        chip->config = &exynos_gpio_cfg;
2934                        chip->group = group++;
2935                }
2936                exynos_gpiolib_attach_ofnode(chip,
2937                                EXYNOS5_PA_GPIO2, i * 0x20);
2938        }
2939        samsung_gpiolib_add_4bit_chips(exynos5_gpios_2,
2940                                       nr_chips, gpio_base2);
2941
2942        /* gpio part3 */
2943        gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K);
2944        if (gpio_base3 == NULL) {
2945                pr_err("unable to ioremap for gpio_base3\n");
2946                goto err_ioremap3;
2947        }
2948
2949        /* need to set base address for gpv */
2950        exynos5_gpios_3[0].base = gpio_base3;
2951        exynos5_gpios_3[1].base = gpio_base3 + 0x20;
2952        exynos5_gpios_3[2].base = gpio_base3 + 0x60;
2953        exynos5_gpios_3[3].base = gpio_base3 + 0x80;
2954        exynos5_gpios_3[4].base = gpio_base3 + 0xC0;
2955
2956        chip = exynos5_gpios_3;
2957        nr_chips = ARRAY_SIZE(exynos5_gpios_3);
2958
2959        for (i = 0; i < nr_chips; i++, chip++) {
2960                if (!chip->config) {
2961                        chip->config = &exynos_gpio_cfg;
2962                        chip->group = group++;
2963                }
2964                exynos_gpiolib_attach_ofnode(chip,
2965                                EXYNOS5_PA_GPIO3, i * 0x20);
2966        }
2967        samsung_gpiolib_add_4bit_chips(exynos5_gpios_3,
2968                                       nr_chips, gpio_base3);
2969
2970        /* gpio part4 */
2971        gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K);
2972        if (gpio_base4 == NULL) {
2973                pr_err("unable to ioremap for gpio_base4\n");
2974                goto err_ioremap4;
2975        }
2976
2977        chip = exynos5_gpios_4;
2978        nr_chips = ARRAY_SIZE(exynos5_gpios_4);
2979
2980        for (i = 0; i < nr_chips; i++, chip++) {
2981                if (!chip->config) {
2982                        chip->config = &exynos_gpio_cfg;
2983                        chip->group = group++;
2984                }
2985                exynos_gpiolib_attach_ofnode(chip,
2986                                EXYNOS5_PA_GPIO4, i * 0x20);
2987        }
2988        samsung_gpiolib_add_4bit_chips(exynos5_gpios_4,
2989                                       nr_chips, gpio_base4);
2990        return;
2991
2992err_ioremap4:
2993        iounmap(gpio_base3);
2994err_ioremap3:
2995        iounmap(gpio_base2);
2996err_ioremap2:
2997        iounmap(gpio_base1);
2998err_ioremap1:
2999        return;
3000
3001#endif  /* CONFIG_SOC_EXYNOS5250 */
3002}
3003
3004/* TODO: cleanup soc_is_* */
3005static __init int samsung_gpiolib_init(void)
3006{
3007        struct samsung_gpio_chip *chip;
3008        int i, nr_chips;
3009        int group = 0;
3010
3011#if defined(CONFIG_PINCTRL_EXYNOS) || defined(CONFIG_PINCTRL_EXYNOS5440)
3012        /*
3013        * This gpio driver includes support for device tree support and there
3014        * are platforms using it. In order to maintain compatibility with those
3015        * platforms, and to allow non-dt Exynos4210 platforms to use this
3016        * gpiolib support, a check is added to find out if there is a active
3017        * pin-controller driver support available. If it is available, this
3018        * gpiolib support is ignored and the gpiolib support available in
3019        * pin-controller driver is used. This is a temporary check and will go
3020        * away when all of the Exynos4210 platforms have switched to using
3021        * device tree and the pin-ctrl driver.
3022        */
3023        struct device_node *pctrl_np;
3024        static const struct of_device_id exynos_pinctrl_ids[] = {
3025                { .compatible = "samsung,exynos4210-pinctrl", },
3026                { .compatible = "samsung,exynos4x12-pinctrl", },
3027                { .compatible = "samsung,exynos5440-pinctrl", },
3028        };
3029        for_each_matching_node(pctrl_np, exynos_pinctrl_ids)
3030                if (pctrl_np && of_device_is_available(pctrl_np))
3031                        return -ENODEV;
3032#endif
3033
3034        samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
3035
3036        if (soc_is_s3c24xx()) {
3037                s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
3038                                ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
3039        } else if (soc_is_s3c64xx()) {
3040                samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
3041                                ARRAY_SIZE(s3c64xx_gpios_2bit),
3042                                S3C64XX_VA_GPIO + 0xE0, 0x20);
3043                samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
3044                                ARRAY_SIZE(s3c64xx_gpios_4bit),
3045                                S3C64XX_VA_GPIO);
3046                samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
3047                                ARRAY_SIZE(s3c64xx_gpios_4bit2));
3048        } else if (soc_is_s5p6440()) {
3049                samsung_gpiolib_add_2bit_chips(s5p6440_gpios_2bit,
3050                                ARRAY_SIZE(s5p6440_gpios_2bit), NULL, 0x0);
3051                samsung_gpiolib_add_4bit_chips(s5p6440_gpios_4bit,
3052                                ARRAY_SIZE(s5p6440_gpios_4bit), S5P_VA_GPIO);
3053                samsung_gpiolib_add_4bit2_chips(s5p6440_gpios_4bit2,
3054                                ARRAY_SIZE(s5p6440_gpios_4bit2));
3055                s5p64x0_gpiolib_add_rbank(s5p6440_gpios_rbank,
3056                                ARRAY_SIZE(s5p6440_gpios_rbank));
3057        } else if (soc_is_s5p6450()) {
3058                samsung_gpiolib_add_2bit_chips(s5p6450_gpios_2bit,
3059                                ARRAY_SIZE(s5p6450_gpios_2bit), NULL, 0x0);
3060                samsung_gpiolib_add_4bit_chips(s5p6450_gpios_4bit,
3061                                ARRAY_SIZE(s5p6450_gpios_4bit), S5P_VA_GPIO);
3062                samsung_gpiolib_add_4bit2_chips(s5p6450_gpios_4bit2,
3063                                ARRAY_SIZE(s5p6450_gpios_4bit2));
3064                s5p64x0_gpiolib_add_rbank(s5p6450_gpios_rbank,
3065                                ARRAY_SIZE(s5p6450_gpios_rbank));
3066        } else if (soc_is_s5pc100()) {
3067                group = 0;
3068                chip = s5pc100_gpios_4bit;
3069                nr_chips = ARRAY_SIZE(s5pc100_gpios_4bit);
3070
3071                for (i = 0; i < nr_chips; i++, chip++) {
3072                        if (!chip->config) {
3073                                chip->config = &samsung_gpio_cfgs[3];
3074                                chip->group = group++;
3075                        }
3076                }
3077                samsung_gpiolib_add_4bit_chips(s5pc100_gpios_4bit, nr_chips, S5P_VA_GPIO);
3078#if defined(CONFIG_CPU_S5PC100) && defined(CONFIG_S5P_GPIO_INT)
3079                s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
3080#endif
3081        } else if (soc_is_s5pv210()) {
3082                group = 0;
3083                chip = s5pv210_gpios_4bit;
3084                nr_chips = ARRAY_SIZE(s5pv210_gpios_4bit);
3085
3086                for (i = 0; i < nr_chips; i++, chip++) {
3087                        if (!chip->config) {
3088                                chip->config = &samsung_gpio_cfgs[3];
3089                                chip->group = group++;
3090                        }
3091                }
3092                samsung_gpiolib_add_4bit_chips(s5pv210_gpios_4bit, nr_chips, S5P_VA_GPIO);
3093#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_S5P_GPIO_INT)
3094                s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
3095#endif
3096        } else if (soc_is_exynos4210()) {
3097                exynos4_gpiolib_init();
3098        } else if (soc_is_exynos5250()) {
3099                exynos5_gpiolib_init();
3100        } else {
3101                WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
3102                return -ENODEV;
3103        }
3104
3105        return 0;
3106}
3107core_initcall(samsung_gpiolib_init);
3108
3109int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
3110{
3111        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3112        unsigned long flags;
3113        int offset;
3114        int ret;
3115
3116        if (!chip)
3117                return -EINVAL;
3118
3119        offset = pin - chip->chip.base;
3120
3121        samsung_gpio_lock(chip, flags);
3122        ret = samsung_gpio_do_setcfg(chip, offset, config);
3123        samsung_gpio_unlock(chip, flags);
3124
3125        return ret;
3126}
3127EXPORT_SYMBOL(s3c_gpio_cfgpin);
3128
3129int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
3130                          unsigned int cfg)
3131{
3132        int ret;
3133
3134        for (; nr > 0; nr--, start++) {
3135                ret = s3c_gpio_cfgpin(start, cfg);
3136                if (ret != 0)
3137                        return ret;
3138        }
3139
3140        return 0;
3141}
3142EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
3143
3144int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
3145                          unsigned int cfg, samsung_gpio_pull_t pull)
3146{
3147        int ret;
3148
3149        for (; nr > 0; nr--, start++) {
3150                s3c_gpio_setpull(start, pull);
3151                ret = s3c_gpio_cfgpin(start, cfg);
3152                if (ret != 0)
3153                        return ret;
3154        }
3155
3156        return 0;
3157}
3158EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
3159
3160unsigned s3c_gpio_getcfg(unsigned int pin)
3161{
3162        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3163        unsigned long flags;
3164        unsigned ret = 0;
3165        int offset;
3166
3167        if (chip) {
3168                offset = pin - chip->chip.base;
3169
3170                samsung_gpio_lock(chip, flags);
3171                ret = samsung_gpio_do_getcfg(chip, offset);
3172                samsung_gpio_unlock(chip, flags);
3173        }
3174
3175        return ret;
3176}
3177EXPORT_SYMBOL(s3c_gpio_getcfg);
3178
3179int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
3180{
3181        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3182        unsigned long flags;
3183        int offset, ret;
3184
3185        if (!chip)
3186                return -EINVAL;
3187
3188        offset = pin - chip->chip.base;
3189
3190        samsung_gpio_lock(chip, flags);
3191        ret = samsung_gpio_do_setpull(chip, offset, pull);
3192        samsung_gpio_unlock(chip, flags);
3193
3194        return ret;
3195}
3196EXPORT_SYMBOL(s3c_gpio_setpull);
3197
3198samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
3199{
3200        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3201        unsigned long flags;
3202        int offset;
3203        u32 pup = 0;
3204
3205        if (chip) {
3206                offset = pin - chip->chip.base;
3207
3208                samsung_gpio_lock(chip, flags);
3209                pup = samsung_gpio_do_getpull(chip, offset);
3210                samsung_gpio_unlock(chip, flags);
3211        }
3212
3213        return (__force samsung_gpio_pull_t)pup;
3214}
3215EXPORT_SYMBOL(s3c_gpio_getpull);
3216
3217#ifdef CONFIG_S5P_GPIO_DRVSTR
3218s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
3219{
3220        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3221        unsigned int off;
3222        void __iomem *reg;
3223        int shift;
3224        u32 drvstr;
3225
3226        if (!chip)
3227                return -EINVAL;
3228
3229        off = pin - chip->chip.base;
3230        shift = off * 2;
3231        reg = chip->base + 0x0C;
3232
3233        drvstr = __raw_readl(reg);
3234        drvstr = drvstr >> shift;
3235        drvstr &= 0x3;
3236
3237        return (__force s5p_gpio_drvstr_t)drvstr;
3238}
3239EXPORT_SYMBOL(s5p_gpio_get_drvstr);
3240
3241int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
3242{
3243        struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3244        unsigned int off;
3245        void __iomem *reg;
3246        int shift;
3247        u32 tmp;
3248
3249        if (!chip)
3250                return -EINVAL;
3251
3252        off = pin - chip->chip.base;
3253        shift = off * 2;
3254        reg = chip->base + 0x0C;
3255
3256        tmp = __raw_readl(reg);
3257        tmp &= ~(0x3 << shift);
3258        tmp |= drvstr << shift;
3259
3260        __raw_writel(tmp, reg);
3261
3262        return 0;
3263}
3264EXPORT_SYMBOL(s5p_gpio_set_drvstr);
3265#endif  /* CONFIG_S5P_GPIO_DRVSTR */
3266
3267#ifdef CONFIG_PLAT_S3C24XX
3268unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
3269{
3270        unsigned long flags;
3271        unsigned long misccr;
3272
3273        local_irq_save(flags);
3274        misccr = __raw_readl(S3C24XX_MISCCR);
3275        misccr &= ~clear;
3276        misccr ^= change;
3277        __raw_writel(misccr, S3C24XX_MISCCR);
3278        local_irq_restore(flags);
3279
3280        return misccr;
3281}
3282EXPORT_SYMBOL(s3c2410_modify_misccr);
3283#endif
3284
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.