169 lines
4.2 KiB
Diff
169 lines
4.2 KiB
Diff
From 6be3809614db2d52724eb4b5193c27d2466142be Mon Sep 17 00:00:00 2001
|
|
From: notro <notro@tronnes.org>
|
|
Date: Wed, 9 Jul 2014 14:47:48 +0200
|
|
Subject: [PATCH 050/114] BCM2708: armctrl: Add IRQ Device Tree support
|
|
|
|
Add Device Tree IRQ support for BCM2708.
|
|
Usage is the same as for irq-bcm2835.
|
|
See binding document: brcm,bcm2835-armctrl-ic.txt
|
|
|
|
A bank 3 is added to handle GPIO interrupts. This is done because
|
|
armctrl also handles GPIO interrupts.
|
|
|
|
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
|
|
|
|
BCM2708: armctrl: remove irq bank 3
|
|
|
|
irq bank 3 was needed by the pinctrl-bcm2708 and bcm2708_gpio
|
|
combination. It is no longer required.
|
|
|
|
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
|
|
---
|
|
arch/arm/boot/dts/bcm2708.dtsi | 9 ++++
|
|
arch/arm/mach-bcm2708/armctrl.c | 96 +++++++++++++++++++++++++++++++++++++++++
|
|
2 files changed, 105 insertions(+)
|
|
|
|
--- a/arch/arm/boot/dts/bcm2708.dtsi
|
|
+++ b/arch/arm/boot/dts/bcm2708.dtsi
|
|
@@ -4,6 +4,8 @@
|
|
compatible = "brcm,bcm2708";
|
|
model = "BCM2708";
|
|
|
|
+ interrupt-parent = <&intc>;
|
|
+
|
|
chosen {
|
|
/*
|
|
bootargs must be 1024 characters long because the
|
|
@@ -17,6 +19,13 @@
|
|
#address-cells = <1>;
|
|
#size-cells = <1>;
|
|
ranges = <0x7e000000 0x20000000 0x02000000>;
|
|
+
|
|
+ intc: interrupt-controller {
|
|
+ compatible = "brcm,bcm2708-armctrl-ic";
|
|
+ reg = <0x7e00b200 0x200>;
|
|
+ interrupt-controller;
|
|
+ #interrupt-cells = <2>;
|
|
+ };
|
|
};
|
|
|
|
clocks {
|
|
--- a/arch/arm/mach-bcm2708/armctrl.c
|
|
+++ b/arch/arm/mach-bcm2708/armctrl.c
|
|
@@ -23,6 +23,8 @@
|
|
#include <linux/version.h>
|
|
#include <linux/syscore_ops.h>
|
|
#include <linux/interrupt.h>
|
|
+#include <linux/irqdomain.h>
|
|
+#include <linux/of.h>
|
|
|
|
#include <asm/mach/irq.h>
|
|
#include <mach/hardware.h>
|
|
@@ -79,6 +81,99 @@ static void armctrl_unmask_irq(struct ir
|
|
}
|
|
}
|
|
|
|
+#ifdef CONFIG_OF
|
|
+
|
|
+#define NR_IRQS_BANK0 21
|
|
+#define NR_BANKS 3
|
|
+#define IRQS_PER_BANK 32
|
|
+
|
|
+/* from drivers/irqchip/irq-bcm2835.c */
|
|
+static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr,
|
|
+ const u32 *intspec, unsigned int intsize,
|
|
+ unsigned long *out_hwirq, unsigned int *out_type)
|
|
+{
|
|
+ if (WARN_ON(intsize != 2))
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (WARN_ON(intspec[0] >= NR_BANKS))
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (WARN_ON(intspec[1] >= IRQS_PER_BANK))
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0))
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (intspec[0] == 0)
|
|
+ *out_hwirq = ARM_IRQ0_BASE + intspec[1];
|
|
+ else if (intspec[0] == 1)
|
|
+ *out_hwirq = ARM_IRQ1_BASE + intspec[1];
|
|
+ else
|
|
+ *out_hwirq = ARM_IRQ2_BASE + intspec[1];
|
|
+
|
|
+ /* reverse remap_irqs[] */
|
|
+ switch (*out_hwirq) {
|
|
+ case INTERRUPT_VC_JPEG:
|
|
+ *out_hwirq = INTERRUPT_JPEG;
|
|
+ break;
|
|
+ case INTERRUPT_VC_USB:
|
|
+ *out_hwirq = INTERRUPT_USB;
|
|
+ break;
|
|
+ case INTERRUPT_VC_3D:
|
|
+ *out_hwirq = INTERRUPT_3D;
|
|
+ break;
|
|
+ case INTERRUPT_VC_DMA2:
|
|
+ *out_hwirq = INTERRUPT_DMA2;
|
|
+ break;
|
|
+ case INTERRUPT_VC_DMA3:
|
|
+ *out_hwirq = INTERRUPT_DMA3;
|
|
+ break;
|
|
+ case INTERRUPT_VC_I2C:
|
|
+ *out_hwirq = INTERRUPT_I2C;
|
|
+ break;
|
|
+ case INTERRUPT_VC_SPI:
|
|
+ *out_hwirq = INTERRUPT_SPI;
|
|
+ break;
|
|
+ case INTERRUPT_VC_I2SPCM:
|
|
+ *out_hwirq = INTERRUPT_I2SPCM;
|
|
+ break;
|
|
+ case INTERRUPT_VC_SDIO:
|
|
+ *out_hwirq = INTERRUPT_SDIO;
|
|
+ break;
|
|
+ case INTERRUPT_VC_UART:
|
|
+ *out_hwirq = INTERRUPT_UART;
|
|
+ break;
|
|
+ case INTERRUPT_VC_ARASANSDIO:
|
|
+ *out_hwirq = INTERRUPT_ARASANSDIO;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ *out_type = IRQ_TYPE_NONE;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static struct irq_domain_ops armctrl_ops = {
|
|
+ .xlate = armctrl_xlate
|
|
+};
|
|
+
|
|
+void __init armctrl_dt_init(void)
|
|
+{
|
|
+ struct device_node *np;
|
|
+ struct irq_domain *domain;
|
|
+
|
|
+ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic");
|
|
+ if (!np)
|
|
+ return;
|
|
+
|
|
+ domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS,
|
|
+ IRQ_ARMCTRL_START, 0,
|
|
+ &armctrl_ops, NULL);
|
|
+ WARN_ON(!domain);
|
|
+}
|
|
+#else
|
|
+void __init armctrl_dt_init(void) { }
|
|
+#endif /* CONFIG_OF */
|
|
+
|
|
#if defined(CONFIG_PM)
|
|
|
|
/* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */
|
|
@@ -215,5 +310,6 @@ int __init armctrl_init(void __iomem * b
|
|
|
|
armctrl_pm_register(base, irq_start, resume_sources);
|
|
init_FIQ(FIQ_START);
|
|
+ armctrl_dt_init();
|
|
return 0;
|
|
}
|