From mboxrd@z Thu Jan 1 00:00:00 1970 From: Roland Stigge Subject: [PATCH RESEND v9 2/2] gpio: Device tree support for LPC32xx Date: Wed, 16 May 2012 22:40:32 +0200 Message-ID: <1337200832-26630-2-git-send-email-stigge@antcom.de> References: <1337200832-26630-1-git-send-email-stigge@antcom.de> Return-path: In-Reply-To: <1337200832-26630-1-git-send-email-stigge@antcom.de> Sender: linux-kernel-owner@vger.kernel.org To: glikely@secretlab.ca, arm@kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linus.walleij@stericsson.com, kevin.wells@nxp.com, srinivas.bakki@nxp.com, devicetree-discuss@lists.ozlabs.org, rob.herring@calxeda.com Cc: Roland Stigge List-Id: devicetree@vger.kernel.org This patch adds device tree support for gpio-lpc32xx.c. To register the various GPIO banks as (struct) gpio_chips via the same DT gpio-controller, we utilize the adjusted of_xlate API to manipulate the actually used struct gpio_chip. Signed-off-by: Roland Stigge Reviewed-by: Arnd Bergmann --- Applies to v3.4-rc7 Changes since last version: * Use new of_xlate API: Register all GPIO banks at once via the same GPIO controller DT entry by manipulating the actually used struct gpio_chip. * Updated devicetree binding documentation Thanks to Jean-Christophe PLAGNIOL-VILLARD, Grant Likely, Arnd Bergmann, Jon Smirl, Mark Brown for reviewing! You can also pull from: git://git.antcom.de/linux-2.6.git dt/gpio http://git.antcom.de/linux-2.6.git dt/gpio http://git.antcom.de/?p=linux-2.6.git;a=shortlog;h=refs/heads/dt/gpio Documentation/devicetree/bindings/gpio/gpio_lpc32xx.txt | 43 ++++++++++++ arch/arm/mach-lpc32xx/include/mach/gpio.h | 9 ++ drivers/gpio/gpio-lpc32xx.c | 55 +++++++++++++++- 3 files changed, 105 insertions(+), 2 deletions(-) --- /dev/null +++ linux-2.6/Documentation/devicetree/bindings/gpio/gpio_lpc32xx.txt @@ -0,0 +1,43 @@ +NXP LPC32xx SoC GPIO controller + +Required properties: +- compatible: must be "nxp,lpc3220-gpio" +- reg: Physical base address and length of the controller's registers. +- gpio-controller: Marks the device node as a GPIO controller. +- #gpio-cells: Should be 3: + 1) bank: + 0: GPIO P0 + 1: GPIO P1 + 2: GPIO P2 + 3: GPIO P3 + 4: GPI P3 + 5: GPO P3 + 2) pin number + 3) optional parameters: + - bit 0 specifies polarity (0 for normal, 1 for inverted) +- reg: Index of the GPIO group + +Example: + + gpio: gpio@40028000 { + compatible = "nxp,lpc3220-gpio"; + reg = <0x40028000 0x1000>; + gpio-controller; + #gpio-cells = <3>; /* bank, pin, flags */ + }; + + leds { + compatible = "gpio-leds"; + + led0 { + gpios = <&gpio 5 1 1>; /* GPO_P3 1, active low */ + linux,default-trigger = "heartbeat"; + default-state = "off"; + }; + + led1 { + gpios = <&gpio 5 14 1>; /* GPO_P3 14, active low */ + linux,default-trigger = "timer"; + default-state = "off"; + }; + }; --- linux-2.6.orig/arch/arm/mach-lpc32xx/include/mach/gpio.h +++ linux-2.6/arch/arm/mach-lpc32xx/include/mach/gpio.h @@ -1 +1,8 @@ -/* empty */ +#ifndef __MACH_GPIO_H +#define __MACH_GPIO_H + +#include "gpio-lpc32xx.h" + +#define ARCH_NR_GPIOS (LPC32XX_GPO_P3_GRP + LPC32XX_GPO_P3_MAX) + +#endif /* __MACH_GPIO_H */ --- linux-2.6.orig/drivers/gpio/gpio-lpc32xx.c +++ linux-2.6/drivers/gpio/gpio-lpc32xx.c @@ -21,6 +21,9 @@ #include #include #include +#include +#include +#include #include #include @@ -454,10 +457,60 @@ static struct lpc32xx_gpio_chip lpc32xx_ }, }; +/* Empty now, can be removed later when mach-lpc32xx is finally switched over + * to DT support + */ void __init lpc32xx_gpio_init(void) { +} + +static int lpc32xx_of_xlate(struct gpio_chip **gc, + const struct of_phandle_args *gpiospec, u32 *flags) +{ + u32 bank; + if (WARN_ON(gpiospec->args_count < 3)) + return -EINVAL; + + bank = gpiospec->args[0]; + if (WARN_ON(bank > 5)) + return -EINVAL; + + *gc = &lpc32xx_gpiochip[bank].chip; + if (flags) + *flags = gpiospec->args[2]; + return gpiospec->args[1]; +} + +static int __devinit lpc32xx_gpio_probe(struct platform_device *pdev) +{ int i; - for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) + for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) { + if (pdev->dev.of_node) { + lpc32xx_gpiochip[i].chip.of_xlate = lpc32xx_of_xlate; + lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3; + lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node; + } gpiochip_add(&lpc32xx_gpiochip[i].chip); + } + + return 0; } + +#ifdef CONFIG_OF +static struct of_device_id lpc32xx_gpio_of_match[] __devinitdata = { + { .compatible = "nxp,lpc3220-gpio", }, + { }, +}; +#endif + +static struct platform_driver lpc32xx_gpio_driver = { + .driver = { + .name = "lpc32xx-gpio", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(lpc32xx_gpio_of_match), + }, + .probe = lpc32xx_gpio_probe, +}; + +module_platform_driver(lpc32xx_gpio_driver);