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