summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.4/0084-mfd-Add-Raspberry-Pi-Sense-HAT-core-driver.patch
Commit message (Expand)AuthorAgeFilesLines
* brcm2708: update linux 4.4 patches to latest versionJohn Crispin2016-03-081-2/+2
* brcm2708: switch to linux 4.4 and update patchesJohn Crispin2016-02-251-2/+2
* brcm2708: add linux 4.4 supportFelix Fietkau2016-01-171-0/+838
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
From 229bcf2e73ce37e8a18d68773471024c848d84bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 12 Jun 2015 19:01:05 +0200
Subject: [PATCH 006/170] irqchip: bcm2835: Add FIQ support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add a duplicate irq range with an offset on the hwirq's so the
driver can detect that enable_fiq() is used.
Tested with downstream dwc_otg USB controller driver.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
Acked-by: Stephen Warren <swarren@wwwdotorg.org>
---
 arch/arm/mach-bcm/Kconfig     |  1 +
 drivers/irqchip/irq-bcm2835.c | 51 ++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 47 insertions(+), 5 deletions(-)

--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -128,6 +128,7 @@ config ARCH_BCM2835
 	select ARM_ERRATA_411920
 	select ARM_TIMER_SP804
 	select CLKSRC_OF
+	select FIQ
 	select PINCTRL
 	select PINCTRL_BCM2835
 	help
--- a/drivers/irqchip/irq-bcm2835.c
+++ b/drivers/irqchip/irq-bcm2835.c
@@ -55,7 +55,7 @@
 #include <asm/mach/irq.h>
 
 /* Put the bank and irq (32 bits) into the hwirq */
-#define MAKE_HWIRQ(b, n)	((b << 5) | (n))
+#define MAKE_HWIRQ(b, n)	(((b) << 5) | (n))
 #define HWIRQ_BANK(i)		(i >> 5)
 #define HWIRQ_BIT(i)		BIT(i & 0x1f)
 
@@ -71,9 +71,13 @@
 					| SHORTCUT1_MASK | SHORTCUT2_MASK)
 
 #define REG_FIQ_CONTROL		0x0c
+#define REG_FIQ_ENABLE		0x80
+#define REG_FIQ_DISABLE		0
 
 #define NR_BANKS		3
 #define IRQS_PER_BANK		32
+#define NUMBER_IRQS		MAKE_HWIRQ(NR_BANKS, 0)
+#define FIQ_START		(NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0))
 
 static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 };
 static const int reg_enable[] __initconst = { 0x18, 0x10, 0x14 };
@@ -98,14 +102,38 @@ static void __exception_irq_entry bcm283
 	struct pt_regs *regs);
 static void bcm2836_chained_handle_irq(struct irq_desc *desc);
 
+static inline unsigned int hwirq_to_fiq(unsigned long hwirq)
+{
+	hwirq -= NUMBER_IRQS;
+	/*
+	 * The hwirq numbering used in this driver is:
+	 *   BASE (0-7) GPU1 (32-63) GPU2 (64-95).
+	 * This differ from the one used in the FIQ register:
+	 *   GPU1 (0-31) GPU2 (32-63) BASE (64-71)
+	 */
+	if (hwirq >= 32)
+		return hwirq - 32;
+
+	return hwirq + 64;
+}
+
 static void armctrl_mask_irq(struct irq_data *d)
 {
-	writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]);
+	if (d->hwirq >= NUMBER_IRQS)
+		writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL);
+	else
+		writel_relaxed(HWIRQ_BIT(d->hwirq),
+			       intc.disable[HWIRQ_BANK(d->hwirq)]);
 }
 
 static void armctrl_unmask_irq(struct irq_data *d)
 {
-	writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]);
+	if (d->hwirq >= NUMBER_IRQS)
+		writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq),
+			       intc.base + REG_FIQ_CONTROL);
+	else
+		writel_relaxed(HWIRQ_BIT(d->hwirq),
+			       intc.enable[HWIRQ_BANK(d->hwirq)]);
 }
 
 static struct irq_chip armctrl_chip = {
@@ -151,8 +179,9 @@ static int __init armctrl_of_init(struct
 		panic("%s: unable to map IC registers\n",
 			node->full_name);
 
-	intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0),
-			&armctrl_ops, NULL);
+	intc.base = base;
+	intc.domain = irq_domain_add_linear(node, NUMBER_IRQS * 2,
+					    &armctrl_ops, NULL);
 	if (!intc.domain)
 		panic("%s: unable to create IRQ domain\n", node->full_name);
 
@@ -182,6 +211,18 @@ static int __init armctrl_of_init(struct
 		set_handle_irq(bcm2835_handle_irq);
 	}
 
+	/* Make a duplicate irq range which is used to enable FIQ */
+	for (b = 0; b < NR_BANKS; b++) {
+		for (i = 0; i < bank_irqs[b]; i++) {
+			irq = irq_create_mapping(intc.domain,
+					MAKE_HWIRQ(b, i) + NUMBER_IRQS);
+			BUG_ON(irq <= 0);
+			irq_set_chip(irq, &armctrl_chip);
+			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+		}
+	}
+	init_FIQ(FIQ_START);
+
 	return 0;
 }