Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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