Linux Audio

Check our new training course

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