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 
samsung_gpio_setpull_updown(struct samsung_gpio_chip * chip,unsigned int off,samsung_gpio_pull_t pull)51 int 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 
samsung_gpio_getpull_updown(struct samsung_gpio_chip * chip,unsigned int off)66 samsung_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 
s3c2443_gpio_setpull(struct samsung_gpio_chip * chip,unsigned int off,samsung_gpio_pull_t pull)79 int 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 
s3c2443_gpio_getpull(struct samsung_gpio_chip * chip,unsigned int off)96 samsung_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 
s3c24xx_gpio_setpull_1(struct samsung_gpio_chip * chip,unsigned int off,samsung_gpio_pull_t pull,samsung_gpio_pull_t updown)119 static 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 
s3c24xx_gpio_getpull_1(struct samsung_gpio_chip * chip,unsigned int off,samsung_gpio_pull_t updown)137 static 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 
s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip * chip,unsigned int off)148 samsung_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 
s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip * chip,unsigned int off,samsung_gpio_pull_t pull)154 int 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 
s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip * chip,unsigned int off)160 samsung_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 
s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip * chip,unsigned int off,samsung_gpio_pull_t pull)166 int 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 
exynos_gpio_setpull(struct samsung_gpio_chip * chip,unsigned int off,samsung_gpio_pull_t pull)172 static 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 
exynos_gpio_getpull(struct samsung_gpio_chip * chip,unsigned int off)181 static 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 
samsung_gpio_setcfg_2bit(struct samsung_gpio_chip * chip,unsigned int off,unsigned int cfg)208 static 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 
samsung_gpio_getcfg_2bit(struct samsung_gpio_chip * chip,unsigned int off)241 static 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 
samsung_gpio_setcfg_4bit(struct samsung_gpio_chip * chip,unsigned int off,unsigned int cfg)271 static 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 
samsung_gpio_getcfg_4bit(struct samsung_gpio_chip * chip,unsigned int off)306 static 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 
s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip * chip,unsigned int off,unsigned int cfg)336 static 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 
s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip * chip,unsigned int off)374 static 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)
s5p64x0_gpio_setcfg_rbank(struct samsung_gpio_chip * chip,unsigned int off,unsigned int cfg)389 static 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 
samsung_gpiolib_set_cfg(struct samsung_gpio_cfg * chipcfg,int nr_chips)428 static 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 
443 struct 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
449 static 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)
456 static 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)
465 static 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 
474 static 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 
samsung_gpiolib_2bit_input(struct gpio_chip * chip,unsigned offset)529 static 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 
samsung_gpiolib_2bit_output(struct gpio_chip * chip,unsigned offset,int value)547 static 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 
samsung_gpiolib_4bit_input(struct gpio_chip * chip,unsigned int offset)591 static 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 
samsung_gpiolib_4bit_output(struct gpio_chip * chip,unsigned int offset,int value)607 static 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 
samsung_gpiolib_4bit2_input(struct gpio_chip * chip,unsigned int offset)657 static 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 
samsung_gpiolib_4bit2_output(struct gpio_chip * chip,unsigned int offset,int value)679 static 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 
s3c24xx_gpiolib_banka_input(struct gpio_chip * chip,unsigned offset)717 static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
718 {
719 	return -EINVAL;
720 }
721 
s3c24xx_gpiolib_banka_output(struct gpio_chip * chip,unsigned offset,int value)722 static 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 
s5p64x0_gpiolib_rbank_input(struct gpio_chip * chip,unsigned int offset)754 static 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 
s5p64x0_gpiolib_rbank_output(struct gpio_chip * chip,unsigned int offset,int value)790 static 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 
samsung_gpiolib_set(struct gpio_chip * chip,unsigned offset,int value)837 static 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 
samsung_gpiolib_get(struct gpio_chip * chip,unsigned offset)856 static 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
881 struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
882 
s3c_gpiolib_track(struct samsung_gpio_chip * chip)883 static __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 
samsung_gpiolib_add(struct samsung_gpio_chip * chip)906 static 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 
s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip * chip,int nr_chips,void __iomem * base)941 static 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 
samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip * chip,int nr_chips,void __iomem * base,unsigned int offset)968 static 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 
samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip * chip,int nr_chips,void __iomem * base)1005 static 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 
samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip * chip,int nr_chips)1025 static 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 
s5p64x0_gpiolib_add_rbank(struct samsung_gpio_chip * chip,int nr_chips)1041 static 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 
samsung_gpiolib_to_irq(struct gpio_chip * chip,unsigned int offset)1055 int 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
s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip * chip,unsigned offset)1063 static 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
s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip * chip,unsigned pin)1076 static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
1077 {
1078 	return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
1079 }
1080 
s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip * chip,unsigned pin)1081 static 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 
1087 struct 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 
1215 static 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 
1268 static 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 
1298 static 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 
1374 static 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 
1405 static 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 
1418 static 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 
1432 static 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 
1502 static 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 
1539 static 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 
1559 static 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 
1573 static 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 
1674 static 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 
1907 static 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
2129 static 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
2231 static 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
2376 static 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
2388 static 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
2550 static 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
2611 static 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
2647 static 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)
exynos_gpio_xlate(struct gpio_chip * gc,const struct of_phandle_args * gpiospec,u32 * flags)2660 static 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 
2686 static const struct of_device_id exynos_gpio_dt_match[] __initdata = {
2687 	{ .compatible = "samsung,exynos4-gpio", },
2688 	{}
2689 };
2690 
exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip * chip,u64 base,u64 offset)2691 static __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)
exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip * chip,u64 base,u64 offset)2712 static __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_* */
samsung_gpiolib_init(void)2720 static __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)
2979 err_ioremap4:
2980 	iounmap(gpio_base3);
2981 err_ioremap3:
2982 	iounmap(gpio_base2);
2983 err_ioremap2:
2984 	iounmap(gpio_base1);
2985 err_ioremap1:
2986 	return -ENOMEM;
2987 #endif
2988 }
2989 core_initcall(samsung_gpiolib_init);
2990 
s3c_gpio_cfgpin(unsigned int pin,unsigned int config)2991 int 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 }
3009 EXPORT_SYMBOL(s3c_gpio_cfgpin);
3010 
s3c_gpio_cfgpin_range(unsigned int start,unsigned int nr,unsigned int cfg)3011 int 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 }
3024 EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
3025 
s3c_gpio_cfgall_range(unsigned int start,unsigned int nr,unsigned int cfg,samsung_gpio_pull_t pull)3026 int 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 }
3040 EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
3041 
s3c_gpio_getcfg(unsigned int pin)3042 unsigned 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 }
3059 EXPORT_SYMBOL(s3c_gpio_getcfg);
3060 
s3c_gpio_setpull(unsigned int pin,samsung_gpio_pull_t pull)3061 int 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 }
3078 EXPORT_SYMBOL(s3c_gpio_setpull);
3079 
s3c_gpio_getpull(unsigned int pin)3080 samsung_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 }
3097 EXPORT_SYMBOL(s3c_gpio_getpull);
3098 
3099 /* gpiolib wrappers until these are totally eliminated */
3100 
s3c2410_gpio_pullup(unsigned int pin,unsigned int to)3101 void 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 }
3118 EXPORT_SYMBOL(s3c2410_gpio_pullup);
3119 
s3c2410_gpio_setpin(unsigned int pin,unsigned int to)3120 void 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 }
3128 EXPORT_SYMBOL(s3c2410_gpio_setpin);
3129 
s3c2410_gpio_getpin(unsigned int pin)3130 unsigned 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 }
3137 EXPORT_SYMBOL(s3c2410_gpio_getpin);
3138 
3139 #ifdef CONFIG_S5P_GPIO_DRVSTR
s5p_gpio_get_drvstr(unsigned int pin)3140 s5p_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 }
3161 EXPORT_SYMBOL(s5p_gpio_get_drvstr);
3162 
s5p_gpio_set_drvstr(unsigned int pin,s5p_gpio_drvstr_t drvstr)3163 int 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 }
3186 EXPORT_SYMBOL(s5p_gpio_set_drvstr);
3187 #endif	/* CONFIG_S5P_GPIO_DRVSTR */
3188 
3189 #ifdef CONFIG_PLAT_S3C24XX
s3c2410_modify_misccr(unsigned int clear,unsigned int change)3190 unsigned 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 }
3204 EXPORT_SYMBOL(s3c2410_modify_misccr);
3205 #endif
3206