This patch is trying to add device tree support to the GPIOs found on the kirkwood/orion/mv78xx0 SoCs. not-yet-Signed-off-by: Arnaud Patard Index: arm-soc/arch/arm/boot/dts/kirkwood.dtsi =================================================================== --- arm-soc.orig/arch/arm/boot/dts/kirkwood.dtsi 2012-04-22 19:24:43.496917390 +0200 +++ arm-soc/arch/arm/boot/dts/kirkwood.dtsi 2012-04-22 19:25:10.348916210 +0200 @@ -3,6 +3,11 @@ / { compatible = "mrvl,kirkwood"; + aliases { + gpio0 = &gpio_low; + gpio1 = &gpio_high; + }; + ocp@f1000000 { compatible = "simple-bus"; ranges = <0 0xf1000000 0x1000000>; @@ -27,10 +32,29 @@ status = "disabled"; }; + gpio_low: gpio@10100 { + compatible = "mrvl,kirkwood-gpio","mrvl,orion-gpio"; + reg = <0x10100 0x40>; + interrupts = <64>; + #gpio-cells = <2>; + gpio-controller; + }; + + gpio_high: gpio@10140 { + compatible = "mrvl,kirkwood-gpio","mrvl,orion-gpio"; + reg = <0x10140 0x40>; + interrupts = <96>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + rtc@10300 { compatible = "mrvl,kirkwood-rtc", "mrvl,orion-rtc"; reg = <0x10300 0x20>; interrupts = <53>; + interrupt-controller; }; + }; }; Index: arm-soc/arch/arm/mach-kirkwood/irq.c =================================================================== --- arm-soc.orig/arch/arm/mach-kirkwood/irq.c 2012-04-22 19:24:43.516917390 +0200 +++ arm-soc/arch/arm/mach-kirkwood/irq.c 2012-04-22 19:25:10.348916210 +0200 @@ -32,15 +32,17 @@ void __init kirkwood_init_irq(void) /* * Initialize gpiolib for GPIOs 0-49. */ - orion_gpio_init(0, 32, GPIO_LOW_VIRT_BASE, 0, + if (orion_of_gpio_init() < 0) { + orion_gpio_init(0, 32, GPIO_LOW_VIRT_BASE, 0, IRQ_KIRKWOOD_GPIO_START); + orion_gpio_init(32, 18, GPIO_HIGH_VIRT_BASE, 0, + IRQ_KIRKWOOD_GPIO_START + 32); + } irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_0_7, gpio_irq_handler); irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_8_15, gpio_irq_handler); irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_16_23, gpio_irq_handler); irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_24_31, gpio_irq_handler); - orion_gpio_init(32, 18, GPIO_HIGH_VIRT_BASE, 0, - IRQ_KIRKWOOD_GPIO_START + 32); irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_0_7, gpio_irq_handler); irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_8_15, gpio_irq_handler); irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_16_23, Index: arm-soc/arch/arm/plat-orion/gpio.c =================================================================== --- arm-soc.orig/arch/arm/plat-orion/gpio.c 2012-04-22 19:25:10.104916220 +0200 +++ arm-soc/arch/arm/plat-orion/gpio.c 2012-04-22 19:25:10.356916209 +0200 @@ -17,6 +17,9 @@ #include #include #include +#include +#include +#include /* * GPIO unit register offsets. @@ -401,8 +404,9 @@ static int gpio_irq_set_type(struct irq_ return 0; } -void __init orion_gpio_init(int gpio_base, int ngpio, - u32 base, int mask_offset, int secondary_irq_base) +static void __init _orion_gpio_init(int gpio_base, int ngpio, + u32 base, int mask_offset, + int secondary_irq_base, struct device_node *np) { struct orion_gpio_chip *ochip; struct irq_chip_generic *gc; @@ -426,13 +430,15 @@ void __init orion_gpio_init(int gpio_bas ochip->chip.base = gpio_base; ochip->chip.ngpio = ngpio; ochip->chip.can_sleep = 0; +#if defined(CONFIG_OF_GPIO) + ochip->chip.of_node = np; +#endif spin_lock_init(&ochip->lock); ochip->base = (void __iomem *)base; ochip->valid_input = 0; ochip->valid_output = 0; ochip->mask_offset = mask_offset; ochip->secondary_irq_base = secondary_irq_base; - gpiochip_add(&ochip->chip); orion_gpio_chip_count++; @@ -469,6 +475,62 @@ void __init orion_gpio_init(int gpio_bas IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); } +void __init orion_gpio_init(int gpio_base, int ngpio, + u32 base, int mask_offset, int secondary_irq_base) +{ + _orion_gpio_init(gpio_base, ngpio, base, mask_offset, + secondary_irq_base, NULL); +} + +static const int mv78xx0_ngpios[] = { 32 }; +static const int orion5x_ngpios[] = { 32 }; +static const int kirkwood_ngpios[] = { 32, 18 }; +static const int dove_ngpios[] = { 32, 32, 8 }; + +#ifdef CONFIG_OF_GPIO +int __init orion_of_gpio_init(void) +{ + struct device_node *np = NULL; + int idx, found; + u32 base, irq, ngpios; + + found = 0; + ngpios = 32; + for_each_compatible_node(np, NULL, "mrvl,orion-gpio") { + idx = of_alias_get_id(np, "gpio"); + + base = (u32)of_iomap(np, 0); + if (!base) { + pr_err("orion-gpio%d, failed to map registers, ignoring.\n", + idx); + continue; + } + + if (of_property_read_u32(np, "interrupts", &irq)) { + pr_err("orion-gpio%d, failed to get interrupts property, ignoring.\n", + idx); + continue; + } + + if (of_device_is_compatible(np, "mrvl,mv78xx0-gpio")) + ngpios = mv78xx0_ngpios[idx]; + if (of_device_is_compatible(np, "mrvl,orion5x-gpio")) + ngpios = orion5x_ngpios[idx]; + if (of_device_is_compatible(np, "mrvl,kirkwood-gpio")) + ngpios = kirkwood_ngpios[idx]; + if (of_device_is_compatible(np, "mrvl,dove-gpio")) + ngpios = dove_ngpios[idx]; + + found = 1; + _orion_gpio_init(idx*32, ngpios, base, 0, irq, np); + } + if (found) + return 0; + + return -EINVAL; +} +#endif + void orion_gpio_irq_handler(int pinoff) { struct orion_gpio_chip *ochip; Index: arm-soc/arch/arm/plat-orion/include/plat/gpio.h =================================================================== --- arm-soc.orig/arch/arm/plat-orion/include/plat/gpio.h 2012-04-22 19:25:10.124916220 +0200 +++ arm-soc/arch/arm/plat-orion/include/plat/gpio.h 2012-04-22 19:25:10.364916209 +0200 @@ -13,6 +13,7 @@ #include #include +#include /* * Orion-specific GPIO API extensions. @@ -29,6 +30,14 @@ void orion_gpio_set_valid(unsigned pin, /* Initialize gpiolib. */ void __init orion_gpio_init(int gpio_base, int ngpio, u32 base, int mask_offset, int secondary_irq_base); +#ifdef CONFIG_OF_GPIO +int __init orion_of_gpio_init(void); +#else +static inline int __init orion_of_gpio_init(void) +{ + return -EINVAL; +} +#endif /* * GPIO interrupt handling. Index: arm-soc/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt =================================================================== --- arm-soc.orig/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt 2012-04-15 21:19:57.631222232 +0200 +++ arm-soc/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt 2012-04-22 21:08:15.404644090 +0200 @@ -21,3 +21,23 @@ Example: interrupt-controller; #interrupt-cells = <1>; }; + +* Marvell orion / kirkwood GPIO controller + +Required properties: +- compatible : should be at least "mrvl,orion-gpio" +- reg : address/length of the gpio registers +- interrupts : base interrupt for the gpios +- #gpio-cells : should be 2. First is the pin number and the second gpio flag + (for instance for the active low flag) +- gpio-controller + +Example: + gpio_low: gpio@10100 { + compatible = "mrvl,kirkwood-gpio","mrvl,orion-gpio"; + reg = <0x10100 0x40>; + interrupts = <64>; + #gpio-cells = <2>; + gpio-controller; + }; +