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_GPD0(0),
2458			.ngpio	= EXYNOS5_GPIO_D0_NR,
2459			.label	= "GPD0",
2460		},
2461	}, {
2462		.chip	= {
2463			.base	= EXYNOS5_GPD1(0),
2464			.ngpio	= EXYNOS5_GPIO_D1_NR,
2465			.label	= "GPD1",
2466		},
2467	}, {
2468		.chip	= {
2469			.base	= EXYNOS5_GPY0(0),
2470			.ngpio	= EXYNOS5_GPIO_Y0_NR,
2471			.label	= "GPY0",
2472		},
2473	}, {
2474		.chip	= {
2475			.base	= EXYNOS5_GPY1(0),
2476			.ngpio	= EXYNOS5_GPIO_Y1_NR,
2477			.label	= "GPY1",
2478		},
2479	}, {
2480		.chip	= {
2481			.base	= EXYNOS5_GPY2(0),
2482			.ngpio	= EXYNOS5_GPIO_Y2_NR,
2483			.label	= "GPY2",
2484		},
2485	}, {
2486		.chip	= {
2487			.base	= EXYNOS5_GPY3(0),
2488			.ngpio	= EXYNOS5_GPIO_Y3_NR,
2489			.label	= "GPY3",
2490		},
2491	}, {
2492		.chip	= {
2493			.base	= EXYNOS5_GPY4(0),
2494			.ngpio	= EXYNOS5_GPIO_Y4_NR,
2495			.label	= "GPY4",
2496		},
2497	}, {
2498		.chip	= {
2499			.base	= EXYNOS5_GPY5(0),
2500			.ngpio	= EXYNOS5_GPIO_Y5_NR,
2501			.label	= "GPY5",
2502		},
2503	}, {
2504		.chip	= {
2505			.base	= EXYNOS5_GPY6(0),
2506			.ngpio	= EXYNOS5_GPIO_Y6_NR,
2507			.label	= "GPY6",
2508		},
2509	}, {
2510		.config	= &samsung_gpio_cfgs[9],
2511		.irq_base = IRQ_EINT(0),
2512		.chip	= {
2513			.base	= EXYNOS5_GPX0(0),
2514			.ngpio	= EXYNOS5_GPIO_X0_NR,
2515			.label	= "GPX0",
2516			.to_irq	= samsung_gpiolib_to_irq,
2517		},
2518	}, {
2519		.config	= &samsung_gpio_cfgs[9],
2520		.irq_base = IRQ_EINT(8),
2521		.chip	= {
2522			.base	= EXYNOS5_GPX1(0),
2523			.ngpio	= EXYNOS5_GPIO_X1_NR,
2524			.label	= "GPX1",
2525			.to_irq	= samsung_gpiolib_to_irq,
2526		},
2527	}, {
2528		.config	= &samsung_gpio_cfgs[9],
2529		.irq_base = IRQ_EINT(16),
2530		.chip	= {
2531			.base	= EXYNOS5_GPX2(0),
2532			.ngpio	= EXYNOS5_GPIO_X2_NR,
2533			.label	= "GPX2",
2534			.to_irq	= samsung_gpiolib_to_irq,
2535		},
2536	}, {
2537		.config	= &samsung_gpio_cfgs[9],
2538		.irq_base = IRQ_EINT(24),
2539		.chip	= {
2540			.base	= EXYNOS5_GPX3(0),
2541			.ngpio	= EXYNOS5_GPIO_X3_NR,
2542			.label	= "GPX3",
2543			.to_irq	= samsung_gpiolib_to_irq,
2544		},
2545	},
2546};
2547#endif
2548
2549#ifdef CONFIG_ARCH_EXYNOS5
2550static struct samsung_gpio_chip exynos5_gpios_2[] = {
2551	{
2552		.chip	= {
2553			.base	= EXYNOS5_GPE0(0),
2554			.ngpio	= EXYNOS5_GPIO_E0_NR,
2555			.label	= "GPE0",
2556		},
2557	}, {
2558		.chip	= {
2559			.base	= EXYNOS5_GPE1(0),
2560			.ngpio	= EXYNOS5_GPIO_E1_NR,
2561			.label	= "GPE1",
2562		},
2563	}, {
2564		.chip	= {
2565			.base	= EXYNOS5_GPF0(0),
2566			.ngpio	= EXYNOS5_GPIO_F0_NR,
2567			.label	= "GPF0",
2568		},
2569	}, {
2570		.chip	= {
2571			.base	= EXYNOS5_GPF1(0),
2572			.ngpio	= EXYNOS5_GPIO_F1_NR,
2573			.label	= "GPF1",
2574		},
2575	}, {
2576		.chip	= {
2577			.base	= EXYNOS5_GPG0(0),
2578			.ngpio	= EXYNOS5_GPIO_G0_NR,
2579			.label	= "GPG0",
2580		},
2581	}, {
2582		.chip	= {
2583			.base	= EXYNOS5_GPG1(0),
2584			.ngpio	= EXYNOS5_GPIO_G1_NR,
2585			.label	= "GPG1",
2586		},
2587	}, {
2588		.chip	= {
2589			.base	= EXYNOS5_GPG2(0),
2590			.ngpio	= EXYNOS5_GPIO_G2_NR,
2591			.label	= "GPG2",
2592		},
2593	}, {
2594		.chip	= {
2595			.base	= EXYNOS5_GPH0(0),
2596			.ngpio	= EXYNOS5_GPIO_H0_NR,
2597			.label	= "GPH0",
2598		},
2599	}, {
2600		.chip	= {
2601			.base	= EXYNOS5_GPH1(0),
2602			.ngpio	= EXYNOS5_GPIO_H1_NR,
2603			.label	= "GPH1",
2604
2605		},
2606	},
2607};
2608#endif
2609
2610#ifdef CONFIG_ARCH_EXYNOS5
2611static struct samsung_gpio_chip exynos5_gpios_3[] = {
2612	{
2613		.chip	= {
2614			.base	= EXYNOS5_GPV0(0),
2615			.ngpio	= EXYNOS5_GPIO_V0_NR,
2616			.label	= "GPV0",
2617		},
2618	}, {
2619		.chip	= {
2620			.base	= EXYNOS5_GPV1(0),
2621			.ngpio	= EXYNOS5_GPIO_V1_NR,
2622			.label	= "GPV1",
2623		},
2624	}, {
2625		.chip	= {
2626			.base	= EXYNOS5_GPV2(0),
2627			.ngpio	= EXYNOS5_GPIO_V2_NR,
2628			.label	= "GPV2",
2629		},
2630	}, {
2631		.chip	= {
2632			.base	= EXYNOS5_GPV3(0),
2633			.ngpio	= EXYNOS5_GPIO_V3_NR,
2634			.label	= "GPV3",
2635		},
2636	}, {
2637		.chip	= {
2638			.base	= EXYNOS5_GPV4(0),
2639			.ngpio	= EXYNOS5_GPIO_V4_NR,
2640			.label	= "GPV4",
2641		},
2642	},
2643};
2644#endif
2645
2646#ifdef CONFIG_ARCH_EXYNOS5
2647static struct samsung_gpio_chip exynos5_gpios_4[] = {
2648	{
2649		.chip	= {
2650			.base	= EXYNOS5_GPZ(0),
2651			.ngpio	= EXYNOS5_GPIO_Z_NR,
2652			.label	= "GPZ",
2653		},
2654	},
2655};
2656#endif
2657
2658
2659#if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF)
2660static int exynos_gpio_xlate(struct gpio_chip *gc,
2661			const struct of_phandle_args *gpiospec, u32 *flags)
2662{
2663	unsigned int pin;
2664
2665	if (WARN_ON(gc->of_gpio_n_cells < 4))
2666		return -EINVAL;
2667
2668	if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
2669		return -EINVAL;
2670
2671	if (gpiospec->args[0] > gc->ngpio)
2672		return -EINVAL;
2673
2674	pin = gc->base + gpiospec->args[0];
2675
2676	if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
2677		pr_warn("gpio_xlate: failed to set pin function\n");
2678	if (s3c_gpio_setpull(pin, gpiospec->args[2]))
2679		pr_warn("gpio_xlate: failed to set pin pull up/down\n");
2680	if (s5p_gpio_set_drvstr(pin, gpiospec->args[3]))
2681		pr_warn("gpio_xlate: failed to set pin drive strength\n");
2682
2683	return gpiospec->args[0];
2684}
2685
2686static const struct of_device_id exynos_gpio_dt_match[] __initdata = {
2687	{ .compatible = "samsung,exynos4-gpio", },
2688	{}
2689};
2690
2691static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
2692						u64 base, u64 offset)
2693{
2694	struct gpio_chip *gc =  &chip->chip;
2695	u64 address;
2696
2697	if (!of_have_populated_dt())
2698		return;
2699
2700	address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
2701	gc->of_node = of_find_matching_node_by_address(NULL,
2702			exynos_gpio_dt_match, address);
2703	if (!gc->of_node) {
2704		pr_info("gpio: device tree node not found for gpio controller"
2705			" with base address %08llx\n", address);
2706		return;
2707	}
2708	gc->of_gpio_n_cells = 4;
2709	gc->of_xlate = exynos_gpio_xlate;
2710}
2711#elif defined(CONFIG_ARCH_EXYNOS)
2712static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
2713						u64 base, u64 offset)
2714{
2715	return;
2716}
2717#endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */
2718
2719/* TODO: cleanup soc_is_* */
2720static __init int samsung_gpiolib_init(void)
2721{
2722	struct samsung_gpio_chip *chip;
2723	int i, nr_chips;
2724#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS5250)
2725	void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4;
2726#endif
2727	int group = 0;
2728
2729	samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
2730
2731	if (soc_is_s3c24xx()) {
2732		s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
2733				ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
2734	} else if (soc_is_s3c64xx()) {
2735		samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
2736				ARRAY_SIZE(s3c64xx_gpios_2bit),
2737				S3C64XX_VA_GPIO + 0xE0, 0x20);
2738		samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
2739				ARRAY_SIZE(s3c64xx_gpios_4bit),
2740				S3C64XX_VA_GPIO);
2741		samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
2742				ARRAY_SIZE(s3c64xx_gpios_4bit2));
2743	} else if (soc_is_s5p6440()) {
2744		samsung_gpiolib_add_2bit_chips(s5p6440_gpios_2bit,
2745				ARRAY_SIZE(s5p6440_gpios_2bit), NULL, 0x0);
2746		samsung_gpiolib_add_4bit_chips(s5p6440_gpios_4bit,
2747				ARRAY_SIZE(s5p6440_gpios_4bit), S5P_VA_GPIO);
2748		samsung_gpiolib_add_4bit2_chips(s5p6440_gpios_4bit2,
2749				ARRAY_SIZE(s5p6440_gpios_4bit2));
2750		s5p64x0_gpiolib_add_rbank(s5p6440_gpios_rbank,
2751				ARRAY_SIZE(s5p6440_gpios_rbank));
2752	} else if (soc_is_s5p6450()) {
2753		samsung_gpiolib_add_2bit_chips(s5p6450_gpios_2bit,
2754				ARRAY_SIZE(s5p6450_gpios_2bit), NULL, 0x0);
2755		samsung_gpiolib_add_4bit_chips(s5p6450_gpios_4bit,
2756				ARRAY_SIZE(s5p6450_gpios_4bit), S5P_VA_GPIO);
2757		samsung_gpiolib_add_4bit2_chips(s5p6450_gpios_4bit2,
2758				ARRAY_SIZE(s5p6450_gpios_4bit2));
2759		s5p64x0_gpiolib_add_rbank(s5p6450_gpios_rbank,
2760				ARRAY_SIZE(s5p6450_gpios_rbank));
2761	} else if (soc_is_s5pc100()) {
2762		group = 0;
2763		chip = s5pc100_gpios_4bit;
2764		nr_chips = ARRAY_SIZE(s5pc100_gpios_4bit);
2765
2766		for (i = 0; i < nr_chips; i++, chip++) {
2767			if (!chip->config) {
2768				chip->config = &samsung_gpio_cfgs[3];
2769				chip->group = group++;
2770			}
2771		}
2772		samsung_gpiolib_add_4bit_chips(s5pc100_gpios_4bit, nr_chips, S5P_VA_GPIO);
2773#if defined(CONFIG_CPU_S5PC100) && defined(CONFIG_S5P_GPIO_INT)
2774		s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
2775#endif
2776	} else if (soc_is_s5pv210()) {
2777		group = 0;
2778		chip = s5pv210_gpios_4bit;
2779		nr_chips = ARRAY_SIZE(s5pv210_gpios_4bit);
2780
2781		for (i = 0; i < nr_chips; i++, chip++) {
2782			if (!chip->config) {
2783				chip->config = &samsung_gpio_cfgs[3];
2784				chip->group = group++;
2785			}
2786		}
2787		samsung_gpiolib_add_4bit_chips(s5pv210_gpios_4bit, nr_chips, S5P_VA_GPIO);
2788#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_S5P_GPIO_INT)
2789		s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
2790#endif
2791	} else if (soc_is_exynos4210()) {
2792#ifdef CONFIG_CPU_EXYNOS4210
2793		void __iomem *gpx_base;
2794
2795		/* gpio part1 */
2796		gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K);
2797		if (gpio_base1 == NULL) {
2798			pr_err("unable to ioremap for gpio_base1\n");
2799			goto err_ioremap1;
2800		}
2801
2802		chip = exynos4_gpios_1;
2803		nr_chips = ARRAY_SIZE(exynos4_gpios_1);
2804
2805		for (i = 0; i < nr_chips; i++, chip++) {
2806			if (!chip->config) {
2807				chip->config = &exynos_gpio_cfg;
2808				chip->group = group++;
2809			}
2810			exynos_gpiolib_attach_ofnode(chip,
2811					EXYNOS4_PA_GPIO1, i * 0x20);
2812		}
2813		samsung_gpiolib_add_4bit_chips(exynos4_gpios_1,
2814					       nr_chips, gpio_base1);
2815
2816		/* gpio part2 */
2817		gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
2818		if (gpio_base2 == NULL) {
2819			pr_err("unable to ioremap for gpio_base2\n");
2820			goto err_ioremap2;
2821		}
2822
2823		/* need to set base address for gpx */
2824		chip = &exynos4_gpios_2[16];
2825		gpx_base = gpio_base2 + 0xC00;
2826		for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
2827			chip->base = gpx_base;
2828
2829		chip = exynos4_gpios_2;
2830		nr_chips = ARRAY_SIZE(exynos4_gpios_2);
2831
2832		for (i = 0; i < nr_chips; i++, chip++) {
2833			if (!chip->config) {
2834				chip->config = &exynos_gpio_cfg;
2835				chip->group = group++;
2836			}
2837			exynos_gpiolib_attach_ofnode(chip,
2838					EXYNOS4_PA_GPIO2, i * 0x20);
2839		}
2840		samsung_gpiolib_add_4bit_chips(exynos4_gpios_2,
2841					       nr_chips, gpio_base2);
2842
2843		/* gpio part3 */
2844		gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256);
2845		if (gpio_base3 == NULL) {
2846			pr_err("unable to ioremap for gpio_base3\n");
2847			goto err_ioremap3;
2848		}
2849
2850		chip = exynos4_gpios_3;
2851		nr_chips = ARRAY_SIZE(exynos4_gpios_3);
2852
2853		for (i = 0; i < nr_chips; i++, chip++) {
2854			if (!chip->config) {
2855				chip->config = &exynos_gpio_cfg;
2856				chip->group = group++;
2857			}
2858			exynos_gpiolib_attach_ofnode(chip,
2859					EXYNOS4_PA_GPIO3, i * 0x20);
2860		}
2861		samsung_gpiolib_add_4bit_chips(exynos4_gpios_3,
2862					       nr_chips, gpio_base3);
2863
2864#if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT)
2865		s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
2866		s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
2867#endif
2868
2869#endif	/* CONFIG_CPU_EXYNOS4210 */
2870	} else if (soc_is_exynos5250()) {
2871#ifdef CONFIG_SOC_EXYNOS5250
2872		void __iomem *gpx_base;
2873
2874		/* gpio part1 */
2875		gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
2876		if (gpio_base1 == NULL) {
2877			pr_err("unable to ioremap for gpio_base1\n");
2878			goto err_ioremap1;
2879		}
2880
2881		/* need to set base address for gpx */
2882		chip = &exynos5_gpios_1[20];
2883		gpx_base = gpio_base1 + 0xC00;
2884		for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
2885			chip->base = gpx_base;
2886
2887		chip = exynos5_gpios_1;
2888		nr_chips = ARRAY_SIZE(exynos5_gpios_1);
2889
2890		for (i = 0; i < nr_chips; i++, chip++) {
2891			if (!chip->config) {
2892				chip->config = &exynos_gpio_cfg;
2893				chip->group = group++;
2894			}
2895			exynos_gpiolib_attach_ofnode(chip,
2896					EXYNOS5_PA_GPIO1, i * 0x20);
2897		}
2898		samsung_gpiolib_add_4bit_chips(exynos5_gpios_1,
2899					       nr_chips, gpio_base1);
2900
2901		/* gpio part2 */
2902		gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K);
2903		if (gpio_base2 == NULL) {
2904			pr_err("unable to ioremap for gpio_base2\n");
2905			goto err_ioremap2;
2906		}
2907
2908		chip = exynos5_gpios_2;
2909		nr_chips = ARRAY_SIZE(exynos5_gpios_2);
2910
2911		for (i = 0; i < nr_chips; i++, chip++) {
2912			if (!chip->config) {
2913				chip->config = &exynos_gpio_cfg;
2914				chip->group = group++;
2915			}
2916			exynos_gpiolib_attach_ofnode(chip,
2917					EXYNOS5_PA_GPIO2, i * 0x20);
2918		}
2919		samsung_gpiolib_add_4bit_chips(exynos5_gpios_2,
2920					       nr_chips, gpio_base2);
2921
2922		/* gpio part3 */
2923		gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K);
2924		if (gpio_base3 == NULL) {
2925			pr_err("unable to ioremap for gpio_base3\n");
2926			goto err_ioremap3;
2927		}
2928
2929		/* need to set base address for gpv */
2930		exynos5_gpios_3[0].base = gpio_base3;
2931		exynos5_gpios_3[1].base = gpio_base3 + 0x20;
2932		exynos5_gpios_3[2].base = gpio_base3 + 0x60;
2933		exynos5_gpios_3[3].base = gpio_base3 + 0x80;
2934		exynos5_gpios_3[4].base = gpio_base3 + 0xC0;
2935
2936		chip = exynos5_gpios_3;
2937		nr_chips = ARRAY_SIZE(exynos5_gpios_3);
2938
2939		for (i = 0; i < nr_chips; i++, chip++) {
2940			if (!chip->config) {
2941				chip->config = &exynos_gpio_cfg;
2942				chip->group = group++;
2943			}
2944			exynos_gpiolib_attach_ofnode(chip,
2945					EXYNOS5_PA_GPIO3, i * 0x20);
2946		}
2947		samsung_gpiolib_add_4bit_chips(exynos5_gpios_3,
2948					       nr_chips, gpio_base3);
2949
2950		/* gpio part4 */
2951		gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K);
2952		if (gpio_base4 == NULL) {
2953			pr_err("unable to ioremap for gpio_base4\n");
2954			goto err_ioremap4;
2955		}
2956
2957		chip = exynos5_gpios_4;
2958		nr_chips = ARRAY_SIZE(exynos5_gpios_4);
2959
2960		for (i = 0; i < nr_chips; i++, chip++) {
2961			if (!chip->config) {
2962				chip->config = &exynos_gpio_cfg;
2963				chip->group = group++;
2964			}
2965			exynos_gpiolib_attach_ofnode(chip,
2966					EXYNOS5_PA_GPIO4, i * 0x20);
2967		}
2968		samsung_gpiolib_add_4bit_chips(exynos5_gpios_4,
2969					       nr_chips, gpio_base4);
2970#endif	/* CONFIG_SOC_EXYNOS5250 */
2971	} else {
2972		WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
2973		return -ENODEV;
2974	}
2975
2976	return 0;
2977
2978#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS5250)
2979err_ioremap4:
2980	iounmap(gpio_base3);
2981err_ioremap3:
2982	iounmap(gpio_base2);
2983err_ioremap2:
2984	iounmap(gpio_base1);
2985err_ioremap1:
2986	return -ENOMEM;
2987#endif
2988}
2989core_initcall(samsung_gpiolib_init);
2990
2991int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
2992{
2993	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2994	unsigned long flags;
2995	int offset;
2996	int ret;
2997
2998	if (!chip)
2999		return -EINVAL;
3000
3001	offset = pin - chip->chip.base;
3002
3003	samsung_gpio_lock(chip, flags);
3004	ret = samsung_gpio_do_setcfg(chip, offset, config);
3005	samsung_gpio_unlock(chip, flags);
3006
3007	return ret;
3008}
3009EXPORT_SYMBOL(s3c_gpio_cfgpin);
3010
3011int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
3012			  unsigned int cfg)
3013{
3014	int ret;
3015
3016	for (; nr > 0; nr--, start++) {
3017		ret = s3c_gpio_cfgpin(start, cfg);
3018		if (ret != 0)
3019			return ret;
3020	}
3021
3022	return 0;
3023}
3024EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
3025
3026int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
3027			  unsigned int cfg, samsung_gpio_pull_t pull)
3028{
3029	int ret;
3030
3031	for (; nr > 0; nr--, start++) {
3032		s3c_gpio_setpull(start, pull);
3033		ret = s3c_gpio_cfgpin(start, cfg);
3034		if (ret != 0)
3035			return ret;
3036	}
3037
3038	return 0;
3039}
3040EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
3041
3042unsigned s3c_gpio_getcfg(unsigned int pin)
3043{
3044	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3045	unsigned long flags;
3046	unsigned ret = 0;
3047	int offset;
3048
3049	if (chip) {
3050		offset = pin - chip->chip.base;
3051
3052		samsung_gpio_lock(chip, flags);
3053		ret = samsung_gpio_do_getcfg(chip, offset);
3054		samsung_gpio_unlock(chip, flags);
3055	}
3056
3057	return ret;
3058}
3059EXPORT_SYMBOL(s3c_gpio_getcfg);
3060
3061int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
3062{
3063	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3064	unsigned long flags;
3065	int offset, ret;
3066
3067	if (!chip)
3068		return -EINVAL;
3069
3070	offset = pin - chip->chip.base;
3071
3072	samsung_gpio_lock(chip, flags);
3073	ret = samsung_gpio_do_setpull(chip, offset, pull);
3074	samsung_gpio_unlock(chip, flags);
3075
3076	return ret;
3077}
3078EXPORT_SYMBOL(s3c_gpio_setpull);
3079
3080samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
3081{
3082	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3083	unsigned long flags;
3084	int offset;
3085	u32 pup = 0;
3086
3087	if (chip) {
3088		offset = pin - chip->chip.base;
3089
3090		samsung_gpio_lock(chip, flags);
3091		pup = samsung_gpio_do_getpull(chip, offset);
3092		samsung_gpio_unlock(chip, flags);
3093	}
3094
3095	return (__force samsung_gpio_pull_t)pup;
3096}
3097EXPORT_SYMBOL(s3c_gpio_getpull);
3098
3099/* gpiolib wrappers until these are totally eliminated */
3100
3101void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
3102{
3103	int ret;
3104
3105	WARN_ON(to);	/* should be none of these left */
3106
3107	if (!to) {
3108		/* if pull is enabled, try first with up, and if that
3109		 * fails, try using down */
3110
3111		ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
3112		if (ret)
3113			s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
3114	} else {
3115		s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
3116	}
3117}
3118EXPORT_SYMBOL(s3c2410_gpio_pullup);
3119
3120void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
3121{
3122	/* do this via gpiolib until all users removed */
3123
3124	gpio_request(pin, "temporary");
3125	gpio_set_value(pin, to);
3126	gpio_free(pin);
3127}
3128EXPORT_SYMBOL(s3c2410_gpio_setpin);
3129
3130unsigned int s3c2410_gpio_getpin(unsigned int pin)
3131{
3132	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3133	unsigned long offs = pin - chip->chip.base;
3134
3135	return __raw_readl(chip->base + 0x04) & (1 << offs);
3136}
3137EXPORT_SYMBOL(s3c2410_gpio_getpin);
3138
3139#ifdef CONFIG_S5P_GPIO_DRVSTR
3140s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
3141{
3142	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3143	unsigned int off;
3144	void __iomem *reg;
3145	int shift;
3146	u32 drvstr;
3147
3148	if (!chip)
3149		return -EINVAL;
3150
3151	off = pin - chip->chip.base;
3152	shift = off * 2;
3153	reg = chip->base + 0x0C;
3154
3155	drvstr = __raw_readl(reg);
3156	drvstr = drvstr >> shift;
3157	drvstr &= 0x3;
3158
3159	return (__force s5p_gpio_drvstr_t)drvstr;
3160}
3161EXPORT_SYMBOL(s5p_gpio_get_drvstr);
3162
3163int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
3164{
3165	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3166	unsigned int off;
3167	void __iomem *reg;
3168	int shift;
3169	u32 tmp;
3170
3171	if (!chip)
3172		return -EINVAL;
3173
3174	off = pin - chip->chip.base;
3175	shift = off * 2;
3176	reg = chip->base + 0x0C;
3177
3178	tmp = __raw_readl(reg);
3179	tmp &= ~(0x3 << shift);
3180	tmp |= drvstr << shift;
3181
3182	__raw_writel(tmp, reg);
3183
3184	return 0;
3185}
3186EXPORT_SYMBOL(s5p_gpio_set_drvstr);
3187#endif	/* CONFIG_S5P_GPIO_DRVSTR */
3188
3189#ifdef CONFIG_PLAT_S3C24XX
3190unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
3191{
3192	unsigned long flags;
3193	unsigned long misccr;
3194
3195	local_irq_save(flags);
3196	misccr = __raw_readl(S3C24XX_MISCCR);
3197	misccr &= ~clear;
3198	misccr ^= change;
3199	__raw_writel(misccr, S3C24XX_MISCCR);
3200	local_irq_restore(flags);
3201
3202	return misccr;
3203}
3204EXPORT_SYMBOL(s3c2410_modify_misccr);
3205#endif
3206