kernel: bump 5.4 to 5.4.48
[oweals/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0010-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch
1 From 42c41d1381e50a2b4378401c1e4e1a4d1f506d8a Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
3 Date: Fri, 23 Oct 2015 16:26:55 +0200
4 Subject: [PATCH] irqchip: irq-bcm2835: Add 2836 FIQ support
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
10 ---
11  drivers/irqchip/irq-bcm2835.c | 43 +++++++++++++++++++++++++++++++++--
12  1 file changed, 41 insertions(+), 2 deletions(-)
13
14 --- a/drivers/irqchip/irq-bcm2835.c
15 +++ b/drivers/irqchip/irq-bcm2835.c
16 @@ -41,8 +41,11 @@
17  #include <linux/of_irq.h>
18  #include <linux/irqchip.h>
19  #include <linux/irqdomain.h>
20 +#include <linux/mfd/syscon.h>
21 +#include <linux/regmap.h>
22  
23  #include <asm/exception.h>
24 +#include <asm/mach/irq.h>
25  
26  /* Put the bank and irq (32 bits) into the hwirq */
27  #define MAKE_HWIRQ(b, n)       (((b) << 5) | (n))
28 @@ -60,6 +63,9 @@
29  #define BANK0_VALID_MASK       (BANK0_HWIRQ_MASK | BANK1_HWIRQ | BANK2_HWIRQ \
30                                         | SHORTCUT1_MASK | SHORTCUT2_MASK)
31  
32 +#undef ARM_LOCAL_GPU_INT_ROUTING
33 +#define ARM_LOCAL_GPU_INT_ROUTING 0x0c
34 +
35  #define REG_FIQ_CONTROL                0x0c
36  #define REG_FIQ_ENABLE         0x80
37  #define REG_FIQ_DISABLE                0
38 @@ -85,6 +91,7 @@ struct armctrl_ic {
39         void __iomem *enable[NR_BANKS];
40         void __iomem *disable[NR_BANKS];
41         struct irq_domain *domain;
42 +       struct regmap *local_regmap;
43  };
44  
45  static struct armctrl_ic intc __read_mostly;
46 @@ -118,12 +125,35 @@ static void armctrl_mask_irq(struct irq_
47  
48  static void armctrl_unmask_irq(struct irq_data *d)
49  {
50 -       if (d->hwirq >= NUMBER_IRQS)
51 +       if (d->hwirq >= NUMBER_IRQS) {
52 +               if (num_online_cpus() > 1) {
53 +                       unsigned int data;
54 +                       int ret;
55 +
56 +                       if (!intc.local_regmap) {
57 +                               pr_err("FIQ is disabled due to missing regmap\n");
58 +                               return;
59 +                       }
60 +
61 +                       ret = regmap_read(intc.local_regmap,
62 +                                         ARM_LOCAL_GPU_INT_ROUTING, &data);
63 +                       if (ret) {
64 +                               pr_err("Failed to read int routing %d\n", ret);
65 +                               return;
66 +                       }
67 +
68 +                       data &= ~0xc;
69 +                       data |= (1 << 2);
70 +                       regmap_write(intc.local_regmap,
71 +                                    ARM_LOCAL_GPU_INT_ROUTING, data);
72 +               }
73 +
74                 writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq),
75                                intc.base + REG_FIQ_CONTROL);
76 -       else
77 +       } else {
78                 writel_relaxed(HWIRQ_BIT(d->hwirq),
79                                intc.enable[HWIRQ_BANK(d->hwirq)]);
80 +       }
81  }
82  
83  static struct irq_chip armctrl_chip = {
84 @@ -200,6 +230,15 @@ static int __init armctrl_of_init(struct
85                 set_handle_irq(bcm2835_handle_irq);
86         }
87  
88 +       if (is_2836) {
89 +               intc.local_regmap =
90 +                       syscon_regmap_lookup_by_compatible("brcm,bcm2836-arm-local");
91 +               if (IS_ERR(intc.local_regmap)) {
92 +                       pr_err("Failed to get local register map. FIQ is disabled for cpus > 1\n");
93 +                       intc.local_regmap = NULL;
94 +               }
95 +       }
96 +
97         /* Make a duplicate irq range which is used to enable FIQ */
98         for (b = 0; b < NR_BANKS; b++) {
99                 for (i = 0; i < bank_irqs[b]; i++) {