ARM: Kirkwood: Add DT support for GPIO controllers
Subsystems (7)
Andrew Lunn
maintainerPATCH 8/9 ARM: Kirkwood: Add DT support for GPIO controllers
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.
--- .../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(-)
Documentation/devicetree/bindings/gpio/mrvl-gpio.txt +25 -0
@@ -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 at 10100 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x10100 0x40>; + gpio-base = <0>; + ngpio = <32>; + secondary-irq-base = <64>; + };
arch/arm/boot/dts/kirkwood.dtsi +20 -0
@@ -18,6 +18,26 @@ #address-cells = <1>; #size-cells = <1>; + gpio0: gpio at 10100 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x10100 0x40>; + gpio-base = <0>; + ngpio = <32>; + secondary-irq-base = <64>; + }; + + gpio1: gpio at 10140 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x10140 0x40>; + gpio-base = <32>; + ngpio = <18>; + secondary-irq-base = <96>; + }; + serial at 12000 { compatible = "ns16550a"; reg = <0x12000 0x100>;
arch/arm/mach-kirkwood/irq.c +14 -6
@@ -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 (); }
arch/arm/plat-orion/gpio.c +65 -3
96 lines not on this page · raw message
arch/arm/plat-orion/include/plat/gpio.h +2 -0
@@ -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. */
Signature · 1 line
1.7.10
PATCH 8/9 ARM: Kirkwood: Add DT support for GPIO controllers
Quoted 2 lines · Andrew Lunn
The GPIO controllers can now be described in DT. Origionally GPIO controllers were instantiated during IRQ setup. The origional none-DT
nit. "non-DT"
Quoted 4 lines
code has been split out, and is only called if no DT GPIO controllers are found.
Signed-off-by Andrew Lunn <[email protected]>
Quoted 237 lines
--- .../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(-)Documentation/devicetree/bindings/gpio/mrvl-gpio.txt +25
-0@@ -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 at 10100 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x10100 0x40>; + gpio-base = <0>; + ngpio = <32>; + secondary-irq-base = <64>; + };arch/arm/boot/dts/kirkwood.dtsi +20
-0@@ -18,6 +18,26 @@ #address-cells = <1>; #size-cells = <1>; + gpio0: gpio at 10100 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x10100 0x40>; + gpio-base = <0>; + ngpio = <32>; + secondary-irq-base = <64>; + }; + + gpio1: gpio at 10140 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x10140 0x40>; + gpio-base = <32>; + ngpio = <18>; + secondary-irq-base = <96>; + }; + serial at 12000 { compatible = "ns16550a"; reg = <0x12000 0x100>;arch/arm/mach-kirkwood/irq.c +14
-6@@ -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 (); }arch/arm/plat-orion/gpio.c +65
-3@@ -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 arch/arm/plat-orion/include/plat/gpio.h +2
-0@@ -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. */ Signature · 1 line
1.7.10
PATCH 8/9 ARM: Kirkwood: Add DT support for GPIO controllers
In reply to Andrew LunnQuoted 36 lines · 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 <[email protected]>--- .../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(-)Documentation/devicetree/bindings/gpio/mrvl-gpio.txt +14
-0@@ -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 +
Documentation/devicetree/bindings/gpio/mrvl-gpio.txt Example: · line 53
Quoted 10 lines
Documentation/devicetree/bindings/gpio/mrvl-gpio.txt +10
-0+Example: + + gpio0: gpio at 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
Quoted 194 lines
Documentation/devicetree/bindings/gpio/mrvl-gpio.txt +1
-0+ };arch/arm/boot/dts/kirkwood.dtsi +20
-0@@ -18,6 +18,26 @@ #address-cells = <1>; #size-cells = <1>; + gpio0: gpio at 10100 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x10100 0x40>; + gpio-base = <0>; + ngpio = <32>; + secondary-irq-base = <64>; + }; + + gpio1: gpio at 10140 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x10140 0x40>; + gpio-base = <32>; + ngpio = <18>; + secondary-irq-base = <96>; + }; + serial at 12000 { compatible = "ns16550a"; reg = <0x12000 0x100>;arch/arm/mach-kirkwood/irq.c +14
-6@@ -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 (); }arch/arm/plat-orion/gpio.c +65
-3@@ -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 arch/arm/plat-orion/include/plat/gpio.h +2
-0@@ -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. */