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