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