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