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