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