123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- From ead6c040137ae0efb3936f186740b600aff48c6e Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
- Date: Fri, 23 Oct 2015 16:26:55 +0200
- Subject: [PATCH 007/381] irqchip: irq-bcm2835: Add 2836 FIQ support
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
- ---
- drivers/irqchip/irq-bcm2835.c | 42 ++++++++++++++++++++++++++++++++++++++++--
- 1 file changed, 40 insertions(+), 2 deletions(-)
- --- a/drivers/irqchip/irq-bcm2835.c
- +++ b/drivers/irqchip/irq-bcm2835.c
- @@ -50,6 +50,8 @@
- #include <linux/of_irq.h>
- #include <linux/irqchip.h>
- #include <linux/irqdomain.h>
- +#include <linux/mfd/syscon.h>
- +#include <linux/regmap.h>
-
- #include <asm/exception.h>
- #include <asm/mach/irq.h>
- @@ -70,6 +72,9 @@
- #define BANK0_VALID_MASK (BANK0_HWIRQ_MASK | BANK1_HWIRQ | BANK2_HWIRQ \
- | SHORTCUT1_MASK | SHORTCUT2_MASK)
-
- +#undef ARM_LOCAL_GPU_INT_ROUTING
- +#define ARM_LOCAL_GPU_INT_ROUTING 0x0c
- +
- #define REG_FIQ_CONTROL 0x0c
- #define REG_FIQ_ENABLE 0x80
- #define REG_FIQ_DISABLE 0
- @@ -95,6 +100,7 @@ struct armctrl_ic {
- void __iomem *enable[NR_BANKS];
- void __iomem *disable[NR_BANKS];
- struct irq_domain *domain;
- + struct regmap *local_regmap;
- };
-
- static struct armctrl_ic intc __read_mostly;
- @@ -128,12 +134,35 @@ static void armctrl_mask_irq(struct irq_
-
- static void armctrl_unmask_irq(struct irq_data *d)
- {
- - if (d->hwirq >= NUMBER_IRQS)
- + if (d->hwirq >= NUMBER_IRQS) {
- + if (num_online_cpus() > 1) {
- + unsigned int data;
- + int ret;
- +
- + if (!intc.local_regmap) {
- + pr_err("FIQ is disabled due to missing regmap\n");
- + return;
- + }
- +
- + ret = regmap_read(intc.local_regmap,
- + ARM_LOCAL_GPU_INT_ROUTING, &data);
- + if (ret) {
- + pr_err("Failed to read int routing %d\n", ret);
- + return;
- + }
- +
- + data &= ~0xc;
- + data |= (1 << 2);
- + regmap_write(intc.local_regmap,
- + ARM_LOCAL_GPU_INT_ROUTING, data);
- + }
- +
- writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq),
- intc.base + REG_FIQ_CONTROL);
- - else
- + } else {
- writel_relaxed(HWIRQ_BIT(d->hwirq),
- intc.enable[HWIRQ_BANK(d->hwirq)]);
- + }
- }
-
- static struct irq_chip armctrl_chip = {
- @@ -211,6 +240,15 @@ static int __init armctrl_of_init(struct
- set_handle_irq(bcm2835_handle_irq);
- }
-
- + if (is_2836) {
- + intc.local_regmap =
- + syscon_regmap_lookup_by_compatible("brcm,bcm2836-arm-local");
- + if (IS_ERR(intc.local_regmap)) {
- + pr_err("Failed to get local register map. FIQ is disabled for cpus > 1\n");
- + intc.local_regmap = NULL;
- + }
- + }
- +
- /* 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++) {
|