Skip to content

Commit c1a5966

Browse files
notropopcornmix
authored andcommitted
irqchip: bcm2835: Add FIQ support
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 <[email protected]> Reviewed-by: Eric Anholt <[email protected]> Acked-by: Stephen Warren <[email protected]>
1 parent 66840ef commit c1a5966

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed

arch/arm/mach-bcm/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ config ARCH_BCM2835
114114
select ARM_ERRATA_411920
115115
select ARM_TIMER_SP804
116116
select CLKSRC_OF
117+
select FIQ
117118
select PINCTRL
118119
select PINCTRL_BCM2835
119120
help

drivers/irqchip/irq-bcm2835.c

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
#include "irqchip.h"
5757

5858
/* Put the bank and irq (32 bits) into the hwirq */
59-
#define MAKE_HWIRQ(b, n) ((b << 5) | (n))
59+
#define MAKE_HWIRQ(b, n) (((b) << 5) | (n))
6060
#define HWIRQ_BANK(i) (i >> 5)
6161
#define HWIRQ_BIT(i) BIT(i & 0x1f)
6262

@@ -72,9 +72,13 @@
7272
| SHORTCUT1_MASK | SHORTCUT2_MASK)
7373

7474
#define REG_FIQ_CONTROL 0x0c
75+
#define REG_FIQ_ENABLE 0x80
76+
#define REG_FIQ_DISABLE 0
7577

7678
#define NR_BANKS 3
7779
#define IRQS_PER_BANK 32
80+
#define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0)
81+
#define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0))
7882

7983
static int reg_pending[] __initconst = { 0x00, 0x04, 0x08 };
8084
static int reg_enable[] __initconst = { 0x18, 0x10, 0x14 };
@@ -98,14 +102,38 @@ static struct armctrl_ic intc __read_mostly;
98102
static void __exception_irq_entry bcm2835_handle_irq(
99103
struct pt_regs *regs);
100104

105+
static inline unsigned int hwirq_to_fiq(unsigned long hwirq)
106+
{
107+
hwirq -= NUMBER_IRQS;
108+
/*
109+
* The hwirq numbering used in this driver is:
110+
* BASE (0-7) GPU1 (32-63) GPU2 (64-95).
111+
* This differ from the one used in the FIQ register:
112+
* GPU1 (0-31) GPU2 (32-63) BASE (64-71)
113+
*/
114+
if (hwirq >= 32)
115+
return hwirq - 32;
116+
117+
return hwirq + 64;
118+
}
119+
101120
static void armctrl_mask_irq(struct irq_data *d)
102121
{
103-
writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]);
122+
if (d->hwirq >= NUMBER_IRQS)
123+
writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL);
124+
else
125+
writel_relaxed(HWIRQ_BIT(d->hwirq),
126+
intc.disable[HWIRQ_BANK(d->hwirq)]);
104127
}
105128

106129
static void armctrl_unmask_irq(struct irq_data *d)
107130
{
108-
writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]);
131+
if (d->hwirq >= NUMBER_IRQS)
132+
writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq),
133+
intc.base + REG_FIQ_CONTROL);
134+
else
135+
writel_relaxed(HWIRQ_BIT(d->hwirq),
136+
intc.enable[HWIRQ_BANK(d->hwirq)]);
109137
}
110138

111139
static struct irq_chip armctrl_chip = {
@@ -150,8 +178,9 @@ static int __init armctrl_of_init(struct device_node *node,
150178
panic("%s: unable to map IC registers\n",
151179
node->full_name);
152180

153-
intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0),
154-
&armctrl_ops, NULL);
181+
intc.base = base;
182+
intc.domain = irq_domain_add_linear(node, NUMBER_IRQS * 2,
183+
&armctrl_ops, NULL);
155184
if (!intc.domain)
156185
panic("%s: unable to create IRQ domain\n", node->full_name);
157186

@@ -168,8 +197,20 @@ static int __init armctrl_of_init(struct device_node *node,
168197
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
169198
}
170199
}
171-
172200
set_handle_irq(bcm2835_handle_irq);
201+
202+
/* Make a duplicate irq range which is used to enable FIQ */
203+
for (b = 0; b < NR_BANKS; b++) {
204+
for (i = 0; i < bank_irqs[b]; i++) {
205+
irq = irq_create_mapping(intc.domain,
206+
MAKE_HWIRQ(b, i) + NUMBER_IRQS);
207+
BUG_ON(irq <= 0);
208+
irq_set_chip(irq, &armctrl_chip);
209+
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
210+
}
211+
}
212+
init_FIQ(FIQ_START);
213+
173214
return 0;
174215
}
175216

0 commit comments

Comments
 (0)