Linux Audio

Check our new training course

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