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