* [PATCH 8/9] ARM: Kirkwood: Add DT support for GPIO controllers @ 2012-06-10 10:32 Andrew Lunn [not found] ` <1339324322-29388-9-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org> 0 siblings, 1 reply; 3+ messages in thread From: Andrew Lunn @ 2012-06-10 10:32 UTC (permalink / raw) To: jason-NLaQJdtUoK4Be96aLqz0jA Cc: grant.likely-s3s/WqlpOiPyB63q8FvJNQ, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, linux-i2c-u79uwXL29TY76Z2rM5mHXA, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, machael-QKn5cuLxLXY, Andrew Lunn The GPIO controllers can now be described in DT. Origionally GPIO controllers were instantiated during IRQ setup. The origional none-DT code has been split out, and is only called if no DT GPIO controllers are found. Signed-off-by: Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org> --- .../devicetree/bindings/gpio/mrvl-gpio.txt | 25 +++++++ arch/arm/boot/dts/kirkwood.dtsi | 20 ++++++ arch/arm/mach-kirkwood/irq.c | 20 ++++-- arch/arm/plat-orion/gpio.c | 68 +++++++++++++++++++- arch/arm/plat-orion/include/plat/gpio.h | 2 + 5 files changed, 126 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt index 05428f3..d94ebc1 100644 --- a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt +++ b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt @@ -27,3 +27,28 @@ Example: interrupt-controller; #interrupt-cells = <1>; }; + +* Marvell Orion GPIO Controller + +Required properties: +- compatible : Should be "marvell,orion-gpio" +- reg : Address and length of the register set for controller. +- gpio-controller : So we know this is a gpio controller. +- gpio-base : Number of first gpio pin. +- ngpio : How many gpios this controller has. +- secondary-irq-base : IRQ number base + +Optional properties: +- mask-offset : For SMP Orions, offset for Nth CPU + +Example: + + gpio0: gpio@10100 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x10100 0x40>; + gpio-base = <0>; + ngpio = <32>; + secondary-irq-base = <64>; + }; diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index 3091c01..6de66dc 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -18,6 +18,26 @@ #address-cells = <1>; #size-cells = <1>; + gpio0: gpio@10100 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x10100 0x40>; + gpio-base = <0>; + ngpio = <32>; + secondary-irq-base = <64>; + }; + + gpio1: gpio@10140 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x10140 0x40>; + gpio-base = <32>; + ngpio = <18>; + secondary-irq-base = <96>; + }; + serial@12000 { compatible = "ns16550a"; reg = <0x12000 0x100>; diff --git a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c index c4c68e5..81340c2 100644 --- a/arch/arm/mach-kirkwood/irq.c +++ b/arch/arm/mach-kirkwood/irq.c @@ -24,25 +24,33 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) orion_gpio_irq_handler((irq - IRQ_KIRKWOOD_GPIO_LOW_0_7) << 3); } -void __init kirkwood_init_irq(void) +static void __init kirkwood_init_gpio(void) { - orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)); - orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)); - /* * Initialize gpiolib for GPIOs 0-49. */ 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); +} +void __init kirkwood_init_irq(void) +{ + orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)); + orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)); + 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, gpio_irq_handler); + + /* Try initializing the GPIO controllers via DT. If zero + controllers are found, fall back to hard coded values */ + if (orion_gpio_init_dt() == 0) + kirkwood_init_gpio(); } diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c index af95af2..cc29367 100644 --- a/arch/arm/plat-orion/gpio.c +++ b/arch/arm/plat-orion/gpio.c @@ -17,6 +17,9 @@ #include <linux/io.h> #include <linux/gpio.h> #include <linux/leds.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <plat/gpio.h> /* * GPIO unit register offsets. @@ -401,8 +404,9 @@ static int gpio_irq_set_type(struct irq_data *d, u32 type) return 0; } -void __init orion_gpio_init(int gpio_base, int ngpio, - u32 base, int mask_offset, int secondary_irq_base) +void __init _orion_gpio_init(int gpio_base, int ngpio, + void __iomem *base, int mask_offset, + int secondary_irq_base, struct device_node *np) { struct orion_gpio_chip *ochip; struct irq_chip_generic *gc; @@ -426,8 +430,11 @@ void __init orion_gpio_init(int gpio_base, int ngpio, ochip->chip.base = gpio_base; ochip->chip.ngpio = ngpio; ochip->chip.can_sleep = 0; +#ifdef CONFIG_OF + ochip->chip.of_node = np; +#endif spin_lock_init(&ochip->lock); - ochip->base = (void __iomem *)base; + ochip->base = base; ochip->valid_input = 0; ochip->valid_output = 0; ochip->mask_offset = mask_offset; @@ -469,6 +476,15 @@ void __init orion_gpio_init(int gpio_base, int ngpio, IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); } +/* None DT version */ +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, (void __iomem *)base, + mask_offset, secondary_irq_base, NULL); +} + void orion_gpio_irq_handler(int pinoff) { struct orion_gpio_chip *ochip; @@ -502,3 +518,49 @@ void orion_gpio_irq_handler(int pinoff) generic_handle_irq(irq); } } + +/* Configure all the gpio chips we can find. Return the number + * actually configured, so that we can fall back to the old way, + * for none-DT platforms.*/ +#ifdef CONFIG_OF +int __init orion_gpio_init_dt(void) +{ + int chips = 0; + + struct device_node *np = NULL; + int gpio_base, ngpio, mask_offset, secondary_irq_base; + void __iomem *base; + int ret; + + for_each_compatible_node(np, NULL, "marvell,orion-gpio") { + ret = of_property_read_u32(np, "gpio-base", &gpio_base); + if (ret) + continue; + ret = of_property_read_u32(np, "ngpio", &ngpio); + if (ret) + continue; + ret = of_property_read_u32(np, "mask-offset", &mask_offset); + if (ret == -EINVAL) + mask_offset = 0; + else + continue; + ret = of_property_read_u32(np, "secondary-irq-base", + &secondary_irq_base); + if (ret) + continue; + base = of_iomap(np, 0); + if (!base) + continue; + + _orion_gpio_init(gpio_base, ngpio, base, mask_offset, + secondary_irq_base, np); + chips++; + } + return chips; +} +#else +int __init orion_gpio_init_dt(void) +{ + return 0; +} +#endif diff --git a/arch/arm/plat-orion/include/plat/gpio.h b/arch/arm/plat-orion/include/plat/gpio.h index bec0c98..68039de 100644 --- a/arch/arm/plat-orion/include/plat/gpio.h +++ b/arch/arm/plat-orion/include/plat/gpio.h @@ -30,6 +30,8 @@ void orion_gpio_set_valid(unsigned pin, int mode); void __init orion_gpio_init(int gpio_base, int ngpio, u32 base, int mask_offset, int secondary_irq_base); +/* Initialize gpiolib using DT. */ +int __init orion_gpio_init_dt(void); /* * GPIO interrupt handling. */ -- 1.7.10 ^ permalink raw reply related [flat|nested] 3+ messages in thread
[parent not found: <1339324322-29388-9-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org>]
* Re: [PATCH 8/9] ARM: Kirkwood: Add DT support for GPIO controllers [not found] ` <1339324322-29388-9-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org> @ 2012-06-10 17:18 ` Jason Cooper 2012-06-10 22:48 ` Rob Herring 1 sibling, 0 replies; 3+ messages in thread From: Jason Cooper @ 2012-06-10 17:18 UTC (permalink / raw) To: Andrew Lunn Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ, linux-i2c-u79uwXL29TY76Z2rM5mHXA, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, machael-QKn5cuLxLXY, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r On Sun, Jun 10, 2012 at 12:32:00PM +0200, Andrew Lunn wrote: > The GPIO controllers can now be described in DT. Origionally GPIO > controllers were instantiated during IRQ setup. The origional none-DT nit. "non-DT" > code has been split out, and is only called if no DT GPIO controllers > are found. > > Signed-off-by: Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org> Acked-by: Jason Cooper <jason-NLaQJdtUoK4Be96aLqz0jA@public.gmane.org> > --- > .../devicetree/bindings/gpio/mrvl-gpio.txt | 25 +++++++ > arch/arm/boot/dts/kirkwood.dtsi | 20 ++++++ > arch/arm/mach-kirkwood/irq.c | 20 ++++-- > arch/arm/plat-orion/gpio.c | 68 +++++++++++++++++++- > arch/arm/plat-orion/include/plat/gpio.h | 2 + > 5 files changed, 126 insertions(+), 9 deletions(-) > > diff --git a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt > index 05428f3..d94ebc1 100644 > --- a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt > +++ b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt > @@ -27,3 +27,28 @@ Example: > interrupt-controller; > #interrupt-cells = <1>; > }; > + > +* Marvell Orion GPIO Controller > + > +Required properties: > +- compatible : Should be "marvell,orion-gpio" > +- reg : Address and length of the register set for controller. > +- gpio-controller : So we know this is a gpio controller. > +- gpio-base : Number of first gpio pin. > +- ngpio : How many gpios this controller has. > +- secondary-irq-base : IRQ number base > + > +Optional properties: > +- mask-offset : For SMP Orions, offset for Nth CPU > + > +Example: > + > + gpio0: gpio@10100 { > + compatible = "marvell,orion-gpio"; > + #gpio-cells = <2>; > + gpio-controller; > + reg = <0x10100 0x40>; > + gpio-base = <0>; > + ngpio = <32>; > + secondary-irq-base = <64>; > + }; > diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi > index 3091c01..6de66dc 100644 > --- a/arch/arm/boot/dts/kirkwood.dtsi > +++ b/arch/arm/boot/dts/kirkwood.dtsi > @@ -18,6 +18,26 @@ > #address-cells = <1>; > #size-cells = <1>; > > + gpio0: gpio@10100 { > + compatible = "marvell,orion-gpio"; > + #gpio-cells = <2>; > + gpio-controller; > + reg = <0x10100 0x40>; > + gpio-base = <0>; > + ngpio = <32>; > + secondary-irq-base = <64>; > + }; > + > + gpio1: gpio@10140 { > + compatible = "marvell,orion-gpio"; > + #gpio-cells = <2>; > + gpio-controller; > + reg = <0x10140 0x40>; > + gpio-base = <32>; > + ngpio = <18>; > + secondary-irq-base = <96>; > + }; > + > serial@12000 { > compatible = "ns16550a"; > reg = <0x12000 0x100>; > diff --git a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c > index c4c68e5..81340c2 100644 > --- a/arch/arm/mach-kirkwood/irq.c > +++ b/arch/arm/mach-kirkwood/irq.c > @@ -24,25 +24,33 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) > orion_gpio_irq_handler((irq - IRQ_KIRKWOOD_GPIO_LOW_0_7) << 3); > } > > -void __init kirkwood_init_irq(void) > +static void __init kirkwood_init_gpio(void) > { > - orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)); > - orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)); > - > /* > * Initialize gpiolib for GPIOs 0-49. > */ > 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); > +} > +void __init kirkwood_init_irq(void) > +{ > + orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)); > + orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)); > + > 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, > gpio_irq_handler); > + > + /* Try initializing the GPIO controllers via DT. If zero > + controllers are found, fall back to hard coded values */ > + if (orion_gpio_init_dt() == 0) > + kirkwood_init_gpio(); > } > diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c > index af95af2..cc29367 100644 > --- a/arch/arm/plat-orion/gpio.c > +++ b/arch/arm/plat-orion/gpio.c > @@ -17,6 +17,9 @@ > #include <linux/io.h> > #include <linux/gpio.h> > #include <linux/leds.h> > +#include <linux/of.h> > +#include <linux/of_address.h> > +#include <plat/gpio.h> > > /* > * GPIO unit register offsets. > @@ -401,8 +404,9 @@ static int gpio_irq_set_type(struct irq_data *d, u32 type) > return 0; > } > > -void __init orion_gpio_init(int gpio_base, int ngpio, > - u32 base, int mask_offset, int secondary_irq_base) > +void __init _orion_gpio_init(int gpio_base, int ngpio, > + void __iomem *base, int mask_offset, > + int secondary_irq_base, struct device_node *np) > { > struct orion_gpio_chip *ochip; > struct irq_chip_generic *gc; > @@ -426,8 +430,11 @@ void __init orion_gpio_init(int gpio_base, int ngpio, > ochip->chip.base = gpio_base; > ochip->chip.ngpio = ngpio; > ochip->chip.can_sleep = 0; > +#ifdef CONFIG_OF > + ochip->chip.of_node = np; > +#endif > spin_lock_init(&ochip->lock); > - ochip->base = (void __iomem *)base; > + ochip->base = base; > ochip->valid_input = 0; > ochip->valid_output = 0; > ochip->mask_offset = mask_offset; > @@ -469,6 +476,15 @@ void __init orion_gpio_init(int gpio_base, int ngpio, > IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); > } > > +/* None DT version */ > +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, (void __iomem *)base, > + mask_offset, secondary_irq_base, NULL); > +} > + > void orion_gpio_irq_handler(int pinoff) > { > struct orion_gpio_chip *ochip; > @@ -502,3 +518,49 @@ void orion_gpio_irq_handler(int pinoff) > generic_handle_irq(irq); > } > } > + > +/* Configure all the gpio chips we can find. Return the number > + * actually configured, so that we can fall back to the old way, > + * for none-DT platforms.*/ > +#ifdef CONFIG_OF > +int __init orion_gpio_init_dt(void) > +{ > + int chips = 0; > + > + struct device_node *np = NULL; > + int gpio_base, ngpio, mask_offset, secondary_irq_base; > + void __iomem *base; > + int ret; > + > + for_each_compatible_node(np, NULL, "marvell,orion-gpio") { > + ret = of_property_read_u32(np, "gpio-base", &gpio_base); > + if (ret) > + continue; > + ret = of_property_read_u32(np, "ngpio", &ngpio); > + if (ret) > + continue; > + ret = of_property_read_u32(np, "mask-offset", &mask_offset); > + if (ret == -EINVAL) > + mask_offset = 0; > + else > + continue; > + ret = of_property_read_u32(np, "secondary-irq-base", > + &secondary_irq_base); > + if (ret) > + continue; > + base = of_iomap(np, 0); > + if (!base) > + continue; > + > + _orion_gpio_init(gpio_base, ngpio, base, mask_offset, > + secondary_irq_base, np); > + chips++; > + } > + return chips; > +} > +#else > +int __init orion_gpio_init_dt(void) > +{ > + return 0; > +} > +#endif > diff --git a/arch/arm/plat-orion/include/plat/gpio.h b/arch/arm/plat-orion/include/plat/gpio.h > index bec0c98..68039de 100644 > --- a/arch/arm/plat-orion/include/plat/gpio.h > +++ b/arch/arm/plat-orion/include/plat/gpio.h > @@ -30,6 +30,8 @@ void orion_gpio_set_valid(unsigned pin, int mode); > void __init orion_gpio_init(int gpio_base, int ngpio, > u32 base, int mask_offset, int secondary_irq_base); > > +/* Initialize gpiolib using DT. */ > +int __init orion_gpio_init_dt(void); > /* > * GPIO interrupt handling. > */ > -- > 1.7.10 > ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 8/9] ARM: Kirkwood: Add DT support for GPIO controllers [not found] ` <1339324322-29388-9-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org> 2012-06-10 17:18 ` Jason Cooper @ 2012-06-10 22:48 ` Rob Herring 1 sibling, 0 replies; 3+ messages in thread From: Rob Herring @ 2012-06-10 22:48 UTC (permalink / raw) To: Andrew Lunn Cc: jason-NLaQJdtUoK4Be96aLqz0jA, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ, grant.likely-s3s/WqlpOiPyB63q8FvJNQ, linux-i2c-u79uwXL29TY76Z2rM5mHXA, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, machael-QKn5cuLxLXY, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r On 06/10/2012 05:32 AM, Andrew Lunn wrote: > The GPIO controllers can now be described in DT. Origionally GPIO > controllers were instantiated during IRQ setup. The origional none-DT > code has been split out, and is only called if no DT GPIO controllers > are found. > > Signed-off-by: Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org> > --- > .../devicetree/bindings/gpio/mrvl-gpio.txt | 25 +++++++ > arch/arm/boot/dts/kirkwood.dtsi | 20 ++++++ > arch/arm/mach-kirkwood/irq.c | 20 ++++-- > arch/arm/plat-orion/gpio.c | 68 +++++++++++++++++++- > arch/arm/plat-orion/include/plat/gpio.h | 2 + > 5 files changed, 126 insertions(+), 9 deletions(-) > > diff --git a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt > index 05428f3..d94ebc1 100644 > --- a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt > +++ b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt > @@ -27,3 +27,28 @@ Example: > interrupt-controller; > #interrupt-cells = <1>; > }; > + > +* Marvell Orion GPIO Controller > + > +Required properties: > +- compatible : Should be "marvell,orion-gpio" > +- reg : Address and length of the register set for controller. > +- gpio-controller : So we know this is a gpio controller. > +- gpio-base : Number of first gpio pin. > +- ngpio : How many gpios this controller has. > +- secondary-irq-base : IRQ number base > + > +Optional properties: > +- mask-offset : For SMP Orions, offset for Nth CPU > + > +Example: > + > + gpio0: gpio@10100 { > + compatible = "marvell,orion-gpio"; > + #gpio-cells = <2>; > + gpio-controller; > + reg = <0x10100 0x40>; > + gpio-base = <0>; > + ngpio = <32>; > + secondary-irq-base = <64>; This and gpio-base are wrong. The DT should describe h/w and these are Linux gpio and irq numbers. You need to create an irqdomain for the gpio controller. Rob > + }; > diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi > index 3091c01..6de66dc 100644 > --- a/arch/arm/boot/dts/kirkwood.dtsi > +++ b/arch/arm/boot/dts/kirkwood.dtsi > @@ -18,6 +18,26 @@ > #address-cells = <1>; > #size-cells = <1>; > > + gpio0: gpio@10100 { > + compatible = "marvell,orion-gpio"; > + #gpio-cells = <2>; > + gpio-controller; > + reg = <0x10100 0x40>; > + gpio-base = <0>; > + ngpio = <32>; > + secondary-irq-base = <64>; > + }; > + > + gpio1: gpio@10140 { > + compatible = "marvell,orion-gpio"; > + #gpio-cells = <2>; > + gpio-controller; > + reg = <0x10140 0x40>; > + gpio-base = <32>; > + ngpio = <18>; > + secondary-irq-base = <96>; > + }; > + > serial@12000 { > compatible = "ns16550a"; > reg = <0x12000 0x100>; > diff --git a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c > index c4c68e5..81340c2 100644 > --- a/arch/arm/mach-kirkwood/irq.c > +++ b/arch/arm/mach-kirkwood/irq.c > @@ -24,25 +24,33 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) > orion_gpio_irq_handler((irq - IRQ_KIRKWOOD_GPIO_LOW_0_7) << 3); > } > > -void __init kirkwood_init_irq(void) > +static void __init kirkwood_init_gpio(void) > { > - orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)); > - orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)); > - > /* > * Initialize gpiolib for GPIOs 0-49. > */ > 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); > +} > +void __init kirkwood_init_irq(void) > +{ > + orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)); > + orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)); > + > 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, > gpio_irq_handler); > + > + /* Try initializing the GPIO controllers via DT. If zero > + controllers are found, fall back to hard coded values */ > + if (orion_gpio_init_dt() == 0) > + kirkwood_init_gpio(); > } > diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c > index af95af2..cc29367 100644 > --- a/arch/arm/plat-orion/gpio.c > +++ b/arch/arm/plat-orion/gpio.c > @@ -17,6 +17,9 @@ > #include <linux/io.h> > #include <linux/gpio.h> > #include <linux/leds.h> > +#include <linux/of.h> > +#include <linux/of_address.h> > +#include <plat/gpio.h> > > /* > * GPIO unit register offsets. > @@ -401,8 +404,9 @@ static int gpio_irq_set_type(struct irq_data *d, u32 type) > return 0; > } > > -void __init orion_gpio_init(int gpio_base, int ngpio, > - u32 base, int mask_offset, int secondary_irq_base) > +void __init _orion_gpio_init(int gpio_base, int ngpio, > + void __iomem *base, int mask_offset, > + int secondary_irq_base, struct device_node *np) > { > struct orion_gpio_chip *ochip; > struct irq_chip_generic *gc; > @@ -426,8 +430,11 @@ void __init orion_gpio_init(int gpio_base, int ngpio, > ochip->chip.base = gpio_base; > ochip->chip.ngpio = ngpio; > ochip->chip.can_sleep = 0; > +#ifdef CONFIG_OF > + ochip->chip.of_node = np; > +#endif > spin_lock_init(&ochip->lock); > - ochip->base = (void __iomem *)base; > + ochip->base = base; > ochip->valid_input = 0; > ochip->valid_output = 0; > ochip->mask_offset = mask_offset; > @@ -469,6 +476,15 @@ void __init orion_gpio_init(int gpio_base, int ngpio, > IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); > } > > +/* None DT version */ > +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, (void __iomem *)base, > + mask_offset, secondary_irq_base, NULL); > +} > + > void orion_gpio_irq_handler(int pinoff) > { > struct orion_gpio_chip *ochip; > @@ -502,3 +518,49 @@ void orion_gpio_irq_handler(int pinoff) > generic_handle_irq(irq); > } > } > + > +/* Configure all the gpio chips we can find. Return the number > + * actually configured, so that we can fall back to the old way, > + * for none-DT platforms.*/ > +#ifdef CONFIG_OF > +int __init orion_gpio_init_dt(void) > +{ > + int chips = 0; > + > + struct device_node *np = NULL; > + int gpio_base, ngpio, mask_offset, secondary_irq_base; > + void __iomem *base; > + int ret; > + > + for_each_compatible_node(np, NULL, "marvell,orion-gpio") { > + ret = of_property_read_u32(np, "gpio-base", &gpio_base); > + if (ret) > + continue; > + ret = of_property_read_u32(np, "ngpio", &ngpio); > + if (ret) > + continue; > + ret = of_property_read_u32(np, "mask-offset", &mask_offset); > + if (ret == -EINVAL) > + mask_offset = 0; > + else > + continue; > + ret = of_property_read_u32(np, "secondary-irq-base", > + &secondary_irq_base); > + if (ret) > + continue; > + base = of_iomap(np, 0); > + if (!base) > + continue; > + > + _orion_gpio_init(gpio_base, ngpio, base, mask_offset, > + secondary_irq_base, np); > + chips++; > + } > + return chips; > +} > +#else > +int __init orion_gpio_init_dt(void) > +{ > + return 0; > +} > +#endif > diff --git a/arch/arm/plat-orion/include/plat/gpio.h b/arch/arm/plat-orion/include/plat/gpio.h > index bec0c98..68039de 100644 > --- a/arch/arm/plat-orion/include/plat/gpio.h > +++ b/arch/arm/plat-orion/include/plat/gpio.h > @@ -30,6 +30,8 @@ void orion_gpio_set_valid(unsigned pin, int mode); > void __init orion_gpio_init(int gpio_base, int ngpio, > u32 base, int mask_offset, int secondary_irq_base); > > +/* Initialize gpiolib using DT. */ > +int __init orion_gpio_init_dt(void); > /* > * GPIO interrupt handling. > */ ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-06-10 22:48 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-06-10 10:32 [PATCH 8/9] ARM: Kirkwood: Add DT support for GPIO controllers Andrew Lunn [not found] ` <1339324322-29388-9-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org> 2012-06-10 17:18 ` Jason Cooper 2012-06-10 22:48 ` Rob Herring
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).