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