Merge branch 'cleanup' into for-linus
[firefly-linux-kernel-4.4.55.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 #if defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF)
937 static int s3c24xx_gpio_xlate(struct gpio_chip *gc,
938                         const struct of_phandle_args *gpiospec, u32 *flags)
939 {
940         unsigned int pin;
941
942         if (WARN_ON(gc->of_gpio_n_cells < 3))
943                 return -EINVAL;
944
945         if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
946                 return -EINVAL;
947
948         if (gpiospec->args[0] > gc->ngpio)
949                 return -EINVAL;
950
951         pin = gc->base + gpiospec->args[0];
952
953         if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
954                 pr_warn("gpio_xlate: failed to set pin function\n");
955         if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff))
956                 pr_warn("gpio_xlate: failed to set pin pull up/down\n");
957
958         if (flags)
959                 *flags = gpiospec->args[2] >> 16;
960
961         return gpiospec->args[0];
962 }
963
964 static const struct of_device_id s3c24xx_gpio_dt_match[] __initdata = {
965         { .compatible = "samsung,s3c24xx-gpio", },
966         {}
967 };
968
969 static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
970                                                  u64 base, u64 offset)
971 {
972         struct gpio_chip *gc =  &chip->chip;
973         u64 address;
974
975         if (!of_have_populated_dt())
976                 return;
977
978         address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
979         gc->of_node = of_find_matching_node_by_address(NULL,
980                         s3c24xx_gpio_dt_match, address);
981         if (!gc->of_node) {
982                 pr_info("gpio: device tree node not found for gpio controller"
983                         " with base address %08llx\n", address);
984                 return;
985         }
986         gc->of_gpio_n_cells = 3;
987         gc->of_xlate = s3c24xx_gpio_xlate;
988 }
989 #else
990 static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
991                                                  u64 base, u64 offset)
992 {
993         return;
994 }
995 #endif /* defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF) */
996
997 static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
998                                              int nr_chips, void __iomem *base)
999 {
1000         int i;
1001         struct gpio_chip *gc = &chip->chip;
1002
1003         for (i = 0 ; i < nr_chips; i++, chip++) {
1004                 /* skip banks not present on SoC */
1005                 if (chip->chip.base >= S3C_GPIO_END)
1006                         continue;
1007
1008                 if (!chip->config)
1009                         chip->config = &s3c24xx_gpiocfg_default;
1010                 if (!chip->pm)
1011                         chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
1012                 if ((base != NULL) && (chip->base == NULL))
1013                         chip->base = base + ((i) * 0x10);
1014
1015                 if (!gc->direction_input)
1016                         gc->direction_input = samsung_gpiolib_2bit_input;
1017                 if (!gc->direction_output)
1018                         gc->direction_output = samsung_gpiolib_2bit_output;
1019
1020                 samsung_gpiolib_add(chip);
1021
1022                 s3c24xx_gpiolib_attach_ofnode(chip, S3C24XX_PA_GPIO, i * 0x10);
1023         }
1024 }
1025
1026 static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
1027                                                   int nr_chips, void __iomem *base,
1028                                                   unsigned int offset)
1029 {
1030         int i;
1031
1032         for (i = 0 ; i < nr_chips; i++, chip++) {
1033                 chip->chip.direction_input = samsung_gpiolib_2bit_input;
1034                 chip->chip.direction_output = samsung_gpiolib_2bit_output;
1035
1036                 if (!chip->config)
1037                         chip->config = &samsung_gpio_cfgs[7];
1038                 if (!chip->pm)
1039                         chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
1040                 if ((base != NULL) && (chip->base == NULL))
1041                         chip->base = base + ((i) * offset);
1042
1043                 samsung_gpiolib_add(chip);
1044         }
1045 }
1046
1047 /*
1048  * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
1049  * @chip: The gpio chip that is being configured.
1050  * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
1051  *
1052  * This helper deal with the GPIO cases where the control register has 4 bits
1053  * of control per GPIO, generally in the form of:
1054  * 0000 = Input
1055  * 0001 = Output
1056  * others = Special functions (dependent on bank)
1057  *
1058  * Note, since the code to deal with the case where there are two control
1059  * registers instead of one, we do not have a separate set of function
1060  * (samsung_gpiolib_add_4bit2_chips)for each case.
1061  */
1062
1063 static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
1064                                                   int nr_chips, void __iomem *base)
1065 {
1066         int i;
1067
1068         for (i = 0 ; i < nr_chips; i++, chip++) {
1069                 chip->chip.direction_input = samsung_gpiolib_4bit_input;
1070                 chip->chip.direction_output = samsung_gpiolib_4bit_output;
1071
1072                 if (!chip->config)
1073                         chip->config = &samsung_gpio_cfgs[2];
1074                 if (!chip->pm)
1075                         chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1076                 if ((base != NULL) && (chip->base == NULL))
1077                         chip->base = base + ((i) * 0x20);
1078
1079                 chip->bitmap_gpio_int = 0;
1080
1081                 samsung_gpiolib_add(chip);
1082         }
1083 }
1084
1085 static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
1086                                                    int nr_chips)
1087 {
1088         for (; nr_chips > 0; nr_chips--, chip++) {
1089                 chip->chip.direction_input = samsung_gpiolib_4bit2_input;
1090                 chip->chip.direction_output = samsung_gpiolib_4bit2_output;
1091
1092                 if (!chip->config)
1093                         chip->config = &samsung_gpio_cfgs[2];
1094                 if (!chip->pm)
1095                         chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1096
1097                 samsung_gpiolib_add(chip);
1098         }
1099 }
1100
1101 static void __init s5p64x0_gpiolib_add_rbank(struct samsung_gpio_chip *chip,
1102                                              int nr_chips)
1103 {
1104         for (; nr_chips > 0; nr_chips--, chip++) {
1105                 chip->chip.direction_input = s5p64x0_gpiolib_rbank_input;
1106                 chip->chip.direction_output = s5p64x0_gpiolib_rbank_output;
1107
1108                 if (!chip->pm)
1109                         chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1110
1111                 samsung_gpiolib_add(chip);
1112         }
1113 }
1114
1115 int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
1116 {
1117         struct samsung_gpio_chip *samsung_chip = container_of(chip, struct samsung_gpio_chip, chip);
1118
1119         return samsung_chip->irq_base + offset;
1120 }
1121
1122 #ifdef CONFIG_PLAT_S3C24XX
1123 static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
1124 {
1125         if (offset < 4)
1126                 return IRQ_EINT0 + offset;
1127
1128         if (offset < 8)
1129                 return IRQ_EINT4 + offset - 4;
1130
1131         return -EINVAL;
1132 }
1133 #endif
1134
1135 #ifdef CONFIG_PLAT_S3C64XX
1136 static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
1137 {
1138         return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
1139 }
1140
1141 static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
1142 {
1143         return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
1144 }
1145 #endif
1146
1147 struct samsung_gpio_chip s3c24xx_gpios[] = {
1148 #ifdef CONFIG_PLAT_S3C24XX
1149         {
1150                 .config = &s3c24xx_gpiocfg_banka,
1151                 .chip   = {
1152                         .base                   = S3C2410_GPA(0),
1153                         .owner                  = THIS_MODULE,
1154                         .label                  = "GPIOA",
1155                         .ngpio                  = 24,
1156                         .direction_input        = s3c24xx_gpiolib_banka_input,
1157                         .direction_output       = s3c24xx_gpiolib_banka_output,
1158                 },
1159         }, {
1160                 .chip   = {
1161                         .base   = S3C2410_GPB(0),
1162                         .owner  = THIS_MODULE,
1163                         .label  = "GPIOB",
1164                         .ngpio  = 16,
1165                 },
1166         }, {
1167                 .chip   = {
1168                         .base   = S3C2410_GPC(0),
1169                         .owner  = THIS_MODULE,
1170                         .label  = "GPIOC",
1171                         .ngpio  = 16,
1172                 },
1173         }, {
1174                 .chip   = {
1175                         .base   = S3C2410_GPD(0),
1176                         .owner  = THIS_MODULE,
1177                         .label  = "GPIOD",
1178                         .ngpio  = 16,
1179                 },
1180         }, {
1181                 .chip   = {
1182                         .base   = S3C2410_GPE(0),
1183                         .label  = "GPIOE",
1184                         .owner  = THIS_MODULE,
1185                         .ngpio  = 16,
1186                 },
1187         }, {
1188                 .chip   = {
1189                         .base   = S3C2410_GPF(0),
1190                         .owner  = THIS_MODULE,
1191                         .label  = "GPIOF",
1192                         .ngpio  = 8,
1193                         .to_irq = s3c24xx_gpiolib_fbank_to_irq,
1194                 },
1195         }, {
1196                 .irq_base = IRQ_EINT8,
1197                 .chip   = {
1198                         .base   = S3C2410_GPG(0),
1199                         .owner  = THIS_MODULE,
1200                         .label  = "GPIOG",
1201                         .ngpio  = 16,
1202                         .to_irq = samsung_gpiolib_to_irq,
1203                 },
1204         }, {
1205                 .chip   = {
1206                         .base   = S3C2410_GPH(0),
1207                         .owner  = THIS_MODULE,
1208                         .label  = "GPIOH",
1209                         .ngpio  = 11,
1210                 },
1211         },
1212                 /* GPIOS for the S3C2443 and later devices. */
1213         {
1214                 .base   = S3C2440_GPJCON,
1215                 .chip   = {
1216                         .base   = S3C2410_GPJ(0),
1217                         .owner  = THIS_MODULE,
1218                         .label  = "GPIOJ",
1219                         .ngpio  = 16,
1220                 },
1221         }, {
1222                 .base   = S3C2443_GPKCON,
1223                 .chip   = {
1224                         .base   = S3C2410_GPK(0),
1225                         .owner  = THIS_MODULE,
1226                         .label  = "GPIOK",
1227                         .ngpio  = 16,
1228                 },
1229         }, {
1230                 .base   = S3C2443_GPLCON,
1231                 .chip   = {
1232                         .base   = S3C2410_GPL(0),
1233                         .owner  = THIS_MODULE,
1234                         .label  = "GPIOL",
1235                         .ngpio  = 15,
1236                 },
1237         }, {
1238                 .base   = S3C2443_GPMCON,
1239                 .chip   = {
1240                         .base   = S3C2410_GPM(0),
1241                         .owner  = THIS_MODULE,
1242                         .label  = "GPIOM",
1243                         .ngpio  = 2,
1244                 },
1245         },
1246 #endif
1247 };
1248
1249 /*
1250  * GPIO bank summary:
1251  *
1252  * Bank GPIOs   Style   SlpCon  ExtInt Group
1253  * A    8       4Bit    Yes     1
1254  * B    7       4Bit    Yes     1
1255  * C    8       4Bit    Yes     2
1256  * D    5       4Bit    Yes     3
1257  * E    5       4Bit    Yes     None
1258  * F    16      2Bit    Yes     4 [1]
1259  * G    7       4Bit    Yes     5
1260  * H    10      4Bit[2] Yes     6
1261  * I    16      2Bit    Yes     None
1262  * J    12      2Bit    Yes     None
1263  * K    16      4Bit[2] No      None
1264  * L    15      4Bit[2] No      None
1265  * M    6       4Bit    No      IRQ_EINT
1266  * N    16      2Bit    No      IRQ_EINT
1267  * O    16      2Bit    Yes     7
1268  * P    15      2Bit    Yes     8
1269  * Q    9       2Bit    Yes     9
1270  *
1271  * [1] BANKF pins 14,15 do not form part of the external interrupt sources
1272  * [2] BANK has two control registers, GPxCON0 and GPxCON1
1273  */
1274
1275 static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
1276 #ifdef CONFIG_PLAT_S3C64XX
1277         {
1278                 .chip   = {
1279                         .base   = S3C64XX_GPA(0),
1280                         .ngpio  = S3C64XX_GPIO_A_NR,
1281                         .label  = "GPA",
1282                 },
1283         }, {
1284                 .chip   = {
1285                         .base   = S3C64XX_GPB(0),
1286                         .ngpio  = S3C64XX_GPIO_B_NR,
1287                         .label  = "GPB",
1288                 },
1289         }, {
1290                 .chip   = {
1291                         .base   = S3C64XX_GPC(0),
1292                         .ngpio  = S3C64XX_GPIO_C_NR,
1293                         .label  = "GPC",
1294                 },
1295         }, {
1296                 .chip   = {
1297                         .base   = S3C64XX_GPD(0),
1298                         .ngpio  = S3C64XX_GPIO_D_NR,
1299                         .label  = "GPD",
1300                 },
1301         }, {
1302                 .config = &samsung_gpio_cfgs[0],
1303                 .chip   = {
1304                         .base   = S3C64XX_GPE(0),
1305                         .ngpio  = S3C64XX_GPIO_E_NR,
1306                         .label  = "GPE",
1307                 },
1308         }, {
1309                 .base   = S3C64XX_GPG_BASE,
1310                 .chip   = {
1311                         .base   = S3C64XX_GPG(0),
1312                         .ngpio  = S3C64XX_GPIO_G_NR,
1313                         .label  = "GPG",
1314                 },
1315         }, {
1316                 .base   = S3C64XX_GPM_BASE,
1317                 .config = &samsung_gpio_cfgs[1],
1318                 .chip   = {
1319                         .base   = S3C64XX_GPM(0),
1320                         .ngpio  = S3C64XX_GPIO_M_NR,
1321                         .label  = "GPM",
1322                         .to_irq = s3c64xx_gpiolib_mbank_to_irq,
1323                 },
1324         },
1325 #endif
1326 };
1327
1328 static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
1329 #ifdef CONFIG_PLAT_S3C64XX
1330         {
1331                 .base   = S3C64XX_GPH_BASE + 0x4,
1332                 .chip   = {
1333                         .base   = S3C64XX_GPH(0),
1334                         .ngpio  = S3C64XX_GPIO_H_NR,
1335                         .label  = "GPH",
1336                 },
1337         }, {
1338                 .base   = S3C64XX_GPK_BASE + 0x4,
1339                 .config = &samsung_gpio_cfgs[0],
1340                 .chip   = {
1341                         .base   = S3C64XX_GPK(0),
1342                         .ngpio  = S3C64XX_GPIO_K_NR,
1343                         .label  = "GPK",
1344                 },
1345         }, {
1346                 .base   = S3C64XX_GPL_BASE + 0x4,
1347                 .config = &samsung_gpio_cfgs[1],
1348                 .chip   = {
1349                         .base   = S3C64XX_GPL(0),
1350                         .ngpio  = S3C64XX_GPIO_L_NR,
1351                         .label  = "GPL",
1352                         .to_irq = s3c64xx_gpiolib_lbank_to_irq,
1353                 },
1354         },
1355 #endif
1356 };
1357
1358 static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
1359 #ifdef CONFIG_PLAT_S3C64XX
1360         {
1361                 .base   = S3C64XX_GPF_BASE,
1362                 .config = &samsung_gpio_cfgs[6],
1363                 .chip   = {
1364                         .base   = S3C64XX_GPF(0),
1365                         .ngpio  = S3C64XX_GPIO_F_NR,
1366                         .label  = "GPF",
1367                 },
1368         }, {
1369                 .config = &samsung_gpio_cfgs[7],
1370                 .chip   = {
1371                         .base   = S3C64XX_GPI(0),
1372                         .ngpio  = S3C64XX_GPIO_I_NR,
1373                         .label  = "GPI",
1374                 },
1375         }, {
1376                 .config = &samsung_gpio_cfgs[7],
1377                 .chip   = {
1378                         .base   = S3C64XX_GPJ(0),
1379                         .ngpio  = S3C64XX_GPIO_J_NR,
1380                         .label  = "GPJ",
1381                 },
1382         }, {
1383                 .config = &samsung_gpio_cfgs[6],
1384                 .chip   = {
1385                         .base   = S3C64XX_GPO(0),
1386                         .ngpio  = S3C64XX_GPIO_O_NR,
1387                         .label  = "GPO",
1388                 },
1389         }, {
1390                 .config = &samsung_gpio_cfgs[6],
1391                 .chip   = {
1392                         .base   = S3C64XX_GPP(0),
1393                         .ngpio  = S3C64XX_GPIO_P_NR,
1394                         .label  = "GPP",
1395                 },
1396         }, {
1397                 .config = &samsung_gpio_cfgs[6],
1398                 .chip   = {
1399                         .base   = S3C64XX_GPQ(0),
1400                         .ngpio  = S3C64XX_GPIO_Q_NR,
1401                         .label  = "GPQ",
1402                 },
1403         }, {
1404                 .base   = S3C64XX_GPN_BASE,
1405                 .irq_base = IRQ_EINT(0),
1406                 .config = &samsung_gpio_cfgs[5],
1407                 .chip   = {
1408                         .base   = S3C64XX_GPN(0),
1409                         .ngpio  = S3C64XX_GPIO_N_NR,
1410                         .label  = "GPN",
1411                         .to_irq = samsung_gpiolib_to_irq,
1412                 },
1413         },
1414 #endif
1415 };
1416
1417 /*
1418  * S5P6440 GPIO bank summary:
1419  *
1420  * Bank GPIOs   Style   SlpCon  ExtInt Group
1421  * A    6       4Bit    Yes     1
1422  * B    7       4Bit    Yes     1
1423  * C    8       4Bit    Yes     2
1424  * F    2       2Bit    Yes     4 [1]
1425  * G    7       4Bit    Yes     5
1426  * H    10      4Bit[2] Yes     6
1427  * I    16      2Bit    Yes     None
1428  * J    12      2Bit    Yes     None
1429  * N    16      2Bit    No      IRQ_EINT
1430  * P    8       2Bit    Yes     8
1431  * R    15      4Bit[2] Yes     8
1432  */
1433
1434 static struct samsung_gpio_chip s5p6440_gpios_4bit[] = {
1435 #ifdef CONFIG_CPU_S5P6440
1436         {
1437                 .chip   = {
1438                         .base   = S5P6440_GPA(0),
1439                         .ngpio  = S5P6440_GPIO_A_NR,
1440                         .label  = "GPA",
1441                 },
1442         }, {
1443                 .chip   = {
1444                         .base   = S5P6440_GPB(0),
1445                         .ngpio  = S5P6440_GPIO_B_NR,
1446                         .label  = "GPB",
1447                 },
1448         }, {
1449                 .chip   = {
1450                         .base   = S5P6440_GPC(0),
1451                         .ngpio  = S5P6440_GPIO_C_NR,
1452                         .label  = "GPC",
1453                 },
1454         }, {
1455                 .base   = S5P64X0_GPG_BASE,
1456                 .chip   = {
1457                         .base   = S5P6440_GPG(0),
1458                         .ngpio  = S5P6440_GPIO_G_NR,
1459                         .label  = "GPG",
1460                 },
1461         },
1462 #endif
1463 };
1464
1465 static struct samsung_gpio_chip s5p6440_gpios_4bit2[] = {
1466 #ifdef CONFIG_CPU_S5P6440
1467         {
1468                 .base   = S5P64X0_GPH_BASE + 0x4,
1469                 .chip   = {
1470                         .base   = S5P6440_GPH(0),
1471                         .ngpio  = S5P6440_GPIO_H_NR,
1472                         .label  = "GPH",
1473                 },
1474         },
1475 #endif
1476 };
1477
1478 static struct samsung_gpio_chip s5p6440_gpios_rbank[] = {
1479 #ifdef CONFIG_CPU_S5P6440
1480         {
1481                 .base   = S5P64X0_GPR_BASE + 0x4,
1482                 .config = &s5p64x0_gpio_cfg_rbank,
1483                 .chip   = {
1484                         .base   = S5P6440_GPR(0),
1485                         .ngpio  = S5P6440_GPIO_R_NR,
1486                         .label  = "GPR",
1487                 },
1488         },
1489 #endif
1490 };
1491
1492 static struct samsung_gpio_chip s5p6440_gpios_2bit[] = {
1493 #ifdef CONFIG_CPU_S5P6440
1494         {
1495                 .base   = S5P64X0_GPF_BASE,
1496                 .config = &samsung_gpio_cfgs[6],
1497                 .chip   = {
1498                         .base   = S5P6440_GPF(0),
1499                         .ngpio  = S5P6440_GPIO_F_NR,
1500                         .label  = "GPF",
1501                 },
1502         }, {
1503                 .base   = S5P64X0_GPI_BASE,
1504                 .config = &samsung_gpio_cfgs[4],
1505                 .chip   = {
1506                         .base   = S5P6440_GPI(0),
1507                         .ngpio  = S5P6440_GPIO_I_NR,
1508                         .label  = "GPI",
1509                 },
1510         }, {
1511                 .base   = S5P64X0_GPJ_BASE,
1512                 .config = &samsung_gpio_cfgs[4],
1513                 .chip   = {
1514                         .base   = S5P6440_GPJ(0),
1515                         .ngpio  = S5P6440_GPIO_J_NR,
1516                         .label  = "GPJ",
1517                 },
1518         }, {
1519                 .base   = S5P64X0_GPN_BASE,
1520                 .config = &samsung_gpio_cfgs[5],
1521                 .chip   = {
1522                         .base   = S5P6440_GPN(0),
1523                         .ngpio  = S5P6440_GPIO_N_NR,
1524                         .label  = "GPN",
1525                 },
1526         }, {
1527                 .base   = S5P64X0_GPP_BASE,
1528                 .config = &samsung_gpio_cfgs[6],
1529                 .chip   = {
1530                         .base   = S5P6440_GPP(0),
1531                         .ngpio  = S5P6440_GPIO_P_NR,
1532                         .label  = "GPP",
1533                 },
1534         },
1535 #endif
1536 };
1537
1538 /*
1539  * S5P6450 GPIO bank summary:
1540  *
1541  * Bank GPIOs   Style   SlpCon  ExtInt Group
1542  * A    6       4Bit    Yes     1
1543  * B    7       4Bit    Yes     1
1544  * C    8       4Bit    Yes     2
1545  * D    8       4Bit    Yes     None
1546  * F    2       2Bit    Yes     None
1547  * G    14      4Bit[2] Yes     5
1548  * H    10      4Bit[2] Yes     6
1549  * I    16      2Bit    Yes     None
1550  * J    12      2Bit    Yes     None
1551  * K    5       4Bit    Yes     None
1552  * N    16      2Bit    No      IRQ_EINT
1553  * P    11      2Bit    Yes     8
1554  * Q    14      2Bit    Yes     None
1555  * R    15      4Bit[2] Yes     None
1556  * S    8       2Bit    Yes     None
1557  *
1558  * [1] BANKF pins 14,15 do not form part of the external interrupt sources
1559  * [2] BANK has two control registers, GPxCON0 and GPxCON1
1560  */
1561
1562 static struct samsung_gpio_chip s5p6450_gpios_4bit[] = {
1563 #ifdef CONFIG_CPU_S5P6450
1564         {
1565                 .chip   = {
1566                         .base   = S5P6450_GPA(0),
1567                         .ngpio  = S5P6450_GPIO_A_NR,
1568                         .label  = "GPA",
1569                 },
1570         }, {
1571                 .chip   = {
1572                         .base   = S5P6450_GPB(0),
1573                         .ngpio  = S5P6450_GPIO_B_NR,
1574                         .label  = "GPB",
1575                 },
1576         }, {
1577                 .chip   = {
1578                         .base   = S5P6450_GPC(0),
1579                         .ngpio  = S5P6450_GPIO_C_NR,
1580                         .label  = "GPC",
1581                 },
1582         }, {
1583                 .chip   = {
1584                         .base   = S5P6450_GPD(0),
1585                         .ngpio  = S5P6450_GPIO_D_NR,
1586                         .label  = "GPD",
1587                 },
1588         }, {
1589                 .base   = S5P6450_GPK_BASE,
1590                 .chip   = {
1591                         .base   = S5P6450_GPK(0),
1592                         .ngpio  = S5P6450_GPIO_K_NR,
1593                         .label  = "GPK",
1594                 },
1595         },
1596 #endif
1597 };
1598
1599 static struct samsung_gpio_chip s5p6450_gpios_4bit2[] = {
1600 #ifdef CONFIG_CPU_S5P6450
1601         {
1602                 .base   = S5P64X0_GPG_BASE + 0x4,
1603                 .chip   = {
1604                         .base   = S5P6450_GPG(0),
1605                         .ngpio  = S5P6450_GPIO_G_NR,
1606                         .label  = "GPG",
1607                 },
1608         }, {
1609                 .base   = S5P64X0_GPH_BASE + 0x4,
1610                 .chip   = {
1611                         .base   = S5P6450_GPH(0),
1612                         .ngpio  = S5P6450_GPIO_H_NR,
1613                         .label  = "GPH",
1614                 },
1615         },
1616 #endif
1617 };
1618
1619 static struct samsung_gpio_chip s5p6450_gpios_rbank[] = {
1620 #ifdef CONFIG_CPU_S5P6450
1621         {
1622                 .base   = S5P64X0_GPR_BASE + 0x4,
1623                 .config = &s5p64x0_gpio_cfg_rbank,
1624                 .chip   = {
1625                         .base   = S5P6450_GPR(0),
1626                         .ngpio  = S5P6450_GPIO_R_NR,
1627                         .label  = "GPR",
1628                 },
1629         },
1630 #endif
1631 };
1632
1633 static struct samsung_gpio_chip s5p6450_gpios_2bit[] = {
1634 #ifdef CONFIG_CPU_S5P6450
1635         {
1636                 .base   = S5P64X0_GPF_BASE,
1637                 .config = &samsung_gpio_cfgs[6],
1638                 .chip   = {
1639                         .base   = S5P6450_GPF(0),
1640                         .ngpio  = S5P6450_GPIO_F_NR,
1641                         .label  = "GPF",
1642                 },
1643         }, {
1644                 .base   = S5P64X0_GPI_BASE,
1645                 .config = &samsung_gpio_cfgs[4],
1646                 .chip   = {
1647                         .base   = S5P6450_GPI(0),
1648                         .ngpio  = S5P6450_GPIO_I_NR,
1649                         .label  = "GPI",
1650                 },
1651         }, {
1652                 .base   = S5P64X0_GPJ_BASE,
1653                 .config = &samsung_gpio_cfgs[4],
1654                 .chip   = {
1655                         .base   = S5P6450_GPJ(0),
1656                         .ngpio  = S5P6450_GPIO_J_NR,
1657                         .label  = "GPJ",
1658                 },
1659         }, {
1660                 .base   = S5P64X0_GPN_BASE,
1661                 .config = &samsung_gpio_cfgs[5],
1662                 .chip   = {
1663                         .base   = S5P6450_GPN(0),
1664                         .ngpio  = S5P6450_GPIO_N_NR,
1665                         .label  = "GPN",
1666                 },
1667         }, {
1668                 .base   = S5P64X0_GPP_BASE,
1669                 .config = &samsung_gpio_cfgs[6],
1670                 .chip   = {
1671                         .base   = S5P6450_GPP(0),
1672                         .ngpio  = S5P6450_GPIO_P_NR,
1673                         .label  = "GPP",
1674                 },
1675         }, {
1676                 .base   = S5P6450_GPQ_BASE,
1677                 .config = &samsung_gpio_cfgs[5],
1678                 .chip   = {
1679                         .base   = S5P6450_GPQ(0),
1680                         .ngpio  = S5P6450_GPIO_Q_NR,
1681                         .label  = "GPQ",
1682                 },
1683         }, {
1684                 .base   = S5P6450_GPS_BASE,
1685                 .config = &samsung_gpio_cfgs[6],
1686                 .chip   = {
1687                         .base   = S5P6450_GPS(0),
1688                         .ngpio  = S5P6450_GPIO_S_NR,
1689                         .label  = "GPS",
1690                 },
1691         },
1692 #endif
1693 };
1694
1695 /*
1696  * S5PC100 GPIO bank summary:
1697  *
1698  * Bank GPIOs   Style   INT Type
1699  * A0   8       4Bit    GPIO_INT0
1700  * A1   5       4Bit    GPIO_INT1
1701  * B    8       4Bit    GPIO_INT2
1702  * C    5       4Bit    GPIO_INT3
1703  * D    7       4Bit    GPIO_INT4
1704  * E0   8       4Bit    GPIO_INT5
1705  * E1   6       4Bit    GPIO_INT6
1706  * F0   8       4Bit    GPIO_INT7
1707  * F1   8       4Bit    GPIO_INT8
1708  * F2   8       4Bit    GPIO_INT9
1709  * F3   4       4Bit    GPIO_INT10
1710  * G0   8       4Bit    GPIO_INT11
1711  * G1   3       4Bit    GPIO_INT12
1712  * G2   7       4Bit    GPIO_INT13
1713  * G3   7       4Bit    GPIO_INT14
1714  * H0   8       4Bit    WKUP_INT
1715  * H1   8       4Bit    WKUP_INT
1716  * H2   8       4Bit    WKUP_INT
1717  * H3   8       4Bit    WKUP_INT
1718  * I    8       4Bit    GPIO_INT15
1719  * J0   8       4Bit    GPIO_INT16
1720  * J1   5       4Bit    GPIO_INT17
1721  * J2   8       4Bit    GPIO_INT18
1722  * J3   8       4Bit    GPIO_INT19
1723  * J4   4       4Bit    GPIO_INT20
1724  * K0   8       4Bit    None
1725  * K1   6       4Bit    None
1726  * K2   8       4Bit    None
1727  * K3   8       4Bit    None
1728  * L0   8       4Bit    None
1729  * L1   8       4Bit    None
1730  * L2   8       4Bit    None
1731  * L3   8       4Bit    None
1732  */
1733
1734 static struct samsung_gpio_chip s5pc100_gpios_4bit[] = {
1735 #ifdef CONFIG_CPU_S5PC100
1736         {
1737                 .chip   = {
1738                         .base   = S5PC100_GPA0(0),
1739                         .ngpio  = S5PC100_GPIO_A0_NR,
1740                         .label  = "GPA0",
1741                 },
1742         }, {
1743                 .chip   = {
1744                         .base   = S5PC100_GPA1(0),
1745                         .ngpio  = S5PC100_GPIO_A1_NR,
1746                         .label  = "GPA1",
1747                 },
1748         }, {
1749                 .chip   = {
1750                         .base   = S5PC100_GPB(0),
1751                         .ngpio  = S5PC100_GPIO_B_NR,
1752                         .label  = "GPB",
1753                 },
1754         }, {
1755                 .chip   = {
1756                         .base   = S5PC100_GPC(0),
1757                         .ngpio  = S5PC100_GPIO_C_NR,
1758                         .label  = "GPC",
1759                 },
1760         }, {
1761                 .chip   = {
1762                         .base   = S5PC100_GPD(0),
1763                         .ngpio  = S5PC100_GPIO_D_NR,
1764                         .label  = "GPD",
1765                 },
1766         }, {
1767                 .chip   = {
1768                         .base   = S5PC100_GPE0(0),
1769                         .ngpio  = S5PC100_GPIO_E0_NR,
1770                         .label  = "GPE0",
1771                 },
1772         }, {
1773                 .chip   = {
1774                         .base   = S5PC100_GPE1(0),
1775                         .ngpio  = S5PC100_GPIO_E1_NR,
1776                         .label  = "GPE1",
1777                 },
1778         }, {
1779                 .chip   = {
1780                         .base   = S5PC100_GPF0(0),
1781                         .ngpio  = S5PC100_GPIO_F0_NR,
1782                         .label  = "GPF0",
1783                 },
1784         }, {
1785                 .chip   = {
1786                         .base   = S5PC100_GPF1(0),
1787                         .ngpio  = S5PC100_GPIO_F1_NR,
1788                         .label  = "GPF1",
1789                 },
1790         }, {
1791                 .chip   = {
1792                         .base   = S5PC100_GPF2(0),
1793                         .ngpio  = S5PC100_GPIO_F2_NR,
1794                         .label  = "GPF2",
1795                 },
1796         }, {
1797                 .chip   = {
1798                         .base   = S5PC100_GPF3(0),
1799                         .ngpio  = S5PC100_GPIO_F3_NR,
1800                         .label  = "GPF3",
1801                 },
1802         }, {
1803                 .chip   = {
1804                         .base   = S5PC100_GPG0(0),
1805                         .ngpio  = S5PC100_GPIO_G0_NR,
1806                         .label  = "GPG0",
1807                 },
1808         }, {
1809                 .chip   = {
1810                         .base   = S5PC100_GPG1(0),
1811                         .ngpio  = S5PC100_GPIO_G1_NR,
1812                         .label  = "GPG1",
1813                 },
1814         }, {
1815                 .chip   = {
1816                         .base   = S5PC100_GPG2(0),
1817                         .ngpio  = S5PC100_GPIO_G2_NR,
1818                         .label  = "GPG2",
1819                 },
1820         }, {
1821                 .chip   = {
1822                         .base   = S5PC100_GPG3(0),
1823                         .ngpio  = S5PC100_GPIO_G3_NR,
1824                         .label  = "GPG3",
1825                 },
1826         }, {
1827                 .chip   = {
1828                         .base   = S5PC100_GPI(0),
1829                         .ngpio  = S5PC100_GPIO_I_NR,
1830                         .label  = "GPI",
1831                 },
1832         }, {
1833                 .chip   = {
1834                         .base   = S5PC100_GPJ0(0),
1835                         .ngpio  = S5PC100_GPIO_J0_NR,
1836                         .label  = "GPJ0",
1837                 },
1838         }, {
1839                 .chip   = {
1840                         .base   = S5PC100_GPJ1(0),
1841                         .ngpio  = S5PC100_GPIO_J1_NR,
1842                         .label  = "GPJ1",
1843                 },
1844         }, {
1845                 .chip   = {
1846                         .base   = S5PC100_GPJ2(0),
1847                         .ngpio  = S5PC100_GPIO_J2_NR,
1848                         .label  = "GPJ2",
1849                 },
1850         }, {
1851                 .chip   = {
1852                         .base   = S5PC100_GPJ3(0),
1853                         .ngpio  = S5PC100_GPIO_J3_NR,
1854                         .label  = "GPJ3",
1855                 },
1856         }, {
1857                 .chip   = {
1858                         .base   = S5PC100_GPJ4(0),
1859                         .ngpio  = S5PC100_GPIO_J4_NR,
1860                         .label  = "GPJ4",
1861                 },
1862         }, {
1863                 .chip   = {
1864                         .base   = S5PC100_GPK0(0),
1865                         .ngpio  = S5PC100_GPIO_K0_NR,
1866                         .label  = "GPK0",
1867                 },
1868         }, {
1869                 .chip   = {
1870                         .base   = S5PC100_GPK1(0),
1871                         .ngpio  = S5PC100_GPIO_K1_NR,
1872                         .label  = "GPK1",
1873                 },
1874         }, {
1875                 .chip   = {
1876                         .base   = S5PC100_GPK2(0),
1877                         .ngpio  = S5PC100_GPIO_K2_NR,
1878                         .label  = "GPK2",
1879                 },
1880         }, {
1881                 .chip   = {
1882                         .base   = S5PC100_GPK3(0),
1883                         .ngpio  = S5PC100_GPIO_K3_NR,
1884                         .label  = "GPK3",
1885                 },
1886         }, {
1887                 .chip   = {
1888                         .base   = S5PC100_GPL0(0),
1889                         .ngpio  = S5PC100_GPIO_L0_NR,
1890                         .label  = "GPL0",
1891                 },
1892         }, {
1893                 .chip   = {
1894                         .base   = S5PC100_GPL1(0),
1895                         .ngpio  = S5PC100_GPIO_L1_NR,
1896                         .label  = "GPL1",
1897                 },
1898         }, {
1899                 .chip   = {
1900                         .base   = S5PC100_GPL2(0),
1901                         .ngpio  = S5PC100_GPIO_L2_NR,
1902                         .label  = "GPL2",
1903                 },
1904         }, {
1905                 .chip   = {
1906                         .base   = S5PC100_GPL3(0),
1907                         .ngpio  = S5PC100_GPIO_L3_NR,
1908                         .label  = "GPL3",
1909                 },
1910         }, {
1911                 .chip   = {
1912                         .base   = S5PC100_GPL4(0),
1913                         .ngpio  = S5PC100_GPIO_L4_NR,
1914                         .label  = "GPL4",
1915                 },
1916         }, {
1917                 .base   = (S5P_VA_GPIO + 0xC00),
1918                 .irq_base = IRQ_EINT(0),
1919                 .chip   = {
1920                         .base   = S5PC100_GPH0(0),
1921                         .ngpio  = S5PC100_GPIO_H0_NR,
1922                         .label  = "GPH0",
1923                         .to_irq = samsung_gpiolib_to_irq,
1924                 },
1925         }, {
1926                 .base   = (S5P_VA_GPIO + 0xC20),
1927                 .irq_base = IRQ_EINT(8),
1928                 .chip   = {
1929                         .base   = S5PC100_GPH1(0),
1930                         .ngpio  = S5PC100_GPIO_H1_NR,
1931                         .label  = "GPH1",
1932                         .to_irq = samsung_gpiolib_to_irq,
1933                 },
1934         }, {
1935                 .base   = (S5P_VA_GPIO + 0xC40),
1936                 .irq_base = IRQ_EINT(16),
1937                 .chip   = {
1938                         .base   = S5PC100_GPH2(0),
1939                         .ngpio  = S5PC100_GPIO_H2_NR,
1940                         .label  = "GPH2",
1941                         .to_irq = samsung_gpiolib_to_irq,
1942                 },
1943         }, {
1944                 .base   = (S5P_VA_GPIO + 0xC60),
1945                 .irq_base = IRQ_EINT(24),
1946                 .chip   = {
1947                         .base   = S5PC100_GPH3(0),
1948                         .ngpio  = S5PC100_GPIO_H3_NR,
1949                         .label  = "GPH3",
1950                         .to_irq = samsung_gpiolib_to_irq,
1951                 },
1952         },
1953 #endif
1954 };
1955
1956 /*
1957  * Followings are the gpio banks in S5PV210/S5PC110
1958  *
1959  * The 'config' member when left to NULL, is initialized to the default
1960  * structure samsung_gpio_cfgs[3] in the init function below.
1961  *
1962  * The 'base' member is also initialized in the init function below.
1963  * Note: The initialization of 'base' member of samsung_gpio_chip structure
1964  * uses the above macro and depends on the banks being listed in order here.
1965  */
1966
1967 static struct samsung_gpio_chip s5pv210_gpios_4bit[] = {
1968 #ifdef CONFIG_CPU_S5PV210
1969         {
1970                 .chip   = {
1971                         .base   = S5PV210_GPA0(0),
1972                         .ngpio  = S5PV210_GPIO_A0_NR,
1973                         .label  = "GPA0",
1974                 },
1975         }, {
1976                 .chip   = {
1977                         .base   = S5PV210_GPA1(0),
1978                         .ngpio  = S5PV210_GPIO_A1_NR,
1979                         .label  = "GPA1",
1980                 },
1981         }, {
1982                 .chip   = {
1983                         .base   = S5PV210_GPB(0),
1984                         .ngpio  = S5PV210_GPIO_B_NR,
1985                         .label  = "GPB",
1986                 },
1987         }, {
1988                 .chip   = {
1989                         .base   = S5PV210_GPC0(0),
1990                         .ngpio  = S5PV210_GPIO_C0_NR,
1991                         .label  = "GPC0",
1992                 },
1993         }, {
1994                 .chip   = {
1995                         .base   = S5PV210_GPC1(0),
1996                         .ngpio  = S5PV210_GPIO_C1_NR,
1997                         .label  = "GPC1",
1998                 },
1999         }, {
2000                 .chip   = {
2001                         .base   = S5PV210_GPD0(0),
2002                         .ngpio  = S5PV210_GPIO_D0_NR,
2003                         .label  = "GPD0",
2004                 },
2005         }, {
2006                 .chip   = {
2007                         .base   = S5PV210_GPD1(0),
2008                         .ngpio  = S5PV210_GPIO_D1_NR,
2009                         .label  = "GPD1",
2010                 },
2011         }, {
2012                 .chip   = {
2013                         .base   = S5PV210_GPE0(0),
2014                         .ngpio  = S5PV210_GPIO_E0_NR,
2015                         .label  = "GPE0",
2016                 },
2017         }, {
2018                 .chip   = {
2019                         .base   = S5PV210_GPE1(0),
2020                         .ngpio  = S5PV210_GPIO_E1_NR,
2021                         .label  = "GPE1",
2022                 },
2023         }, {
2024                 .chip   = {
2025                         .base   = S5PV210_GPF0(0),
2026                         .ngpio  = S5PV210_GPIO_F0_NR,
2027                         .label  = "GPF0",
2028                 },
2029         }, {
2030                 .chip   = {
2031                         .base   = S5PV210_GPF1(0),
2032                         .ngpio  = S5PV210_GPIO_F1_NR,
2033                         .label  = "GPF1",
2034                 },
2035         }, {
2036                 .chip   = {
2037                         .base   = S5PV210_GPF2(0),
2038                         .ngpio  = S5PV210_GPIO_F2_NR,
2039                         .label  = "GPF2",
2040                 },
2041         }, {
2042                 .chip   = {
2043                         .base   = S5PV210_GPF3(0),
2044                         .ngpio  = S5PV210_GPIO_F3_NR,
2045                         .label  = "GPF3",
2046                 },
2047         }, {
2048                 .chip   = {
2049                         .base   = S5PV210_GPG0(0),
2050                         .ngpio  = S5PV210_GPIO_G0_NR,
2051                         .label  = "GPG0",
2052                 },
2053         }, {
2054                 .chip   = {
2055                         .base   = S5PV210_GPG1(0),
2056                         .ngpio  = S5PV210_GPIO_G1_NR,
2057                         .label  = "GPG1",
2058                 },
2059         }, {
2060                 .chip   = {
2061                         .base   = S5PV210_GPG2(0),
2062                         .ngpio  = S5PV210_GPIO_G2_NR,
2063                         .label  = "GPG2",
2064                 },
2065         }, {
2066                 .chip   = {
2067                         .base   = S5PV210_GPG3(0),
2068                         .ngpio  = S5PV210_GPIO_G3_NR,
2069                         .label  = "GPG3",
2070                 },
2071         }, {
2072                 .chip   = {
2073                         .base   = S5PV210_GPI(0),
2074                         .ngpio  = S5PV210_GPIO_I_NR,
2075                         .label  = "GPI",
2076                 },
2077         }, {
2078                 .chip   = {
2079                         .base   = S5PV210_GPJ0(0),
2080                         .ngpio  = S5PV210_GPIO_J0_NR,
2081                         .label  = "GPJ0",
2082                 },
2083         }, {
2084                 .chip   = {
2085                         .base   = S5PV210_GPJ1(0),
2086                         .ngpio  = S5PV210_GPIO_J1_NR,
2087                         .label  = "GPJ1",
2088                 },
2089         }, {
2090                 .chip   = {
2091                         .base   = S5PV210_GPJ2(0),
2092                         .ngpio  = S5PV210_GPIO_J2_NR,
2093                         .label  = "GPJ2",
2094                 },
2095         }, {
2096                 .chip   = {
2097                         .base   = S5PV210_GPJ3(0),
2098                         .ngpio  = S5PV210_GPIO_J3_NR,
2099                         .label  = "GPJ3",
2100                 },
2101         }, {
2102                 .chip   = {
2103                         .base   = S5PV210_GPJ4(0),
2104                         .ngpio  = S5PV210_GPIO_J4_NR,
2105                         .label  = "GPJ4",
2106                 },
2107         }, {
2108                 .chip   = {
2109                         .base   = S5PV210_MP01(0),
2110                         .ngpio  = S5PV210_GPIO_MP01_NR,
2111                         .label  = "MP01",
2112                 },
2113         }, {
2114                 .chip   = {
2115                         .base   = S5PV210_MP02(0),
2116                         .ngpio  = S5PV210_GPIO_MP02_NR,
2117                         .label  = "MP02",
2118                 },
2119         }, {
2120                 .chip   = {
2121                         .base   = S5PV210_MP03(0),
2122                         .ngpio  = S5PV210_GPIO_MP03_NR,
2123                         .label  = "MP03",
2124                 },
2125         }, {
2126                 .chip   = {
2127                         .base   = S5PV210_MP04(0),
2128                         .ngpio  = S5PV210_GPIO_MP04_NR,
2129                         .label  = "MP04",
2130                 },
2131         }, {
2132                 .chip   = {
2133                         .base   = S5PV210_MP05(0),
2134                         .ngpio  = S5PV210_GPIO_MP05_NR,
2135                         .label  = "MP05",
2136                 },
2137         }, {
2138                 .base   = (S5P_VA_GPIO + 0xC00),
2139                 .irq_base = IRQ_EINT(0),
2140                 .chip   = {
2141                         .base   = S5PV210_GPH0(0),
2142                         .ngpio  = S5PV210_GPIO_H0_NR,
2143                         .label  = "GPH0",
2144                         .to_irq = samsung_gpiolib_to_irq,
2145                 },
2146         }, {
2147                 .base   = (S5P_VA_GPIO + 0xC20),
2148                 .irq_base = IRQ_EINT(8),
2149                 .chip   = {
2150                         .base   = S5PV210_GPH1(0),
2151                         .ngpio  = S5PV210_GPIO_H1_NR,
2152                         .label  = "GPH1",
2153                         .to_irq = samsung_gpiolib_to_irq,
2154                 },
2155         }, {
2156                 .base   = (S5P_VA_GPIO + 0xC40),
2157                 .irq_base = IRQ_EINT(16),
2158                 .chip   = {
2159                         .base   = S5PV210_GPH2(0),
2160                         .ngpio  = S5PV210_GPIO_H2_NR,
2161                         .label  = "GPH2",
2162                         .to_irq = samsung_gpiolib_to_irq,
2163                 },
2164         }, {
2165                 .base   = (S5P_VA_GPIO + 0xC60),
2166                 .irq_base = IRQ_EINT(24),
2167                 .chip   = {
2168                         .base   = S5PV210_GPH3(0),
2169                         .ngpio  = S5PV210_GPIO_H3_NR,
2170                         .label  = "GPH3",
2171                         .to_irq = samsung_gpiolib_to_irq,
2172                 },
2173         },
2174 #endif
2175 };
2176
2177 /*
2178  * Followings are the gpio banks in EXYNOS SoCs
2179  *
2180  * The 'config' member when left to NULL, is initialized to the default
2181  * structure exynos_gpio_cfg in the init function below.
2182  *
2183  * The 'base' member is also initialized in the init function below.
2184  * Note: The initialization of 'base' member of samsung_gpio_chip structure
2185  * uses the above macro and depends on the banks being listed in order here.
2186  */
2187
2188 #ifdef CONFIG_ARCH_EXYNOS4
2189 static struct samsung_gpio_chip exynos4_gpios_1[] = {
2190         {
2191                 .chip   = {
2192                         .base   = EXYNOS4_GPA0(0),
2193                         .ngpio  = EXYNOS4_GPIO_A0_NR,
2194                         .label  = "GPA0",
2195                 },
2196         }, {
2197                 .chip   = {
2198                         .base   = EXYNOS4_GPA1(0),
2199                         .ngpio  = EXYNOS4_GPIO_A1_NR,
2200                         .label  = "GPA1",
2201                 },
2202         }, {
2203                 .chip   = {
2204                         .base   = EXYNOS4_GPB(0),
2205                         .ngpio  = EXYNOS4_GPIO_B_NR,
2206                         .label  = "GPB",
2207                 },
2208         }, {
2209                 .chip   = {
2210                         .base   = EXYNOS4_GPC0(0),
2211                         .ngpio  = EXYNOS4_GPIO_C0_NR,
2212                         .label  = "GPC0",
2213                 },
2214         }, {
2215                 .chip   = {
2216                         .base   = EXYNOS4_GPC1(0),
2217                         .ngpio  = EXYNOS4_GPIO_C1_NR,
2218                         .label  = "GPC1",
2219                 },
2220         }, {
2221                 .chip   = {
2222                         .base   = EXYNOS4_GPD0(0),
2223                         .ngpio  = EXYNOS4_GPIO_D0_NR,
2224                         .label  = "GPD0",
2225                 },
2226         }, {
2227                 .chip   = {
2228                         .base   = EXYNOS4_GPD1(0),
2229                         .ngpio  = EXYNOS4_GPIO_D1_NR,
2230                         .label  = "GPD1",
2231                 },
2232         }, {
2233                 .chip   = {
2234                         .base   = EXYNOS4_GPE0(0),
2235                         .ngpio  = EXYNOS4_GPIO_E0_NR,
2236                         .label  = "GPE0",
2237                 },
2238         }, {
2239                 .chip   = {
2240                         .base   = EXYNOS4_GPE1(0),
2241                         .ngpio  = EXYNOS4_GPIO_E1_NR,
2242                         .label  = "GPE1",
2243                 },
2244         }, {
2245                 .chip   = {
2246                         .base   = EXYNOS4_GPE2(0),
2247                         .ngpio  = EXYNOS4_GPIO_E2_NR,
2248                         .label  = "GPE2",
2249                 },
2250         }, {
2251                 .chip   = {
2252                         .base   = EXYNOS4_GPE3(0),
2253                         .ngpio  = EXYNOS4_GPIO_E3_NR,
2254                         .label  = "GPE3",
2255                 },
2256         }, {
2257                 .chip   = {
2258                         .base   = EXYNOS4_GPE4(0),
2259                         .ngpio  = EXYNOS4_GPIO_E4_NR,
2260                         .label  = "GPE4",
2261                 },
2262         }, {
2263                 .chip   = {
2264                         .base   = EXYNOS4_GPF0(0),
2265                         .ngpio  = EXYNOS4_GPIO_F0_NR,
2266                         .label  = "GPF0",
2267                 },
2268         }, {
2269                 .chip   = {
2270                         .base   = EXYNOS4_GPF1(0),
2271                         .ngpio  = EXYNOS4_GPIO_F1_NR,
2272                         .label  = "GPF1",
2273                 },
2274         }, {
2275                 .chip   = {
2276                         .base   = EXYNOS4_GPF2(0),
2277                         .ngpio  = EXYNOS4_GPIO_F2_NR,
2278                         .label  = "GPF2",
2279                 },
2280         }, {
2281                 .chip   = {
2282                         .base   = EXYNOS4_GPF3(0),
2283                         .ngpio  = EXYNOS4_GPIO_F3_NR,
2284                         .label  = "GPF3",
2285                 },
2286         },
2287 };
2288 #endif
2289
2290 #ifdef CONFIG_ARCH_EXYNOS4
2291 static struct samsung_gpio_chip exynos4_gpios_2[] = {
2292         {
2293                 .chip   = {
2294                         .base   = EXYNOS4_GPJ0(0),
2295                         .ngpio  = EXYNOS4_GPIO_J0_NR,
2296                         .label  = "GPJ0",
2297                 },
2298         }, {
2299                 .chip   = {
2300                         .base   = EXYNOS4_GPJ1(0),
2301                         .ngpio  = EXYNOS4_GPIO_J1_NR,
2302                         .label  = "GPJ1",
2303                 },
2304         }, {
2305                 .chip   = {
2306                         .base   = EXYNOS4_GPK0(0),
2307                         .ngpio  = EXYNOS4_GPIO_K0_NR,
2308                         .label  = "GPK0",
2309                 },
2310         }, {
2311                 .chip   = {
2312                         .base   = EXYNOS4_GPK1(0),
2313                         .ngpio  = EXYNOS4_GPIO_K1_NR,
2314                         .label  = "GPK1",
2315                 },
2316         }, {
2317                 .chip   = {
2318                         .base   = EXYNOS4_GPK2(0),
2319                         .ngpio  = EXYNOS4_GPIO_K2_NR,
2320                         .label  = "GPK2",
2321                 },
2322         }, {
2323                 .chip   = {
2324                         .base   = EXYNOS4_GPK3(0),
2325                         .ngpio  = EXYNOS4_GPIO_K3_NR,
2326                         .label  = "GPK3",
2327                 },
2328         }, {
2329                 .chip   = {
2330                         .base   = EXYNOS4_GPL0(0),
2331                         .ngpio  = EXYNOS4_GPIO_L0_NR,
2332                         .label  = "GPL0",
2333                 },
2334         }, {
2335                 .chip   = {
2336                         .base   = EXYNOS4_GPL1(0),
2337                         .ngpio  = EXYNOS4_GPIO_L1_NR,
2338                         .label  = "GPL1",
2339                 },
2340         }, {
2341                 .chip   = {
2342                         .base   = EXYNOS4_GPL2(0),
2343                         .ngpio  = EXYNOS4_GPIO_L2_NR,
2344                         .label  = "GPL2",
2345                 },
2346         }, {
2347                 .config = &samsung_gpio_cfgs[8],
2348                 .chip   = {
2349                         .base   = EXYNOS4_GPY0(0),
2350                         .ngpio  = EXYNOS4_GPIO_Y0_NR,
2351                         .label  = "GPY0",
2352                 },
2353         }, {
2354                 .config = &samsung_gpio_cfgs[8],
2355                 .chip   = {
2356                         .base   = EXYNOS4_GPY1(0),
2357                         .ngpio  = EXYNOS4_GPIO_Y1_NR,
2358                         .label  = "GPY1",
2359                 },
2360         }, {
2361                 .config = &samsung_gpio_cfgs[8],
2362                 .chip   = {
2363                         .base   = EXYNOS4_GPY2(0),
2364                         .ngpio  = EXYNOS4_GPIO_Y2_NR,
2365                         .label  = "GPY2",
2366                 },
2367         }, {
2368                 .config = &samsung_gpio_cfgs[8],
2369                 .chip   = {
2370                         .base   = EXYNOS4_GPY3(0),
2371                         .ngpio  = EXYNOS4_GPIO_Y3_NR,
2372                         .label  = "GPY3",
2373                 },
2374         }, {
2375                 .config = &samsung_gpio_cfgs[8],
2376                 .chip   = {
2377                         .base   = EXYNOS4_GPY4(0),
2378                         .ngpio  = EXYNOS4_GPIO_Y4_NR,
2379                         .label  = "GPY4",
2380                 },
2381         }, {
2382                 .config = &samsung_gpio_cfgs[8],
2383                 .chip   = {
2384                         .base   = EXYNOS4_GPY5(0),
2385                         .ngpio  = EXYNOS4_GPIO_Y5_NR,
2386                         .label  = "GPY5",
2387                 },
2388         }, {
2389                 .config = &samsung_gpio_cfgs[8],
2390                 .chip   = {
2391                         .base   = EXYNOS4_GPY6(0),
2392                         .ngpio  = EXYNOS4_GPIO_Y6_NR,
2393                         .label  = "GPY6",
2394                 },
2395         }, {
2396                 .config = &samsung_gpio_cfgs[9],
2397                 .irq_base = IRQ_EINT(0),
2398                 .chip   = {
2399                         .base   = EXYNOS4_GPX0(0),
2400                         .ngpio  = EXYNOS4_GPIO_X0_NR,
2401                         .label  = "GPX0",
2402                         .to_irq = samsung_gpiolib_to_irq,
2403                 },
2404         }, {
2405                 .config = &samsung_gpio_cfgs[9],
2406                 .irq_base = IRQ_EINT(8),
2407                 .chip   = {
2408                         .base   = EXYNOS4_GPX1(0),
2409                         .ngpio  = EXYNOS4_GPIO_X1_NR,
2410                         .label  = "GPX1",
2411                         .to_irq = samsung_gpiolib_to_irq,
2412                 },
2413         }, {
2414                 .config = &samsung_gpio_cfgs[9],
2415                 .irq_base = IRQ_EINT(16),
2416                 .chip   = {
2417                         .base   = EXYNOS4_GPX2(0),
2418                         .ngpio  = EXYNOS4_GPIO_X2_NR,
2419                         .label  = "GPX2",
2420                         .to_irq = samsung_gpiolib_to_irq,
2421                 },
2422         }, {
2423                 .config = &samsung_gpio_cfgs[9],
2424                 .irq_base = IRQ_EINT(24),
2425                 .chip   = {
2426                         .base   = EXYNOS4_GPX3(0),
2427                         .ngpio  = EXYNOS4_GPIO_X3_NR,
2428                         .label  = "GPX3",
2429                         .to_irq = samsung_gpiolib_to_irq,
2430                 },
2431         },
2432 };
2433 #endif
2434
2435 #ifdef CONFIG_ARCH_EXYNOS4
2436 static struct samsung_gpio_chip exynos4_gpios_3[] = {
2437         {
2438                 .chip   = {
2439                         .base   = EXYNOS4_GPZ(0),
2440                         .ngpio  = EXYNOS4_GPIO_Z_NR,
2441                         .label  = "GPZ",
2442                 },
2443         },
2444 };
2445 #endif
2446
2447 #ifdef CONFIG_SOC_EXYNOS5250
2448 static struct samsung_gpio_chip exynos5_gpios_1[] = {
2449         {
2450                 .chip   = {
2451                         .base   = EXYNOS5_GPA0(0),
2452                         .ngpio  = EXYNOS5_GPIO_A0_NR,
2453                         .label  = "GPA0",
2454                 },
2455         }, {
2456                 .chip   = {
2457                         .base   = EXYNOS5_GPA1(0),
2458                         .ngpio  = EXYNOS5_GPIO_A1_NR,
2459                         .label  = "GPA1",
2460                 },
2461         }, {
2462                 .chip   = {
2463                         .base   = EXYNOS5_GPA2(0),
2464                         .ngpio  = EXYNOS5_GPIO_A2_NR,
2465                         .label  = "GPA2",
2466                 },
2467         }, {
2468                 .chip   = {
2469                         .base   = EXYNOS5_GPB0(0),
2470                         .ngpio  = EXYNOS5_GPIO_B0_NR,
2471                         .label  = "GPB0",
2472                 },
2473         }, {
2474                 .chip   = {
2475                         .base   = EXYNOS5_GPB1(0),
2476                         .ngpio  = EXYNOS5_GPIO_B1_NR,
2477                         .label  = "GPB1",
2478                 },
2479         }, {
2480                 .chip   = {
2481                         .base   = EXYNOS5_GPB2(0),
2482                         .ngpio  = EXYNOS5_GPIO_B2_NR,
2483                         .label  = "GPB2",
2484                 },
2485         }, {
2486                 .chip   = {
2487                         .base   = EXYNOS5_GPB3(0),
2488                         .ngpio  = EXYNOS5_GPIO_B3_NR,
2489                         .label  = "GPB3",
2490                 },
2491         }, {
2492                 .chip   = {
2493                         .base   = EXYNOS5_GPC0(0),
2494                         .ngpio  = EXYNOS5_GPIO_C0_NR,
2495                         .label  = "GPC0",
2496                 },
2497         }, {
2498                 .chip   = {
2499                         .base   = EXYNOS5_GPC1(0),
2500                         .ngpio  = EXYNOS5_GPIO_C1_NR,
2501                         .label  = "GPC1",
2502                 },
2503         }, {
2504                 .chip   = {
2505                         .base   = EXYNOS5_GPC2(0),
2506                         .ngpio  = EXYNOS5_GPIO_C2_NR,
2507                         .label  = "GPC2",
2508                 },
2509         }, {
2510                 .chip   = {
2511                         .base   = EXYNOS5_GPC3(0),
2512                         .ngpio  = EXYNOS5_GPIO_C3_NR,
2513                         .label  = "GPC3",
2514                 },
2515         }, {
2516                 .chip   = {
2517                         .base   = EXYNOS5_GPD0(0),
2518                         .ngpio  = EXYNOS5_GPIO_D0_NR,
2519                         .label  = "GPD0",
2520                 },
2521         }, {
2522                 .chip   = {
2523                         .base   = EXYNOS5_GPD1(0),
2524                         .ngpio  = EXYNOS5_GPIO_D1_NR,
2525                         .label  = "GPD1",
2526                 },
2527         }, {
2528                 .chip   = {
2529                         .base   = EXYNOS5_GPY0(0),
2530                         .ngpio  = EXYNOS5_GPIO_Y0_NR,
2531                         .label  = "GPY0",
2532                 },
2533         }, {
2534                 .chip   = {
2535                         .base   = EXYNOS5_GPY1(0),
2536                         .ngpio  = EXYNOS5_GPIO_Y1_NR,
2537                         .label  = "GPY1",
2538                 },
2539         }, {
2540                 .chip   = {
2541                         .base   = EXYNOS5_GPY2(0),
2542                         .ngpio  = EXYNOS5_GPIO_Y2_NR,
2543                         .label  = "GPY2",
2544                 },
2545         }, {
2546                 .chip   = {
2547                         .base   = EXYNOS5_GPY3(0),
2548                         .ngpio  = EXYNOS5_GPIO_Y3_NR,
2549                         .label  = "GPY3",
2550                 },
2551         }, {
2552                 .chip   = {
2553                         .base   = EXYNOS5_GPY4(0),
2554                         .ngpio  = EXYNOS5_GPIO_Y4_NR,
2555                         .label  = "GPY4",
2556                 },
2557         }, {
2558                 .chip   = {
2559                         .base   = EXYNOS5_GPY5(0),
2560                         .ngpio  = EXYNOS5_GPIO_Y5_NR,
2561                         .label  = "GPY5",
2562                 },
2563         }, {
2564                 .chip   = {
2565                         .base   = EXYNOS5_GPY6(0),
2566                         .ngpio  = EXYNOS5_GPIO_Y6_NR,
2567                         .label  = "GPY6",
2568                 },
2569         }, {
2570                 .chip   = {
2571                         .base   = EXYNOS5_GPC4(0),
2572                         .ngpio  = EXYNOS5_GPIO_C4_NR,
2573                         .label  = "GPC4",
2574                 },
2575         }, {
2576                 .config = &samsung_gpio_cfgs[9],
2577                 .irq_base = IRQ_EINT(0),
2578                 .chip   = {
2579                         .base   = EXYNOS5_GPX0(0),
2580                         .ngpio  = EXYNOS5_GPIO_X0_NR,
2581                         .label  = "GPX0",
2582                         .to_irq = samsung_gpiolib_to_irq,
2583                 },
2584         }, {
2585                 .config = &samsung_gpio_cfgs[9],
2586                 .irq_base = IRQ_EINT(8),
2587                 .chip   = {
2588                         .base   = EXYNOS5_GPX1(0),
2589                         .ngpio  = EXYNOS5_GPIO_X1_NR,
2590                         .label  = "GPX1",
2591                         .to_irq = samsung_gpiolib_to_irq,
2592                 },
2593         }, {
2594                 .config = &samsung_gpio_cfgs[9],
2595                 .irq_base = IRQ_EINT(16),
2596                 .chip   = {
2597                         .base   = EXYNOS5_GPX2(0),
2598                         .ngpio  = EXYNOS5_GPIO_X2_NR,
2599                         .label  = "GPX2",
2600                         .to_irq = samsung_gpiolib_to_irq,
2601                 },
2602         }, {
2603                 .config = &samsung_gpio_cfgs[9],
2604                 .irq_base = IRQ_EINT(24),
2605                 .chip   = {
2606                         .base   = EXYNOS5_GPX3(0),
2607                         .ngpio  = EXYNOS5_GPIO_X3_NR,
2608                         .label  = "GPX3",
2609                         .to_irq = samsung_gpiolib_to_irq,
2610                 },
2611         },
2612 };
2613 #endif
2614
2615 #ifdef CONFIG_SOC_EXYNOS5250
2616 static struct samsung_gpio_chip exynos5_gpios_2[] = {
2617         {
2618                 .chip   = {
2619                         .base   = EXYNOS5_GPE0(0),
2620                         .ngpio  = EXYNOS5_GPIO_E0_NR,
2621                         .label  = "GPE0",
2622                 },
2623         }, {
2624                 .chip   = {
2625                         .base   = EXYNOS5_GPE1(0),
2626                         .ngpio  = EXYNOS5_GPIO_E1_NR,
2627                         .label  = "GPE1",
2628                 },
2629         }, {
2630                 .chip   = {
2631                         .base   = EXYNOS5_GPF0(0),
2632                         .ngpio  = EXYNOS5_GPIO_F0_NR,
2633                         .label  = "GPF0",
2634                 },
2635         }, {
2636                 .chip   = {
2637                         .base   = EXYNOS5_GPF1(0),
2638                         .ngpio  = EXYNOS5_GPIO_F1_NR,
2639                         .label  = "GPF1",
2640                 },
2641         }, {
2642                 .chip   = {
2643                         .base   = EXYNOS5_GPG0(0),
2644                         .ngpio  = EXYNOS5_GPIO_G0_NR,
2645                         .label  = "GPG0",
2646                 },
2647         }, {
2648                 .chip   = {
2649                         .base   = EXYNOS5_GPG1(0),
2650                         .ngpio  = EXYNOS5_GPIO_G1_NR,
2651                         .label  = "GPG1",
2652                 },
2653         }, {
2654                 .chip   = {
2655                         .base   = EXYNOS5_GPG2(0),
2656                         .ngpio  = EXYNOS5_GPIO_G2_NR,
2657                         .label  = "GPG2",
2658                 },
2659         }, {
2660                 .chip   = {
2661                         .base   = EXYNOS5_GPH0(0),
2662                         .ngpio  = EXYNOS5_GPIO_H0_NR,
2663                         .label  = "GPH0",
2664                 },
2665         }, {
2666                 .chip   = {
2667                         .base   = EXYNOS5_GPH1(0),
2668                         .ngpio  = EXYNOS5_GPIO_H1_NR,
2669                         .label  = "GPH1",
2670
2671                 },
2672         },
2673 };
2674 #endif
2675
2676 #ifdef CONFIG_SOC_EXYNOS5250
2677 static struct samsung_gpio_chip exynos5_gpios_3[] = {
2678         {
2679                 .chip   = {
2680                         .base   = EXYNOS5_GPV0(0),
2681                         .ngpio  = EXYNOS5_GPIO_V0_NR,
2682                         .label  = "GPV0",
2683                 },
2684         }, {
2685                 .chip   = {
2686                         .base   = EXYNOS5_GPV1(0),
2687                         .ngpio  = EXYNOS5_GPIO_V1_NR,
2688                         .label  = "GPV1",
2689                 },
2690         }, {
2691                 .chip   = {
2692                         .base   = EXYNOS5_GPV2(0),
2693                         .ngpio  = EXYNOS5_GPIO_V2_NR,
2694                         .label  = "GPV2",
2695                 },
2696         }, {
2697                 .chip   = {
2698                         .base   = EXYNOS5_GPV3(0),
2699                         .ngpio  = EXYNOS5_GPIO_V3_NR,
2700                         .label  = "GPV3",
2701                 },
2702         }, {
2703                 .chip   = {
2704                         .base   = EXYNOS5_GPV4(0),
2705                         .ngpio  = EXYNOS5_GPIO_V4_NR,
2706                         .label  = "GPV4",
2707                 },
2708         },
2709 };
2710 #endif
2711
2712 #ifdef CONFIG_SOC_EXYNOS5250
2713 static struct samsung_gpio_chip exynos5_gpios_4[] = {
2714         {
2715                 .chip   = {
2716                         .base   = EXYNOS5_GPZ(0),
2717                         .ngpio  = EXYNOS5_GPIO_Z_NR,
2718                         .label  = "GPZ",
2719                 },
2720         },
2721 };
2722 #endif
2723
2724
2725 #if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF)
2726 static int exynos_gpio_xlate(struct gpio_chip *gc,
2727                         const struct of_phandle_args *gpiospec, u32 *flags)
2728 {
2729         unsigned int pin;
2730
2731         if (WARN_ON(gc->of_gpio_n_cells < 4))
2732                 return -EINVAL;
2733
2734         if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
2735                 return -EINVAL;
2736
2737         if (gpiospec->args[0] > gc->ngpio)
2738                 return -EINVAL;
2739
2740         pin = gc->base + gpiospec->args[0];
2741
2742         if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
2743                 pr_warn("gpio_xlate: failed to set pin function\n");
2744         if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff))
2745                 pr_warn("gpio_xlate: failed to set pin pull up/down\n");
2746         if (s5p_gpio_set_drvstr(pin, gpiospec->args[3]))
2747                 pr_warn("gpio_xlate: failed to set pin drive strength\n");
2748
2749         if (flags)
2750                 *flags = gpiospec->args[2] >> 16;
2751
2752         return gpiospec->args[0];
2753 }
2754
2755 static const struct of_device_id exynos_gpio_dt_match[] __initdata = {
2756         { .compatible = "samsung,exynos4-gpio", },
2757         {}
2758 };
2759
2760 static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
2761                                                 u64 base, u64 offset)
2762 {
2763         struct gpio_chip *gc =  &chip->chip;
2764         u64 address;
2765
2766         if (!of_have_populated_dt())
2767                 return;
2768
2769         address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
2770         gc->of_node = of_find_matching_node_by_address(NULL,
2771                         exynos_gpio_dt_match, address);
2772         if (!gc->of_node) {
2773                 pr_info("gpio: device tree node not found for gpio controller"
2774                         " with base address %08llx\n", address);
2775                 return;
2776         }
2777         gc->of_gpio_n_cells = 4;
2778         gc->of_xlate = exynos_gpio_xlate;
2779 }
2780 #elif defined(CONFIG_ARCH_EXYNOS)
2781 static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
2782                                                 u64 base, u64 offset)
2783 {
2784         return;
2785 }
2786 #endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */
2787
2788 static __init void exynos4_gpiolib_init(void)
2789 {
2790 #ifdef CONFIG_CPU_EXYNOS4210
2791         struct samsung_gpio_chip *chip;
2792         int i, nr_chips;
2793         void __iomem *gpio_base1, *gpio_base2, *gpio_base3;
2794         int group = 0;
2795         void __iomem *gpx_base;
2796
2797         /* gpio part1 */
2798         gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K);
2799         if (gpio_base1 == NULL) {
2800                 pr_err("unable to ioremap for gpio_base1\n");
2801                 goto err_ioremap1;
2802         }
2803
2804         chip = exynos4_gpios_1;
2805         nr_chips = ARRAY_SIZE(exynos4_gpios_1);
2806
2807         for (i = 0; i < nr_chips; i++, chip++) {
2808                 if (!chip->config) {
2809                         chip->config = &exynos_gpio_cfg;
2810                         chip->group = group++;
2811                 }
2812                 exynos_gpiolib_attach_ofnode(chip,
2813                                 EXYNOS4_PA_GPIO1, i * 0x20);
2814         }
2815         samsung_gpiolib_add_4bit_chips(exynos4_gpios_1,
2816                                        nr_chips, gpio_base1);
2817
2818         /* gpio part2 */
2819         gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
2820         if (gpio_base2 == NULL) {
2821                 pr_err("unable to ioremap for gpio_base2\n");
2822                 goto err_ioremap2;
2823         }
2824
2825         /* need to set base address for gpx */
2826         chip = &exynos4_gpios_2[16];
2827         gpx_base = gpio_base2 + 0xC00;
2828         for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
2829                 chip->base = gpx_base;
2830
2831         chip = exynos4_gpios_2;
2832         nr_chips = ARRAY_SIZE(exynos4_gpios_2);
2833
2834         for (i = 0; i < nr_chips; i++, chip++) {
2835                 if (!chip->config) {
2836                         chip->config = &exynos_gpio_cfg;
2837                         chip->group = group++;
2838                 }
2839                 exynos_gpiolib_attach_ofnode(chip,
2840                                 EXYNOS4_PA_GPIO2, i * 0x20);
2841         }
2842         samsung_gpiolib_add_4bit_chips(exynos4_gpios_2,
2843                                        nr_chips, gpio_base2);
2844
2845         /* gpio part3 */
2846         gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256);
2847         if (gpio_base3 == NULL) {
2848                 pr_err("unable to ioremap for gpio_base3\n");
2849                 goto err_ioremap3;
2850         }
2851
2852         chip = exynos4_gpios_3;
2853         nr_chips = ARRAY_SIZE(exynos4_gpios_3);
2854
2855         for (i = 0; i < nr_chips; i++, chip++) {
2856                 if (!chip->config) {
2857                         chip->config = &exynos_gpio_cfg;
2858                         chip->group = group++;
2859                 }
2860                 exynos_gpiolib_attach_ofnode(chip,
2861                                 EXYNOS4_PA_GPIO3, i * 0x20);
2862         }
2863         samsung_gpiolib_add_4bit_chips(exynos4_gpios_3,
2864                                        nr_chips, gpio_base3);
2865
2866 #if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT)
2867         s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
2868         s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
2869 #endif
2870
2871         return;
2872
2873 err_ioremap3:
2874         iounmap(gpio_base2);
2875 err_ioremap2:
2876         iounmap(gpio_base1);
2877 err_ioremap1:
2878         return;
2879 #endif  /* CONFIG_CPU_EXYNOS4210 */
2880 }
2881
2882 static __init void exynos5_gpiolib_init(void)
2883 {
2884 #ifdef CONFIG_SOC_EXYNOS5250
2885         struct samsung_gpio_chip *chip;
2886         int i, nr_chips;
2887         void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4;
2888         int group = 0;
2889         void __iomem *gpx_base;
2890
2891         /* gpio part1 */
2892         gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
2893         if (gpio_base1 == NULL) {
2894                 pr_err("unable to ioremap for gpio_base1\n");
2895                 goto err_ioremap1;
2896         }
2897
2898         /* need to set base address for gpc4 */
2899         exynos5_gpios_1[20].base = gpio_base1 + 0x2E0;
2900
2901         /* need to set base address for gpx */
2902         chip = &exynos5_gpios_1[21];
2903         gpx_base = gpio_base1 + 0xC00;
2904         for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
2905                 chip->base = gpx_base;
2906
2907         chip = exynos5_gpios_1;
2908         nr_chips = ARRAY_SIZE(exynos5_gpios_1);
2909
2910         for (i = 0; i < nr_chips; i++, chip++) {
2911                 if (!chip->config) {
2912                         chip->config = &exynos_gpio_cfg;
2913                         chip->group = group++;
2914                 }
2915                 exynos_gpiolib_attach_ofnode(chip,
2916                                 EXYNOS5_PA_GPIO1, i * 0x20);
2917         }
2918         samsung_gpiolib_add_4bit_chips(exynos5_gpios_1,
2919                                        nr_chips, gpio_base1);
2920
2921         /* gpio part2 */
2922         gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K);
2923         if (gpio_base2 == NULL) {
2924                 pr_err("unable to ioremap for gpio_base2\n");
2925                 goto err_ioremap2;
2926         }
2927
2928         chip = exynos5_gpios_2;
2929         nr_chips = ARRAY_SIZE(exynos5_gpios_2);
2930
2931         for (i = 0; i < nr_chips; i++, chip++) {
2932                 if (!chip->config) {
2933                         chip->config = &exynos_gpio_cfg;
2934                         chip->group = group++;
2935                 }
2936                 exynos_gpiolib_attach_ofnode(chip,
2937                                 EXYNOS5_PA_GPIO2, i * 0x20);
2938         }
2939         samsung_gpiolib_add_4bit_chips(exynos5_gpios_2,
2940                                        nr_chips, gpio_base2);
2941
2942         /* gpio part3 */
2943         gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K);
2944         if (gpio_base3 == NULL) {
2945                 pr_err("unable to ioremap for gpio_base3\n");
2946                 goto err_ioremap3;
2947         }
2948
2949         /* need to set base address for gpv */
2950         exynos5_gpios_3[0].base = gpio_base3;
2951         exynos5_gpios_3[1].base = gpio_base3 + 0x20;
2952         exynos5_gpios_3[2].base = gpio_base3 + 0x60;
2953         exynos5_gpios_3[3].base = gpio_base3 + 0x80;
2954         exynos5_gpios_3[4].base = gpio_base3 + 0xC0;
2955
2956         chip = exynos5_gpios_3;
2957         nr_chips = ARRAY_SIZE(exynos5_gpios_3);
2958
2959         for (i = 0; i < nr_chips; i++, chip++) {
2960                 if (!chip->config) {
2961                         chip->config = &exynos_gpio_cfg;
2962                         chip->group = group++;
2963                 }
2964                 exynos_gpiolib_attach_ofnode(chip,
2965                                 EXYNOS5_PA_GPIO3, i * 0x20);
2966         }
2967         samsung_gpiolib_add_4bit_chips(exynos5_gpios_3,
2968                                        nr_chips, gpio_base3);
2969
2970         /* gpio part4 */
2971         gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K);
2972         if (gpio_base4 == NULL) {
2973                 pr_err("unable to ioremap for gpio_base4\n");
2974                 goto err_ioremap4;
2975         }
2976
2977         chip = exynos5_gpios_4;
2978         nr_chips = ARRAY_SIZE(exynos5_gpios_4);
2979
2980         for (i = 0; i < nr_chips; i++, chip++) {
2981                 if (!chip->config) {
2982                         chip->config = &exynos_gpio_cfg;
2983                         chip->group = group++;
2984                 }
2985                 exynos_gpiolib_attach_ofnode(chip,
2986                                 EXYNOS5_PA_GPIO4, i * 0x20);
2987         }
2988         samsung_gpiolib_add_4bit_chips(exynos5_gpios_4,
2989                                        nr_chips, gpio_base4);
2990         return;
2991
2992 err_ioremap4:
2993         iounmap(gpio_base3);
2994 err_ioremap3:
2995         iounmap(gpio_base2);
2996 err_ioremap2:
2997         iounmap(gpio_base1);
2998 err_ioremap1:
2999         return;
3000
3001 #endif  /* CONFIG_SOC_EXYNOS5250 */
3002 }
3003
3004 /* TODO: cleanup soc_is_* */
3005 static __init int samsung_gpiolib_init(void)
3006 {
3007         struct samsung_gpio_chip *chip;
3008         int i, nr_chips;
3009         int group = 0;
3010
3011 #if defined(CONFIG_PINCTRL_EXYNOS) || defined(CONFIG_PINCTRL_EXYNOS5440)
3012         /*
3013         * This gpio driver includes support for device tree support and there
3014         * are platforms using it. In order to maintain compatibility with those
3015         * platforms, and to allow non-dt Exynos4210 platforms to use this
3016         * gpiolib support, a check is added to find out if there is a active
3017         * pin-controller driver support available. If it is available, this
3018         * gpiolib support is ignored and the gpiolib support available in
3019         * pin-controller driver is used. This is a temporary check and will go
3020         * away when all of the Exynos4210 platforms have switched to using
3021         * device tree and the pin-ctrl driver.
3022         */
3023         struct device_node *pctrl_np;
3024         static const struct of_device_id exynos_pinctrl_ids[] = {
3025                 { .compatible = "samsung,exynos4210-pinctrl", },
3026                 { .compatible = "samsung,exynos4x12-pinctrl", },
3027                 { .compatible = "samsung,exynos5440-pinctrl", },
3028         };
3029         for_each_matching_node(pctrl_np, exynos_pinctrl_ids)
3030                 if (pctrl_np && of_device_is_available(pctrl_np))
3031                         return -ENODEV;
3032 #endif
3033
3034         samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
3035
3036         if (soc_is_s3c24xx()) {
3037                 s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
3038                                 ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
3039         } else if (soc_is_s3c64xx()) {
3040                 samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
3041                                 ARRAY_SIZE(s3c64xx_gpios_2bit),
3042                                 S3C64XX_VA_GPIO + 0xE0, 0x20);
3043                 samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
3044                                 ARRAY_SIZE(s3c64xx_gpios_4bit),
3045                                 S3C64XX_VA_GPIO);
3046                 samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
3047                                 ARRAY_SIZE(s3c64xx_gpios_4bit2));
3048         } else if (soc_is_s5p6440()) {
3049                 samsung_gpiolib_add_2bit_chips(s5p6440_gpios_2bit,
3050                                 ARRAY_SIZE(s5p6440_gpios_2bit), NULL, 0x0);
3051                 samsung_gpiolib_add_4bit_chips(s5p6440_gpios_4bit,
3052                                 ARRAY_SIZE(s5p6440_gpios_4bit), S5P_VA_GPIO);
3053                 samsung_gpiolib_add_4bit2_chips(s5p6440_gpios_4bit2,
3054                                 ARRAY_SIZE(s5p6440_gpios_4bit2));
3055                 s5p64x0_gpiolib_add_rbank(s5p6440_gpios_rbank,
3056                                 ARRAY_SIZE(s5p6440_gpios_rbank));
3057         } else if (soc_is_s5p6450()) {
3058                 samsung_gpiolib_add_2bit_chips(s5p6450_gpios_2bit,
3059                                 ARRAY_SIZE(s5p6450_gpios_2bit), NULL, 0x0);
3060                 samsung_gpiolib_add_4bit_chips(s5p6450_gpios_4bit,
3061                                 ARRAY_SIZE(s5p6450_gpios_4bit), S5P_VA_GPIO);
3062                 samsung_gpiolib_add_4bit2_chips(s5p6450_gpios_4bit2,
3063                                 ARRAY_SIZE(s5p6450_gpios_4bit2));
3064                 s5p64x0_gpiolib_add_rbank(s5p6450_gpios_rbank,
3065                                 ARRAY_SIZE(s5p6450_gpios_rbank));
3066         } else if (soc_is_s5pc100()) {
3067                 group = 0;
3068                 chip = s5pc100_gpios_4bit;
3069                 nr_chips = ARRAY_SIZE(s5pc100_gpios_4bit);
3070
3071                 for (i = 0; i < nr_chips; i++, chip++) {
3072                         if (!chip->config) {
3073                                 chip->config = &samsung_gpio_cfgs[3];
3074                                 chip->group = group++;
3075                         }
3076                 }
3077                 samsung_gpiolib_add_4bit_chips(s5pc100_gpios_4bit, nr_chips, S5P_VA_GPIO);
3078 #if defined(CONFIG_CPU_S5PC100) && defined(CONFIG_S5P_GPIO_INT)
3079                 s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
3080 #endif
3081         } else if (soc_is_s5pv210()) {
3082                 group = 0;
3083                 chip = s5pv210_gpios_4bit;
3084                 nr_chips = ARRAY_SIZE(s5pv210_gpios_4bit);
3085
3086                 for (i = 0; i < nr_chips; i++, chip++) {
3087                         if (!chip->config) {
3088                                 chip->config = &samsung_gpio_cfgs[3];
3089                                 chip->group = group++;
3090                         }
3091                 }
3092                 samsung_gpiolib_add_4bit_chips(s5pv210_gpios_4bit, nr_chips, S5P_VA_GPIO);
3093 #if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_S5P_GPIO_INT)
3094                 s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
3095 #endif
3096         } else if (soc_is_exynos4210()) {
3097                 exynos4_gpiolib_init();
3098         } else if (soc_is_exynos5250()) {
3099                 exynos5_gpiolib_init();
3100         } else {
3101                 WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
3102                 return -ENODEV;
3103         }
3104
3105         return 0;
3106 }
3107 core_initcall(samsung_gpiolib_init);
3108
3109 int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
3110 {
3111         struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3112         unsigned long flags;
3113         int offset;
3114         int ret;
3115
3116         if (!chip)
3117                 return -EINVAL;
3118
3119         offset = pin - chip->chip.base;
3120
3121         samsung_gpio_lock(chip, flags);
3122         ret = samsung_gpio_do_setcfg(chip, offset, config);
3123         samsung_gpio_unlock(chip, flags);
3124
3125         return ret;
3126 }
3127 EXPORT_SYMBOL(s3c_gpio_cfgpin);
3128
3129 int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
3130                           unsigned int cfg)
3131 {
3132         int ret;
3133
3134         for (; nr > 0; nr--, start++) {
3135                 ret = s3c_gpio_cfgpin(start, cfg);
3136                 if (ret != 0)
3137                         return ret;
3138         }
3139
3140         return 0;
3141 }
3142 EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
3143
3144 int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
3145                           unsigned int cfg, samsung_gpio_pull_t pull)
3146 {
3147         int ret;
3148
3149         for (; nr > 0; nr--, start++) {
3150                 s3c_gpio_setpull(start, pull);
3151                 ret = s3c_gpio_cfgpin(start, cfg);
3152                 if (ret != 0)
3153                         return ret;
3154         }
3155
3156         return 0;
3157 }
3158 EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
3159
3160 unsigned s3c_gpio_getcfg(unsigned int pin)
3161 {
3162         struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3163         unsigned long flags;
3164         unsigned ret = 0;
3165         int offset;
3166
3167         if (chip) {
3168                 offset = pin - chip->chip.base;
3169
3170                 samsung_gpio_lock(chip, flags);
3171                 ret = samsung_gpio_do_getcfg(chip, offset);
3172                 samsung_gpio_unlock(chip, flags);
3173         }
3174
3175         return ret;
3176 }
3177 EXPORT_SYMBOL(s3c_gpio_getcfg);
3178
3179 int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
3180 {
3181         struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3182         unsigned long flags;
3183         int offset, ret;
3184
3185         if (!chip)
3186                 return -EINVAL;
3187
3188         offset = pin - chip->chip.base;
3189
3190         samsung_gpio_lock(chip, flags);
3191         ret = samsung_gpio_do_setpull(chip, offset, pull);
3192         samsung_gpio_unlock(chip, flags);
3193
3194         return ret;
3195 }
3196 EXPORT_SYMBOL(s3c_gpio_setpull);
3197
3198 samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
3199 {
3200         struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3201         unsigned long flags;
3202         int offset;
3203         u32 pup = 0;
3204
3205         if (chip) {
3206                 offset = pin - chip->chip.base;
3207
3208                 samsung_gpio_lock(chip, flags);
3209                 pup = samsung_gpio_do_getpull(chip, offset);
3210                 samsung_gpio_unlock(chip, flags);
3211         }
3212
3213         return (__force samsung_gpio_pull_t)pup;
3214 }
3215 EXPORT_SYMBOL(s3c_gpio_getpull);
3216
3217 #ifdef CONFIG_S5P_GPIO_DRVSTR
3218 s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
3219 {
3220         struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3221         unsigned int off;
3222         void __iomem *reg;
3223         int shift;
3224         u32 drvstr;
3225
3226         if (!chip)
3227                 return -EINVAL;
3228
3229         off = pin - chip->chip.base;
3230         shift = off * 2;
3231         reg = chip->base + 0x0C;
3232
3233         drvstr = __raw_readl(reg);
3234         drvstr = drvstr >> shift;
3235         drvstr &= 0x3;
3236
3237         return (__force s5p_gpio_drvstr_t)drvstr;
3238 }
3239 EXPORT_SYMBOL(s5p_gpio_get_drvstr);
3240
3241 int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
3242 {
3243         struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
3244         unsigned int off;
3245         void __iomem *reg;
3246         int shift;
3247         u32 tmp;
3248
3249         if (!chip)
3250                 return -EINVAL;
3251
3252         off = pin - chip->chip.base;
3253         shift = off * 2;
3254         reg = chip->base + 0x0C;
3255
3256         tmp = __raw_readl(reg);
3257         tmp &= ~(0x3 << shift);
3258         tmp |= drvstr << shift;
3259
3260         __raw_writel(tmp, reg);
3261
3262         return 0;
3263 }
3264 EXPORT_SYMBOL(s5p_gpio_set_drvstr);
3265 #endif  /* CONFIG_S5P_GPIO_DRVSTR */
3266
3267 #ifdef CONFIG_PLAT_S3C24XX
3268 unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
3269 {
3270         unsigned long flags;
3271         unsigned long misccr;
3272
3273         local_irq_save(flags);
3274         misccr = __raw_readl(S3C24XX_MISCCR);
3275         misccr &= ~clear;
3276         misccr ^= change;
3277         __raw_writel(misccr, S3C24XX_MISCCR);
3278         local_irq_restore(flags);
3279
3280         return misccr;
3281 }
3282 EXPORT_SYMBOL(s3c2410_modify_misccr);
3283 #endif