OpenWrt – Blame information for rev 2
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From 3bf3bf7064d688dae7fdf7b49b28073eccd9dd99 Mon Sep 17 00:00:00 2001 |
2 | From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org> |
||
3 | Date: Fri, 12 Jun 2015 19:01:05 +0200 |
||
4 | Subject: [PATCH 008/454] irqchip: bcm2835: Add FIQ support |
||
5 | MIME-Version: 1.0 |
||
6 | Content-Type: text/plain; charset=UTF-8 |
||
7 | Content-Transfer-Encoding: 8bit |
||
8 | |||
9 | Add a duplicate irq range with an offset on the hwirq's so the |
||
10 | driver can detect that enable_fiq() is used. |
||
11 | Tested with downstream dwc_otg USB controller driver. |
||
12 | |||
13 | Signed-off-by: Noralf Trønnes <noralf@tronnes.org> |
||
14 | Reviewed-by: Eric Anholt <eric@anholt.net> |
||
15 | Acked-by: Stephen Warren <swarren@wwwdotorg.org> |
||
16 | --- |
||
17 | arch/arm/mach-bcm/Kconfig | 1 + |
||
18 | drivers/irqchip/irq-bcm2835.c | 51 +++++++++++++++++++++++++++++++---- |
||
19 | 2 files changed, 47 insertions(+), 5 deletions(-) |
||
20 | |||
21 | --- a/arch/arm/mach-bcm/Kconfig |
||
22 | +++ b/arch/arm/mach-bcm/Kconfig |
||
23 | @@ -155,6 +155,7 @@ config ARCH_BCM2835 |
||
24 | select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7 |
||
25 | select TIMER_OF |
||
26 | select BCM2835_TIMER |
||
27 | + select FIQ |
||
28 | select PINCTRL |
||
29 | select PINCTRL_BCM2835 |
||
30 | help |
||
31 | --- a/drivers/irqchip/irq-bcm2835.c |
||
32 | +++ b/drivers/irqchip/irq-bcm2835.c |
||
33 | @@ -54,7 +54,7 @@ |
||
34 | #include <asm/exception.h> |
||
35 | |||
36 | /* Put the bank and irq (32 bits) into the hwirq */ |
||
37 | -#define MAKE_HWIRQ(b, n) ((b << 5) | (n)) |
||
38 | +#define MAKE_HWIRQ(b, n) (((b) << 5) | (n)) |
||
39 | #define HWIRQ_BANK(i) (i >> 5) |
||
40 | #define HWIRQ_BIT(i) BIT(i & 0x1f) |
||
41 | |||
42 | @@ -70,9 +70,13 @@ |
||
43 | | SHORTCUT1_MASK | SHORTCUT2_MASK) |
||
44 | |||
45 | #define REG_FIQ_CONTROL 0x0c |
||
46 | +#define REG_FIQ_ENABLE 0x80 |
||
47 | +#define REG_FIQ_DISABLE 0 |
||
48 | |||
49 | #define NR_BANKS 3 |
||
50 | #define IRQS_PER_BANK 32 |
||
51 | +#define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) |
||
52 | +#define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0)) |
||
53 | |||
54 | static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; |
||
55 | static const int reg_enable[] __initconst = { 0x18, 0x10, 0x14 }; |
||
56 | @@ -97,14 +101,38 @@ static void __exception_irq_entry bcm283 |
||
57 | struct pt_regs *regs); |
||
58 | static void bcm2836_chained_handle_irq(struct irq_desc *desc); |
||
59 | |||
60 | +static inline unsigned int hwirq_to_fiq(unsigned long hwirq) |
||
61 | +{ |
||
62 | + hwirq -= NUMBER_IRQS; |
||
63 | + /* |
||
64 | + * The hwirq numbering used in this driver is: |
||
65 | + * BASE (0-7) GPU1 (32-63) GPU2 (64-95). |
||
66 | + * This differ from the one used in the FIQ register: |
||
67 | + * GPU1 (0-31) GPU2 (32-63) BASE (64-71) |
||
68 | + */ |
||
69 | + if (hwirq >= 32) |
||
70 | + return hwirq - 32; |
||
71 | + |
||
72 | + return hwirq + 64; |
||
73 | +} |
||
74 | + |
||
75 | static void armctrl_mask_irq(struct irq_data *d) |
||
76 | { |
||
77 | - writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]); |
||
78 | + if (d->hwirq >= NUMBER_IRQS) |
||
79 | + writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL); |
||
80 | + else |
||
81 | + writel_relaxed(HWIRQ_BIT(d->hwirq), |
||
82 | + intc.disable[HWIRQ_BANK(d->hwirq)]); |
||
83 | } |
||
84 | |||
85 | static void armctrl_unmask_irq(struct irq_data *d) |
||
86 | { |
||
87 | - writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]); |
||
88 | + if (d->hwirq >= NUMBER_IRQS) |
||
89 | + writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq), |
||
90 | + intc.base + REG_FIQ_CONTROL); |
||
91 | + else |
||
92 | + writel_relaxed(HWIRQ_BIT(d->hwirq), |
||
93 | + intc.enable[HWIRQ_BANK(d->hwirq)]); |
||
94 | } |
||
95 | |||
96 | static struct irq_chip armctrl_chip = { |
||
97 | @@ -149,8 +177,9 @@ static int __init armctrl_of_init(struct |
||
98 | if (!base) |
||
99 | panic("%pOF: unable to map IC registers\n", node); |
||
100 | |||
101 | - intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0), |
||
102 | - &armctrl_ops, NULL); |
||
103 | + intc.base = base; |
||
104 | + intc.domain = irq_domain_add_linear(node, NUMBER_IRQS * 2, |
||
105 | + &armctrl_ops, NULL); |
||
106 | if (!intc.domain) |
||
107 | panic("%pOF: unable to create IRQ domain\n", node); |
||
108 | |||
109 | @@ -180,6 +209,18 @@ static int __init armctrl_of_init(struct |
||
110 | set_handle_irq(bcm2835_handle_irq); |
||
111 | } |
||
112 | |||
113 | + /* Make a duplicate irq range which is used to enable FIQ */ |
||
114 | + for (b = 0; b < NR_BANKS; b++) { |
||
115 | + for (i = 0; i < bank_irqs[b]; i++) { |
||
116 | + irq = irq_create_mapping(intc.domain, |
||
117 | + MAKE_HWIRQ(b, i) + NUMBER_IRQS); |
||
118 | + BUG_ON(irq <= 0); |
||
119 | + irq_set_chip(irq, &armctrl_chip); |
||
120 | + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
||
121 | + } |
||
122 | + } |
||
123 | + init_FIQ(FIQ_START); |
||
124 | + |
||
125 | return 0; |
||
126 | } |
||
127 |