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