Skip to content

Commit

Permalink
ARM: Orion: DT support for IRQ and GPIO Controllers
Browse files Browse the repository at this point in the history
Both IRQ and GPIO controllers can now be represented in DT.  The IRQ
controllers are setup first, and then the GPIO controllers. Interrupts
for GPIO lines are placed directly after the main interrupts in the
interrupt space.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth@googlemail.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Josh Coombs <josh.coombs@gmail.com>
Tested-by: Simon Baatz <gmbnomis@gmail.com>
  • Loading branch information
Andrew Lunn committed Jul 27, 2012
1 parent 89fb2d7 commit 278b45b
Show file tree
Hide file tree
Showing 13 changed files with 307 additions and 132 deletions.
20 changes: 20 additions & 0 deletions Documentation/devicetree/bindings/arm/mrvl/intc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,23 @@ Example:
reg-names = "mux status", "mux mask";
mrvl,intc-nr-irqs = <2>;
};

* Marvell Orion Interrupt controller

Required properties
- compatible : Should be "marvell,orion-intc".
- #interrupt-cells: Specifies the number of cells needed to encode an
interrupt source. Supported value is <1>.
- interrupt-controller : Declare this node to be an interrupt controller.
- reg : Interrupt mask address. A list of 4 byte ranges, one per controller.
One entry in the list represents 32 interrupts.

Example:

intc: interrupt-controller {
compatible = "marvell,orion-intc", "marvell,intc";
interrupt-controller;
#interrupt-cells = <1>;
reg = <0xfed20204 0x04>,
<0xfed20214 0x04>;
};
23 changes: 23 additions & 0 deletions Documentation/devicetree/bindings/gpio/mrvl-gpio.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,26 @@ 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.
- ngpio : How many gpios this controller has.
- interrupts : Up to 4 Interrupts for the controller.

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>;
ngpio = <32>;
interrupts = <35>, <36>, <37>, <38>;
};
1 change: 1 addition & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,7 @@ config PLAT_ORION
bool
select CLKSRC_MMIO
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
select COMMON_CLK

config PLAT_PXA
Expand Down
27 changes: 27 additions & 0 deletions arch/arm/boot/dts/kirkwood.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,40 @@

/ {
compatible = "marvell,kirkwood";
interrupt-parent = <&intc>;

intc: interrupt-controller {
compatible = "marvell,orion-intc", "marvell,intc";
interrupt-controller;
#interrupt-cells = <1>;
reg = <0xf1020204 0x04>,
<0xf1020214 0x04>;
};

ocp@f1000000 {
compatible = "simple-bus";
ranges = <0 0xf1000000 0x4000000>;
#address-cells = <1>;
#size-cells = <1>;

gpio0: gpio@10100 {
compatible = "marvell,orion-gpio";
#gpio-cells = <2>;
gpio-controller;
reg = <0x10100 0x40>;
ngpio = <32>;
interrupts = <35>, <36>, <37>, <38>;
};

gpio1: gpio@10140 {
compatible = "marvell,orion-gpio";
#gpio-cells = <2>;
gpio-controller;
reg = <0x10140 0x40>;
ngpio = <18>;
interrupts = <39>, <40>, <41>;
};

serial@12000 {
compatible = "ns16550a";
reg = <0x12000 0x100>;
Expand Down
58 changes: 29 additions & 29 deletions arch/arm/mach-dove/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,6 @@
#include <mach/bridge-regs.h>
#include "common.h"

static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
int irqoff;
BUG_ON(irq < IRQ_DOVE_GPIO_0_7 || irq > IRQ_DOVE_HIGH_GPIO);

irqoff = irq <= IRQ_DOVE_GPIO_16_23 ? irq - IRQ_DOVE_GPIO_0_7 :
3 + irq - IRQ_DOVE_GPIO_24_31;

orion_gpio_irq_handler(irqoff << 3);
if (irq == IRQ_DOVE_HIGH_GPIO) {
orion_gpio_irq_handler(40);
orion_gpio_irq_handler(48);
orion_gpio_irq_handler(56);
}
}

static void pmu_irq_mask(struct irq_data *d)
{
int pin = irq_to_pmu(d->irq);
Expand Down Expand Up @@ -90,6 +74,27 @@ static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc)
}
}

static int __initdata gpio0_irqs[4] = {
IRQ_DOVE_GPIO_0_7,
IRQ_DOVE_GPIO_8_15,
IRQ_DOVE_GPIO_16_23,
IRQ_DOVE_GPIO_24_31,
};

static int __initdata gpio1_irqs[4] = {
IRQ_DOVE_HIGH_GPIO,
0,
0,
0,
};

static int __initdata gpio2_irqs[4] = {
0,
0,
0,
0,
};

void __init dove_init_irq(void)
{
int i;
Expand All @@ -100,19 +105,14 @@ void __init dove_init_irq(void)
/*
* Initialize gpiolib for GPIOs 0-71.
*/
orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START);
irq_set_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler);
irq_set_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler);
irq_set_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler);
irq_set_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler);

orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 32);
irq_set_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler);

orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 64);
orion_gpio_init(NULL, 0, 32, (void __iomem *)DOVE_GPIO_LO_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START, gpio0_irqs);

orion_gpio_init(NULL, 32, 32, (void __iomem *)DOVE_GPIO_HI_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 32, gpio1_irqs);

orion_gpio_init(NULL, 64, 8, (void __iomem *)DOVE_GPIO2_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 64, gpio2_irqs);

/*
* Mask and clear PMU interrupts
Expand Down
3 changes: 2 additions & 1 deletion arch/arm/mach-kirkwood/board-dt.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/bridge-regs.h>
#include <plat/irq.h>
#include "common.h"

static struct of_device_id kirkwood_dt_match_table[] __initdata = {
Expand Down Expand Up @@ -84,7 +85,7 @@ DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)")
/* Maintainer: Jason Cooper <jason@lakedaemon.net> */
.map_io = kirkwood_map_io,
.init_early = kirkwood_init_early,
.init_irq = kirkwood_init_irq,
.init_irq = orion_dt_init_irq,
.timer = &kirkwood_timer,
.init_machine = kirkwood_dt_init,
.restart = kirkwood_restart,
Expand Down
38 changes: 16 additions & 22 deletions arch/arm/mach-kirkwood/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,23 @@
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <mach/bridge-regs.h>
#include <plat/irq.h>
#include "common.h"

static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
BUG_ON(irq < IRQ_KIRKWOOD_GPIO_LOW_0_7);
BUG_ON(irq > IRQ_KIRKWOOD_GPIO_HIGH_16_23);
static int __initdata gpio0_irqs[4] = {
IRQ_KIRKWOOD_GPIO_LOW_0_7,
IRQ_KIRKWOOD_GPIO_LOW_8_15,
IRQ_KIRKWOOD_GPIO_LOW_16_23,
IRQ_KIRKWOOD_GPIO_LOW_24_31,
};

orion_gpio_irq_handler((irq - IRQ_KIRKWOOD_GPIO_LOW_0_7) << 3);
}
static int __initdata gpio1_irqs[4] = {
IRQ_KIRKWOOD_GPIO_HIGH_0_7,
IRQ_KIRKWOOD_GPIO_HIGH_8_15,
IRQ_KIRKWOOD_GPIO_HIGH_16_23,
0,
};

void __init kirkwood_init_irq(void)
{
Expand All @@ -32,17 +35,8 @@ void __init kirkwood_init_irq(void)
/*
* Initialize gpiolib for GPIOs 0-49.
*/
orion_gpio_init(0, 32, GPIO_LOW_VIRT_BASE, 0,
IRQ_KIRKWOOD_GPIO_START);
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);
orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_LOW_VIRT_BASE, 0,
IRQ_KIRKWOOD_GPIO_START, gpio0_irqs);
orion_gpio_init(NULL, 32, 18, (void __iomem *)GPIO_HIGH_VIRT_BASE, 0,
IRQ_KIRKWOOD_GPIO_START + 32, gpio1_irqs);
}
22 changes: 8 additions & 14 deletions arch/arm/mach-mv78xx0/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,17 @@
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/irq.h>
#include <mach/bridge-regs.h>
#include <plat/irq.h>
#include "common.h"

static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
BUG_ON(irq < IRQ_MV78XX0_GPIO_0_7 || irq > IRQ_MV78XX0_GPIO_24_31);

orion_gpio_irq_handler((irq - IRQ_MV78XX0_GPIO_0_7) << 3);
}
static int __initdata gpio0_irqs[4] = {
IRQ_MV78XX0_GPIO_0_7,
IRQ_MV78XX0_GPIO_8_15,
IRQ_MV78XX0_GPIO_16_23,
IRQ_MV78XX0_GPIO_24_31,
};

void __init mv78xx0_init_irq(void)
{
Expand All @@ -34,11 +32,7 @@ void __init mv78xx0_init_irq(void)
* registers for core #1 are at an offset of 0x18 from those of
* core #0.)
*/
orion_gpio_init(0, 32, GPIO_VIRT_BASE,
orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_VIRT_BASE,
mv78xx0_core_index() ? 0x18 : 0,
IRQ_MV78XX0_GPIO_START);
irq_set_chained_handler(IRQ_MV78XX0_GPIO_0_7, gpio_irq_handler);
irq_set_chained_handler(IRQ_MV78XX0_GPIO_8_15, gpio_irq_handler);
irq_set_chained_handler(IRQ_MV78XX0_GPIO_16_23, gpio_irq_handler);
irq_set_chained_handler(IRQ_MV78XX0_GPIO_24_31, gpio_irq_handler);
IRQ_MV78XX0_GPIO_START, gpio0_irqs);
}
22 changes: 8 additions & 14 deletions arch/arm/mach-orion5x/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,16 @@
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <mach/bridge-regs.h>
#include <plat/irq.h>
#include "common.h"

static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31);

orion_gpio_irq_handler((irq - IRQ_ORION5X_GPIO_0_7) << 3);
}
static int __initdata gpio0_irqs[4] = {
IRQ_ORION5X_GPIO_0_7,
IRQ_ORION5X_GPIO_8_15,
IRQ_ORION5X_GPIO_16_23,
IRQ_ORION5X_GPIO_24_31,
};

void __init orion5x_init_irq(void)
{
Expand All @@ -32,9 +29,6 @@ void __init orion5x_init_irq(void)
/*
* Initialize gpiolib for GPIOs 0-31.
*/
orion_gpio_init(0, 32, GPIO_VIRT_BASE, 0, IRQ_ORION5X_GPIO_START);
irq_set_chained_handler(IRQ_ORION5X_GPIO_0_7, gpio_irq_handler);
irq_set_chained_handler(IRQ_ORION5X_GPIO_8_15, gpio_irq_handler);
irq_set_chained_handler(IRQ_ORION5X_GPIO_16_23, gpio_irq_handler);
irq_set_chained_handler(IRQ_ORION5X_GPIO_24_31, gpio_irq_handler);
orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_VIRT_BASE, 0,
IRQ_ORION5X_GPIO_START, gpio0_irqs);
}
Loading

0 comments on commit 278b45b

Please sign in to comment.