From 7603f7442bdd473c6986279c41ee7a7321ba1847 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 21 Nov 2013 08:21:21 +0100 Subject: gpio: omap: move to drivers/gpio/ Signed-off-by: Sascha Hauer --- drivers/gpio/Kconfig | 3 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-omap.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+) create mode 100644 drivers/gpio/gpio-omap.c (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 18d3135eb8..7c426563e7 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -30,6 +30,9 @@ config GPIO_GENERIC_PLATFORM config GPIO_IMX def_bool ARCH_IMX +config GPIO_OMAP + def_bool ARCH_OMAP + config GPIO_ORION bool "GPIO support for Marvell Orion/MVEBU SoCs" depends on ARCH_MVEBU diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index dc9fb13d29..b7c536d21b 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o obj-$(CONFIG_GPIO_IMX) += gpio-imx.o obj-$(CONFIG_GPIO_ORION) += gpio-orion.o +obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c new file mode 100644 index 0000000000..49ffbda503 --- /dev/null +++ b/drivers/gpio/gpio-omap.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2009 Wind River Systems, Inc. + * Tom Rix + * + * 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. + * + * + * This work is derived from the linux 2.6.27 kernel source + * To fetch, use the kernel repository + * git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git + * Use the v2.6.27 tag. + * + * Below is the original's header including its copyright + * + * linux/arch/arm/plat-omap/gpio.c + * + * Support functions for OMAP GPIO + * + * Copyright (C) 2003-2005 Nokia Corporation + * Written by Juha Yrjölä + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#define OMAP_GPIO_OE 0x0034 +#define OMAP_GPIO_DATAIN 0x0038 +#define OMAP_GPIO_DATAOUT 0x003c +#define OMAP_GPIO_CLEARDATAOUT 0x0090 +#define OMAP_GPIO_SETDATAOUT 0x0094 + +struct omap_gpio_chip { + void __iomem *base; + struct gpio_chip chip; +}; + +static inline int omap_get_gpio_index(int gpio) +{ + return gpio & 0x1f; +} + +static void omap_gpio_set_value(struct gpio_chip *chip, + unsigned gpio, int value) +{ + struct omap_gpio_chip *omapgpio = + container_of(chip, struct omap_gpio_chip, chip); + void __iomem *base = omapgpio->base; + u32 l = 0; + + if (value) + base += OMAP_GPIO_SETDATAOUT; + else + base += OMAP_GPIO_CLEARDATAOUT; + + l = 1 << omap_get_gpio_index(gpio); + + writel(l, base); +} + +static int omap_gpio_direction_input(struct gpio_chip *chip, + unsigned gpio) +{ + struct omap_gpio_chip *omapgpio = + container_of(chip, struct omap_gpio_chip, chip); + void __iomem *base = omapgpio->base; + u32 val; + + base += OMAP_GPIO_OE; + + val = readl(base); + val |= 1 << omap_get_gpio_index(gpio); + writel(val, base); + + return 0; +} + +static int omap_gpio_direction_output(struct gpio_chip *chip, + unsigned gpio, int value) +{ + struct omap_gpio_chip *omapgpio = + container_of(chip, struct omap_gpio_chip, chip); + void __iomem *base = omapgpio->base; + u32 val; + + omap_gpio_set_value(chip, gpio, value); + + base += OMAP_GPIO_OE; + + val = readl(base); + val &= ~(1 << omap_get_gpio_index(gpio)); + writel(val, base); + + return 0; +} + +static int omap_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + struct omap_gpio_chip *omapgpio = + container_of(chip, struct omap_gpio_chip, chip); + void __iomem *base = omapgpio->base; + + base += OMAP_GPIO_DATAIN; + + return (readl(base) & (1 << omap_get_gpio_index(gpio))) != 0; + +} + +static struct gpio_ops omap_gpio_ops = { + .direction_input = omap_gpio_direction_input, + .direction_output = omap_gpio_direction_output, + .get = omap_gpio_get_value, + .set = omap_gpio_set_value, +}; + +static int omap_gpio_probe(struct device_d *dev) +{ + struct omap_gpio_chip *omapgpio; + + omapgpio = xzalloc(sizeof(*omapgpio)); + omapgpio->base = dev_request_mem_region(dev, 0); + omapgpio->chip.ops = &omap_gpio_ops; + omapgpio->chip.base = dev->id * 32; + omapgpio->chip.ngpio = 32; + omapgpio->chip.dev = dev; + gpiochip_add(&omapgpio->chip); + + dev_dbg(dev, "probed gpiochip%d with base %d\n", + dev->id, omapgpio->chip.base); + + return 0; +} + +static struct driver_d omap_gpio_driver = { + .name = "omap-gpio", + .probe = omap_gpio_probe, +}; + +static int omap_gpio_add(void) +{ + return platform_driver_register(&omap_gpio_driver); +} +coredevice_initcall(omap_gpio_add); -- cgit v1.2.3 From 15d60e523086a642ced3bf4f07e2666098845fc6 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 21 Nov 2013 11:19:36 +0100 Subject: gpio: omap: Add devicetree probe support This adds devicetree probe support for the OMAP gpio ports and also makes sure the corresponding platform_devices don't get registered when they are already present from devicetree. Signed-off-by: Sascha Hauer --- drivers/gpio/gpio-omap.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 49ffbda503..e66a614f21 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -48,6 +48,18 @@ struct omap_gpio_chip { struct gpio_chip chip; }; +struct omap_gpio_drvdata { + unsigned int regofs; +}; + +static struct omap_gpio_drvdata gpio_omap3_drvdata = { + .regofs = 0x0, +}; + +static struct omap_gpio_drvdata gpio_omap4_drvdata = { + .regofs = 0x100, +}; + static inline int omap_get_gpio_index(int gpio) { return gpio & 0x1f; @@ -129,11 +141,24 @@ static struct gpio_ops omap_gpio_ops = { static int omap_gpio_probe(struct device_d *dev) { struct omap_gpio_chip *omapgpio; + struct omap_gpio_drvdata *drvdata = NULL; + + dev_get_drvdata(dev, (unsigned long *)&drvdata); omapgpio = xzalloc(sizeof(*omapgpio)); omapgpio->base = dev_request_mem_region(dev, 0); + if (drvdata) + omapgpio->base += drvdata->regofs; + omapgpio->chip.ops = &omap_gpio_ops; - omapgpio->chip.base = dev->id * 32; + if (dev->id < 0) { + omapgpio->chip.base = of_alias_get_id(dev->device_node, "gpio"); + if (omapgpio->chip.base < 0) + return omapgpio->chip.base; + omapgpio->chip.base *= 32; + } else { + omapgpio->chip.base = dev->id * 32; + } omapgpio->chip.ngpio = 32; omapgpio->chip.dev = dev; gpiochip_add(&omapgpio->chip); @@ -144,9 +169,21 @@ static int omap_gpio_probe(struct device_d *dev) return 0; } +static __maybe_unused struct of_device_id omap_gpio_dt_ids[] = { + { + .compatible = "ti,omap4-gpio", + .data = (unsigned long)&gpio_omap4_drvdata, + }, { + .compatible = "ti,omap3-gpio", + .data = (unsigned long)&gpio_omap3_drvdata, + }, { + } +}; + static struct driver_d omap_gpio_driver = { .name = "omap-gpio", .probe = omap_gpio_probe, + .of_compatible = DRV_OF_COMPAT(omap_gpio_dt_ids), }; static int omap_gpio_add(void) -- cgit v1.2.3