From b395e8bfb08444a5dbc391e64e0b8e2358906093 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 3 Sep 2012 10:18:09 +0200 Subject: [PATCH] ARM i.MX: switch to gpiolib support Signed-off-by: Sascha Hauer Signed-off-by: Steffen Trumtrar --- arch/arm/Kconfig | 1 + arch/arm/mach-imx/gpio.c | 94 ++++++++++++++++++++++++--------------- arch/arm/mach-imx/gpio.h | 4 -- arch/arm/mach-imx/imx1.c | 21 +++++---- arch/arm/mach-imx/imx21.c | 23 +++++----- arch/arm/mach-imx/imx25.c | 15 ++----- arch/arm/mach-imx/imx27.c | 19 +++----- arch/arm/mach-imx/imx31.c | 14 ++---- arch/arm/mach-imx/imx35.c | 14 ++---- arch/arm/mach-imx/imx51.c | 16 +++---- arch/arm/mach-imx/imx53.c | 21 +++------ arch/arm/mach-imx/imx6.c | 28 ++++++------ drivers/Kconfig | 1 + 13 files changed, 126 insertions(+), 145 deletions(-) delete mode 100644 arch/arm/mach-imx/gpio.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 08c742bfb..bcc3882cd 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -32,6 +32,7 @@ config ARCH_EP93XX config ARCH_IMX bool "Freescale iMX-based" select GENERIC_GPIO + select GPIOLIB config ARCH_MXS bool "Freescale i.MX23/28 (mxs) based" diff --git a/arch/arm/mach-imx/gpio.c b/arch/arm/mach-imx/gpio.c index fdee20b86..8d5d4ce2b 100644 --- a/arch/arm/mach-imx/gpio.c +++ b/arch/arm/mach-imx/gpio.c @@ -27,7 +27,8 @@ #include #include #include -#include +#include +#include #if defined CONFIG_ARCH_IMX1 || defined CONFIG_ARCH_IMX21 || defined CONFIG_ARCH_IMX27 #define GPIO_DR 0x1c @@ -48,21 +49,15 @@ #define GPIO_ISR 0x18 #endif -extern void __iomem *imx_gpio_base[]; -extern int imx_gpio_count; +struct imx_gpio_chip { + void __iomem *base; + struct gpio_chip chip; +}; -static void __iomem *gpio_get_base(unsigned gpio) +static void imx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) { - if (gpio >= imx_gpio_count) - return NULL; - - return imx_gpio_base[gpio / 32]; -} - -void gpio_set_value(unsigned gpio, int value) -{ - void __iomem *base = gpio_get_base(gpio); - int shift = gpio % 32; + struct imx_gpio_chip *imxgpio = container_of(chip, struct imx_gpio_chip, chip); + void __iomem *base = imxgpio->base; u32 val; if (!base) @@ -71,59 +66,88 @@ void gpio_set_value(unsigned gpio, int value) val = readl(base + GPIO_DR); if (value) - val |= 1 << shift; + val |= 1 << gpio; else - val &= ~(1 << shift); + val &= ~(1 << gpio); writel(val, base + GPIO_DR); } -int gpio_direction_input(unsigned gpio) +static int imx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) { - void __iomem *base = gpio_get_base(gpio); - int shift = gpio % 32; + struct imx_gpio_chip *imxgpio = container_of(chip, struct imx_gpio_chip, chip); + void __iomem *base = imxgpio->base; u32 val; if (!base) return -EINVAL; val = readl(base + GPIO_GDIR); - val &= ~(1 << shift); + val &= ~(1 << gpio); writel(val, base + GPIO_GDIR); return 0; } -int gpio_direction_output(unsigned gpio, int value) +static int imx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) { - void __iomem *base = gpio_get_base(gpio); - int shift = gpio % 32; + struct imx_gpio_chip *imxgpio = container_of(chip, struct imx_gpio_chip, chip); + void __iomem *base = imxgpio->base; u32 val; - if (!base) - return -EINVAL; - - gpio_set_value(gpio, value); + gpio_set_value(gpio + chip->base, value); val = readl(base + GPIO_GDIR); - val |= 1 << shift; + val |= 1 << gpio; writel(val, base + GPIO_GDIR); return 0; } -int gpio_get_value(unsigned gpio) +static int imx_gpio_get_value(struct gpio_chip *chip, unsigned gpio) { - void __iomem *base = gpio_get_base(gpio); - int shift = gpio % 32; + struct imx_gpio_chip *imxgpio = container_of(chip, struct imx_gpio_chip, chip); + void __iomem *base = imxgpio->base; u32 val; - if (!base) - return -EINVAL; - val = readl(base + GPIO_PSR); - return val & (1 << shift) ? 1 : 0; + return val & (1 << gpio) ? 1 : 0; } +static struct gpio_ops imx_gpio_ops = { + .direction_input = imx_gpio_direction_input, + .direction_output = imx_gpio_direction_output, + .get = imx_gpio_get_value, + .set = imx_gpio_set_value, +}; + +static int imx_gpio_probe(struct device_d *dev) +{ + struct imx_gpio_chip *imxgpio; + + imxgpio = xzalloc(sizeof(*imxgpio)); + imxgpio->base = dev_request_mem_region(dev, 0); + imxgpio->chip.ops = &imx_gpio_ops; + imxgpio->chip.base = -1; + imxgpio->chip.ngpio = 32; + imxgpio->chip.dev = dev; + gpiochip_add(&imxgpio->chip); + + dev_info(dev, "probed gpiochip%d with base %d\n", dev->id, imxgpio->chip.base); + + return 0; +} + +static struct driver_d imx_gpio_driver = { + .name = "imx-gpio", + .probe = imx_gpio_probe, +}; + +static int imx_gpio_add(void) +{ + register_driver(&imx_gpio_driver); + return 0; +} +coredevice_initcall(imx_gpio_add); diff --git a/arch/arm/mach-imx/gpio.h b/arch/arm/mach-imx/gpio.h deleted file mode 100644 index 545cebef3..000000000 --- a/arch/arm/mach-imx/gpio.h +++ /dev/null @@ -1,4 +0,0 @@ - -extern void *imx_gpio_base[]; -extern int imx_gpio_count; - diff --git a/arch/arm/mach-imx/imx1.c b/arch/arm/mach-imx/imx1.c index 742a260f0..5a000bc96 100644 --- a/arch/arm/mach-imx/imx1.c +++ b/arch/arm/mach-imx/imx1.c @@ -16,16 +16,15 @@ */ #include +#include -#include "gpio.h" - -void *imx_gpio_base[] = { - (void *)0x0021c000, - (void *)0x0021c100, - (void *)0x0021c200, - (void *)0x0021c300, -}; - -int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; - +static int imx1_init(void) +{ + add_generic_device("imx-gpio", 0, NULL, 0x0021c000, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 1, NULL, 0x0021c100, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 2, NULL, 0x0021c200, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 3, NULL, 0x0021c300, 0x100, IORESOURCE_MEM, NULL); + return 0; +} +coredevice_initcall(imx1_init); diff --git a/arch/arm/mach-imx/imx21.c b/arch/arm/mach-imx/imx21.c index bbef33d2d..85590ee8f 100644 --- a/arch/arm/mach-imx/imx21.c +++ b/arch/arm/mach-imx/imx21.c @@ -18,8 +18,6 @@ #include #include -#include "gpio.h" - int imx_silicon_revision(void) { // Known values: @@ -28,14 +26,15 @@ int imx_silicon_revision(void) return CID; } -void *imx_gpio_base[] = { - (void *)0x10015000, - (void *)0x10015100, - (void *)0x10015200, - (void *)0x10015300, - (void *)0x10015400, - (void *)0x10015500, -}; - -int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; +static int imx21_init(void) +{ + add_generic_device("imx-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 3, NULL, 0x10015300, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 4, NULL, 0x10015400, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 5, NULL, 0x10015500, 0x100, IORESOURCE_MEM, NULL); + return 0; +} +coredevice_initcall(imx21_init); diff --git a/arch/arm/mach-imx/imx25.c b/arch/arm/mach-imx/imx25.c index 19a2909e1..d60502251 100644 --- a/arch/arm/mach-imx/imx25.c +++ b/arch/arm/mach-imx/imx25.c @@ -22,17 +22,6 @@ #include #include -#include "gpio.h" - -void *imx_gpio_base[] = { - (void *)0x53fcc000, - (void *)0x53fd0000, - (void *)0x53fa4000, - (void *)0x53f9c000, -}; - -int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; - u64 imx_uid(void) { u64 uid = 0; @@ -59,6 +48,10 @@ static int imx25_init(void) add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K, IORESOURCE_MEM, &imx25_iim_pdata); + add_generic_device("imx-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 3, NULL, 0x53f9c000, 0x1000, IORESOURCE_MEM, NULL); return 0; } coredevice_initcall(imx25_init); diff --git a/arch/arm/mach-imx/imx27.c b/arch/arm/mach-imx/imx27.c index 1af291d33..c6e6942c5 100644 --- a/arch/arm/mach-imx/imx27.c +++ b/arch/arm/mach-imx/imx27.c @@ -21,24 +21,11 @@ #include #include -#include "gpio.h" - int imx_silicon_revision(void) { return CID >> 28; } -void *imx_gpio_base[] = { - (void *)0x10015000, - (void *)0x10015100, - (void *)0x10015200, - (void *)0x10015300, - (void *)0x10015400, - (void *)0x10015500, -}; - -int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; - /* * Initialize MAX on i.MX27. necessary to give the DMA engine * higher priority to the memory than the CPU. Needed for proper @@ -86,6 +73,12 @@ static int imx27_init(void) imx27_init_max(); + add_generic_device("imx-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 3, NULL, 0x10015300, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 4, NULL, 0x10015400, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 5, NULL, 0x10015500, 0x100, IORESOURCE_MEM, NULL); return 0; } coredevice_initcall(imx27_init); diff --git a/arch/arm/mach-imx/imx31.c b/arch/arm/mach-imx/imx31.c index bb713ca87..90dc4e318 100644 --- a/arch/arm/mach-imx/imx31.c +++ b/arch/arm/mach-imx/imx31.c @@ -20,21 +20,15 @@ #include #include -#include "gpio.h" - -void *imx_gpio_base[] = { - (void *)0x53fcc000, - (void *)0x53fd0000, - (void *)0x53fa4000, -}; - -int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; - static int imx31_init(void) { add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL); + return 0; } coredevice_initcall(imx31_init); diff --git a/arch/arm/mach-imx/imx35.c b/arch/arm/mach-imx/imx35.c index fe0c99ea7..efbee985d 100644 --- a/arch/arm/mach-imx/imx35.c +++ b/arch/arm/mach-imx/imx35.c @@ -23,16 +23,6 @@ #include #include -#include "gpio.h" - -void *imx_gpio_base[] = { - (void *)0x53fcc000, - (void *)0x53fd0000, - (void *)0x53fa4000, -}; - -int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; - int imx_silicon_revision() { uint32_t reg; @@ -66,6 +56,10 @@ static int imx35_init(void) add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL); + return 0; } coredevice_initcall(imx35_init); diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c index 53205a921..e43cc65ec 100644 --- a/arch/arm/mach-imx/imx51.c +++ b/arch/arm/mach-imx/imx51.c @@ -24,17 +24,6 @@ #include #include -#include "gpio.h" - -void *imx_gpio_base[] = { - (void *)MX51_GPIO1_BASE_ADDR, - (void *)MX51_GPIO2_BASE_ADDR, - (void *)MX51_GPIO3_BASE_ADDR, - (void *)MX51_GPIO4_BASE_ADDR, -}; - -int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; - #define SI_REV 0x48 static u32 mx51_silicon_revision; @@ -89,6 +78,11 @@ static int imx51_init(void) add_generic_device("imx_iim", 0, NULL, MX51_IIM_BASE_ADDR, SZ_4K, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 0, NULL, 0x73f84000, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 1, NULL, 0x73f88000, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 2, NULL, 0x73f8c000, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 3, NULL, 0x73f90000, 0x1000, IORESOURCE_MEM, NULL); + return 0; } coredevice_initcall(imx51_init); diff --git a/arch/arm/mach-imx/imx53.c b/arch/arm/mach-imx/imx53.c index 7c679bbe7..cb945753b 100644 --- a/arch/arm/mach-imx/imx53.c +++ b/arch/arm/mach-imx/imx53.c @@ -24,20 +24,6 @@ #include #include -#include "gpio.h" - -void *imx_gpio_base[] = { - (void *)MX53_GPIO1_BASE_ADDR, - (void *)MX53_GPIO2_BASE_ADDR, - (void *)MX53_GPIO3_BASE_ADDR, - (void *)MX53_GPIO4_BASE_ADDR, - (void *)MX53_GPIO5_BASE_ADDR, - (void *)MX53_GPIO6_BASE_ADDR, - (void *)MX53_GPIO7_BASE_ADDR, -}; - -int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; - #define SI_REV 0x48 static u32 mx53_silicon_revision; @@ -88,6 +74,13 @@ static int imx53_init(void) add_generic_device("imx_iim", 0, NULL, MX53_IIM_BASE_ADDR, SZ_4K, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 0, NULL, MX53_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 1, NULL, MX53_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 2, NULL, MX53_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 3, NULL, MX53_GPIO4_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 4, NULL, MX53_GPIO5_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 5, NULL, MX53_GPIO6_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 6, NULL, MX53_GPIO7_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); return 0; } coredevice_initcall(imx53_init); diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c index a44334385..c693724a5 100644 --- a/arch/arm/mach-imx/imx6.c +++ b/arch/arm/mach-imx/imx6.c @@ -21,20 +21,6 @@ #include #include -#include "gpio.h" - -void *imx_gpio_base[] = { - (void *)MX6_GPIO1_BASE_ADDR, - (void *)MX6_GPIO2_BASE_ADDR, - (void *)MX6_GPIO3_BASE_ADDR, - (void *)MX6_GPIO4_BASE_ADDR, - (void *)MX6_GPIO5_BASE_ADDR, - (void *)MX6_GPIO6_BASE_ADDR, - (void *)MX6_GPIO7_BASE_ADDR, -}; - -int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32; - void imx6_init_lowlevel(void) { void __iomem *aips1 = (void *)MX6_AIPS1_ON_BASE_ADDR; @@ -69,3 +55,17 @@ void imx6_init_lowlevel(void) writel(0xffffffff, 0x020c407c); writel(0xffffffff, 0x020c4080); } + +static int imx6_init(void) +{ + add_generic_device("imx-gpio", 0, NULL, MX6_GPIO1_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 1, NULL, MX6_GPIO2_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 2, NULL, MX6_GPIO3_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 3, NULL, MX6_GPIO4_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 4, NULL, MX6_GPIO5_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 5, NULL, MX6_GPIO6_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); + add_generic_device("imx-gpio", 6, NULL, MX6_GPIO7_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); + + return 0; +} +coredevice_initcall(imx6_init); diff --git a/drivers/Kconfig b/drivers/Kconfig index 883b0e7bc..adf8fcd16 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -18,5 +18,6 @@ source "drivers/input/Kconfig" source "drivers/watchdog/Kconfig" source "drivers/pwm/Kconfig" source "drivers/dma/Kconfig" +source "drivers/gpio/Kconfig" endmenu