Loading arch/arm/plat-s3c24xx/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ config PLAT_S3C24XX depends on ARCH_S3C2410 default y if ARCH_S3C2410 select NO_IOPORT select HAVE_GPIO_LIB help Base platform code for any Samsung S3C24XX device Loading arch/arm/plat-s3c24xx/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ obj-y += cpu.o obj-y += irq.o obj-y += devs.o obj-y += gpio.o obj-y += gpiolib.o obj-y += time.o obj-y += clock.o Loading arch/arm/plat-s3c24xx/gpiolib.c 0 → 100644 +259 −0 Original line number Diff line number Diff line /* linux/arch/arm/plat-s3c24xx/gpiolib.c * * Copyright (c) 2008 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks <ben@simtec.co.uk> * * S3C24XX GPIOlib support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. */ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/io.h> #include <linux/gpio.h> #include <asm/hardware.h> #include <asm/irq.h> #include <asm/arch/regs-gpio.h> struct s3c24xx_gpio_chip { struct gpio_chip chip; void __iomem *base; }; static inline struct s3c24xx_gpio_chip *to_s3c_chip(struct gpio_chip *gpc) { return container_of(gpc, struct s3c24xx_gpio_chip, chip); } /* these routines are exported for use by other parts of the platform * and system support, but are not intended to be used directly by the * drivers themsevles. */ int s3c24xx_gpiolib_input(struct gpio_chip *chip, unsigned offset) { struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); void __iomem *base = ourchip->base; unsigned long flags; unsigned long con; local_irq_save(flags); con = __raw_readl(base + 0x00); con &= ~(3 << (offset * 2)); con |= (S3C2410_GPIO_OUTPUT & 0xf) << (offset * 2); __raw_writel(con, base + 0x00); local_irq_restore(flags); return 0; } int s3c24xx_gpiolib_output(struct gpio_chip *chip, unsigned offset, int value) { struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); void __iomem *base = ourchip->base; unsigned long flags; unsigned long dat; unsigned long con; local_irq_save(flags); dat = __raw_readl(base + 0x04); dat &= ~(1 << offset); if (value) dat |= 1 << offset; __raw_writel(dat, base + 0x04); con = __raw_readl(base + 0x00); con &= ~(3 << (offset * 2)); con |= (S3C2410_GPIO_OUTPUT & 0xf) << (offset * 2); __raw_writel(con, base + 0x00); __raw_writel(dat, base + 0x04); local_irq_restore(flags); return 0; } void s3c24xx_gpiolib_set(struct gpio_chip *chip, unsigned offset, int value) { struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); void __iomem *base = ourchip->base; unsigned long flags; unsigned long dat; local_irq_save(flags); dat = __raw_readl(base + 0x04); dat &= ~(1 << offset); if (value) dat |= 1 << offset; __raw_writel(dat, base + 0x04); local_irq_restore(flags); } int s3c24xx_gpiolib_get(struct gpio_chip *chip, unsigned offset) { struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); unsigned long val; val = __raw_readl(ourchip->base + 0x04); val >>= offset; val &= 1; return val; } static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset) { return -EINVAL; } static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip, unsigned offset, int value) { struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); void __iomem *base = ourchip->base; unsigned long flags; unsigned long dat; unsigned long con; local_irq_save(flags); con = __raw_readl(base + 0x00); dat = __raw_readl(base + 0x04); dat &= ~(1 << offset); if (value) dat |= 1 << offset; __raw_writel(dat, base + 0x04); con &= ~(1 << offset); __raw_writel(con, base + 0x00); __raw_writel(dat, base + 0x04); local_irq_restore(flags); return 0; } struct s3c24xx_gpio_chip gpios[] = { [0] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPA0), .chip = { .base = S3C2410_GPA0, .owner = THIS_MODULE, .label = "GPIOA", .ngpio = 24, .direction_input = s3c24xx_gpiolib_banka_input, .direction_output = s3c24xx_gpiolib_banka_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, [1] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPB0), .chip = { .base = S3C2410_GPB0, .owner = THIS_MODULE, .label = "GPIOB", .ngpio = 16, .direction_input = s3c24xx_gpiolib_input, .direction_output = s3c24xx_gpiolib_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, [2] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPC0), .chip = { .base = S3C2410_GPC0, .owner = THIS_MODULE, .label = "GPIOC", .ngpio = 16, .direction_input = s3c24xx_gpiolib_input, .direction_output = s3c24xx_gpiolib_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, [3] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPD0), .chip = { .base = S3C2410_GPD0, .owner = THIS_MODULE, .label = "GPIOD", .ngpio = 16, .direction_input = s3c24xx_gpiolib_input, .direction_output = s3c24xx_gpiolib_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, [4] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPE0), .chip = { .base = S3C2410_GPE0, .label = "GPIOE", .owner = THIS_MODULE, .ngpio = 16, .direction_input = s3c24xx_gpiolib_input, .direction_output = s3c24xx_gpiolib_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, [5] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPF0), .chip = { .base = S3C2410_GPF0, .owner = THIS_MODULE, .label = "GPIOF", .ngpio = 8, .direction_input = s3c24xx_gpiolib_input, .direction_output = s3c24xx_gpiolib_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, [6] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPG0), .chip = { .base = S3C2410_GPG0, .owner = THIS_MODULE, .label = "GPIOG", .ngpio = 10, .direction_input = s3c24xx_gpiolib_input, .direction_output = s3c24xx_gpiolib_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, }; static __init int s3c24xx_gpiolib_init(void) { struct s3c24xx_gpio_chip *chip = gpios; int gpn; for (gpn = 0; gpn < ARRAY_SIZE(gpios); gpn++, chip++) gpiochip_add(&chip->chip); return 0; } arch_initcall(s3c24xx_gpiolib_init); include/asm-arm/arch-s3c2410/gpio.h +12 −62 Original line number Diff line number Diff line /* * linux/include/asm-arm/arch-s3c2410/gpio.h /* linux/include/asm-arm/arch-s3c2410/gpio.h * * S3C2410 GPIO wrappers for arch-neutral GPIO calls * Copyright (c) 2008 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks <ben@simtec.co.uk> * * Written by Philipp Zabel <philipp.zabel@gmail.com> * S3C2410 - GPIO lib support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #ifndef __ASM_ARCH_S3C2410_GPIO_H #define __ASM_ARCH_S3C2410_GPIO_H #include <asm/irq.h> #include <asm/hardware.h> #include <asm/arch/regs-gpio.h> static inline int gpio_request(unsigned gpio, const char *label) { return 0; } static inline void gpio_free(unsigned gpio) { return; } static inline int gpio_direction_input(unsigned gpio) { s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_INPUT); return 0; } static inline int gpio_direction_output(unsigned gpio, int value) { s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_OUTPUT); /* REVISIT can we write the value first, to avoid glitching? */ s3c2410_gpio_setpin(gpio, value); return 0; } #define gpio_get_value(gpio) s3c2410_gpio_getpin(gpio) #define gpio_set_value(gpio,value) s3c2410_gpio_setpin(gpio, value) #include <asm-generic/gpio.h> /* cansleep wrappers */ #ifdef CONFIG_CPU_S3C2400 #define gpio_to_irq(gpio) s3c2400_gpio_getirq(gpio) #else #define gpio_to_irq(gpio) s3c2410_gpio_getirq(gpio) #endif /* FIXME implement irq_to_gpio() */ #define gpio_get_value __gpio_get_value #define gpio_set_value __gpio_set_value #define gpio_cansleep __gpio_cansleep #endif #include <asm-generic/gpio.h> Loading
arch/arm/plat-s3c24xx/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ config PLAT_S3C24XX depends on ARCH_S3C2410 default y if ARCH_S3C2410 select NO_IOPORT select HAVE_GPIO_LIB help Base platform code for any Samsung S3C24XX device Loading
arch/arm/plat-s3c24xx/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ obj-y += cpu.o obj-y += irq.o obj-y += devs.o obj-y += gpio.o obj-y += gpiolib.o obj-y += time.o obj-y += clock.o Loading
arch/arm/plat-s3c24xx/gpiolib.c 0 → 100644 +259 −0 Original line number Diff line number Diff line /* linux/arch/arm/plat-s3c24xx/gpiolib.c * * Copyright (c) 2008 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks <ben@simtec.co.uk> * * S3C24XX GPIOlib support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. */ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/io.h> #include <linux/gpio.h> #include <asm/hardware.h> #include <asm/irq.h> #include <asm/arch/regs-gpio.h> struct s3c24xx_gpio_chip { struct gpio_chip chip; void __iomem *base; }; static inline struct s3c24xx_gpio_chip *to_s3c_chip(struct gpio_chip *gpc) { return container_of(gpc, struct s3c24xx_gpio_chip, chip); } /* these routines are exported for use by other parts of the platform * and system support, but are not intended to be used directly by the * drivers themsevles. */ int s3c24xx_gpiolib_input(struct gpio_chip *chip, unsigned offset) { struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); void __iomem *base = ourchip->base; unsigned long flags; unsigned long con; local_irq_save(flags); con = __raw_readl(base + 0x00); con &= ~(3 << (offset * 2)); con |= (S3C2410_GPIO_OUTPUT & 0xf) << (offset * 2); __raw_writel(con, base + 0x00); local_irq_restore(flags); return 0; } int s3c24xx_gpiolib_output(struct gpio_chip *chip, unsigned offset, int value) { struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); void __iomem *base = ourchip->base; unsigned long flags; unsigned long dat; unsigned long con; local_irq_save(flags); dat = __raw_readl(base + 0x04); dat &= ~(1 << offset); if (value) dat |= 1 << offset; __raw_writel(dat, base + 0x04); con = __raw_readl(base + 0x00); con &= ~(3 << (offset * 2)); con |= (S3C2410_GPIO_OUTPUT & 0xf) << (offset * 2); __raw_writel(con, base + 0x00); __raw_writel(dat, base + 0x04); local_irq_restore(flags); return 0; } void s3c24xx_gpiolib_set(struct gpio_chip *chip, unsigned offset, int value) { struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); void __iomem *base = ourchip->base; unsigned long flags; unsigned long dat; local_irq_save(flags); dat = __raw_readl(base + 0x04); dat &= ~(1 << offset); if (value) dat |= 1 << offset; __raw_writel(dat, base + 0x04); local_irq_restore(flags); } int s3c24xx_gpiolib_get(struct gpio_chip *chip, unsigned offset) { struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); unsigned long val; val = __raw_readl(ourchip->base + 0x04); val >>= offset; val &= 1; return val; } static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset) { return -EINVAL; } static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip, unsigned offset, int value) { struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); void __iomem *base = ourchip->base; unsigned long flags; unsigned long dat; unsigned long con; local_irq_save(flags); con = __raw_readl(base + 0x00); dat = __raw_readl(base + 0x04); dat &= ~(1 << offset); if (value) dat |= 1 << offset; __raw_writel(dat, base + 0x04); con &= ~(1 << offset); __raw_writel(con, base + 0x00); __raw_writel(dat, base + 0x04); local_irq_restore(flags); return 0; } struct s3c24xx_gpio_chip gpios[] = { [0] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPA0), .chip = { .base = S3C2410_GPA0, .owner = THIS_MODULE, .label = "GPIOA", .ngpio = 24, .direction_input = s3c24xx_gpiolib_banka_input, .direction_output = s3c24xx_gpiolib_banka_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, [1] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPB0), .chip = { .base = S3C2410_GPB0, .owner = THIS_MODULE, .label = "GPIOB", .ngpio = 16, .direction_input = s3c24xx_gpiolib_input, .direction_output = s3c24xx_gpiolib_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, [2] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPC0), .chip = { .base = S3C2410_GPC0, .owner = THIS_MODULE, .label = "GPIOC", .ngpio = 16, .direction_input = s3c24xx_gpiolib_input, .direction_output = s3c24xx_gpiolib_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, [3] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPD0), .chip = { .base = S3C2410_GPD0, .owner = THIS_MODULE, .label = "GPIOD", .ngpio = 16, .direction_input = s3c24xx_gpiolib_input, .direction_output = s3c24xx_gpiolib_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, [4] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPE0), .chip = { .base = S3C2410_GPE0, .label = "GPIOE", .owner = THIS_MODULE, .ngpio = 16, .direction_input = s3c24xx_gpiolib_input, .direction_output = s3c24xx_gpiolib_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, [5] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPF0), .chip = { .base = S3C2410_GPF0, .owner = THIS_MODULE, .label = "GPIOF", .ngpio = 8, .direction_input = s3c24xx_gpiolib_input, .direction_output = s3c24xx_gpiolib_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, [6] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPG0), .chip = { .base = S3C2410_GPG0, .owner = THIS_MODULE, .label = "GPIOG", .ngpio = 10, .direction_input = s3c24xx_gpiolib_input, .direction_output = s3c24xx_gpiolib_output, .set = s3c24xx_gpiolib_set, .get = s3c24xx_gpiolib_get, }, }, }; static __init int s3c24xx_gpiolib_init(void) { struct s3c24xx_gpio_chip *chip = gpios; int gpn; for (gpn = 0; gpn < ARRAY_SIZE(gpios); gpn++, chip++) gpiochip_add(&chip->chip); return 0; } arch_initcall(s3c24xx_gpiolib_init);
include/asm-arm/arch-s3c2410/gpio.h +12 −62 Original line number Diff line number Diff line /* * linux/include/asm-arm/arch-s3c2410/gpio.h /* linux/include/asm-arm/arch-s3c2410/gpio.h * * S3C2410 GPIO wrappers for arch-neutral GPIO calls * Copyright (c) 2008 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks <ben@simtec.co.uk> * * Written by Philipp Zabel <philipp.zabel@gmail.com> * S3C2410 - GPIO lib support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #ifndef __ASM_ARCH_S3C2410_GPIO_H #define __ASM_ARCH_S3C2410_GPIO_H #include <asm/irq.h> #include <asm/hardware.h> #include <asm/arch/regs-gpio.h> static inline int gpio_request(unsigned gpio, const char *label) { return 0; } static inline void gpio_free(unsigned gpio) { return; } static inline int gpio_direction_input(unsigned gpio) { s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_INPUT); return 0; } static inline int gpio_direction_output(unsigned gpio, int value) { s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_OUTPUT); /* REVISIT can we write the value first, to avoid glitching? */ s3c2410_gpio_setpin(gpio, value); return 0; } #define gpio_get_value(gpio) s3c2410_gpio_getpin(gpio) #define gpio_set_value(gpio,value) s3c2410_gpio_setpin(gpio, value) #include <asm-generic/gpio.h> /* cansleep wrappers */ #ifdef CONFIG_CPU_S3C2400 #define gpio_to_irq(gpio) s3c2400_gpio_getirq(gpio) #else #define gpio_to_irq(gpio) s3c2410_gpio_getirq(gpio) #endif /* FIXME implement irq_to_gpio() */ #define gpio_get_value __gpio_get_value #define gpio_set_value __gpio_set_value #define gpio_cansleep __gpio_cansleep #endif #include <asm-generic/gpio.h>