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