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