aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2010-05-19 05:04:08 -0400
committerBen Dooks <ben-linux@fluff.org>2010-05-19 05:04:08 -0400
commitff1b8ba01dc80da338890a187c112fdd3c0b9202 (patch)
tree415999aa2c3ac52e48c2b6f690bba393e3d7a00c /arch
parent5fcdb16bd04fdeb313ee33bb269b04e59a9abf91 (diff)
parent32b6cb3872883861f3a2669cce880f3a7ef8979a (diff)
ARM: Merge for-2635/gpio2
Merge branch 'for-2635/gpio2' into for-linus/samsung2
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-s3c2410/Kconfig1
-rw-r--r--arch/arm/mach-s3c2410/h1940-bluetooth.c32
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-fns.h47
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-nrs.h37
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-track.h4
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio.h8
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-gpio.h39
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-gpioj.h36
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c5
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c9
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c20
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c3
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c10
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c5
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c8
-rw-r--r--arch/arm/mach-s3c2412/gpio.c20
-rw-r--r--arch/arm/mach-s3c2412/mach-jive.c26
-rw-r--r--arch/arm/mach-s3c2412/mach-smdk2413.c8
-rw-r--r--arch/arm/mach-s3c2440/Kconfig1
-rw-r--r--arch/arm/mach-s3c2440/mach-mini2440.c23
-rw-r--r--arch/arm/mach-s3c2440/mach-nexcoder.c9
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c5
-rw-r--r--arch/arm/mach-s3c2440/s3c2440.c8
-rw-r--r--arch/arm/mach-s3c64xx/gpiolib.c6
-rw-r--r--arch/arm/mach-s5p6440/gpio.c5
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig1
-rw-r--r--arch/arm/plat-s3c24xx/common-smdk.c9
-rw-r--r--arch/arm/plat-s3c24xx/gpio.c150
-rw-r--r--arch/arm/plat-s3c24xx/gpiolib.c60
-rw-r--r--arch/arm/plat-s3c24xx/pm.c9
-rw-r--r--arch/arm/plat-s3c24xx/setup-i2c.c5
-rw-r--r--arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c16
-rw-r--r--arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c16
-rw-r--r--arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c16
-rw-r--r--arch/arm/plat-samsung/gpio-config.c111
-rw-r--r--arch/arm/plat-samsung/gpio.c15
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h58
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg.h11
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h17
-rw-r--r--arch/arm/plat-samsung/pm-gpio.c4
40 files changed, 531 insertions, 342 deletions
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 163b60e2af96..a4c0b3fcdbba 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -6,6 +6,7 @@ config CPU_S3C2410
6 bool 6 bool
7 depends on ARCH_S3C2410 7 depends on ARCH_S3C2410
8 select CPU_ARM920T 8 select CPU_ARM920T
9 select S3C_GPIO_PULL_UP
9 select S3C2410_CLOCK 10 select S3C2410_CLOCK
10 select S3C2410_GPIO 11 select S3C2410_GPIO
11 select CPU_LLSERIAL_S3C2410 12 select CPU_LLSERIAL_S3C2410
diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c
index a3f3c7b1ca38..8cdeb14af592 100644
--- a/arch/arm/mach-s3c2410/h1940-bluetooth.c
+++ b/arch/arm/mach-s3c2410/h1940-bluetooth.c
@@ -33,14 +33,15 @@ static void h1940bt_enable(int on)
33 h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER); 33 h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER);
34 /* Reset the chip */ 34 /* Reset the chip */
35 mdelay(10); 35 mdelay(10);
36 s3c2410_gpio_setpin(S3C2410_GPH(1), 1); 36
37 gpio_set_value(S3C2410_GPH(1), 1);
37 mdelay(10); 38 mdelay(10);
38 s3c2410_gpio_setpin(S3C2410_GPH(1), 0); 39 gpio_set_value(S3C2410_GPH(1), 0);
39 } 40 }
40 else { 41 else {
41 s3c2410_gpio_setpin(S3C2410_GPH(1), 1); 42 gpio_set_value(S3C2410_GPH(1), 1);
42 mdelay(10); 43 mdelay(10);
43 s3c2410_gpio_setpin(S3C2410_GPH(1), 0); 44 gpio_set_value(S3C2410_GPH(1), 0);
44 mdelay(10); 45 mdelay(10);
45 h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0); 46 h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0);
46 } 47 }
@@ -61,15 +62,21 @@ static int __devinit h1940bt_probe(struct platform_device *pdev)
61 struct rfkill *rfk; 62 struct rfkill *rfk;
62 int ret = 0; 63 int ret = 0;
63 64
65 ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev));
66 if (ret) {
67 dev_err(&pdev->dev, "could not get GPH1\n");\
68 return ret;
69 }
70
64 /* Configures BT serial port GPIOs */ 71 /* Configures BT serial port GPIOs */
65 s3c2410_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); 72 s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
66 s3c2410_gpio_pullup(S3C2410_GPH(0), 1); 73 s3c_gpio_cfgpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE);
67 s3c2410_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT); 74 s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
68 s3c2410_gpio_pullup(S3C2410_GPH(1), 1); 75 s3c_gpio_cfgpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE);
69 s3c2410_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0); 76 s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
70 s3c2410_gpio_pullup(S3C2410_GPH(2), 1); 77 s3c_gpio_cfgpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE);
71 s3c2410_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); 78 s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
72 s3c2410_gpio_pullup(S3C2410_GPH(3), 1); 79 s3c_gpio_cfgpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE);
73 80
74 81
75 rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH, 82 rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH,
@@ -100,6 +107,7 @@ static int h1940bt_remove(struct platform_device *pdev)
100 struct rfkill *rfk = platform_get_drvdata(pdev); 107 struct rfkill *rfk = platform_get_drvdata(pdev);
101 108
102 platform_set_drvdata(pdev, NULL); 109 platform_set_drvdata(pdev, NULL);
110 gpio_free(S3C2410_GPH(1));
103 111
104 if (rfk) { 112 if (rfk) {
105 rfkill_unregister(rfk); 113 rfkill_unregister(rfk);
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
index 035a493952db..f453c4f2cb8e 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
@@ -10,14 +10,28 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11*/ 11*/
12 12
13#ifndef __MACH_GPIO_FNS_H
14#define __MACH_GPIO_FNS_H __FILE__
15
13/* These functions are in the to-be-removed category and it is strongly 16/* These functions are in the to-be-removed category and it is strongly
14 * encouraged not to use these in new code. They will be marked deprecated 17 * encouraged not to use these in new code. They will be marked deprecated
15 * very soon. 18 * very soon.
16 * 19 *
17 * Most of the functionality can be either replaced by the gpiocfg calls 20 * Most of the functionality can be either replaced by the gpiocfg calls
18 * for the s3c platform or by the generic GPIOlib API. 21 * for the s3c platform or by the generic GPIOlib API.
22 *
23 * As of 2.6.35-rc, these will be removed, with the few drivers using them
24 * either replaced or given a wrapper until the calls can be removed.
19*/ 25*/
20 26
27#include <plat/gpio-cfg.h>
28
29static inline void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg)
30{
31 /* 1:1 mapping between cfgpin and setcfg calls at the moment */
32 s3c_gpio_cfgpin(pin, cfg);
33}
34
21/* external functions for GPIO support 35/* external functions for GPIO support
22 * 36 *
23 * These allow various different clients to access the same GPIO 37 * These allow various different clients to access the same GPIO
@@ -25,17 +39,6 @@
25 * GPIO register, then it is safe to ioremap/__raw_{read|write} to it. 39 * GPIO register, then it is safe to ioremap/__raw_{read|write} to it.
26*/ 40*/
27 41
28/* s3c2410_gpio_cfgpin
29 *
30 * set the configuration of the given pin to the value passed.
31 *
32 * eg:
33 * s3c2410_gpio_cfgpin(S3C2410_GPA(0), S3C2410_GPA0_ADDR0);
34 * s3c2410_gpio_cfgpin(S3C2410_GPE(8), S3C2410_GPE8_SDDAT1);
35*/
36
37extern void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);
38
39extern unsigned int s3c2410_gpio_getcfg(unsigned int pin); 42extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
40 43
41/* s3c2410_gpio_getirq 44/* s3c2410_gpio_getirq
@@ -73,6 +76,14 @@ extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
73 76
74/* s3c2410_gpio_pullup 77/* s3c2410_gpio_pullup
75 * 78 *
79 * This call should be replaced with s3c_gpio_setpull().
80 *
81 * As a note, there is currently no distinction between pull-up and pull-down
82 * in the s3c24xx series devices with only an on/off configuration.
83 */
84
85/* s3c2410_gpio_pullup
86 *
76 * configure the pull-up control on the given pin 87 * configure the pull-up control on the given pin
77 * 88 *
78 * to = 1 => disable the pull-up 89 * to = 1 => disable the pull-up
@@ -86,18 +97,8 @@ extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
86 97
87extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to); 98extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
88 99
89/* s3c2410_gpio_getpull
90 *
91 * Read the state of the pull-up on a given pin
92 *
93 * return:
94 * < 0 => error code
95 * 0 => enabled
96 * 1 => disabled
97*/
98
99extern int s3c2410_gpio_getpull(unsigned int pin);
100
101extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to); 100extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
102 101
103extern unsigned int s3c2410_gpio_getpin(unsigned int pin); 102extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
103
104#endif /* __MACH_GPIO_FNS_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
index 2edbb9c88ab3..4f7bf3272e87 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
@@ -16,15 +16,28 @@
16 16
17#define S3C2410_GPIONO(bank,offset) ((bank) + (offset)) 17#define S3C2410_GPIONO(bank,offset) ((bank) + (offset))
18 18
19#define S3C2410_GPIO_BANKA (32*0)
20#define S3C2410_GPIO_BANKB (32*1)
21#define S3C2410_GPIO_BANKC (32*2)
22#define S3C2410_GPIO_BANKD (32*3)
23#define S3C2410_GPIO_BANKE (32*4)
24#define S3C2410_GPIO_BANKF (32*5)
25#define S3C2410_GPIO_BANKG (32*6) 19#define S3C2410_GPIO_BANKG (32*6)
26#define S3C2410_GPIO_BANKH (32*7) 20#define S3C2410_GPIO_BANKH (32*7)
27 21
22/* GPIO sizes for various SoCs:
23 *
24 * 2442
25 * 2410 2412 2440 2443 2416
26 * ---- ---- ---- ---- ----
27 * A 23 22 25 16 25
28 * B 11 11 11 11 9
29 * C 16 15 16 16 16
30 * D 16 16 16 16 16
31 * E 16 16 16 16 16
32 * F 8 8 8 8 8
33 * G 16 16 16 16 8
34 * H 11 11 9 15 15
35 * J -- -- 13 16 --
36 * K -- -- -- -- 16
37 * L -- -- -- 15 7
38 * M -- -- -- 2 2
39 */
40
28/* GPIO bank sizes */ 41/* GPIO bank sizes */
29#define S3C2410_GPIO_A_NR (32) 42#define S3C2410_GPIO_A_NR (32)
30#define S3C2410_GPIO_B_NR (32) 43#define S3C2410_GPIO_B_NR (32)
@@ -34,6 +47,10 @@
34#define S3C2410_GPIO_F_NR (32) 47#define S3C2410_GPIO_F_NR (32)
35#define S3C2410_GPIO_G_NR (32) 48#define S3C2410_GPIO_G_NR (32)
36#define S3C2410_GPIO_H_NR (32) 49#define S3C2410_GPIO_H_NR (32)
50#define S3C2410_GPIO_J_NR (32) /* technically 16. */
51#define S3C2410_GPIO_K_NR (32) /* technically 16. */
52#define S3C2410_GPIO_L_NR (32) /* technically 15. */
53#define S3C2410_GPIO_M_NR (32) /* technically 2. */
37 54
38#if CONFIG_S3C_GPIO_SPACE != 0 55#if CONFIG_S3C_GPIO_SPACE != 0
39#error CONFIG_S3C_GPIO_SPACE cannot be zero at the moment 56#error CONFIG_S3C_GPIO_SPACE cannot be zero at the moment
@@ -53,6 +70,10 @@ enum s3c_gpio_number {
53 S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E), 70 S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E),
54 S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F), 71 S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F),
55 S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G), 72 S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G),
73 S3C2410_GPIO_J_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_H),
74 S3C2410_GPIO_K_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_J),
75 S3C2410_GPIO_L_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_K),
76 S3C2410_GPIO_M_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_L),
56}; 77};
57 78
58#endif /* __ASSEMBLY__ */ 79#endif /* __ASSEMBLY__ */
@@ -67,6 +88,10 @@ enum s3c_gpio_number {
67#define S3C2410_GPF(_nr) (S3C2410_GPIO_F_START + (_nr)) 88#define S3C2410_GPF(_nr) (S3C2410_GPIO_F_START + (_nr))
68#define S3C2410_GPG(_nr) (S3C2410_GPIO_G_START + (_nr)) 89#define S3C2410_GPG(_nr) (S3C2410_GPIO_G_START + (_nr))
69#define S3C2410_GPH(_nr) (S3C2410_GPIO_H_START + (_nr)) 90#define S3C2410_GPH(_nr) (S3C2410_GPIO_H_START + (_nr))
91#define S3C2410_GPJ(_nr) (S3C2410_GPIO_J_START + (_nr))
92#define S3C2410_GPK(_nr) (S3C2410_GPIO_K_START + (_nr))
93#define S3C2410_GPL(_nr) (S3C2410_GPIO_L_START + (_nr))
94#define S3C2410_GPM(_nr) (S3C2410_GPIO_M_START + (_nr))
70 95
71/* compatibility until drivers can be modified */ 96/* compatibility until drivers can be modified */
72 97
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-track.h b/arch/arm/mach-s3c2410/include/mach/gpio-track.h
index acb259103808..d67819dde42a 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio-track.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-track.h
@@ -23,11 +23,11 @@ static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
23{ 23{
24 struct s3c_gpio_chip *chip; 24 struct s3c_gpio_chip *chip;
25 25
26 if (pin > S3C2410_GPG(10)) 26 if (pin > S3C_GPIO_END)
27 return NULL; 27 return NULL;
28 28
29 chip = &s3c24xx_gpios[pin/32]; 29 chip = &s3c24xx_gpios[pin/32];
30 return (S3C2410_GPIO_OFFSET(pin) < chip->chip.ngpio) ? chip : NULL; 30 return ((pin - chip->chip.base) < chip->chip.ngpio) ? chip : NULL;
31} 31}
32 32
33#endif /* __ASM_ARCH_GPIO_CORE_H */ 33#endif /* __ASM_ARCH_GPIO_CORE_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio.h b/arch/arm/mach-s3c2410/include/mach/gpio.h
index 15f0b3e7ce69..b649bf2ccd5c 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio.h
@@ -20,10 +20,18 @@
20 * devices that need GPIO. 20 * devices that need GPIO.
21 */ 21 */
22 22
23#ifdef CONFIG_CPU_S3C244X
24#define ARCH_NR_GPIOS (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
25#else
23#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA) 26#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA)
27#endif
24 28
25#include <asm-generic/gpio.h> 29#include <asm-generic/gpio.h>
26#include <mach/gpio-nrs.h> 30#include <mach/gpio-nrs.h>
27#include <mach/gpio-fns.h> 31#include <mach/gpio-fns.h>
28 32
33#ifdef CONFIG_CPU_S3C24XX
34#define S3C_GPIO_END (S3C2410_GPIO_BANKJ + 32)
35#else
29#define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32) 36#define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32)
37#endif
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
index fd672f330bf2..95e29fefec34 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
@@ -17,29 +17,11 @@
17#include <mach/gpio-nrs.h> 17#include <mach/gpio-nrs.h>
18 18
19#ifdef CONFIG_CPU_S3C2400 19#ifdef CONFIG_CPU_S3C2400
20#define S3C24XX_GPIO_BASE(x) S3C2400_GPIO_BASE(x) 20#define S3C24XX_MISCCR S3C2400_MISCCR
21#define S3C24XX_MISCCR S3C2400_MISCCR
22#else 21#else
23#define S3C24XX_GPIO_BASE(x) S3C2410_GPIO_BASE(x) 22#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80)
24#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80)
25#endif /* CONFIG_CPU_S3C2400 */ 23#endif /* CONFIG_CPU_S3C2400 */
26 24
27
28/* S3C2400 doesn't have a 1:1 mapping to S3C2410 gpio base pins */
29
30#define S3C2400_BANKNUM(pin) (((pin) & ~31) / 32)
31#define S3C2400_BASEA2B(pin) ((((pin) & ~31) >> 2))
32#define S3C2400_BASEC2H(pin) ((S3C2400_BANKNUM(pin) * 10) + \
33 (2 * (S3C2400_BANKNUM(pin)-2)))
34
35#define S3C2400_GPIO_BASE(pin) (pin < S3C2410_GPIO_BANKC ? \
36 S3C2400_BASEA2B(pin)+S3C24XX_VA_GPIO : \
37 S3C2400_BASEC2H(pin)+S3C24XX_VA_GPIO)
38
39
40#define S3C2410_GPIO_BASE(pin) ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO)
41#define S3C2410_GPIO_OFFSET(pin) ((pin) & 31)
42
43/* general configuration options */ 25/* general configuration options */
44 26
45#define S3C2410_GPIO_LEAVE (0xFFFFFFFF) 27#define S3C2410_GPIO_LEAVE (0xFFFFFFFF)
@@ -639,6 +621,23 @@
639 * for the 2412/2413 from the 2410/2440/2442 621 * for the 2412/2413 from the 2410/2440/2442
640*/ 622*/
641 623
624/* S3C2443 and above */
625#define S3C2440_GPJCON S3C2410_GPIOREG(0xD0)
626#define S3C2440_GPJDAT S3C2410_GPIOREG(0xD4)
627#define S3C2440_GPJUP S3C2410_GPIOREG(0xD8)
628
629#define S3C2443_GPKCON S3C2410_GPIOREG(0xE0)
630#define S3C2443_GPKDAT S3C2410_GPIOREG(0xE4)
631#define S3C2443_GPKUP S3C2410_GPIOREG(0xE8)
632
633#define S3C2443_GPLCON S3C2410_GPIOREG(0xF0)
634#define S3C2443_GPLDAT S3C2410_GPIOREG(0xF4)
635#define S3C2443_GPLUP S3C2410_GPIOREG(0xF8)
636
637#define S3C2443_GPMCON S3C2410_GPIOREG(0x100)
638#define S3C2443_GPMDAT S3C2410_GPIOREG(0x104)
639#define S3C2443_GPMUP S3C2410_GPIOREG(0x108)
640
642/* miscellaneous control */ 641/* miscellaneous control */
643#define S3C2400_MISCCR S3C2410_GPIOREG(0x54) 642#define S3C2400_MISCCR S3C2410_GPIOREG(0x54)
644#define S3C2410_MISCCR S3C2410_GPIOREG(0x80) 643#define S3C2410_MISCCR S3C2410_GPIOREG(0x80)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
index 1202ca5e99f6..19575e061114 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
@@ -22,85 +22,49 @@
22 * pull up works like all other ports. 22 * pull up works like all other ports.
23*/ 23*/
24 24
25#define S3C2440_GPIO_BANKJ (416)
26
27#define S3C2440_GPJCON S3C2410_GPIOREG(0xd0)
28#define S3C2440_GPJDAT S3C2410_GPIOREG(0xd4)
29#define S3C2440_GPJUP S3C2410_GPIOREG(0xd8)
30
31#define S3C2413_GPJCON S3C2410_GPIOREG(0x80) 25#define S3C2413_GPJCON S3C2410_GPIOREG(0x80)
32#define S3C2413_GPJDAT S3C2410_GPIOREG(0x84) 26#define S3C2413_GPJDAT S3C2410_GPIOREG(0x84)
33#define S3C2413_GPJUP S3C2410_GPIOREG(0x88) 27#define S3C2413_GPJUP S3C2410_GPIOREG(0x88)
34#define S3C2413_GPJSLPCON S3C2410_GPIOREG(0x8C) 28#define S3C2413_GPJSLPCON S3C2410_GPIOREG(0x8C)
35 29
36#define S3C2440_GPJ0 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 0)
37#define S3C2440_GPJ0_INP (0x00 << 0)
38#define S3C2440_GPJ0_OUTP (0x01 << 0) 30#define S3C2440_GPJ0_OUTP (0x01 << 0)
39#define S3C2440_GPJ0_CAMDATA0 (0x02 << 0) 31#define S3C2440_GPJ0_CAMDATA0 (0x02 << 0)
40 32
41#define S3C2440_GPJ1 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 1)
42#define S3C2440_GPJ1_INP (0x00 << 2)
43#define S3C2440_GPJ1_OUTP (0x01 << 2) 33#define S3C2440_GPJ1_OUTP (0x01 << 2)
44#define S3C2440_GPJ1_CAMDATA1 (0x02 << 2) 34#define S3C2440_GPJ1_CAMDATA1 (0x02 << 2)
45 35
46#define S3C2440_GPJ2 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 2)
47#define S3C2440_GPJ2_INP (0x00 << 4)
48#define S3C2440_GPJ2_OUTP (0x01 << 4) 36#define S3C2440_GPJ2_OUTP (0x01 << 4)
49#define S3C2440_GPJ2_CAMDATA2 (0x02 << 4) 37#define S3C2440_GPJ2_CAMDATA2 (0x02 << 4)
50 38
51#define S3C2440_GPJ3 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 3)
52#define S3C2440_GPJ3_INP (0x00 << 6)
53#define S3C2440_GPJ3_OUTP (0x01 << 6) 39#define S3C2440_GPJ3_OUTP (0x01 << 6)
54#define S3C2440_GPJ3_CAMDATA3 (0x02 << 6) 40#define S3C2440_GPJ3_CAMDATA3 (0x02 << 6)
55 41
56#define S3C2440_GPJ4 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 4)
57#define S3C2440_GPJ4_INP (0x00 << 8)
58#define S3C2440_GPJ4_OUTP (0x01 << 8) 42#define S3C2440_GPJ4_OUTP (0x01 << 8)
59#define S3C2440_GPJ4_CAMDATA4 (0x02 << 8) 43#define S3C2440_GPJ4_CAMDATA4 (0x02 << 8)
60 44
61#define S3C2440_GPJ5 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 5)
62#define S3C2440_GPJ5_INP (0x00 << 10)
63#define S3C2440_GPJ5_OUTP (0x01 << 10) 45#define S3C2440_GPJ5_OUTP (0x01 << 10)
64#define S3C2440_GPJ5_CAMDATA5 (0x02 << 10) 46#define S3C2440_GPJ5_CAMDATA5 (0x02 << 10)
65 47
66#define S3C2440_GPJ6 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 6)
67#define S3C2440_GPJ6_INP (0x00 << 12)
68#define S3C2440_GPJ6_OUTP (0x01 << 12) 48#define S3C2440_GPJ6_OUTP (0x01 << 12)
69#define S3C2440_GPJ6_CAMDATA6 (0x02 << 12) 49#define S3C2440_GPJ6_CAMDATA6 (0x02 << 12)
70 50
71#define S3C2440_GPJ7 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 7)
72#define S3C2440_GPJ7_INP (0x00 << 14)
73#define S3C2440_GPJ7_OUTP (0x01 << 14) 51#define S3C2440_GPJ7_OUTP (0x01 << 14)
74#define S3C2440_GPJ7_CAMDATA7 (0x02 << 14) 52#define S3C2440_GPJ7_CAMDATA7 (0x02 << 14)
75 53
76#define S3C2440_GPJ8 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 8)
77#define S3C2440_GPJ8_INP (0x00 << 16)
78#define S3C2440_GPJ8_OUTP (0x01 << 16) 54#define S3C2440_GPJ8_OUTP (0x01 << 16)
79#define S3C2440_GPJ8_CAMPCLK (0x02 << 16) 55#define S3C2440_GPJ8_CAMPCLK (0x02 << 16)
80 56
81#define S3C2440_GPJ9 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 9)
82#define S3C2440_GPJ9_INP (0x00 << 18)
83#define S3C2440_GPJ9_OUTP (0x01 << 18) 57#define S3C2440_GPJ9_OUTP (0x01 << 18)
84#define S3C2440_GPJ9_CAMVSYNC (0x02 << 18) 58#define S3C2440_GPJ9_CAMVSYNC (0x02 << 18)
85 59
86#define S3C2440_GPJ10 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 10)
87#define S3C2440_GPJ10_INP (0x00 << 20)
88#define S3C2440_GPJ10_OUTP (0x01 << 20) 60#define S3C2440_GPJ10_OUTP (0x01 << 20)
89#define S3C2440_GPJ10_CAMHREF (0x02 << 20) 61#define S3C2440_GPJ10_CAMHREF (0x02 << 20)
90 62
91#define S3C2440_GPJ11 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 11)
92#define S3C2440_GPJ11_INP (0x00 << 22)
93#define S3C2440_GPJ11_OUTP (0x01 << 22) 63#define S3C2440_GPJ11_OUTP (0x01 << 22)
94#define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22) 64#define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22)
95 65
96#define S3C2440_GPJ12 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 12)
97#define S3C2440_GPJ12_INP (0x00 << 24)
98#define S3C2440_GPJ12_OUTP (0x01 << 24) 66#define S3C2440_GPJ12_OUTP (0x01 << 24)
99#define S3C2440_GPJ12_CAMRESET (0x02 << 24) 67#define S3C2440_GPJ12_CAMRESET (0x02 << 24)
100 68
101#define S3C2443_GPJ13 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 13)
102#define S3C2443_GPJ14 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 14)
103#define S3C2443_GPJ15 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 15)
104
105#endif /* __ASM_ARCH_REGS_GPIOJ_H */ 69#endif /* __ASM_ARCH_REGS_GPIOJ_H */
106 70
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index 7047317ed7f4..34fc05a4244b 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -56,6 +56,7 @@
56#include <plat/iic.h> 56#include <plat/iic.h>
57#include <plat/devs.h> 57#include <plat/devs.h>
58#include <plat/cpu.h> 58#include <plat/cpu.h>
59#include <plat/gpio-cfg.h>
59 60
60#ifdef CONFIG_MTD_PARTITIONS 61#ifdef CONFIG_MTD_PARTITIONS
61 62
@@ -225,8 +226,8 @@ static void amlm5900_init_pm(void)
225 } else { 226 } else {
226 enable_irq_wake(IRQ_EINT9); 227 enable_irq_wake(IRQ_EINT9);
227 /* configure the suspend/resume status pin */ 228 /* configure the suspend/resume status pin */
228 s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); 229 s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
229 s3c2410_gpio_pullup(S3C2410_GPF(2), 0); 230 s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_UP);
230 } 231 }
231} 232}
232static void __init amlm5900_init(void) 233static void __init amlm5900_init(void)
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index c8786df72b9e..c1f90f6fab42 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -61,6 +61,7 @@
61#include <plat/devs.h> 61#include <plat/devs.h>
62#include <plat/cpu.h> 62#include <plat/cpu.h>
63#include <plat/cpu-freq.h> 63#include <plat/cpu-freq.h>
64#include <plat/gpio-cfg.h>
64#include <plat/audio-simtec.h> 65#include <plat/audio-simtec.h>
65 66
66#include "usb-simtec.h" 67#include "usb-simtec.h"
@@ -216,15 +217,13 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
216static int bast_pm_suspend(struct sys_device *sd, pm_message_t state) 217static int bast_pm_suspend(struct sys_device *sd, pm_message_t state)
217{ 218{
218 /* ensure that an nRESET is not generated on resume. */ 219 /* ensure that an nRESET is not generated on resume. */
219 s3c2410_gpio_setpin(S3C2410_GPA(21), 1); 220 gpio_direction_output(S3C2410_GPA(21), 1);
220 s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
221
222 return 0; 221 return 0;
223} 222}
224 223
225static int bast_pm_resume(struct sys_device *sd) 224static int bast_pm_resume(struct sys_device *sd)
226{ 225{
227 s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT); 226 s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
228 return 0; 227 return 0;
229} 228}
230 229
@@ -658,6 +657,8 @@ static void __init bast_init(void)
658 nor_simtec_init(); 657 nor_simtec_init();
659 simtec_audio_add(NULL, true, &bast_audio); 658 simtec_audio_add(NULL, true, &bast_audio);
660 659
660 WARN_ON(gpio_request(S3C2410_GPA(21), "bast nreset"));
661
661 s3c_cpufreq_setboard(&bast_cpufreq); 662 s3c_cpufreq_setboard(&bast_cpufreq);
662} 663}
663 664
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 03028b98f362..d2a2fad7db97 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -50,6 +50,7 @@
50#include <plat/udc.h> 50#include <plat/udc.h>
51#include <plat/iic.h> 51#include <plat/iic.h>
52 52
53#include <plat/gpio-cfg.h>
53#include <plat/clock.h> 54#include <plat/clock.h>
54#include <plat/devs.h> 55#include <plat/devs.h>
55#include <plat/cpu.h> 56#include <plat/cpu.h>
@@ -207,16 +208,16 @@ static int h1940_backlight_init(struct device *dev)
207{ 208{
208 gpio_request(S3C2410_GPB(0), "Backlight"); 209 gpio_request(S3C2410_GPB(0), "Backlight");
209 210
210 s3c2410_gpio_setpin(S3C2410_GPB(0), 0); 211 gpio_direction_output(S3C2410_GPB(0), 0);
211 s3c2410_gpio_pullup(S3C2410_GPB(0), 0); 212 s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
212 s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0); 213 s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
213 214
214 return 0; 215 return 0;
215} 216}
216 217
217static void h1940_backlight_exit(struct device *dev) 218static void h1940_backlight_exit(struct device *dev)
218{ 219{
219 s3c2410_gpio_cfgpin(S3C2410_GPB(0), 1/*S3C2410_GPB0_OUTP*/); 220 gpio_direction_output(S3C2410_GPB(0), 1);
220} 221}
221 222
222static struct platform_pwm_backlight_data backlight_data = { 223static struct platform_pwm_backlight_data backlight_data = {
@@ -245,18 +246,18 @@ static void h1940_lcd_power_set(struct plat_lcd_data *pd,
245 246
246 if (!power) { 247 if (!power) {
247 /* set to 3ec */ 248 /* set to 3ec */
248 s3c2410_gpio_setpin(S3C2410_GPC(0), 0); 249 gpio_direction_output(S3C2410_GPC(0), 0);
249 /* wait for 3ac */ 250 /* wait for 3ac */
250 do { 251 do {
251 value = s3c2410_gpio_getpin(S3C2410_GPC(6)); 252 value = gpio_get_value(S3C2410_GPC(6));
252 } while (value); 253 } while (value);
253 /* set to 38c */ 254 /* set to 38c */
254 s3c2410_gpio_setpin(S3C2410_GPC(5), 0); 255 gpio_direction_output(S3C2410_GPC(5), 0);
255 } else { 256 } else {
256 /* Set to 3ac */ 257 /* Set to 3ac */
257 s3c2410_gpio_setpin(S3C2410_GPC(5), 1); 258 gpio_direction_output(S3C2410_GPC(5), 1);
258 /* Set to 3ad */ 259 /* Set to 3ad */
259 s3c2410_gpio_setpin(S3C2410_GPC(0), 1); 260 gpio_direction_output(S3C2410_GPC(0), 1);
260 } 261 }
261} 262}
262 263
@@ -333,6 +334,7 @@ static void __init h1940_init(void)
333 gpio_request(S3C2410_GPC(5), "LCD power"); 334 gpio_request(S3C2410_GPC(5), "LCD power");
334 gpio_request(S3C2410_GPC(6), "LCD power"); 335 gpio_request(S3C2410_GPC(6), "LCD power");
335 336
337 gpio_direction_input(S3C2410_GPC(6));
336 338
337 platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices)); 339 platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
338} 340}
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 9e2565ad973d..41f299d983eb 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -596,6 +596,9 @@ static void __init n30_init(void)
596 596
597 platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices)); 597 platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices));
598 } 598 }
599
600 WARN_ON(gpio_request(S3C2410_GPB(3), "udc pup"));
601 gpio_direction_output(S3C2410_GPB(3), 0);
599} 602}
600 603
601MACHINE_START(N30, "Acer-N30") 604MACHINE_START(N30, "Acer-N30")
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index 92a4ec375d82..d0e87b6e2e0f 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -58,6 +58,7 @@
58#include <plat/iic.h> 58#include <plat/iic.h>
59 59
60#include <plat/common-smdk.h> 60#include <plat/common-smdk.h>
61#include <plat/gpio-cfg.h>
61#include <plat/devs.h> 62#include <plat/devs.h>
62#include <plat/cpu.h> 63#include <plat/cpu.h>
63#include <plat/pm.h> 64#include <plat/pm.h>
@@ -219,10 +220,10 @@ static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int cs)
219{ 220{
220 switch (cs) { 221 switch (cs) {
221 case BITBANG_CS_ACTIVE: 222 case BITBANG_CS_ACTIVE:
222 s3c2410_gpio_setpin(S3C2410_GPB(5), 0); 223 gpio_set_value(S3C2410_GPB(5), 0);
223 break; 224 break;
224 case BITBANG_CS_INACTIVE: 225 case BITBANG_CS_INACTIVE:
225 s3c2410_gpio_setpin(S3C2410_GPB(5), 1); 226 gpio_set_value(S3C2410_GPB(5), 1);
226 break; 227 break;
227 } 228 }
228} 229}
@@ -347,13 +348,14 @@ static void __init qt2410_machine_init(void)
347 } 348 }
348 s3c24xx_fb_set_platdata(&qt2410_fb_info); 349 s3c24xx_fb_set_platdata(&qt2410_fb_info);
349 350
350 s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT); 351 s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
351 s3c2410_gpio_setpin(S3C2410_GPB(0), 1); 352 s3c2410_gpio_setpin(S3C2410_GPB(0), 1);
352 353
353 s3c24xx_udc_set_platdata(&qt2410_udc_cfg); 354 s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
354 s3c_i2c0_set_platdata(NULL); 355 s3c_i2c0_set_platdata(NULL);
355 356
356 s3c2410_gpio_cfgpin(S3C2410_GPB(5), S3C2410_GPIO_OUTPUT); 357 WARN_ON(gpio_request(S3C2410_GPB(5), "spi cs"));
358 gpio_direction_output(S3C2410_GPB(5), 1);
357 359
358 platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices)); 360 platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
359 s3c_pm_init(); 361 s3c_pm_init();
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 9051f0d31123..d540d79dd264 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -357,8 +357,7 @@ static struct clk *vr1000_clocks[] __initdata = {
357 357
358static void vr1000_power_off(void) 358static void vr1000_power_off(void)
359{ 359{
360 s3c2410_gpio_cfgpin(S3C2410_GPB(9), S3C2410_GPIO_OUTPUT); 360 gpio_direction_output(S3C2410_GPB(9), 1);
361 s3c2410_gpio_setpin(S3C2410_GPB(9), 1);
362} 361}
363 362
364static void __init vr1000_map_io(void) 363static void __init vr1000_map_io(void)
@@ -395,6 +394,8 @@ static void __init vr1000_init(void)
395 394
396 nor_simtec_init(); 395 nor_simtec_init();
397 simtec_audio_add(NULL, true, NULL); 396 simtec_audio_add(NULL, true, NULL);
397
398 WARN_ON(gpio_request(S3C2410_GPB(9), "power off"));
398} 399}
399 400
400MACHINE_START(VR1000, "Thorcom-VR1000") 401MACHINE_START(VR1000, "Thorcom-VR1000")
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 91ba42f688ac..adc90a3c5890 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -16,6 +16,7 @@
16#include <linux/list.h> 16#include <linux/list.h>
17#include <linux/timer.h> 17#include <linux/timer.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/gpio.h>
19#include <linux/clk.h> 20#include <linux/clk.h>
20#include <linux/sysdev.h> 21#include <linux/sysdev.h>
21#include <linux/serial_core.h> 22#include <linux/serial_core.h>
@@ -40,6 +41,10 @@
40#include <plat/clock.h> 41#include <plat/clock.h>
41#include <plat/pll.h> 42#include <plat/pll.h>
42 43
44#include <plat/gpio-core.h>
45#include <plat/gpio-cfg.h>
46#include <plat/gpio-cfg-helpers.h>
47
43/* Initial IO mappings */ 48/* Initial IO mappings */
44 49
45static struct map_desc s3c2410_iodesc[] __initdata = { 50static struct map_desc s3c2410_iodesc[] __initdata = {
@@ -65,6 +70,9 @@ void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
65 70
66void __init s3c2410_map_io(void) 71void __init s3c2410_map_io(void)
67{ 72{
73 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
74 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
75
68 iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc)); 76 iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
69} 77}
70 78
diff --git a/arch/arm/mach-s3c2412/gpio.c b/arch/arm/mach-s3c2412/gpio.c
index f7afece7fc38..3404a876b33e 100644
--- a/arch/arm/mach-s3c2412/gpio.c
+++ b/arch/arm/mach-s3c2412/gpio.c
@@ -16,41 +16,43 @@
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/gpio.h>
19 20
20#include <asm/mach/arch.h> 21#include <asm/mach/arch.h>
21#include <asm/mach/map.h> 22#include <asm/mach/map.h>
22 23
23#include <mach/regs-gpio.h> 24#include <mach/regs-gpio.h>
24
25#include <mach/hardware.h> 25#include <mach/hardware.h>
26 26
27#include <plat/gpio-core.h>
28
27int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state) 29int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state)
28{ 30{
29 void __iomem *base = S3C24XX_GPIO_BASE(pin); 31 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
30 unsigned long offs = S3C2410_GPIO_OFFSET(pin); 32 unsigned long offs = pin - chip->chip.base;
31 unsigned long flags; 33 unsigned long flags;
32 unsigned long slpcon; 34 unsigned long slpcon;
33 35
34 offs *= 2; 36 offs *= 2;
35 37
36 if (pin < S3C2410_GPIO_BANKB) 38 if (pin < S3C2410_GPB(0))
37 return -EINVAL; 39 return -EINVAL;
38 40
39 if (pin >= S3C2410_GPIO_BANKF && 41 if (pin >= S3C2410_GPF(0) &&
40 pin <= S3C2410_GPIO_BANKG) 42 pin <= S3C2410_GPG(16))
41 return -EINVAL; 43 return -EINVAL;
42 44
43 if (pin > (S3C2410_GPIO_BANKH + 32)) 45 if (pin > S3C2410_GPH(16))
44 return -EINVAL; 46 return -EINVAL;
45 47
46 local_irq_save(flags); 48 local_irq_save(flags);
47 49
48 slpcon = __raw_readl(base + 0x0C); 50 slpcon = __raw_readl(chip->base + 0x0C);
49 51
50 slpcon &= ~(3 << offs); 52 slpcon &= ~(3 << offs);
51 slpcon |= state << offs; 53 slpcon |= state << offs;
52 54
53 __raw_writel(slpcon, base + 0x0C); 55 __raw_writel(slpcon, chip->base + 0x0C);
54 56
55 local_irq_restore(flags); 57 local_irq_restore(flags);
56 58
diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c
index 20647f09aed6..478f4b4606c2 100644
--- a/arch/arm/mach-s3c2412/mach-jive.c
+++ b/arch/arm/mach-s3c2412/mach-jive.c
@@ -48,6 +48,7 @@
48#include <linux/mtd/nand_ecc.h> 48#include <linux/mtd/nand_ecc.h>
49#include <linux/mtd/partitions.h> 49#include <linux/mtd/partitions.h>
50 50
51#include <plat/gpio-cfg.h>
51#include <plat/clock.h> 52#include <plat/clock.h>
52#include <plat/devs.h> 53#include <plat/devs.h>
53#include <plat/cpu.h> 54#include <plat/cpu.h>
@@ -357,8 +358,7 @@ static void jive_lcm_reset(unsigned int set)
357{ 358{
358 printk(KERN_DEBUG "%s(%d)\n", __func__, set); 359 printk(KERN_DEBUG "%s(%d)\n", __func__, set);
359 360
360 s3c2410_gpio_setpin(S3C2410_GPG(13), set); 361 gpio_set_value(S3C2410_GPG(13), set);
361 s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT);
362} 362}
363 363
364#undef LCD_UPPER_MARGIN 364#undef LCD_UPPER_MARGIN
@@ -391,7 +391,7 @@ static struct ili9320_platdata jive_lcm_config = {
391 391
392static void jive_lcd_spi_chipselect(struct s3c2410_spigpio_info *spi, int cs) 392static void jive_lcd_spi_chipselect(struct s3c2410_spigpio_info *spi, int cs)
393{ 393{
394 s3c2410_gpio_setpin(S3C2410_GPB(7), cs ? 0 : 1); 394 gpio_set_value(S3C2410_GPB(7), cs ? 0 : 1);
395} 395}
396 396
397static struct s3c2410_spigpio_info jive_lcd_spi = { 397static struct s3c2410_spigpio_info jive_lcd_spi = {
@@ -413,7 +413,7 @@ static struct platform_device jive_device_lcdspi = {
413 413
414static void jive_wm8750_chipselect(struct s3c2410_spigpio_info *spi, int cs) 414static void jive_wm8750_chipselect(struct s3c2410_spigpio_info *spi, int cs)
415{ 415{
416 s3c2410_gpio_setpin(S3C2410_GPH(10), cs ? 0 : 1); 416 gpio_set_value(S3C2410_GPH(10), cs ? 0 : 1);
417} 417}
418 418
419static struct s3c2410_spigpio_info jive_wm8750_spi = { 419static struct s3c2410_spigpio_info jive_wm8750_spi = {
@@ -531,7 +531,7 @@ static void jive_power_off(void)
531 printk(KERN_INFO "powering system down...\n"); 531 printk(KERN_INFO "powering system down...\n");
532 532
533 s3c2410_gpio_setpin(S3C2410_GPC(5), 1); 533 s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
534 s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT); 534 s3c_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
535} 535}
536 536
537static void __init jive_machine_init(void) 537static void __init jive_machine_init(void)
@@ -636,22 +636,22 @@ static void __init jive_machine_init(void)
636 636
637 /* initialise the spi */ 637 /* initialise the spi */
638 638
639 s3c2410_gpio_setpin(S3C2410_GPG(13), 0); 639 gpio_request(S3C2410_GPG(13), "lcm reset");
640 s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT); 640 gpio_direction_output(S3C2410_GPG(13), 0);
641 641
642 s3c2410_gpio_setpin(S3C2410_GPB(7), 1); 642 gpio_request(S3C2410_GPB(7), "jive spi");
643 s3c2410_gpio_cfgpin(S3C2410_GPB(7), S3C2410_GPIO_OUTPUT); 643 gpio_direction_output(S3C2410_GPB(7), 1);
644 644
645 s3c2410_gpio_setpin(S3C2410_GPB(6), 0); 645 s3c2410_gpio_setpin(S3C2410_GPB(6), 0);
646 s3c2410_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT); 646 s3c_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
647 647
648 s3c2410_gpio_setpin(S3C2410_GPG(8), 1); 648 s3c2410_gpio_setpin(S3C2410_GPG(8), 1);
649 s3c2410_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT); 649 s3c_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT);
650 650
651 /* initialise the WM8750 spi */ 651 /* initialise the WM8750 spi */
652 652
653 s3c2410_gpio_setpin(S3C2410_GPH(10), 1); 653 gpio_request(S3C2410_GPH(10), "jive wm8750 spi");
654 s3c2410_gpio_cfgpin(S3C2410_GPH(10), S3C2410_GPIO_OUTPUT); 654 gpio_direction_output(S3C2410_GPH(10), 1);
655 655
656 /* Turn off suspend on both USB ports, and switch the 656 /* Turn off suspend on both USB ports, and switch the
657 * selectable USB port to USB device mode. */ 657 * selectable USB port to USB device mode. */
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
index 3d41aa74c362..ba93a356a839 100644
--- a/arch/arm/mach-s3c2412/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -85,10 +85,10 @@ static void smdk2413_udc_pullup(enum s3c2410_udc_cmd_e cmd)
85 switch (cmd) 85 switch (cmd)
86 { 86 {
87 case S3C2410_UDC_P_ENABLE : 87 case S3C2410_UDC_P_ENABLE :
88 s3c2410_gpio_setpin(S3C2410_GPF(2), 1); 88 gpio_set_value(S3C2410_GPF(2), 1);
89 break; 89 break;
90 case S3C2410_UDC_P_DISABLE : 90 case S3C2410_UDC_P_DISABLE :
91 s3c2410_gpio_setpin(S3C2410_GPF(2), 0); 91 gpio_set_value(S3C2410_GPF(2), 0);
92 break; 92 break;
93 case S3C2410_UDC_P_RESET : 93 case S3C2410_UDC_P_RESET :
94 break; 94 break;
@@ -134,8 +134,8 @@ static void __init smdk2413_machine_init(void)
134{ /* Turn off suspend on both USB ports, and switch the 134{ /* Turn off suspend on both USB ports, and switch the
135 * selectable USB port to USB device mode. */ 135 * selectable USB port to USB device mode. */
136 136
137 s3c2410_gpio_setpin(S3C2410_GPF(2), 0); 137 WARN_ON(gpio_request(S3C2410_GPF(2), "udc pull"));
138 s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); 138 gpio_direction_output(S3C2410_GPF(2), 0);
139 139
140 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST | 140 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
141 S3C2410_MISCCR_USBSUSPND0 | 141 S3C2410_MISCCR_USBSUSPND0 |
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index a6c5df6d41ef..cd8e7de388f0 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -6,6 +6,7 @@ config CPU_S3C2440
6 bool 6 bool
7 depends on ARCH_S3C2410 7 depends on ARCH_S3C2410
8 select CPU_ARM920T 8 select CPU_ARM920T
9 select S3C_GPIO_PULL_UP
9 select S3C2410_CLOCK 10 select S3C2410_CLOCK
10 select S3C2410_PM if PM 11 select S3C2410_PM if PM
11 select S3C2410_GPIO 12 select S3C2410_GPIO
diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c
index 571b17683d96..a76bcda210ad 100644
--- a/arch/arm/mach-s3c2440/mach-mini2440.c
+++ b/arch/arm/mach-s3c2440/mach-mini2440.c
@@ -53,6 +53,7 @@
53#include <linux/mtd/nand_ecc.h> 53#include <linux/mtd/nand_ecc.h>
54#include <linux/mtd/partitions.h> 54#include <linux/mtd/partitions.h>
55 55
56#include <plat/gpio-cfg.h>
56#include <plat/clock.h> 57#include <plat/clock.h>
57#include <plat/devs.h> 58#include <plat/devs.h>
58#include <plat/cpu.h> 59#include <plat/cpu.h>
@@ -102,10 +103,10 @@ static void mini2440_udc_pullup(enum s3c2410_udc_cmd_e cmd)
102 103
103 switch (cmd) { 104 switch (cmd) {
104 case S3C2410_UDC_P_ENABLE : 105 case S3C2410_UDC_P_ENABLE :
105 s3c2410_gpio_setpin(S3C2410_GPC(5), 1); 106 gpio_set_value(S3C2410_GPC(5), 1);
106 break; 107 break;
107 case S3C2410_UDC_P_DISABLE : 108 case S3C2410_UDC_P_DISABLE :
108 s3c2410_gpio_setpin(S3C2410_GPC(5), 0); 109 gpio_set_value(S3C2410_GPC(5), 0);
109 break; 110 break;
110 case S3C2410_UDC_P_RESET : 111 case S3C2410_UDC_P_RESET :
111 break; 112 break;
@@ -632,25 +633,25 @@ static void __init mini2440_init(void)
632 mini2440_parse_features(&features, mini2440_features_str); 633 mini2440_parse_features(&features, mini2440_features_str);
633 634
634 /* turn LCD on */ 635 /* turn LCD on */
635 s3c2410_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND); 636 s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
636 637
637 /* Turn the backlight early on */ 638 /* Turn the backlight early on */
638 s3c2410_gpio_setpin(S3C2410_GPG(4), 1); 639 WARN_ON(gpio_request(S3C2410_GPG(4), "backlight"));
639 s3c2410_gpio_cfgpin(S3C2410_GPG(4), S3C2410_GPIO_OUTPUT); 640 gpio_direction_output(S3C2410_GPG(4), 1);
640 641
641 /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */ 642 /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
642 s3c2410_gpio_pullup(S3C2410_GPB(1), 0); 643 s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);
643 s3c2410_gpio_setpin(S3C2410_GPB(1), 0); 644 s3c2410_gpio_setpin(S3C2410_GPB(1), 0);
644 s3c2410_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT); 645 s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
645 646
646 /* Make sure the D+ pullup pin is output */ 647 /* Make sure the D+ pullup pin is output */
647 s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT); 648 WARN_ON(gpio_request(S3C2410_GPC(5), "udc pup"));
649 gpio_direction_output(S3C2410_GPC(5), 0);
648 650
649 /* mark the key as input, without pullups (there is one on the board) */ 651 /* mark the key as input, without pullups (there is one on the board) */
650 for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) { 652 for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) {
651 s3c2410_gpio_pullup(mini2440_buttons[i].gpio, 0); 653 s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP);
652 s3c2410_gpio_cfgpin(mini2440_buttons[i].gpio, 654 s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT);
653 S3C2410_GPIO_INPUT);
654 } 655 }
655 if (features.lcd_index != -1) { 656 if (features.lcd_index != -1) {
656 int li; 657 int li;
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
index 342041593f22..3ff62de45fde 100644
--- a/arch/arm/mach-s3c2440/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2440/mach-nexcoder.c
@@ -40,6 +40,7 @@
40#include <plat/regs-serial.h> 40#include <plat/regs-serial.h>
41#include <plat/iic.h> 41#include <plat/iic.h>
42 42
43#include <plat/gpio-cfg.h>
43#include <plat/s3c2410.h> 44#include <plat/s3c2410.h>
44#include <plat/s3c244x.h> 45#include <plat/s3c244x.h>
45#include <plat/clock.h> 46#include <plat/clock.h>
@@ -122,15 +123,15 @@ static void __init nexcoder_sensorboard_init(void)
122{ 123{
123 // Initialize SCCB bus 124 // Initialize SCCB bus
124 s3c2410_gpio_setpin(S3C2410_GPE(14), 1); // IICSCL 125 s3c2410_gpio_setpin(S3C2410_GPE(14), 1); // IICSCL
125 s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT); 126 s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
126 s3c2410_gpio_setpin(S3C2410_GPE(15), 1); // IICSDA 127 s3c2410_gpio_setpin(S3C2410_GPE(15), 1); // IICSDA
127 s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT); 128 s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
128 129
129 // Power up the sensor board 130 // Power up the sensor board
130 s3c2410_gpio_setpin(S3C2410_GPF(1), 1); 131 s3c2410_gpio_setpin(S3C2410_GPF(1), 1);
131 s3c2410_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN 132 s3c_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN
132 s3c2410_gpio_setpin(S3C2410_GPF(2), 0); 133 s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
133 s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN 134 s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN
134} 135}
135 136
136static void __init nexcoder_map_io(void) 137static void __init nexcoder_map_io(void)
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index f35371db33f5..319458da71a0 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -49,6 +49,7 @@
49#include <linux/mtd/nand_ecc.h> 49#include <linux/mtd/nand_ecc.h>
50#include <linux/mtd/partitions.h> 50#include <linux/mtd/partitions.h>
51 51
52#include <plat/gpio-cfg.h>
52#include <plat/clock.h> 53#include <plat/clock.h>
53#include <plat/devs.h> 54#include <plat/devs.h>
54#include <plat/cpu.h> 55#include <plat/cpu.h>
@@ -298,7 +299,7 @@ static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state)
298 299
299 /* ensure that an nRESET is not generated on resume. */ 300 /* ensure that an nRESET is not generated on resume. */
300 s3c2410_gpio_setpin(S3C2410_GPA(21), 1); 301 s3c2410_gpio_setpin(S3C2410_GPA(21), 1);
301 s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT); 302 s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
302 303
303 return 0; 304 return 0;
304} 305}
@@ -310,7 +311,7 @@ static int osiris_pm_resume(struct sys_device *sd)
310 311
311 __raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0); 312 __raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0);
312 313
313 s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT); 314 s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
314 315
315 return 0; 316 return 0;
316} 317}
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
index 2b68f7ea45ae..d50f3ae6173d 100644
--- a/arch/arm/mach-s3c2440/s3c2440.c
+++ b/arch/arm/mach-s3c2440/s3c2440.c
@@ -19,6 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/serial_core.h> 20#include <linux/serial_core.h>
21#include <linux/sysdev.h> 21#include <linux/sysdev.h>
22#include <linux/gpio.h>
22#include <linux/clk.h> 23#include <linux/clk.h>
23#include <linux/io.h> 24#include <linux/io.h>
24 25
@@ -33,6 +34,10 @@
33#include <plat/cpu.h> 34#include <plat/cpu.h>
34#include <plat/s3c244x.h> 35#include <plat/s3c244x.h>
35 36
37#include <plat/gpio-core.h>
38#include <plat/gpio-cfg.h>
39#include <plat/gpio-cfg-helpers.h>
40
36static struct sys_device s3c2440_sysdev = { 41static struct sys_device s3c2440_sysdev = {
37 .cls = &s3c2440_sysclass, 42 .cls = &s3c2440_sysclass,
38}; 43};
@@ -41,6 +46,9 @@ int __init s3c2440_init(void)
41{ 46{
42 printk("S3C2440: Initialising architecture\n"); 47 printk("S3C2440: Initialising architecture\n");
43 48
49 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
50 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
51
44 /* change irq for watchdog */ 52 /* change irq for watchdog */
45 53
46 s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT; 54 s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c
index 66e6794481d2..60c929a3cab6 100644
--- a/arch/arm/mach-s3c64xx/gpiolib.c
+++ b/arch/arm/mach-s3c64xx/gpiolib.c
@@ -51,6 +51,7 @@
51 51
52static struct s3c_gpio_cfg gpio_4bit_cfg_noint = { 52static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
53 .set_config = s3c_gpio_setcfg_s3c64xx_4bit, 53 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
54 .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
54 .set_pull = s3c_gpio_setpull_updown, 55 .set_pull = s3c_gpio_setpull_updown,
55 .get_pull = s3c_gpio_getpull_updown, 56 .get_pull = s3c_gpio_getpull_updown,
56}; 57};
@@ -58,12 +59,14 @@ static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
58static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = { 59static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
59 .cfg_eint = 7, 60 .cfg_eint = 7,
60 .set_config = s3c_gpio_setcfg_s3c64xx_4bit, 61 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
62 .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
61 .set_pull = s3c_gpio_setpull_updown, 63 .set_pull = s3c_gpio_setpull_updown,
62 .get_pull = s3c_gpio_getpull_updown, 64 .get_pull = s3c_gpio_getpull_updown,
63}; 65};
64 66
65static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = { 67static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
66 .cfg_eint = 3, 68 .cfg_eint = 3,
69 .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
67 .set_config = s3c_gpio_setcfg_s3c64xx_4bit, 70 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
68 .set_pull = s3c_gpio_setpull_updown, 71 .set_pull = s3c_gpio_setpull_updown,
69 .get_pull = s3c_gpio_getpull_updown, 72 .get_pull = s3c_gpio_getpull_updown,
@@ -171,6 +174,7 @@ static struct s3c_gpio_chip gpio_4bit2[] = {
171 174
172static struct s3c_gpio_cfg gpio_2bit_cfg_noint = { 175static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
173 .set_config = s3c_gpio_setcfg_s3c24xx, 176 .set_config = s3c_gpio_setcfg_s3c24xx,
177 .get_config = s3c_gpio_getcfg_s3c24xx,
174 .set_pull = s3c_gpio_setpull_updown, 178 .set_pull = s3c_gpio_setpull_updown,
175 .get_pull = s3c_gpio_getpull_updown, 179 .get_pull = s3c_gpio_getpull_updown,
176}; 180};
@@ -178,6 +182,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
178static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = { 182static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
179 .cfg_eint = 2, 183 .cfg_eint = 2,
180 .set_config = s3c_gpio_setcfg_s3c24xx, 184 .set_config = s3c_gpio_setcfg_s3c24xx,
185 .get_config = s3c_gpio_getcfg_s3c24xx,
181 .set_pull = s3c_gpio_setpull_updown, 186 .set_pull = s3c_gpio_setpull_updown,
182 .get_pull = s3c_gpio_getpull_updown, 187 .get_pull = s3c_gpio_getpull_updown,
183}; 188};
@@ -185,6 +190,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
185static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = { 190static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
186 .cfg_eint = 3, 191 .cfg_eint = 3,
187 .set_config = s3c_gpio_setcfg_s3c24xx, 192 .set_config = s3c_gpio_setcfg_s3c24xx,
193 .get_config = s3c_gpio_getcfg_s3c24xx,
188 .set_pull = s3c_gpio_setpull_updown, 194 .set_pull = s3c_gpio_setpull_updown,
189 .get_pull = s3c_gpio_getpull_updown, 195 .get_pull = s3c_gpio_getpull_updown,
190}; 196};
diff --git a/arch/arm/mach-s5p6440/gpio.c b/arch/arm/mach-s5p6440/gpio.c
index b0ea741177ad..262dc75d5bea 100644
--- a/arch/arm/mach-s5p6440/gpio.c
+++ b/arch/arm/mach-s5p6440/gpio.c
@@ -161,12 +161,15 @@ static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = {
161 }, { 161 }, {
162 .cfg_eint = 0, 162 .cfg_eint = 0,
163 .set_config = s3c_gpio_setcfg_s3c24xx, 163 .set_config = s3c_gpio_setcfg_s3c24xx,
164 .get_config = s3c_gpio_getcfg_s3c24xx,
164 }, { 165 }, {
165 .cfg_eint = 2, 166 .cfg_eint = 2,
166 .set_config = s3c_gpio_setcfg_s3c24xx, 167 .set_config = s3c_gpio_setcfg_s3c24xx,
168 .get_config = s3c_gpio_getcfg_s3c24xx,
167 }, { 169 }, {
168 .cfg_eint = 3, 170 .cfg_eint = 3,
169 .set_config = s3c_gpio_setcfg_s3c24xx, 171 .set_config = s3c_gpio_setcfg_s3c24xx,
172 .get_config = s3c_gpio_getcfg_s3c24xx,
170 }, 173 },
171}; 174};
172 175
@@ -279,6 +282,8 @@ void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
279 for (; nr_chips > 0; nr_chips--, chipcfg++) { 282 for (; nr_chips > 0; nr_chips--, chipcfg++) {
280 if (!chipcfg->set_config) 283 if (!chipcfg->set_config)
281 chipcfg->set_config = s3c_gpio_setcfg_s3c64xx_4bit; 284 chipcfg->set_config = s3c_gpio_setcfg_s3c64xx_4bit;
285 if (!chipcfg->get_config)
286 chipcfg->get_config = s3c_gpio_getcfg_s3c64xx_4bit;
282 if (!chipcfg->set_pull) 287 if (!chipcfg->set_pull)
283 chipcfg->set_pull = s3c_gpio_setpull_updown; 288 chipcfg->set_pull = s3c_gpio_setpull_updown;
284 if (!chipcfg->get_pull) 289 if (!chipcfg->get_pull)
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 6e93ef8f3d43..a830fad6f89e 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -9,6 +9,7 @@ config PLAT_S3C24XX
9 select NO_IOPORT 9 select NO_IOPORT
10 select ARCH_REQUIRE_GPIOLIB 10 select ARCH_REQUIRE_GPIOLIB
11 select S3C_DEVICE_NAND 11 select S3C_DEVICE_NAND
12 select S3C_GPIO_CFG_S3C24XX
12 help 13 help
13 Base platform code for any Samsung S3C24XX device 14 Base platform code for any Samsung S3C24XX device
14 15
diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
index 9e0e20ad2e46..7b44d0c592b5 100644
--- a/arch/arm/plat-s3c24xx/common-smdk.c
+++ b/arch/arm/plat-s3c24xx/common-smdk.c
@@ -42,6 +42,7 @@
42#include <plat/nand.h> 42#include <plat/nand.h>
43 43
44#include <plat/common-smdk.h> 44#include <plat/common-smdk.h>
45#include <plat/gpio-cfg.h>
45#include <plat/devs.h> 46#include <plat/devs.h>
46#include <plat/pm.h> 47#include <plat/pm.h>
47 48
@@ -185,10 +186,10 @@ void __init smdk_machine_init(void)
185{ 186{
186 /* Configure the LEDs (even if we have no LED support)*/ 187 /* Configure the LEDs (even if we have no LED support)*/
187 188
188 s3c2410_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT); 189 s3c_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT);
189 s3c2410_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT); 190 s3c_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
190 s3c2410_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT); 191 s3c_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
191 s3c2410_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT); 192 s3c_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
192 193
193 s3c2410_gpio_setpin(S3C2410_GPF(4), 1); 194 s3c2410_gpio_setpin(S3C2410_GPF(4), 1);
194 s3c2410_gpio_setpin(S3C2410_GPF(5), 1); 195 s3c2410_gpio_setpin(S3C2410_GPF(5), 1);
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
index 5467470badfd..2f3d7c089dfa 100644
--- a/arch/arm/plat-s3c24xx/gpio.c
+++ b/arch/arm/plat-s3c24xx/gpio.c
@@ -1,6 +1,6 @@
1/* linux/arch/arm/plat-s3c24xx/gpio.c 1/* linux/arch/arm/plat-s3c24xx/gpio.c
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2010 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * S3C24XX GPIO support 6 * S3C24XX GPIO support
@@ -20,12 +20,12 @@
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/ 21*/
22 22
23
24#include <linux/kernel.h> 23#include <linux/kernel.h>
25#include <linux/init.h> 24#include <linux/init.h>
26#include <linux/module.h> 25#include <linux/module.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
28#include <linux/ioport.h> 27#include <linux/ioport.h>
28#include <linux/gpio.h>
29#include <linux/io.h> 29#include <linux/io.h>
30 30
31#include <mach/hardware.h> 31#include <mach/hardware.h>
@@ -34,133 +34,46 @@
34 34
35#include <mach/regs-gpio.h> 35#include <mach/regs-gpio.h>
36 36
37void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) 37#include <plat/gpio-core.h>
38{
39 void __iomem *base = S3C24XX_GPIO_BASE(pin);
40 unsigned long mask;
41 unsigned long con;
42 unsigned long flags;
43 38
44 if (pin < S3C2410_GPIO_BANKB) { 39/* gpiolib wrappers until these are totally eliminated */
45 mask = 1 << S3C2410_GPIO_OFFSET(pin);
46 } else {
47 mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
48 }
49
50 switch (function) {
51 case S3C2410_GPIO_LEAVE:
52 mask = 0;
53 function = 0;
54 break;
55
56 case S3C2410_GPIO_INPUT:
57 case S3C2410_GPIO_OUTPUT:
58 case S3C2410_GPIO_SFN2:
59 case S3C2410_GPIO_SFN3:
60 if (pin < S3C2410_GPIO_BANKB) {
61 function -= 1;
62 function &= 1;
63 function <<= S3C2410_GPIO_OFFSET(pin);
64 } else {
65 function &= 3;
66 function <<= S3C2410_GPIO_OFFSET(pin)*2;
67 }
68 }
69
70 /* modify the specified register wwith IRQs off */
71
72 local_irq_save(flags);
73
74 con = __raw_readl(base + 0x00);
75 con &= ~mask;
76 con |= function;
77
78 __raw_writel(con, base + 0x00);
79
80 local_irq_restore(flags);
81}
82
83EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
84
85unsigned int s3c2410_gpio_getcfg(unsigned int pin)
86{
87 void __iomem *base = S3C24XX_GPIO_BASE(pin);
88 unsigned long val = __raw_readl(base);
89
90 if (pin < S3C2410_GPIO_BANKB) {
91 val >>= S3C2410_GPIO_OFFSET(pin);
92 val &= 1;
93 val += 1;
94 } else {
95 val >>= S3C2410_GPIO_OFFSET(pin)*2;
96 val &= 3;
97 }
98
99 return val | S3C2410_GPIO_INPUT;
100}
101
102EXPORT_SYMBOL(s3c2410_gpio_getcfg);
103 40
104void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) 41void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
105{ 42{
106 void __iomem *base = S3C24XX_GPIO_BASE(pin); 43 int ret;
107 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
108 unsigned long flags;
109 unsigned long up;
110 44
111 if (pin < S3C2410_GPIO_BANKB) 45 WARN_ON(to); /* should be none of these left */
112 return;
113 46
114 local_irq_save(flags); 47 if (!to) {
115 48 /* if pull is enabled, try first with up, and if that
116 up = __raw_readl(base + 0x08); 49 * fails, try using down */
117 up &= ~(1L << offs);
118 up |= to << offs;
119 __raw_writel(up, base + 0x08);
120 50
121 local_irq_restore(flags); 51 ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
52 if (ret)
53 s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
54 } else {
55 s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
56 }
122} 57}
123
124EXPORT_SYMBOL(s3c2410_gpio_pullup); 58EXPORT_SYMBOL(s3c2410_gpio_pullup);
125 59
126int s3c2410_gpio_getpull(unsigned int pin)
127{
128 void __iomem *base = S3C24XX_GPIO_BASE(pin);
129 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
130
131 if (pin < S3C2410_GPIO_BANKB)
132 return -EINVAL;
133
134 return (__raw_readl(base + 0x08) & (1L << offs)) ? 1 : 0;
135}
136
137EXPORT_SYMBOL(s3c2410_gpio_getpull);
138
139void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) 60void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
140{ 61{
141 void __iomem *base = S3C24XX_GPIO_BASE(pin); 62 /* do this via gpiolib until all users removed */
142 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
143 unsigned long flags;
144 unsigned long dat;
145 63
146 local_irq_save(flags); 64 gpio_request(pin, "temporary");
147 65 gpio_set_value(pin, to);
148 dat = __raw_readl(base + 0x04); 66 gpio_free(pin);
149 dat &= ~(1 << offs);
150 dat |= to << offs;
151 __raw_writel(dat, base + 0x04);
152
153 local_irq_restore(flags);
154} 67}
155 68
156EXPORT_SYMBOL(s3c2410_gpio_setpin); 69EXPORT_SYMBOL(s3c2410_gpio_setpin);
157 70
158unsigned int s3c2410_gpio_getpin(unsigned int pin) 71unsigned int s3c2410_gpio_getpin(unsigned int pin)
159{ 72{
160 void __iomem *base = S3C24XX_GPIO_BASE(pin); 73 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
161 unsigned long offs = S3C2410_GPIO_OFFSET(pin); 74 unsigned long offs = pin - chip->chip.base;
162 75
163 return __raw_readl(base + 0x04) & (1<< offs); 76 return __raw_readl(chip->base + 0x04) & (1<< offs);
164} 77}
165 78
166EXPORT_SYMBOL(s3c2410_gpio_getpin); 79EXPORT_SYMBOL(s3c2410_gpio_getpin);
@@ -181,22 +94,3 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
181} 94}
182 95
183EXPORT_SYMBOL(s3c2410_modify_misccr); 96EXPORT_SYMBOL(s3c2410_modify_misccr);
184
185int s3c2410_gpio_getirq(unsigned int pin)
186{
187 if (pin < S3C2410_GPF(0) || pin > S3C2410_GPG(15))
188 return -EINVAL; /* not valid interrupts */
189
190 if (pin < S3C2410_GPG(0) && pin > S3C2410_GPF(7))
191 return -EINVAL; /* not valid pin */
192
193 if (pin < S3C2410_GPF(4))
194 return (pin - S3C2410_GPF(0)) + IRQ_EINT0;
195
196 if (pin < S3C2410_GPG(0))
197 return (pin - S3C2410_GPF(4)) + IRQ_EINT4;
198
199 return (pin - S3C2410_GPG(0)) + IRQ_EINT8;
200}
201
202EXPORT_SYMBOL(s3c2410_gpio_getirq);
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c
index 4f0f11a6a677..4c0896f2572d 100644
--- a/arch/arm/plat-s3c24xx/gpiolib.c
+++ b/arch/arm/plat-s3c24xx/gpiolib.c
@@ -1,6 +1,6 @@
1/* linux/arch/arm/plat-s3c24xx/gpiolib.c 1/* linux/arch/arm/plat-s3c24xx/gpiolib.c
2 * 2 *
3 * Copyright (c) 2008 Simtec Electronics 3 * Copyright (c) 2008-2010 Simtec Electronics
4 * http://armlinux.simtec.co.uk/ 4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk> 5 * Ben Dooks <ben@simtec.co.uk>
6 * 6 *
@@ -21,6 +21,8 @@
21#include <linux/gpio.h> 21#include <linux/gpio.h>
22 22
23#include <plat/gpio-core.h> 23#include <plat/gpio-core.h>
24#include <plat/gpio-cfg.h>
25#include <plat/gpio-cfg-helpers.h>
24#include <mach/hardware.h> 26#include <mach/hardware.h>
25#include <asm/irq.h> 27#include <asm/irq.h>
26#include <plat/pm.h> 28#include <plat/pm.h>
@@ -77,10 +79,21 @@ static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset)
77 return IRQ_EINT8 + offset; 79 return IRQ_EINT8 + offset;
78} 80}
79 81
82static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
83 .set_config = s3c_gpio_setcfg_s3c24xx_a,
84 .get_config = s3c_gpio_getcfg_s3c24xx_a,
85};
86
87struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
88 .set_config = s3c_gpio_setcfg_s3c24xx,
89 .get_config = s3c_gpio_getcfg_s3c24xx,
90};
91
80struct s3c_gpio_chip s3c24xx_gpios[] = { 92struct s3c_gpio_chip s3c24xx_gpios[] = {
81 [0] = { 93 [0] = {
82 .base = S3C2410_GPACON, 94 .base = S3C2410_GPACON,
83 .pm = __gpio_pm(&s3c_gpio_pm_1bit), 95 .pm = __gpio_pm(&s3c_gpio_pm_1bit),
96 .config = &s3c24xx_gpiocfg_banka,
84 .chip = { 97 .chip = {
85 .base = S3C2410_GPA(0), 98 .base = S3C2410_GPA(0),
86 .owner = THIS_MODULE, 99 .owner = THIS_MODULE,
@@ -161,15 +174,58 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
161 .ngpio = 11, 174 .ngpio = 11,
162 }, 175 },
163 }, 176 },
177 /* GPIOS for the S3C2443 and later devices. */
178 {
179 .base = S3C2440_GPJCON,
180 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
181 .chip = {
182 .base = S3C2410_GPJ(0),
183 .owner = THIS_MODULE,
184 .label = "GPIOJ",
185 .ngpio = 16,
186 },
187 }, {
188 .base = S3C2443_GPKCON,
189 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
190 .chip = {
191 .base = S3C2410_GPK(0),
192 .owner = THIS_MODULE,
193 .label = "GPIOK",
194 .ngpio = 16,
195 },
196 }, {
197 .base = S3C2443_GPLCON,
198 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
199 .chip = {
200 .base = S3C2410_GPL(0),
201 .owner = THIS_MODULE,
202 .label = "GPIOL",
203 .ngpio = 15,
204 },
205 }, {
206 .base = S3C2443_GPMCON,
207 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
208 .chip = {
209 .base = S3C2410_GPM(0),
210 .owner = THIS_MODULE,
211 .label = "GPIOM",
212 .ngpio = 2,
213 },
214 },
164}; 215};
165 216
217
166static __init int s3c24xx_gpiolib_init(void) 218static __init int s3c24xx_gpiolib_init(void)
167{ 219{
168 struct s3c_gpio_chip *chip = s3c24xx_gpios; 220 struct s3c_gpio_chip *chip = s3c24xx_gpios;
169 int gpn; 221 int gpn;
170 222
171 for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) 223 for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) {
224 if (!chip->config)
225 chip->config = &s3c24xx_gpiocfg_default;
226
172 s3c_gpiolib_add(chip); 227 s3c_gpiolib_add(chip);
228 }
173 229
174 return 0; 230 return 0;
175} 231}
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
index 3620dd299095..60627e63a254 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -43,6 +43,7 @@
43 43
44#include <asm/mach/time.h> 44#include <asm/mach/time.h>
45 45
46#include <plat/gpio-cfg.h>
46#include <plat/pm.h> 47#include <plat/pm.h>
47 48
48#define PFX "s3c24xx-pm: " 49#define PFX "s3c24xx-pm: "
@@ -90,22 +91,22 @@ static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
90{ 91{
91 unsigned long irqstate; 92 unsigned long irqstate;
92 unsigned long pinstate; 93 unsigned long pinstate;
93 int irq = s3c2410_gpio_getirq(pin); 94 int irq = gpio_to_irq(pin);
94 95
95 if (irqoffs < 4) 96 if (irqoffs < 4)
96 irqstate = s3c_irqwake_intmask & (1L<<irqoffs); 97 irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
97 else 98 else
98 irqstate = s3c_irqwake_eintmask & (1L<<irqoffs); 99 irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
99 100
100 pinstate = s3c2410_gpio_getcfg(pin); 101 pinstate = s3c_gpio_getcfg(pin);
101 102
102 if (!irqstate) { 103 if (!irqstate) {
103 if (pinstate == S3C2410_GPIO_IRQ) 104 if (pinstate == S3C2410_GPIO_IRQ)
104 S3C_PMDBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin); 105 S3C_PMDBG("Leaving IRQ %d (pin %d) as is\n", irq, pin);
105 } else { 106 } else {
106 if (pinstate == S3C2410_GPIO_IRQ) { 107 if (pinstate == S3C2410_GPIO_IRQ) {
107 S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin); 108 S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin);
108 s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT); 109 s3c_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
109 } 110 }
110 } 111 }
111} 112}
diff --git a/arch/arm/plat-s3c24xx/setup-i2c.c b/arch/arm/plat-s3c24xx/setup-i2c.c
index 71a6accf114e..9e90a7cbd1d6 100644
--- a/arch/arm/plat-s3c24xx/setup-i2c.c
+++ b/arch/arm/plat-s3c24xx/setup-i2c.c
@@ -15,12 +15,13 @@
15 15
16struct platform_device; 16struct platform_device;
17 17
18#include <plat/gpio-cfg.h>
18#include <plat/iic.h> 19#include <plat/iic.h>
19#include <mach/hardware.h> 20#include <mach/hardware.h>
20#include <mach/regs-gpio.h> 21#include <mach/regs-gpio.h>
21 22
22void s3c_i2c0_cfg_gpio(struct platform_device *dev) 23void s3c_i2c0_cfg_gpio(struct platform_device *dev)
23{ 24{
24 s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA); 25 s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
25 s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL); 26 s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
26} 27}
diff --git a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
index da7a61728c18..9793544a6ace 100644
--- a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
+++ b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
@@ -21,16 +21,16 @@ void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi,
21 int enable) 21 int enable)
22{ 22{
23 if (enable) { 23 if (enable) {
24 s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0); 24 s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0);
25 s3c2410_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0); 25 s3c_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0);
26 s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0); 26 s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0);
27 s3c2410_gpio_pullup(S3C2410_GPE(11), 0); 27 s3c2410_gpio_pullup(S3C2410_GPE(11), 0);
28 s3c2410_gpio_pullup(S3C2410_GPE(13), 0); 28 s3c2410_gpio_pullup(S3C2410_GPE(13), 0);
29 } else { 29 } else {
30 s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT); 30 s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT);
31 s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT); 31 s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT);
32 s3c2410_gpio_pullup(S3C2410_GPE(11), 1); 32 s3c_gpio_cfgpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE);
33 s3c2410_gpio_pullup(S3C2410_GPE(12), 1); 33 s3c_gpio_cfgpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE);
34 s3c2410_gpio_pullup(S3C2410_GPE(13), 1); 34 s3c_gpio_cfgpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE);
35 } 35 }
36} 36}
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
index 89fcf5308cf6..db9e9e477ec1 100644
--- a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
+++ b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
@@ -23,16 +23,16 @@ void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
23 23
24 printk(KERN_INFO "%s(%d)\n", __func__, enable); 24 printk(KERN_INFO "%s(%d)\n", __func__, enable);
25 if (enable) { 25 if (enable) {
26 s3c2410_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1); 26 s3c_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
27 s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1); 27 s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
28 s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1); 28 s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
29 s3c2410_gpio_pullup(S3C2410_GPD(10), 0); 29 s3c2410_gpio_pullup(S3C2410_GPD(10), 0);
30 s3c2410_gpio_pullup(S3C2410_GPD(9), 0); 30 s3c2410_gpio_pullup(S3C2410_GPD(9), 0);
31 } else { 31 } else {
32 s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT); 32 s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
33 s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT); 33 s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
34 s3c2410_gpio_pullup(S3C2410_GPD(10), 1); 34 s3c_gpio_cfgpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE);
35 s3c2410_gpio_pullup(S3C2410_GPD(9), 1); 35 s3c_gpio_cfgpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE);
36 s3c2410_gpio_pullup(S3C2410_GPD(8), 1); 36 s3c_gpio_cfgpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE);
37 } 37 }
38} 38}
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
index 86b9edc67413..8ea663a438bb 100644
--- a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
+++ b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
@@ -21,16 +21,16 @@ void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi,
21 int enable) 21 int enable)
22{ 22{
23 if (enable) { 23 if (enable) {
24 s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1); 24 s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1);
25 s3c2410_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1); 25 s3c_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1);
26 s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1); 26 s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1);
27 s3c2410_gpio_pullup(S3C2410_GPG(5), 0); 27 s3c2410_gpio_pullup(S3C2410_GPG(5), 0);
28 s3c2410_gpio_pullup(S3C2410_GPG(6), 0); 28 s3c2410_gpio_pullup(S3C2410_GPG(6), 0);
29 } else { 29 } else {
30 s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT); 30 s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT);
31 s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT); 31 s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT);
32 s3c2410_gpio_pullup(S3C2410_GPG(5), 1); 32 s3c_gpio_cfgpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE);
33 s3c2410_gpio_pullup(S3C2410_GPG(6), 1); 33 s3c_gpio_cfgpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE);
34 s3c2410_gpio_pullup(S3C2410_GPG(7), 1); 34 s3c_gpio_cfgpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE);
35 } 35 }
36} 36}
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index 44a84e896546..a76eef533392 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -1,7 +1,7 @@
1/* linux/arch/arm/plat-s3c/gpio-config.c 1/* linux/arch/arm/plat-s3c/gpio-config.c
2 * 2 *
3 * Copyright 2008 Openmoko, Inc. 3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics 4 * Copyright 2008-2010 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk> 5 * Ben Dooks <ben@simtec.co.uk>
6 * http://armlinux.simtec.co.uk/ 6 * http://armlinux.simtec.co.uk/
7 * 7 *
@@ -33,14 +33,34 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
33 33
34 offset = pin - chip->chip.base; 34 offset = pin - chip->chip.base;
35 35
36 local_irq_save(flags); 36 s3c_gpio_lock(chip, flags);
37 ret = s3c_gpio_do_setcfg(chip, offset, config); 37 ret = s3c_gpio_do_setcfg(chip, offset, config);
38 local_irq_restore(flags); 38 s3c_gpio_unlock(chip, flags);
39 39
40 return ret; 40 return ret;
41} 41}
42EXPORT_SYMBOL(s3c_gpio_cfgpin); 42EXPORT_SYMBOL(s3c_gpio_cfgpin);
43 43
44unsigned s3c_gpio_getcfg(unsigned int pin)
45{
46 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
47 unsigned long flags;
48 unsigned ret = 0;
49 int offset;
50
51 if (chip) {
52 offset = pin - chip->chip.base;
53
54 s3c_gpio_lock(chip, flags);
55 ret = s3c_gpio_do_getcfg(chip, offset);
56 s3c_gpio_unlock(chip, flags);
57 }
58
59 return ret;
60}
61EXPORT_SYMBOL(s3c_gpio_getcfg);
62
63
44int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) 64int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
45{ 65{
46 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); 66 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
@@ -52,17 +72,17 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
52 72
53 offset = pin - chip->chip.base; 73 offset = pin - chip->chip.base;
54 74
55 local_irq_save(flags); 75 s3c_gpio_lock(chip, flags);
56 ret = s3c_gpio_do_setpull(chip, offset, pull); 76 ret = s3c_gpio_do_setpull(chip, offset, pull);
57 local_irq_restore(flags); 77 s3c_gpio_unlock(chip, flags);
58 78
59 return ret; 79 return ret;
60} 80}
61EXPORT_SYMBOL(s3c_gpio_setpull); 81EXPORT_SYMBOL(s3c_gpio_setpull);
62 82
63#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX 83#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
64int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip, 84int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
65 unsigned int off, unsigned int cfg) 85 unsigned int off, unsigned int cfg)
66{ 86{
67 void __iomem *reg = chip->base; 87 void __iomem *reg = chip->base;
68 unsigned int shift = off; 88 unsigned int shift = off;
@@ -87,6 +107,19 @@ int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
87 return 0; 107 return 0;
88} 108}
89 109
110unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
111 unsigned int off)
112{
113 u32 con;
114
115 con = __raw_readl(chip->base);
116 con >>= off;
117 con &= 1;
118 con++;
119
120 return S3C_GPIO_SFN(con);
121}
122
90int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, 123int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
91 unsigned int off, unsigned int cfg) 124 unsigned int off, unsigned int cfg)
92{ 125{
@@ -109,6 +142,19 @@ int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
109 142
110 return 0; 143 return 0;
111} 144}
145
146unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
147 unsigned int off)
148{
149 u32 con;
150
151 con = __raw_readl(chip->base);
152 con >>= off * 2;
153 con &= 3;
154
155 /* this conversion works for IN and OUT as well as special mode */
156 return S3C_GPIO_SPECIAL(con);
157}
112#endif 158#endif
113 159
114#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX 160#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
@@ -134,6 +180,25 @@ int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
134 180
135 return 0; 181 return 0;
136} 182}
183
184unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
185 unsigned int off)
186{
187 void __iomem *reg = chip->base;
188 unsigned int shift = (off & 7) * 4;
189 u32 con;
190
191 if (off < 8 && chip->chip.ngpio > 8)
192 reg -= 4;
193
194 con = __raw_readl(reg);
195 con >>= shift;
196 con &= 0xf;
197
198 /* this conversion works for IN and OUT as well as special mode */
199 return S3C_GPIO_SPECIAL(con);
200}
201
137#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */ 202#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
138 203
139#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN 204#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
@@ -164,3 +229,35 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
164 return (__force s3c_gpio_pull_t)pup; 229 return (__force s3c_gpio_pull_t)pup;
165} 230}
166#endif 231#endif
232
233#ifdef CONFIG_S3C_GPIO_PULL_UP
234int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
235 unsigned int off, s3c_gpio_pull_t pull)
236{
237 void __iomem *reg = chip->base + 0x08;
238 u32 pup = __raw_readl(reg);
239
240 pup = __raw_readl(reg);
241
242 if (pup == S3C_GPIO_PULL_UP)
243 pup &= ~(1 << off);
244 else if (pup == S3C_GPIO_PULL_NONE)
245 pup |= (1 << off);
246 else
247 return -EINVAL;
248
249 __raw_writel(pup, reg);
250 return 0;
251}
252
253s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
254 unsigned int off)
255{
256 void __iomem *reg = chip->base + 0x08;
257 u32 pup = __raw_readl(reg);
258
259 pup &= (1 << off);
260 return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP;
261}
262#endif /* CONFIG_S3C_GPIO_PULL_UP */
263
diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c
index 28d2ab8a08db..b83a83351cea 100644
--- a/arch/arm/plat-samsung/gpio.c
+++ b/arch/arm/plat-samsung/gpio.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/gpio.h> 17#include <linux/gpio.h>
18#include <linux/spinlock.h>
18 19
19#include <plat/gpio-core.h> 20#include <plat/gpio-core.h>
20 21
@@ -52,14 +53,14 @@ static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
52 unsigned long flags; 53 unsigned long flags;
53 unsigned long con; 54 unsigned long con;
54 55
55 local_irq_save(flags); 56 s3c_gpio_lock(ourchip, flags);
56 57
57 con = __raw_readl(base + 0x00); 58 con = __raw_readl(base + 0x00);
58 con &= ~(3 << (offset * 2)); 59 con &= ~(3 << (offset * 2));
59 60
60 __raw_writel(con, base + 0x00); 61 __raw_writel(con, base + 0x00);
61 62
62 local_irq_restore(flags); 63 s3c_gpio_unlock(ourchip, flags);
63 return 0; 64 return 0;
64} 65}
65 66
@@ -72,7 +73,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
72 unsigned long dat; 73 unsigned long dat;
73 unsigned long con; 74 unsigned long con;
74 75
75 local_irq_save(flags); 76 s3c_gpio_lock(ourchip, flags);
76 77
77 dat = __raw_readl(base + 0x04); 78 dat = __raw_readl(base + 0x04);
78 dat &= ~(1 << offset); 79 dat &= ~(1 << offset);
@@ -87,7 +88,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
87 __raw_writel(con, base + 0x00); 88 __raw_writel(con, base + 0x00);
88 __raw_writel(dat, base + 0x04); 89 __raw_writel(dat, base + 0x04);
89 90
90 local_irq_restore(flags); 91 s3c_gpio_unlock(ourchip, flags);
91 return 0; 92 return 0;
92} 93}
93 94
@@ -99,7 +100,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
99 unsigned long flags; 100 unsigned long flags;
100 unsigned long dat; 101 unsigned long dat;
101 102
102 local_irq_save(flags); 103 s3c_gpio_lock(ourchip, flags);
103 104
104 dat = __raw_readl(base + 0x04); 105 dat = __raw_readl(base + 0x04);
105 dat &= ~(1 << offset); 106 dat &= ~(1 << offset);
@@ -107,7 +108,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
107 dat |= 1 << offset; 108 dat |= 1 << offset;
108 __raw_writel(dat, base + 0x04); 109 __raw_writel(dat, base + 0x04);
109 110
110 local_irq_restore(flags); 111 s3c_gpio_unlock(ourchip, flags);
111} 112}
112 113
113static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset) 114static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
@@ -131,6 +132,8 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
131 BUG_ON(!gc->label); 132 BUG_ON(!gc->label);
132 BUG_ON(!gc->ngpio); 133 BUG_ON(!gc->ngpio);
133 134
135 spin_lock_init(&chip->lock);
136
134 if (!gc->direction_input) 137 if (!gc->direction_input)
135 gc->direction_input = s3c_gpiolib_input; 138 gc->direction_input = s3c_gpiolib_input;
136 if (!gc->direction_output) 139 if (!gc->direction_output)
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
index dda19da037ad..3e21c75feefa 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -30,6 +30,12 @@ static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
30 return (chip->config->set_config)(chip, off, config); 30 return (chip->config->set_config)(chip, off, config);
31} 31}
32 32
33static inline unsigned s3c_gpio_do_getcfg(struct s3c_gpio_chip *chip,
34 unsigned int off)
35{
36 return (chip->config->get_config)(chip, off);
37}
38
33static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip, 39static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
34 unsigned int off, s3c_gpio_pull_t pull) 40 unsigned int off, s3c_gpio_pull_t pull)
35{ 41{
@@ -53,6 +59,18 @@ extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
53 unsigned int off, unsigned int cfg); 59 unsigned int off, unsigned int cfg);
54 60
55/** 61/**
62 * s3c_gpio_getcfg_s3c24xx - S3C24XX style GPIO configuration read.
63 * @chip: The gpio chip that is being configured.
64 * @off: The offset for the GPIO being configured.
65 *
66 * The reverse of s3c_gpio_setcfg_s3c24xx(). Will return a value whicg
67 * could be directly passed back to s3c_gpio_setcfg_s3c24xx(), from the
68 * S3C_GPIO_SPECIAL() macro.
69 */
70unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
71 unsigned int off);
72
73/**
56 * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A) 74 * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
57 * @chip: The gpio chip that is being configured. 75 * @chip: The gpio chip that is being configured.
58 * @off: The offset for the GPIO being configured. 76 * @off: The offset for the GPIO being configured.
@@ -65,6 +83,21 @@ extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
65extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, 83extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
66 unsigned int off, unsigned int cfg); 84 unsigned int off, unsigned int cfg);
67 85
86
87/**
88 * s3c_gpio_getcfg_s3c24xx_a - S3C24XX style GPIO configuration read (Bank A)
89 * @chip: The gpio chip that is being configured.
90 * @off: The offset for the GPIO being configured.
91 *
92 * The reverse of s3c_gpio_setcfg_s3c24xx_a() turning an GPIO into a usable
93 * GPIO configuration value.
94 *
95 * @sa s3c_gpio_getcfg_s3c24xx
96 * @sa s3c_gpio_getcfg_s3c64xx_4bit
97 */
98extern unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
99 unsigned int off);
100
68/** 101/**
69 * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config. 102 * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
70 * @chip: The gpio chip that is being configured. 103 * @chip: The gpio chip that is being configured.
@@ -85,6 +118,20 @@ extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
85 unsigned int off, unsigned int cfg); 118 unsigned int off, unsigned int cfg);
86 119
87 120
121/**
122 * s3c_gpio_getcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config read.
123 * @chip: The gpio chip that is being configured.
124 * @off: The offset for the GPIO being configured.
125 *
126 * The reverse of s3c_gpio_setcfg_s3c64xx_4bit(), turning a gpio configuration
127 * register setting into a value the software can use, such as could be passed
128 * to s3c_gpio_setcfg_s3c64xx_4bit().
129 *
130 * @sa s3c_gpio_getcfg_s3c24xx
131 */
132extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
133 unsigned int off);
134
88/* Pull-{up,down} resistor controls. 135/* Pull-{up,down} resistor controls.
89 * 136 *
90 * S3C2410,S3C2440,S3C24A0 = Pull-UP, 137 * S3C2410,S3C2440,S3C24A0 = Pull-UP,
@@ -146,6 +193,17 @@ extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
146 unsigned int off); 193 unsigned int off);
147 194
148/** 195/**
196 * s3c_gpio_getpull_1up() - Get configuration for choice of up or none
197 * @chip: The gpio chip that the GPIO pin belongs to
198 * @off: The offset to the pin to get the configuration of.
199 *
200 * This helper function reads the state of the pull-up resistor for the
201 * given GPIO in the same case as s3c_gpio_setpull_1up.
202*/
203extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
204 unsigned int off);
205
206/**
149 * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443. 207 * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
150 * @chip: The gpio chip that is being configured. 208 * @chip: The gpio chip that is being configured.
151 * @off: The offset for the GPIO being configured. 209 * @off: The offset for the GPIO being configured.
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index 29cd6a86cade..8d01e853df39 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -77,6 +77,17 @@ struct s3c_gpio_cfg {
77 */ 77 */
78extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to); 78extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
79 79
80/**
81 * s3c_gpio_getcfg - Read the current function for a GPIO pin
82 * @pin: The pin to read the configuration value for.
83 *
84 * Read the configuration state of the given @pin, returning a value that
85 * could be passed back to s3c_gpio_cfgpin().
86 *
87 * @sa s3c_gpio_cfgpin
88 */
89extern unsigned s3c_gpio_getcfg(unsigned int pin);
90
80/* Define values for the pull-{up,down} available for each gpio pin. 91/* Define values for the pull-{up,down} available for each gpio pin.
81 * 92 *
82 * These values control the state of the weak pull-{up,down} resistors 93 * These values control the state of the weak pull-{up,down} resistors
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 49ff406a7066..f3a68d1a07b9 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -44,16 +44,26 @@ struct s3c_gpio_cfg;
44 * @chip: The chip structure to be exported via gpiolib. 44 * @chip: The chip structure to be exported via gpiolib.
45 * @base: The base pointer to the gpio configuration registers. 45 * @base: The base pointer to the gpio configuration registers.
46 * @config: special function and pull-resistor control information. 46 * @config: special function and pull-resistor control information.
47 * @lock: Lock for exclusive access to this gpio bank.
47 * @pm_save: Save information for suspend/resume support. 48 * @pm_save: Save information for suspend/resume support.
48 * 49 *
49 * This wrapper provides the necessary information for the Samsung 50 * This wrapper provides the necessary information for the Samsung
50 * specific gpios being registered with gpiolib. 51 * specific gpios being registered with gpiolib.
52 *
53 * The lock protects each gpio bank from multiple access of the shared
54 * configuration registers, or from reading of data whilst another thread
55 * is writing to the register set.
56 *
57 * Each chip has its own lock to avoid any contention between different
58 * CPU cores trying to get one lock for different GPIO banks, where each
59 * bank of GPIO has its own register space and configuration registers.
51 */ 60 */
52struct s3c_gpio_chip { 61struct s3c_gpio_chip {
53 struct gpio_chip chip; 62 struct gpio_chip chip;
54 struct s3c_gpio_cfg *config; 63 struct s3c_gpio_cfg *config;
55 struct s3c_gpio_pm *pm; 64 struct s3c_gpio_pm *pm;
56 void __iomem *base; 65 void __iomem *base;
66 spinlock_t lock;
57#ifdef CONFIG_PM 67#ifdef CONFIG_PM
58 u32 pm_save[4]; 68 u32 pm_save[4];
59#endif 69#endif
@@ -108,6 +118,9 @@ extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
108extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip); 118extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
109extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip); 119extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
110 120
121/* exported for core SoC support to change */
122extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
123
111#ifdef CONFIG_S3C_GPIO_TRACK 124#ifdef CONFIG_S3C_GPIO_TRACK
112extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; 125extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
113 126
@@ -135,3 +148,7 @@ extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
135#define __gpio_pm(x) NULL 148#define __gpio_pm(x) NULL
136 149
137#endif /* CONFIG_PM */ 150#endif /* CONFIG_PM */
151
152/* locking wrappers to deal with multiple access to the same gpio bank */
153#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
154#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c
index 69a4c7f02e25..d50ab9d2af53 100644
--- a/arch/arm/plat-samsung/pm-gpio.c
+++ b/arch/arm/plat-samsung/pm-gpio.c
@@ -329,7 +329,7 @@ void s3c_pm_save_gpios(void)
329 struct s3c_gpio_chip *ourchip; 329 struct s3c_gpio_chip *ourchip;
330 unsigned int gpio_nr; 330 unsigned int gpio_nr;
331 331
332 for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) { 332 for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
333 ourchip = s3c_gpiolib_getchip(gpio_nr); 333 ourchip = s3c_gpiolib_getchip(gpio_nr);
334 if (!ourchip) 334 if (!ourchip)
335 continue; 335 continue;
@@ -367,7 +367,7 @@ void s3c_pm_restore_gpios(void)
367 struct s3c_gpio_chip *ourchip; 367 struct s3c_gpio_chip *ourchip;
368 unsigned int gpio_nr; 368 unsigned int gpio_nr;
369 369
370 for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) { 370 for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
371 ourchip = s3c_gpiolib_getchip(gpio_nr); 371 ourchip = s3c_gpiolib_getchip(gpio_nr);
372 if (!ourchip) 372 if (!ourchip)
373 continue; 373 continue;