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