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