diff options
author | Ben Dooks <ben-linux@fluff.org> | 2010-05-19 18:04:08 +0900 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2010-05-19 18:04:08 +0900 |
commit | ff1b8ba01dc80da338890a187c112fdd3c0b9202 (patch) | |
tree | 415999aa2c3ac52e48c2b6f690bba393e3d7a00c /arch/arm/plat-s3c24xx | |
parent | 5fcdb16bd04fdeb313ee33bb269b04e59a9abf91 (diff) | |
parent | 32b6cb3872883861f3a2669cce880f3a7ef8979a (diff) |
ARM: Merge for-2635/gpio2
Merge branch 'for-2635/gpio2' into for-linus/samsung2
Diffstat (limited to 'arch/arm/plat-s3c24xx')
-rw-r--r-- | arch/arm/plat-s3c24xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/common-smdk.c | 9 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/gpio.c | 150 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/gpiolib.c | 60 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/pm.c | 9 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/setup-i2c.c | 5 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c | 16 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c | 16 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c | 16 |
9 files changed, 118 insertions, 164 deletions
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index 6e93ef8f3d4..a830fad6f89 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig @@ -9,6 +9,7 @@ config PLAT_S3C24XX select NO_IOPORT select ARCH_REQUIRE_GPIOLIB select S3C_DEVICE_NAND + select S3C_GPIO_CFG_S3C24XX help Base platform code for any Samsung S3C24XX device diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c index 9e0e20ad2e4..7b44d0c592b 100644 --- a/arch/arm/plat-s3c24xx/common-smdk.c +++ b/arch/arm/plat-s3c24xx/common-smdk.c @@ -42,6 +42,7 @@ #include <plat/nand.h> #include <plat/common-smdk.h> +#include <plat/gpio-cfg.h> #include <plat/devs.h> #include <plat/pm.h> @@ -185,10 +186,10 @@ void __init smdk_machine_init(void) { /* Configure the LEDs (even if we have no LED support)*/ - s3c2410_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT); - s3c2410_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT); - s3c2410_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT); - s3c2410_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT); s3c2410_gpio_setpin(S3C2410_GPF(4), 1); s3c2410_gpio_setpin(S3C2410_GPF(5), 1); diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c index 5467470badf..2f3d7c089df 100644 --- a/arch/arm/plat-s3c24xx/gpio.c +++ b/arch/arm/plat-s3c24xx/gpio.c @@ -1,6 +1,6 @@ /* linux/arch/arm/plat-s3c24xx/gpio.c * - * Copyright (c) 2004-2005 Simtec Electronics + * Copyright (c) 2004-2010 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> * * S3C24XX GPIO support @@ -20,12 +20,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/interrupt.h> #include <linux/ioport.h> +#include <linux/gpio.h> #include <linux/io.h> #include <mach/hardware.h> @@ -34,133 +34,46 @@ #include <mach/regs-gpio.h> -void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) -{ - void __iomem *base = S3C24XX_GPIO_BASE(pin); - unsigned long mask; - unsigned long con; - unsigned long flags; +#include <plat/gpio-core.h> - if (pin < S3C2410_GPIO_BANKB) { - mask = 1 << S3C2410_GPIO_OFFSET(pin); - } else { - mask = 3 << S3C2410_GPIO_OFFSET(pin)*2; - } - - switch (function) { - case S3C2410_GPIO_LEAVE: - mask = 0; - function = 0; - break; - - case S3C2410_GPIO_INPUT: - case S3C2410_GPIO_OUTPUT: - case S3C2410_GPIO_SFN2: - case S3C2410_GPIO_SFN3: - if (pin < S3C2410_GPIO_BANKB) { - function -= 1; - function &= 1; - function <<= S3C2410_GPIO_OFFSET(pin); - } else { - function &= 3; - function <<= S3C2410_GPIO_OFFSET(pin)*2; - } - } - - /* modify the specified register wwith IRQs off */ - - local_irq_save(flags); - - con = __raw_readl(base + 0x00); - con &= ~mask; - con |= function; - - __raw_writel(con, base + 0x00); - - local_irq_restore(flags); -} - -EXPORT_SYMBOL(s3c2410_gpio_cfgpin); - -unsigned int s3c2410_gpio_getcfg(unsigned int pin) -{ - void __iomem *base = S3C24XX_GPIO_BASE(pin); - unsigned long val = __raw_readl(base); - - if (pin < S3C2410_GPIO_BANKB) { - val >>= S3C2410_GPIO_OFFSET(pin); - val &= 1; - val += 1; - } else { - val >>= S3C2410_GPIO_OFFSET(pin)*2; - val &= 3; - } - - return val | S3C2410_GPIO_INPUT; -} - -EXPORT_SYMBOL(s3c2410_gpio_getcfg); +/* gpiolib wrappers until these are totally eliminated */ void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) { - void __iomem *base = S3C24XX_GPIO_BASE(pin); - unsigned long offs = S3C2410_GPIO_OFFSET(pin); - unsigned long flags; - unsigned long up; + int ret; - if (pin < S3C2410_GPIO_BANKB) - return; + WARN_ON(to); /* should be none of these left */ - local_irq_save(flags); - - up = __raw_readl(base + 0x08); - up &= ~(1L << offs); - up |= to << offs; - __raw_writel(up, base + 0x08); + if (!to) { + /* if pull is enabled, try first with up, and if that + * fails, try using down */ - local_irq_restore(flags); + ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP); + if (ret) + s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN); + } else { + s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE); + } } - EXPORT_SYMBOL(s3c2410_gpio_pullup); -int s3c2410_gpio_getpull(unsigned int pin) -{ - void __iomem *base = S3C24XX_GPIO_BASE(pin); - unsigned long offs = S3C2410_GPIO_OFFSET(pin); - - if (pin < S3C2410_GPIO_BANKB) - return -EINVAL; - - return (__raw_readl(base + 0x08) & (1L << offs)) ? 1 : 0; -} - -EXPORT_SYMBOL(s3c2410_gpio_getpull); - void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) { - void __iomem *base = S3C24XX_GPIO_BASE(pin); - unsigned long offs = S3C2410_GPIO_OFFSET(pin); - unsigned long flags; - unsigned long dat; + /* do this via gpiolib until all users removed */ - local_irq_save(flags); - - dat = __raw_readl(base + 0x04); - dat &= ~(1 << offs); - dat |= to << offs; - __raw_writel(dat, base + 0x04); - - local_irq_restore(flags); + gpio_request(pin, "temporary"); + gpio_set_value(pin, to); + gpio_free(pin); } EXPORT_SYMBOL(s3c2410_gpio_setpin); unsigned int s3c2410_gpio_getpin(unsigned int pin) { - void __iomem *base = S3C24XX_GPIO_BASE(pin); - unsigned long offs = S3C2410_GPIO_OFFSET(pin); + struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); + unsigned long offs = pin - chip->chip.base; - return __raw_readl(base + 0x04) & (1<< offs); + return __raw_readl(chip->base + 0x04) & (1<< offs); } EXPORT_SYMBOL(s3c2410_gpio_getpin); @@ -181,22 +94,3 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) } EXPORT_SYMBOL(s3c2410_modify_misccr); - -int s3c2410_gpio_getirq(unsigned int pin) -{ - if (pin < S3C2410_GPF(0) || pin > S3C2410_GPG(15)) - return -EINVAL; /* not valid interrupts */ - - if (pin < S3C2410_GPG(0) && pin > S3C2410_GPF(7)) - return -EINVAL; /* not valid pin */ - - if (pin < S3C2410_GPF(4)) - return (pin - S3C2410_GPF(0)) + IRQ_EINT0; - - if (pin < S3C2410_GPG(0)) - return (pin - S3C2410_GPF(4)) + IRQ_EINT4; - - return (pin - S3C2410_GPG(0)) + IRQ_EINT8; -} - -EXPORT_SYMBOL(s3c2410_gpio_getirq); diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c index 4f0f11a6a67..4c0896f2572 100644 --- a/arch/arm/plat-s3c24xx/gpiolib.c +++ b/arch/arm/plat-s3c24xx/gpiolib.c @@ -1,6 +1,6 @@ /* linux/arch/arm/plat-s3c24xx/gpiolib.c * - * Copyright (c) 2008 Simtec Electronics + * Copyright (c) 2008-2010 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks <ben@simtec.co.uk> * @@ -21,6 +21,8 @@ #include <linux/gpio.h> #include <plat/gpio-core.h> +#include <plat/gpio-cfg.h> +#include <plat/gpio-cfg-helpers.h> #include <mach/hardware.h> #include <asm/irq.h> #include <plat/pm.h> @@ -77,10 +79,21 @@ static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset) return IRQ_EINT8 + offset; } +static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = { + .set_config = s3c_gpio_setcfg_s3c24xx_a, + .get_config = s3c_gpio_getcfg_s3c24xx_a, +}; + +struct s3c_gpio_cfg s3c24xx_gpiocfg_default = { + .set_config = s3c_gpio_setcfg_s3c24xx, + .get_config = s3c_gpio_getcfg_s3c24xx, +}; + struct s3c_gpio_chip s3c24xx_gpios[] = { [0] = { .base = S3C2410_GPACON, .pm = __gpio_pm(&s3c_gpio_pm_1bit), + .config = &s3c24xx_gpiocfg_banka, .chip = { .base = S3C2410_GPA(0), .owner = THIS_MODULE, @@ -161,15 +174,58 @@ struct s3c_gpio_chip s3c24xx_gpios[] = { .ngpio = 11, }, }, + /* GPIOS for the S3C2443 and later devices. */ + { + .base = S3C2440_GPJCON, + .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPJ(0), + .owner = THIS_MODULE, + .label = "GPIOJ", + .ngpio = 16, + }, + }, { + .base = S3C2443_GPKCON, + .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPK(0), + .owner = THIS_MODULE, + .label = "GPIOK", + .ngpio = 16, + }, + }, { + .base = S3C2443_GPLCON, + .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPL(0), + .owner = THIS_MODULE, + .label = "GPIOL", + .ngpio = 15, + }, + }, { + .base = S3C2443_GPMCON, + .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPM(0), + .owner = THIS_MODULE, + .label = "GPIOM", + .ngpio = 2, + }, + }, }; + static __init int s3c24xx_gpiolib_init(void) { struct s3c_gpio_chip *chip = s3c24xx_gpios; int gpn; - for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) + for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) { + if (!chip->config) + chip->config = &s3c24xx_gpiocfg_default; + s3c_gpiolib_add(chip); + } return 0; } diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c index 3620dd29909..60627e63a25 100644 --- a/arch/arm/plat-s3c24xx/pm.c +++ b/arch/arm/plat-s3c24xx/pm.c @@ -43,6 +43,7 @@ #include <asm/mach/time.h> +#include <plat/gpio-cfg.h> #include <plat/pm.h> #define PFX "s3c24xx-pm: " @@ -90,22 +91,22 @@ static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs) { unsigned long irqstate; unsigned long pinstate; - int irq = s3c2410_gpio_getirq(pin); + int irq = gpio_to_irq(pin); if (irqoffs < 4) irqstate = s3c_irqwake_intmask & (1L<<irqoffs); else irqstate = s3c_irqwake_eintmask & (1L<<irqoffs); - pinstate = s3c2410_gpio_getcfg(pin); + pinstate = s3c_gpio_getcfg(pin); if (!irqstate) { if (pinstate == S3C2410_GPIO_IRQ) - S3C_PMDBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin); + S3C_PMDBG("Leaving IRQ %d (pin %d) as is\n", irq, pin); } else { if (pinstate == S3C2410_GPIO_IRQ) { S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin); - s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(pin, S3C2410_GPIO_INPUT); } } } diff --git a/arch/arm/plat-s3c24xx/setup-i2c.c b/arch/arm/plat-s3c24xx/setup-i2c.c index 71a6accf114..9e90a7cbd1d 100644 --- a/arch/arm/plat-s3c24xx/setup-i2c.c +++ b/arch/arm/plat-s3c24xx/setup-i2c.c @@ -15,12 +15,13 @@ struct platform_device; +#include <plat/gpio-cfg.h> #include <plat/iic.h> #include <mach/hardware.h> #include <mach/regs-gpio.h> void s3c_i2c0_cfg_gpio(struct platform_device *dev) { - s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA); - s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL); + s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA); + s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL); } 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 da7a61728c1..9793544a6ac 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, int enable) { if (enable) { - s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0); - s3c2410_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0); - s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0); + s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0); + s3c_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0); + s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0); s3c2410_gpio_pullup(S3C2410_GPE(11), 0); s3c2410_gpio_pullup(S3C2410_GPE(13), 0); } else { - s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT); - s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT); - s3c2410_gpio_pullup(S3C2410_GPE(11), 1); - s3c2410_gpio_pullup(S3C2410_GPE(12), 1); - s3c2410_gpio_pullup(S3C2410_GPE(13), 1); + s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE); } } 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 89fcf5308cf..db9e9e477ec 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, printk(KERN_INFO "%s(%d)\n", __func__, enable); if (enable) { - s3c2410_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1); - s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1); - s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1); + s3c_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1); + s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1); + s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1); s3c2410_gpio_pullup(S3C2410_GPD(10), 0); s3c2410_gpio_pullup(S3C2410_GPD(9), 0); } else { - s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT); - s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT); - s3c2410_gpio_pullup(S3C2410_GPD(10), 1); - s3c2410_gpio_pullup(S3C2410_GPD(9), 1); - s3c2410_gpio_pullup(S3C2410_GPD(8), 1); + s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE); } } 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 86b9edc6741..8ea663a438b 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, int enable) { if (enable) { - s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1); - s3c2410_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1); - s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1); + s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1); + s3c_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1); + s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1); s3c2410_gpio_pullup(S3C2410_GPG(5), 0); s3c2410_gpio_pullup(S3C2410_GPG(6), 0); } else { - s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT); - s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT); - s3c2410_gpio_pullup(S3C2410_GPG(5), 1); - s3c2410_gpio_pullup(S3C2410_GPG(6), 1); - s3c2410_gpio_pullup(S3C2410_GPG(7), 1); + s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT); + s3c_gpio_cfgpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE); } } |