gpio/lpc32xx: Add device tree support

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 <stigge@antcom.de>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
This commit is contained in:
Roland Stigge 2012-05-18 10:19:52 +02:00 committed by Grant Likely
parent 3d0f7cf0f3
commit e92935e13a
3 changed files with 102 additions and 2 deletions

View File

@ -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";
};
};

View File

@ -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 */

View File

@ -21,6 +21,9 @@
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/platform.h>
@ -454,10 +457,57 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
},
};
/* 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)
{
/* Is this the correct bank? */
u32 bank = gpiospec->args[0];
if ((bank > ARRAY_SIZE(lpc32xx_gpiochip) ||
(gc != &lpc32xx_gpiochip[bank].chip)))
return -EINVAL;
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);