History

Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq updates from Thomas Gleixner: "The irq department provides: - a major update to the auto affinity management code, which is used by multi-queue devices - move of the microblaze irq chip driver into the common driver code so it can be shared between microblaze, powerpc and MIPS - a series of updates to the ARM GICV3 interrupt controller - the usual pile of fixes and small improvements all over the place" * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (25 commits) powerpc/virtex: Use generic xilinx irqchip driver irqchip/xilinx: Try to fall back if xlnx,kind-of-intr not provided irqchip/xilinx: Add support for parent intc irqchip/xilinx: Rename get_irq to xintc_get_irq irqchip/xilinx: Restructure and use jump label api irqchip/xilinx: Clean up print messages microblaze/irqchip: Move intc driver to irqchip ARM: virt: Select ARM_GIC_V3_ITS ARM: gic-v3-its: Add 32bit support to GICv3 ITS irqchip/gic-v3-its: Specialise readq and writeq accesses irqchip/gic-v3-its: Specialise flush_dcache operation irqchip/gic-v3-its: Narrow down Entry Size when used as a divider irqchip/gic-v3-its: Change unsigned types for AArch32 compatibility irqchip/gic-v3: Use nops macro for Cavium ThunderX erratum 23154 irqchip/gic-v3: Convert arm64 GIC accessors to {read,write}_sysreg_s genirq/msi: Drop artificial PCI dependency irqchip/bcm7038-l1: Implement irq_cpu_offline() callback genirq/affinity: Use default affinity mask for reserved vectors genirq/affinity: Take reserved vectors into account when spreading irqs PCI: Remove the irq_affinity mask from struct pci_dev ...

Linus Torvalds committed 9 years ago

Commit f082f022 parents 9465d9c 2cae3a125 files · +518 −572Browse files

Unified · Split

25 files
  1. arch/arm/Kconfig +1 −0
  2. arch/arm/include/asm/arch_gicv3.h +47 −7
  3. arch/arm64/include/asm/arch_gicv3.h +31 −30
  4. arch/microblaze/Kconfig +1 −0
  5. arch/microblaze/include/asm/irq.h +1 −1
  6. arch/microblaze/kernel/Makefile +1 −1
  7. arch/microblaze/kernel/intc.c +0 −196
  8. arch/microblaze/kernel/irq.c +2 −2
  9. arch/powerpc/include/asm/xilinx_intc.h +1 −1
  10. arch/powerpc/platforms/40x/Kconfig +1 −0
  11. arch/powerpc/platforms/40x/virtex.c +1 −1
  12. arch/powerpc/platforms/44x/Kconfig +1 −0
  13. arch/powerpc/platforms/44x/virtex.c +1 −1
  14. arch/powerpc/sysdev/xilinx_intc.c +2 −209
  15. drivers/irqchip/Kconfig +4 −0
  16. drivers/irqchip/Makefile +1 −0
  17. drivers/irqchip/irq-bcm7038-l1.c +26 −0
  18. drivers/irqchip/irq-gic-v3-its.c +37 −38
  19. drivers/irqchip/irq-xilinx-intc.c +241 −0
  20. drivers/pci/msi.c +43 −35
  21. include/linux/interrupt.h +16 −4
  22. include/linux/irqchip/arm-gic-v3.h +2 −2
  23. include/linux/pci.h +19 −6
  24. kernel/irq/affinity.c +37 −35
  25. kernel/irq/msi.c +1 −3
arch/arm/Kconfig+1−0
@@ -703,6 +703,7 @@ config ARCH_VIRT · 702 unmodified lines
703703 select ARM_GIC
704704 select ARM_GIC_V2M if PCI
705705 select ARM_GIC_V3
706+ select ARM_GIC_V3_ITS if PCI
706707 select ARM_PSCI
707708 select HAVE_ARM_ARCH_TIMER
708709
arch/arm/include/asm/arch_gicv3.h+47−7
@@ -22,6 +22,7 @@ · 21 unmodified lines
2222
2323 #include <linux/io.h>
2424 #include <asm/barrier.h>
25+#include <asm/cacheflush.h>
2526 #include <asm/cp15.h>
2627
2728 #define ICC_EOIR1 __ACCESS_CP15(c12, 0, c12, 1)
@@ -230,19 +231,14 @@ static inline void gic_write_bpr1(u32 val) · 202 unmodified lines
230231 * AArch32, since the syndrome register doesn't provide any information for
231232 * them.
232233 * Consequently, the following IO helpers use 32bit accesses.
233− *
234− * There are only two registers that need 64bit accesses in this driver:
235− * - GICD_IROUTERn, contain the affinity values associated to each interrupt.
236− * The upper-word (aff3) will always be 0, so there is no need for a lock.
237− * - GICR_TYPER is an ID register and doesn't need atomicity.
238234 */
239−static inline void gic_write_irouter(u64 val, volatile void __iomem *addr)
235+static inline void __gic_writeq_nonatomic(u64 val, volatile void __iomem *addr)
240236 {
241237 writel_relaxed((u32)val, addr);
242238 writel_relaxed((u32)(val >> 32), addr + 4);
243239 }
244240
245−static inline u64 gic_read_typer(const volatile void __iomem *addr)
241+static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr)
246242 {
247243 u64 val;
248244
@@ -251,5 +247,49 @@ static inline u64 gic_read_typer(const volatile void __iomem *addr) · 2 unmodified lines
251247 return val;
252248 }
253249
250+#define gic_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l))
251+
252+/*
253+ * GICD_IROUTERn, contain the affinity values associated to each interrupt.
254+ * The upper-word (aff3) will always be 0, so there is no need for a lock.
255+ */
256+#define gic_write_irouter(v, c) __gic_writeq_nonatomic(v, c)
257+
258+/*
259+ * GICR_TYPER is an ID register and doesn't need atomicity.
260+ */
261+#define gic_read_typer(c) __gic_readq_nonatomic(c)
262+
263+/*
264+ * GITS_BASER - hi and lo bits may be accessed independently.
265+ */
266+#define gits_read_baser(c) __gic_readq_nonatomic(c)
267+#define gits_write_baser(v, c) __gic_writeq_nonatomic(v, c)
268+
269+/*
270+ * GICR_PENDBASER and GICR_PROPBASE are changed with LPIs disabled, so they
271+ * won't be being used during any updates and can be changed non-atomically
272+ */
273+#define gicr_read_propbaser(c) __gic_readq_nonatomic(c)
274+#define gicr_write_propbaser(v, c) __gic_writeq_nonatomic(v, c)
275+#define gicr_read_pendbaser(c) __gic_readq_nonatomic(c)
276+#define gicr_write_pendbaser(v, c) __gic_writeq_nonatomic(v, c)
277+
278+/*
279+ * GITS_TYPER is an ID register and doesn't need atomicity.
280+ */
281+#define gits_read_typer(c) __gic_readq_nonatomic(c)
282+
283+/*
284+ * GITS_CBASER - hi and lo bits may be accessed independently.
285+ */
286+#define gits_read_cbaser(c) __gic_readq_nonatomic(c)
287+#define gits_write_cbaser(v, c) __gic_writeq_nonatomic(v, c)
288+
289+/*
290+ * GITS_CWRITER - hi and lo bits may be accessed independently.
291+ */
292+#define gits_write_cwriter(v, c) __gic_writeq_nonatomic(v, c)
293+
254294 #endif /* !__ASSEMBLY__ */
255295 #endif /* !__ASM_ARCH_GICV3_H */
arch/arm64/include/asm/arch_gicv3.h+31−30
@@ -79,19 +79,10 @@ · 78 unmodified lines
7979
8080 #include <linux/stringify.h>
8181 #include <asm/barrier.h>
82+#include <asm/cacheflush.h>
8283
83−#define read_gicreg(r) \
84− ({ \
85− u64 reg; \
86− asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg)); \
87− reg; \
88− })
89−
90−#define write_gicreg(v,r) \
91− do { \
92− u64 __val = (v); \
93− asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
94− } while (0)
84+#define read_gicreg read_sysreg_s
85+#define write_gicreg write_sysreg_s
9586
9687 /*
9788 * Low-level accessors
@@ -102,13 +93,13 @@ · 4 unmodified lines
10293
10394 static inline void gic_write_eoir(u32 irq)
10495 {
105− asm volatile("msr_s " __stringify(ICC_EOIR1_EL1) ", %0" : : "r" ((u64)irq));
96+ write_sysreg_s(irq, ICC_EOIR1_EL1);
10697 isb();
10798 }
10899
109100 static inline void gic_write_dir(u32 irq)
110101 {
111− asm volatile("msr_s " __stringify(ICC_DIR_EL1) ", %0" : : "r" ((u64)irq));
102+ write_sysreg_s(irq, ICC_DIR_EL1);
112103 isb();
113104 }
114105
@@ -116,7 +107,7 @@ static inline u64 gic_read_iar_common(void) · 1 unmodified line
116107 {
117108 u64 irqstat;
118109
119− asm volatile("mrs_s %0, " __stringify(ICC_IAR1_EL1) : "=r" (irqstat));
110+ irqstat = read_sysreg_s(ICC_IAR1_EL1);
120111 dsb(sy);
121112 return irqstat;
122113 }
@@ -132,12 +123,9 @@ static inline u64 gic_read_iar_cavium_thunderx(void) · 9 unmodified lines
132123 {
133124 u64 irqstat;
134125
135− asm volatile(
136− "nop;nop;nop;nop\n\t"
137− "nop;nop;nop;nop\n\t"
138− "mrs_s %0, " __stringify(ICC_IAR1_EL1) "\n\t"
139− "nop;nop;nop;nop"
140− : "=r" (irqstat));
126+ nops(8);
127+ irqstat = read_sysreg_s(ICC_IAR1_EL1);
128+ nops(4);
141129 mb();
142130
143131 return irqstat;
@@ -145,37 +133,34 @@ static inline u64 gic_read_iar_cavium_thunderx(void) · 1 unmodified line
145133
146134 static inline void gic_write_pmr(u32 val)
147135 {
148− asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" ((u64)val));
136+ write_sysreg_s(val, ICC_PMR_EL1);
149137 }
150138
151139 static inline void gic_write_ctlr(u32 val)
152140 {
153− asm volatile("msr_s " __stringify(ICC_CTLR_EL1) ", %0" : : "r" ((u64)val));
141+ write_sysreg_s(val, ICC_CTLR_EL1);
154142 isb();
155143 }
156144
157145 static inline void gic_write_grpen1(u32 val)
158146 {
159− asm volatile("msr_s " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" ((u64)val));
147+ write_sysreg_s(val, ICC_GRPEN1_EL1);
160148 isb();
161149 }
162150
163151 static inline void gic_write_sgi1r(u64 val)
164152 {
165− asm volatile("msr_s " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val));
153+ write_sysreg_s(val, ICC_SGI1R_EL1);
166154 }
167155
168156 static inline u32 gic_read_sre(void)
169157 {
170− u64 val;
171−
172− asm volatile("mrs_s %0, " __stringify(ICC_SRE_EL1) : "=r" (val));
173− return val;
158+ return read_sysreg_s(ICC_SRE_EL1);
174159 }
175160
176161 static inline void gic_write_sre(u32 val)
177162 {
178− asm volatile("msr_s " __stringify(ICC_SRE_EL1) ", %0" : : "r" ((u64)val));
163+ write_sysreg_s(val, ICC_SRE_EL1);
179164 isb();
180165 }
181166
@@ -187,5 +172,21 @@ static inline void gic_write_bpr1(u32 val) · 5 unmodified lines
187172 #define gic_read_typer(c) readq_relaxed(c)
188173 #define gic_write_irouter(v, c) writeq_relaxed(v, c)
189174
175+#define gic_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l))
176+
177+#define gits_read_baser(c) readq_relaxed(c)
178+#define gits_write_baser(v, c) writeq_relaxed(v, c)
179+
180+#define gits_read_cbaser(c) readq_relaxed(c)
181+#define gits_write_cbaser(v, c) writeq_relaxed(v, c)
182+
183+#define gits_write_cwriter(v, c) writeq_relaxed(v, c)
184+
185+#define gicr_read_propbaser(c) readq_relaxed(c)
186+#define gicr_write_propbaser(v, c) writeq_relaxed(v, c)
187+
188+#define gicr_write_pendbaser(v, c) writeq_relaxed(v, c)
189+#define gicr_read_pendbaser(c) readq_relaxed(c)
190+
190191 #endif /* __ASSEMBLY__ */
191192 #endif /* __ASM_ARCH_GICV3_H */
arch/microblaze/Kconfig+1−0
@@ -27,6 +27,7 @@ config MICROBLAZE · 26 unmodified lines
2727 select HAVE_MEMBLOCK_NODE_MAP
2828 select HAVE_OPROFILE
2929 select IRQ_DOMAIN
30+ select XILINX_INTC
3031 select MODULES_USE_ELF_RELA
3132 select OF
3233 select OF_EARLY_FLATTREE
arch/microblaze/include/asm/irq.h+1−1
@@ -16,6 +16,6 @@ struct pt_regs; · 15 unmodified lines
1616 extern void do_IRQ(struct pt_regs *regs);
1717
1818 /* should be defined in each interrupt controller driver */
19−extern unsigned int get_irq(void);
19+extern unsigned int xintc_get_irq(void);
2020
2121 #endif /* _ASM_MICROBLAZE_IRQ_H */
arch/microblaze/kernel/Makefile+1−1
@@ -15,7 +15,7 @@ endif · 14 unmodified lines
1515 extra-y := head.o vmlinux.lds
1616
1717 obj-y += dma.o exceptions.o \
18− hw_exception_handler.o intc.o irq.o \
18+ hw_exception_handler.o irq.o \
1919 platform.o process.o prom.o ptrace.o \
2020 reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o
2121
arch/microblaze/kernel/intc.c+0−196
@@ -1,196 +0,0 @@
1−/*
2− * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
3− * Copyright (C) 2012-2013 Xilinx, Inc.
4− * Copyright (C) 2007-2009 PetaLogix
5− * Copyright (C) 2006 Atmark Techno, Inc.
6− *
7− * This file is subject to the terms and conditions of the GNU General Public
8− * License. See the file "COPYING" in the main directory of this archive
9− * for more details.
10− */
11−
12−#include <linux/irqdomain.h>
13−#include <linux/irq.h>
14−#include <linux/irqchip.h>
15−#include <linux/of_address.h>
16−#include <linux/io.h>
17−#include <linux/bug.h>
18−
19−static void __iomem *intc_baseaddr;
20−
21−/* No one else should require these constants, so define them locally here. */
22−#define ISR 0x00 /* Interrupt Status Register */
23−#define IPR 0x04 /* Interrupt Pending Register */
24−#define IER 0x08 /* Interrupt Enable Register */
25−#define IAR 0x0c /* Interrupt Acknowledge Register */
26−#define SIE 0x10 /* Set Interrupt Enable bits */
27−#define CIE 0x14 /* Clear Interrupt Enable bits */
28−#define IVR 0x18 /* Interrupt Vector Register */
29−#define MER 0x1c /* Master Enable Register */
30−
31−#define MER_ME (1<<0)
32−#define MER_HIE (1<<1)
33−
34−static unsigned int (*read_fn)(void __iomem *);
35−static void (*write_fn)(u32, void __iomem *);
36−
37−static void intc_write32(u32 val, void __iomem *addr)
38−{
39− iowrite32(val, addr);
40−}
41−
42−static unsigned int intc_read32(void __iomem *addr)
43−{
44− return ioread32(addr);
45−}
46−
47−static void intc_write32_be(u32 val, void __iomem *addr)
48−{
49− iowrite32be(val, addr);
50−}
51−
52−static unsigned int intc_read32_be(void __iomem *addr)
53−{
54− return ioread32be(addr);
55−}
56−
57−static void intc_enable_or_unmask(struct irq_data *d)
58−{
59− unsigned long mask = 1 << d->hwirq;
60−
61− pr_debug("enable_or_unmask: %ld\n", d->hwirq);
62−
63− /* ack level irqs because they can't be acked during
64− * ack function since the handle_level_irq function
65− * acks the irq before calling the interrupt handler
66− */
67− if (irqd_is_level_type(d))
68− write_fn(mask, intc_baseaddr + IAR);
69−
70− write_fn(mask, intc_baseaddr + SIE);
71−}
72−
73−static void intc_disable_or_mask(struct irq_data *d)
74−{
75− pr_debug("disable: %ld\n", d->hwirq);
76− write_fn(1 << d->hwirq, intc_baseaddr + CIE);
77−}
78−
79−static void intc_ack(struct irq_data *d)
80−{
81− pr_debug("ack: %ld\n", d->hwirq);
82− write_fn(1 << d->hwirq, intc_baseaddr + IAR);
83−}
84−
85−static void intc_mask_ack(struct irq_data *d)
86−{
87− unsigned long mask = 1 << d->hwirq;
88−
89− pr_debug("disable_and_ack: %ld\n", d->hwirq);
90− write_fn(mask, intc_baseaddr + CIE);
91− write_fn(mask, intc_baseaddr + IAR);
92−}
93−
94−static struct irq_chip intc_dev = {
95− .name = "Xilinx INTC",
96− .irq_unmask = intc_enable_or_unmask,
97− .irq_mask = intc_disable_or_mask,
98− .irq_ack = intc_ack,
99− .irq_mask_ack = intc_mask_ack,
100−};
101−
102−static struct irq_domain *root_domain;
103−
104−unsigned int get_irq(void)
105−{
106− unsigned int hwirq, irq = -1;
107−
108− hwirq = read_fn(intc_baseaddr + IVR);
109− if (hwirq != -1U)
110− irq = irq_find_mapping(root_domain, hwirq);
111−
112− pr_debug("get_irq: hwirq=%d, irq=%d\n", hwirq, irq);
113−
114− return irq;
115−}
116−
117−static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
118−{
119− u32 intr_mask = (u32)d->host_data;
120−
121− if (intr_mask & (1 << hw)) {
122− irq_set_chip_and_handler_name(irq, &intc_dev,
123− handle_edge_irq, "edge");
124− irq_clear_status_flags(irq, IRQ_LEVEL);
125− } else {
126− irq_set_chip_and_handler_name(irq, &intc_dev,
127− handle_level_irq, "level");
128− irq_set_status_flags(irq, IRQ_LEVEL);
129− }
130− return 0;
131−}
132−
133−static const struct irq_domain_ops xintc_irq_domain_ops = {
134− .xlate = irq_domain_xlate_onetwocell,
135− .map = xintc_map,
136−};
137−
138−static int __init xilinx_intc_of_init(struct device_node *intc,
139− struct device_node *parent)
140−{
141− u32 nr_irq, intr_mask;
142− int ret;
143−
144− intc_baseaddr = of_iomap(intc, 0);
145− BUG_ON(!intc_baseaddr);
146−
147− ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
148− if (ret < 0) {
149− pr_err("%s: unable to read xlnx,num-intr-inputs\n", __func__);
150− return ret;
151− }
152−
153− ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
154− if (ret < 0) {
155− pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
156− return ret;
157− }
158−
159− if (intr_mask >> nr_irq)
160− pr_warn("%s: mismatch in kind-of-intr param\n", __func__);
161−
162− pr_info("%s: num_irq=%d, edge=0x%x\n",
163− intc->full_name, nr_irq, intr_mask);
164−
165− write_fn = intc_write32;
166− read_fn = intc_read32;
167−
168− /*
169− * Disable all external interrupts until they are
170− * explicity requested.
171− */
172− write_fn(0, intc_baseaddr + IER);
173−
174− /* Acknowledge any pending interrupts just in case. */
175− write_fn(0xffffffff, intc_baseaddr + IAR);
176−
177− /* Turn on the Master Enable. */
178− write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
179− if (!(read_fn(intc_baseaddr + MER) & (MER_HIE | MER_ME))) {
180− write_fn = intc_write32_be;
181− read_fn = intc_read32_be;
182− write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
183− }
184−
185− /* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm
186− * lazy and Michal can clean it up to something nicer when he tests
187− * and commits this patch. ~~gcl */
188− root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
189− (void *)intr_mask);
190−
191− irq_set_default_host(root_domain);
192−
193− return 0;
194−}
195−
196−IRQCHIP_DECLARE(xilinx_intc, "xlnx,xps-intc-1.00.a", xilinx_intc_of_init);
arch/microblaze/kernel/irq.c+2−2
@@ -29,12 +29,12 @@ void __irq_entry do_IRQ(struct pt_regs *regs) · 28 unmodified lines
2929 trace_hardirqs_off();
3030
3131 irq_enter();
32− irq = get_irq();
32+ irq = xintc_get_irq();
3333 next_irq:
3434 BUG_ON(!irq);
3535 generic_handle_irq(irq);
3636
37− irq = get_irq();
37+ irq = xintc_get_irq();
3838 if (irq != -1U) {
3939 pr_debug("next irq: %d\n", irq);
4040 ++concurrent_irq;
arch/powerpc/include/asm/xilinx_intc.h+1−1
@@ -14,7 +14,7 @@ · 13 unmodified lines
1414 #ifdef __KERNEL__
1515
1616 extern void __init xilinx_intc_init_tree(void);
17−extern unsigned int xilinx_intc_get_irq(void);
17+extern unsigned int xintc_get_irq(void);
1818
1919 #endif /* __KERNEL__ */
2020 #endif /* _ASM_POWERPC_XILINX_INTC_H */
arch/powerpc/platforms/40x/Kconfig+1−0
@@ -64,6 +64,7 @@ config XILINX_VIRTEX_GENERIC_BOARD · 63 unmodified lines
6464 default n
6565 select XILINX_VIRTEX_II_PRO
6666 select XILINX_VIRTEX_4_FX
67+ select XILINX_INTC
6768 help
6869 This option enables generic support for Xilinx Virtex based boards.
6970
arch/powerpc/platforms/40x/virtex.c+1−1
@@ -48,7 +48,7 @@ define_machine(virtex) { · 47 unmodified lines
4848 .probe = virtex_probe,
4949 .setup_arch = xilinx_pci_init,
5050 .init_IRQ = xilinx_intc_init_tree,
51− .get_irq = xilinx_intc_get_irq,
51+ .get_irq = xintc_get_irq,
5252 .restart = ppc4xx_reset_system,
5353 .calibrate_decr = generic_calibrate_decr,
5454 };
arch/powerpc/platforms/44x/Kconfig+1−0
@@ -241,6 +241,7 @@ config XILINX_VIRTEX440_GENERIC_BOARD · 240 unmodified lines
241241 depends on 44x
242242 default n
243243 select XILINX_VIRTEX_5_FXT
244+ select XILINX_INTC
244245 help
245246 This option enables generic support for Xilinx Virtex based boards
246247 that use a 440 based processor in the Virtex 5 FXT FPGA architecture.
arch/powerpc/platforms/44x/virtex.c+1−1
@@ -54,7 +54,7 @@ define_machine(virtex) { · 53 unmodified lines
5454 .probe = virtex_probe,
5555 .setup_arch = xilinx_pci_init,
5656 .init_IRQ = xilinx_intc_init_tree,
57− .get_irq = xilinx_intc_get_irq,
57+ .get_irq = xintc_get_irq,
5858 .calibrate_decr = generic_calibrate_decr,
5959 .restart = ppc4xx_reset_system,
6060 };
arch/powerpc/sysdev/xilinx_intc.c+2−209
@@ -29,194 +29,7 @@ · 28 unmodified lines
2929 #include <asm/processor.h>
3030 #include <asm/i8259.h>
3131 #include <asm/irq.h>
32−
33−/*
34− * INTC Registers
35− */
36−#define XINTC_ISR 0 /* Interrupt Status */
37−#define XINTC_IPR 4 /* Interrupt Pending */
38−#define XINTC_IER 8 /* Interrupt Enable */
39−#define XINTC_IAR 12 /* Interrupt Acknowledge */
40−#define XINTC_SIE 16 /* Set Interrupt Enable bits */
41−#define XINTC_CIE 20 /* Clear Interrupt Enable bits */
42−#define XINTC_IVR 24 /* Interrupt Vector */
43−#define XINTC_MER 28 /* Master Enable */
44−
45−static struct irq_domain *master_irqhost;
46−
47−#define XILINX_INTC_MAXIRQS (32)
48−
49−/* The following table allows the interrupt type, edge or level,
50− * to be cached after being read from the device tree until the interrupt
51− * is mapped
52− */
53−static int xilinx_intc_typetable[XILINX_INTC_MAXIRQS];
54−
55−/* Map the interrupt type from the device tree to the interrupt types
56− * used by the interrupt subsystem
57− */
58−static unsigned char xilinx_intc_map_senses[] = {
59− IRQ_TYPE_EDGE_RISING,
60− IRQ_TYPE_EDGE_FALLING,
61− IRQ_TYPE_LEVEL_HIGH,
62− IRQ_TYPE_LEVEL_LOW,
63−};
64−
65−/*
66− * The interrupt controller is setup such that it doesn't work well with
67− * the level interrupt handler in the kernel because the handler acks the
68− * interrupt before calling the application interrupt handler. To deal with
69− * that, we use 2 different irq chips so that different functions can be
70− * used for level and edge type interrupts.
71− *
72− * IRQ Chip common (across level and edge) operations
73− */
74−static void xilinx_intc_mask(struct irq_data *d)
75−{
76− int irq = irqd_to_hwirq(d);
77− void * regs = irq_data_get_irq_chip_data(d);
78− pr_debug("mask: %d\n", irq);
79− out_be32(regs + XINTC_CIE, 1 << irq);
80−}
81−
82−static int xilinx_intc_set_type(struct irq_data *d, unsigned int flow_type)
83−{
84− return 0;
85−}
86−
87−/*
88− * IRQ Chip level operations
89− */
90−static void xilinx_intc_level_unmask(struct irq_data *d)
91−{
92− int irq = irqd_to_hwirq(d);
93− void * regs = irq_data_get_irq_chip_data(d);
94− pr_debug("unmask: %d\n", irq);
95− out_be32(regs + XINTC_SIE, 1 << irq);
96−
97− /* ack level irqs because they can't be acked during
98− * ack function since the handle_level_irq function
99− * acks the irq before calling the inerrupt handler
100− */
101− out_be32(regs + XINTC_IAR, 1 << irq);
102−}
103−
104−static struct irq_chip xilinx_intc_level_irqchip = {
105− .name = "Xilinx Level INTC",
106− .irq_mask = xilinx_intc_mask,
107− .irq_mask_ack = xilinx_intc_mask,
108− .irq_unmask = xilinx_intc_level_unmask,
109− .irq_set_type = xilinx_intc_set_type,
110−};
111−
112−/*
113− * IRQ Chip edge operations
114− */
115−static void xilinx_intc_edge_unmask(struct irq_data *d)
116−{
117− int irq = irqd_to_hwirq(d);
118− void *regs = irq_data_get_irq_chip_data(d);
119− pr_debug("unmask: %d\n", irq);
120− out_be32(regs + XINTC_SIE, 1 << irq);
121−}
122−
123−static void xilinx_intc_edge_ack(struct irq_data *d)
124−{
125− int irq = irqd_to_hwirq(d);
126− void * regs = irq_data_get_irq_chip_data(d);
127− pr_debug("ack: %d\n", irq);
128− out_be32(regs + XINTC_IAR, 1 << irq);
129−}
130−
131−static struct irq_chip xilinx_intc_edge_irqchip = {
132− .name = "Xilinx Edge INTC",
133− .irq_mask = xilinx_intc_mask,
134− .irq_unmask = xilinx_intc_edge_unmask,
135− .irq_ack = xilinx_intc_edge_ack,
136− .irq_set_type = xilinx_intc_set_type,
137−};
138−
139−/*
140− * IRQ Host operations
141− */
142−
143−/**
144− * xilinx_intc_xlate - translate virq# from device tree interrupts property
145− */
146−static int xilinx_intc_xlate(struct irq_domain *h, struct device_node *ct,
147− const u32 *intspec, unsigned int intsize,
148− irq_hw_number_t *out_hwirq,
149− unsigned int *out_flags)
150−{
151− if ((intsize < 2) || (intspec[0] >= XILINX_INTC_MAXIRQS))
152− return -EINVAL;
153−
154− /* keep a copy of the interrupt type til the interrupt is mapped
155− */
156− xilinx_intc_typetable[intspec[0]] = xilinx_intc_map_senses[intspec[1]];
157−
158− /* Xilinx uses 2 interrupt entries, the 1st being the h/w
159− * interrupt number, the 2nd being the interrupt type, edge or level
160− */
161− *out_hwirq = intspec[0];
162− *out_flags = xilinx_intc_map_senses[intspec[1]];
163−
164− return 0;
165−}
166−static int xilinx_intc_map(struct irq_domain *h, unsigned int virq,
167− irq_hw_number_t irq)
168−{
169− irq_set_chip_data(virq, h->host_data);
170−
171− if (xilinx_intc_typetable[irq] == IRQ_TYPE_LEVEL_HIGH ||
172− xilinx_intc_typetable[irq] == IRQ_TYPE_LEVEL_LOW) {
173− irq_set_chip_and_handler(virq, &xilinx_intc_level_irqchip,
174− handle_level_irq);
175− } else {
176− irq_set_chip_and_handler(virq, &xilinx_intc_edge_irqchip,
177− handle_edge_irq);
178− }
179− return 0;
180−}
181−
182−static const struct irq_domain_ops xilinx_intc_ops = {
183− .map = xilinx_intc_map,
184− .xlate = xilinx_intc_xlate,
185−};
186−
187−struct irq_domain * __init
188−xilinx_intc_init(struct device_node *np)
189−{
190− struct irq_domain * irq;
191− void * regs;
192−
193− /* Find and map the intc registers */
194− regs = of_iomap(np, 0);
195− if (!regs) {
196− pr_err("xilinx_intc: could not map registers\n");
197− return NULL;
198− }
199−
200− /* Setup interrupt controller */
201− out_be32(regs + XINTC_IER, 0); /* disable all irqs */
202− out_be32(regs + XINTC_IAR, ~(u32) 0); /* Acknowledge pending irqs */
203− out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */
204−
205− /* Allocate and initialize an irq_domain structure. */
206− irq = irq_domain_add_linear(np, XILINX_INTC_MAXIRQS, &xilinx_intc_ops,
207− regs);
208− if (!irq)
209− panic(__FILE__ ": Cannot allocate IRQ host\n");
210−
211− return irq;
212−}
213−
214−int xilinx_intc_get_irq(void)
215−{
216− void * regs = master_irqhost->host_data;
217− pr_debug("get_irq:\n");
218− return irq_linear_revmap(master_irqhost, in_be32(regs + XINTC_IVR));
219−}
32+#include <linux/irqchip.h>
22033
22134 #if defined(CONFIG_PPC_I8259)
22235 /*
@@ -265,31 +78,11 @@ static void __init xilinx_i8259_setup_cascade(void) · 42 unmodified lines
26578 static inline void xilinx_i8259_setup_cascade(void) { return; }
26679 #endif /* defined(CONFIG_PPC_I8259) */
26780
268−static const struct of_device_id xilinx_intc_match[] __initconst = {
269− { .compatible = "xlnx,opb-intc-1.00.c", },
270− { .compatible = "xlnx,xps-intc-1.00.a", },
271− {}
272−};
273−
27481 /*
27582 * Initialize master Xilinx interrupt controller
27683 */
27784 void __init xilinx_intc_init_tree(void)
27885 {
279− struct device_node *np;
280−
281− /* find top level interrupt controller */
282− for_each_matching_node(np, xilinx_intc_match) {
283− if (!of_get_property(np, "interrupts", NULL))
284− break;
285− }
286− BUG_ON(!np);
287−
288− master_irqhost = xilinx_intc_init(np);
289− BUG_ON(!master_irqhost);
290−
291− irq_set_default_host(master_irqhost);
292− of_node_put(np);
293−
86+ irqchip_init();
29487 xilinx_i8259_setup_cascade();
29588 }
drivers/irqchip/Kconfig+4−0
@@ -211,6 +211,10 @@ config XTENSA_MX · 210 unmodified lines
211211 bool
212212 select IRQ_DOMAIN
213213
214+config XILINX_INTC
215+ bool
216+ select IRQ_DOMAIN
217+
214218 config IRQ_CROSSBAR
215219 bool
216220 help
drivers/irqchip/Makefile+1−0
@@ -52,6 +52,7 @@ obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o · 51 unmodified lines
5252 obj-$(CONFIG_TS4800_IRQ) += irq-ts4800.o
5353 obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o
5454 obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o
55+obj-$(CONFIG_XILINX_INTC) += irq-xilinx-intc.o
5556 obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o
5657 obj-$(CONFIG_SOC_VF610) += irq-vf610-mscm-ir.o
5758 obj-$(CONFIG_BCM6345_L1_IRQ) += irq-bcm6345-l1.o
drivers/irqchip/irq-bcm7038-l1.c+26−0
@@ -215,6 +215,31 @@ static int bcm7038_l1_set_affinity(struct irq_data *d, · 214 unmodified lines
215215 return 0;
216216 }
217217
218+static void bcm7038_l1_cpu_offline(struct irq_data *d)
219+{
220+ struct cpumask *mask = irq_data_get_affinity_mask(d);
221+ int cpu = smp_processor_id();
222+ cpumask_t new_affinity;
223+
224+ /* This CPU was not on the affinity mask */
225+ if (!cpumask_test_cpu(cpu, mask))
226+ return;
227+
228+ if (cpumask_weight(mask) > 1) {
229+ /*
230+ * Multiple CPU affinity, remove this CPU from the affinity
231+ * mask
232+ */
233+ cpumask_copy(&new_affinity, mask);
234+ cpumask_clear_cpu(cpu, &new_affinity);
235+ } else {
236+ /* Only CPU, put on the lowest online CPU */
237+ cpumask_clear(&new_affinity);
238+ cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity);
239+ }
240+ irq_set_affinity_locked(d, &new_affinity, false);
241+}
242+
218243 static int __init bcm7038_l1_init_one(struct device_node *dn,
219244 unsigned int idx,
220245 struct bcm7038_l1_chip *intc)
@@ -266,6 +291,7 @@ static struct irq_chip bcm7038_l1_irq_chip = { · 45 unmodified lines
266291 .irq_mask = bcm7038_l1_mask,
267292 .irq_unmask = bcm7038_l1_unmask,
268293 .irq_set_affinity = bcm7038_l1_set_affinity,
294+ .irq_cpu_offline = bcm7038_l1_cpu_offline,
269295 };
270296
271297 static int bcm7038_l1_map(struct irq_domain *d, unsigned int virq,
drivers/irqchip/irq-gic-v3-its.c+37−38
@@ -37,7 +37,6 @@ · 36 unmodified lines
3737 #include <linux/irqchip.h>
3838 #include <linux/irqchip/arm-gic-v3.h>
3939
40−#include <asm/cacheflush.h>
4140 #include <asm/cputype.h>
4241 #include <asm/exception.h>
4342
@@ -196,7 +195,7 @@ typedef struct its_collection *(*its_cmd_builder_t)(struct its_cmd_block *, · 152 unmodified lines
196195
197196 static void its_encode_cmd(struct its_cmd_block *cmd, u8 cmd_nr)
198197 {
199− cmd->raw_cmd[0] &= ~0xffUL;
198+ cmd->raw_cmd[0] &= ~0xffULL;
200199 cmd->raw_cmd[0] |= cmd_nr;
201200 }
202201
@@ -208,43 +207,43 @@ static void its_encode_devid(struct its_cmd_block *cmd, u32 devid) · 5 unmodified lines
208207
209208 static void its_encode_event_id(struct its_cmd_block *cmd, u32 id)
210209 {
211− cmd->raw_cmd[1] &= ~0xffffffffUL;
210+ cmd->raw_cmd[1] &= ~0xffffffffULL;
212211 cmd->raw_cmd[1] |= id;
213212 }
214213
215214 static void its_encode_phys_id(struct its_cmd_block *cmd, u32 phys_id)
216215 {
217− cmd->raw_cmd[1] &= 0xffffffffUL;
216+ cmd->raw_cmd[1] &= 0xffffffffULL;
218217 cmd->raw_cmd[1] |= ((u64)phys_id) << 32;
219218 }
220219
221220 static void its_encode_size(struct its_cmd_block *cmd, u8 size)
222221 {
223− cmd->raw_cmd[1] &= ~0x1fUL;
222+ cmd->raw_cmd[1] &= ~0x1fULL;
224223 cmd->raw_cmd[1] |= size & 0x1f;
225224 }
226225
227226 static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr)
228227 {
229− cmd->raw_cmd[2] &= ~0xffffffffffffUL;
230− cmd->raw_cmd[2] |= itt_addr & 0xffffffffff00UL;
228+ cmd->raw_cmd[2] &= ~0xffffffffffffULL;
229+ cmd->raw_cmd[2] |= itt_addr & 0xffffffffff00ULL;
231230 }
232231
233232 static void its_encode_valid(struct its_cmd_block *cmd, int valid)
234233 {
235− cmd->raw_cmd[2] &= ~(1UL << 63);
234+ cmd->raw_cmd[2] &= ~(1ULL << 63);
236235 cmd->raw_cmd[2] |= ((u64)!!valid) << 63;
237236 }
238237
239238 static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr)
240239 {
241− cmd->raw_cmd[2] &= ~(0xffffffffUL << 16);
242− cmd->raw_cmd[2] |= (target_addr & (0xffffffffUL << 16));
240+ cmd->raw_cmd[2] &= ~(0xffffffffULL << 16);
241+ cmd->raw_cmd[2] |= (target_addr & (0xffffffffULL << 16));
243242 }
244243
245244 static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
246245 {
247− cmd->raw_cmd[2] &= ~0xffffUL;
246+ cmd->raw_cmd[2] &= ~0xffffULL;
248247 cmd->raw_cmd[2] |= col;
249248 }
250249
@@ -433,7 +432,7 @@ static void its_flush_cmd(struct its_node *its, struct its_cmd_block *cmd) · 182 unmodified lines
433432 * the ITS.
434433 */
435434 if (its->flags & ITS_FLAGS_CMDQ_NEEDS_FLUSHING)
436− __flush_dcache_area(cmd, sizeof(*cmd));
435+ gic_flush_dcache_to_poc(cmd, sizeof(*cmd));
437436 else
438437 dsb(ishst);
439438 }
@@ -602,7 +601,7 @@ static void lpi_set_config(struct irq_data *d, bool enable) · 162 unmodified lines
602601 * Humpf...
603602 */
604603 if (gic_rdists->flags & RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING)
605− __flush_dcache_area(cfg, sizeof(*cfg));
604+ gic_flush_dcache_to_poc(cfg, sizeof(*cfg));
606605 else
607606 dsb(ishst);
608607 its_send_inv(its_dev, id);
@@ -657,8 +656,8 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg) · 48 unmodified lines
657656 its = its_dev->its;
658657 addr = its->phys_base + GITS_TRANSLATER;
659658
660− msg->address_lo = addr & ((1UL << 32) - 1);
661− msg->address_hi = addr >> 32;
659+ msg->address_lo = lower_32_bits(addr);
660+ msg->address_hi = upper_32_bits(addr);
662661 msg->data = its_get_event_id(d);
663662
664663 iommu_dma_map_msi_msg(d->irq, msg);
@@ -817,7 +816,7 @@ static int __init its_alloc_lpi_tables(void) · 152 unmodified lines
817816 LPI_PROPBASE_SZ);
818817
819818 /* Make sure the GIC will observe the written configuration */
820− __flush_dcache_area(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ);
819+ gic_flush_dcache_to_poc(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ);
821820
822821 return 0;
823822 }
@@ -836,7 +835,7 @@ static u64 its_read_baser(struct its_node *its, struct its_baser *baser) · 12 unmodified lines
836835 {
837836 u32 idx = baser - its->tables;
838837
839− return readq_relaxed(its->base + GITS_BASER + (idx << 3));
838+ return gits_read_baser(its->base + GITS_BASER + (idx << 3));
840839 }
841840
842841 static void its_write_baser(struct its_node *its, struct its_baser *baser,
@@ -844,7 +843,7 @@ static void its_write_baser(struct its_node *its, struct its_baser *baser, · 1 unmodified line
844843 {
845844 u32 idx = baser - its->tables;
846845
847− writeq_relaxed(val, its->base + GITS_BASER + (idx << 3));
846+ gits_write_baser(val, its->base + GITS_BASER + (idx << 3));
848847 baser->val = its_read_baser(its, baser);
849848 }
850849
@@ -910,7 +909,7 @@ retry_baser: · 59 unmodified lines
910909 shr = tmp & GITS_BASER_SHAREABILITY_MASK;
911910 if (!shr) {
912911 cache = GITS_BASER_nC;
913− __flush_dcache_area(base, PAGE_ORDER_TO_SIZE(order));
912+ gic_flush_dcache_to_poc(base, PAGE_ORDER_TO_SIZE(order));
914913 }
915914 goto retry_baser;
916915 }
@@ -935,9 +934,9 @@ retry_baser: · 18 unmodified lines
935934 }
936935
937936 if (val != tmp) {
938− pr_err("ITS@%pa: %s doesn't stick: %lx %lx\n",
937+ pr_err("ITS@%pa: %s doesn't stick: %llx %llx\n",
939938 &its->phys_base, its_base_type_string[type],
940− (unsigned long) val, (unsigned long) tmp);
939+ val, tmp);
941940 free_pages((unsigned long)base, order);
942941 return -ENXIO;
943942 }
@@ -948,7 +947,7 @@ retry_baser: · 4 unmodified lines
948947 tmp = indirect ? GITS_LVL1_ENTRY_SIZE : esz;
949948
950949 pr_info("ITS@%pa: allocated %d %s @%lx (%s, esz %d, psz %dK, shr %d)\n",
951− &its->phys_base, (int)(PAGE_ORDER_TO_SIZE(order) / tmp),
950+ &its->phys_base, (int)(PAGE_ORDER_TO_SIZE(order) / (int)tmp),
952951 its_base_type_string[type],
953952 (unsigned long)virt_to_phys(base),
954953 indirect ? "indirect" : "flat", (int)esz,
@@ -983,7 +982,7 @@ static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser · 28 unmodified lines
983982 * which is reported by ITS hardware times lvl1 table
984983 * entry size.
985984 */
986− ids -= ilog2(psz / esz);
985+ ids -= ilog2(psz / (int)esz);
987986 esz = GITS_LVL1_ENTRY_SIZE;
988987 }
989988 }
@@ -998,7 +997,7 @@ static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser · 8 unmodified lines
998997 new_order = max_t(u32, get_order(esz << ids), new_order);
999998 if (new_order >= MAX_ORDER) {
1000999 new_order = MAX_ORDER - 1;
1001− ids = ilog2(PAGE_ORDER_TO_SIZE(new_order) / esz);
1000+ ids = ilog2(PAGE_ORDER_TO_SIZE(new_order) / (int)esz);
10021001 pr_warn("ITS@%pa: Device Table too large, reduce ids %u->%u\n",
10031002 &its->phys_base, its->device_ids, ids);
10041003 }
@@ -1102,7 +1101,7 @@ static void its_cpu_init_lpis(void) · 97 unmodified lines
11021101 }
11031102
11041103 /* Make sure the GIC will observe the zero-ed page */
1105− __flush_dcache_area(page_address(pend_page), LPI_PENDBASE_SZ);
1104+ gic_flush_dcache_to_poc(page_address(pend_page), LPI_PENDBASE_SZ);
11061105
11071106 paddr = page_to_phys(pend_page);
11081107 pr_info("CPU%d: using LPI pending table @%pa\n",
@@ -1126,8 +1125,8 @@ static void its_cpu_init_lpis(void) · 17 unmodified lines
11261125 GICR_PROPBASER_WaWb |
11271126 ((LPI_NRBITS - 1) & GICR_PROPBASER_IDBITS_MASK));
11281127
1129− writeq_relaxed(val, rbase + GICR_PROPBASER);
1130− tmp = readq_relaxed(rbase + GICR_PROPBASER);
1128+ gicr_write_propbaser(val, rbase + GICR_PROPBASER);
1129+ tmp = gicr_read_propbaser(rbase + GICR_PROPBASER);
11311130
11321131 if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) {
11331132 if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) {
@@ -1139,7 +1138,7 @@ static void its_cpu_init_lpis(void) · 5 unmodified lines
11391138 val &= ~(GICR_PROPBASER_SHAREABILITY_MASK |
11401139 GICR_PROPBASER_CACHEABILITY_MASK);
11411140 val |= GICR_PROPBASER_nC;
1142− writeq_relaxed(val, rbase + GICR_PROPBASER);
1141+ gicr_write_propbaser(val, rbase + GICR_PROPBASER);
11431142 }
11441143 pr_info_once("GIC: using cache flushing for LPI property table\n");
11451144 gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING;
@@ -1150,8 +1149,8 @@ static void its_cpu_init_lpis(void) · 4 unmodified lines
11501149 GICR_PENDBASER_InnerShareable |
11511150 GICR_PENDBASER_WaWb);
11521151
1153− writeq_relaxed(val, rbase + GICR_PENDBASER);
1154− tmp = readq_relaxed(rbase + GICR_PENDBASER);
1152+ gicr_write_pendbaser(val, rbase + GICR_PENDBASER);
1153+ tmp = gicr_read_pendbaser(rbase + GICR_PENDBASER);
11551154
11561155 if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) {
11571156 /*
@@ -1161,7 +1160,7 @@ static void its_cpu_init_lpis(void) · 3 unmodified lines
11611160 val &= ~(GICR_PENDBASER_SHAREABILITY_MASK |
11621161 GICR_PENDBASER_CACHEABILITY_MASK);
11631162 val |= GICR_PENDBASER_nC;
1164− writeq_relaxed(val, rbase + GICR_PENDBASER);
1163+ gicr_write_pendbaser(val, rbase + GICR_PENDBASER);
11651164 }
11661165
11671166 /* Enable LPIs */
@@ -1287,13 +1286,13 @@ static bool its_alloc_device_table(struct its_node *its, u32 dev_id) · 119 unmodified lines
12871286
12881287 /* Flush Lvl2 table to PoC if hw doesn't support coherency */
12891288 if (!(baser->val & GITS_BASER_SHAREABILITY_MASK))
1290− __flush_dcache_area(page_address(page), baser->psz);
1289+ gic_flush_dcache_to_poc(page_address(page), baser->psz);
12911290
12921291 table[idx] = cpu_to_le64(page_to_phys(page) | GITS_BASER_VALID);
12931292
12941293 /* Flush Lvl1 entry to PoC if hw doesn't support coherency */
12951294 if (!(baser->val & GITS_BASER_SHAREABILITY_MASK))
1296− __flush_dcache_area(table + idx, GITS_LVL1_ENTRY_SIZE);
1295+ gic_flush_dcache_to_poc(table + idx, GITS_LVL1_ENTRY_SIZE);
12971296
12981297 /* Ensure updated table contents are visible to ITS hardware */
12991298 dsb(sy);
@@ -1340,7 +1339,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, · 40 unmodified lines
13401339 return NULL;
13411340 }
13421341
1343− __flush_dcache_area(itt, sz);
1342+ gic_flush_dcache_to_poc(itt, sz);
13441343
13451344 dev->its = its;
13461345 dev->itt = itt;
@@ -1717,8 +1716,8 @@ static int __init its_probe_one(struct resource *res, · 370 unmodified lines
17171716 (ITS_CMD_QUEUE_SZ / SZ_4K - 1) |
17181717 GITS_CBASER_VALID);
17191718
1720− writeq_relaxed(baser, its->base + GITS_CBASER);
1721− tmp = readq_relaxed(its->base + GITS_CBASER);
1719+ gits_write_cbaser(baser, its->base + GITS_CBASER);
1720+ tmp = gits_read_cbaser(its->base + GITS_CBASER);
17221721
17231722 if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) {
17241723 if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) {
@@ -1730,13 +1729,13 @@ static int __init its_probe_one(struct resource *res, · 5 unmodified lines
17301729 baser &= ~(GITS_CBASER_SHAREABILITY_MASK |
17311730 GITS_CBASER_CACHEABILITY_MASK);
17321731 baser |= GITS_CBASER_nC;
1733− writeq_relaxed(baser, its->base + GITS_CBASER);
1732+ gits_write_cbaser(baser, its->base + GITS_CBASER);
17341733 }
17351734 pr_info("ITS: using cache flushing for cmd queue\n");
17361735 its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING;
17371736 }
17381737
1739− writeq_relaxed(0, its->base + GITS_CWRITER);
1738+ gits_write_cwriter(0, its->base + GITS_CWRITER);
17401739 writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
17411740
17421741 err = its_init_domain(handle, its);
drivers/irqchip/irq-xilinx-intc.c+241−0
@@ -0,0 +1,241 @@
1+/*
2+ * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
3+ * Copyright (C) 2012-2013 Xilinx, Inc.
4+ * Copyright (C) 2007-2009 PetaLogix
5+ * Copyright (C) 2006 Atmark Techno, Inc.
6+ *
7+ * This file is subject to the terms and conditions of the GNU General Public
8+ * License. See the file "COPYING" in the main directory of this archive
9+ * for more details.
10+ */
11+
12+#include <linux/irqdomain.h>
13+#include <linux/irq.h>
14+#include <linux/irqchip.h>
15+#include <linux/irqchip/chained_irq.h>
16+#include <linux/of_address.h>
17+#include <linux/io.h>
18+#include <linux/jump_label.h>
19+#include <linux/bug.h>
20+#include <linux/of_irq.h>
21+
22+/* No one else should require these constants, so define them locally here. */
23+#define ISR 0x00 /* Interrupt Status Register */
24+#define IPR 0x04 /* Interrupt Pending Register */
25+#define IER 0x08 /* Interrupt Enable Register */
26+#define IAR 0x0c /* Interrupt Acknowledge Register */
27+#define SIE 0x10 /* Set Interrupt Enable bits */
28+#define CIE 0x14 /* Clear Interrupt Enable bits */
29+#define IVR 0x18 /* Interrupt Vector Register */
30+#define MER 0x1c /* Master Enable Register */
31+
32+#define MER_ME (1<<0)
33+#define MER_HIE (1<<1)
34+
35+static DEFINE_STATIC_KEY_FALSE(xintc_is_be);
36+
37+struct xintc_irq_chip {
38+ void __iomem *base;
39+ struct irq_domain *root_domain;
40+ u32 intr_mask;
41+};
42+
43+static struct xintc_irq_chip *xintc_irqc;
44+
45+static void xintc_write(int reg, u32 data)
46+{
47+ if (static_branch_unlikely(&xintc_is_be))
48+ iowrite32be(data, xintc_irqc->base + reg);
49+ else
50+ iowrite32(data, xintc_irqc->base + reg);
51+}
52+
53+static unsigned int xintc_read(int reg)
54+{
55+ if (static_branch_unlikely(&xintc_is_be))
56+ return ioread32be(xintc_irqc->base + reg);
57+ else
58+ return ioread32(xintc_irqc->base + reg);
59+}
60+
61+static void intc_enable_or_unmask(struct irq_data *d)
62+{
63+ unsigned long mask = 1 << d->hwirq;
64+
65+ pr_debug("irq-xilinx: enable_or_unmask: %ld\n", d->hwirq);
66+
67+ /* ack level irqs because they can't be acked during
68+ * ack function since the handle_level_irq function
69+ * acks the irq before calling the interrupt handler
70+ */
71+ if (irqd_is_level_type(d))
72+ xintc_write(IAR, mask);
73+
74+ xintc_write(SIE, mask);
75+}
76+
77+static void intc_disable_or_mask(struct irq_data *d)
78+{
79+ pr_debug("irq-xilinx: disable: %ld\n", d->hwirq);
80+ xintc_write(CIE, 1 << d->hwirq);
81+}
82+
83+static void intc_ack(struct irq_data *d)
84+{
85+ pr_debug("irq-xilinx: ack: %ld\n", d->hwirq);
86+ xintc_write(IAR, 1 << d->hwirq);
87+}
88+
89+static void intc_mask_ack(struct irq_data *d)
90+{
91+ unsigned long mask = 1 << d->hwirq;
92+
93+ pr_debug("irq-xilinx: disable_and_ack: %ld\n", d->hwirq);
94+ xintc_write(CIE, mask);
95+ xintc_write(IAR, mask);
96+}
97+
98+static struct irq_chip intc_dev = {
99+ .name = "Xilinx INTC",
100+ .irq_unmask = intc_enable_or_unmask,
101+ .irq_mask = intc_disable_or_mask,
102+ .irq_ack = intc_ack,
103+ .irq_mask_ack = intc_mask_ack,
104+};
105+
106+unsigned int xintc_get_irq(void)
107+{
108+ unsigned int hwirq, irq = -1;
109+
110+ hwirq = xintc_read(IVR);
111+ if (hwirq != -1U)
112+ irq = irq_find_mapping(xintc_irqc->root_domain, hwirq);
113+
114+ pr_debug("irq-xilinx: hwirq=%d, irq=%d\n", hwirq, irq);
115+
116+ return irq;
117+}
118+
119+static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
120+{
121+ if (xintc_irqc->intr_mask & (1 << hw)) {
122+ irq_set_chip_and_handler_name(irq, &intc_dev,
123+ handle_edge_irq, "edge");
124+ irq_clear_status_flags(irq, IRQ_LEVEL);
125+ } else {
126+ irq_set_chip_and_handler_name(irq, &intc_dev,
127+ handle_level_irq, "level");
128+ irq_set_status_flags(irq, IRQ_LEVEL);
129+ }
130+ return 0;
131+}
132+
133+static const struct irq_domain_ops xintc_irq_domain_ops = {
134+ .xlate = irq_domain_xlate_onetwocell,
135+ .map = xintc_map,
136+};
137+
138+static void xil_intc_irq_handler(struct irq_desc *desc)
139+{
140+ struct irq_chip *chip = irq_desc_get_chip(desc);
141+ u32 pending;
142+
143+ chained_irq_enter(chip, desc);
144+ do {
145+ pending = xintc_get_irq();
146+ if (pending == -1U)
147+ break;
148+ generic_handle_irq(pending);
149+ } while (true);
150+ chained_irq_exit(chip, desc);
151+}
152+
153+static int __init xilinx_intc_of_init(struct device_node *intc,
154+ struct device_node *parent)
155+{
156+ u32 nr_irq;
157+ int ret, irq;
158+ struct xintc_irq_chip *irqc;
159+
160+ if (xintc_irqc) {
161+ pr_err("irq-xilinx: Multiple instances aren't supported\n");
162+ return -EINVAL;
163+ }
164+
165+ irqc = kzalloc(sizeof(*irqc), GFP_KERNEL);
166+ if (!irqc)
167+ return -ENOMEM;
168+
169+ xintc_irqc = irqc;
170+
171+ irqc->base = of_iomap(intc, 0);
172+ BUG_ON(!irqc->base);
173+
174+ ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
175+ if (ret < 0) {
176+ pr_err("irq-xilinx: unable to read xlnx,num-intr-inputs\n");
177+ goto err_alloc;
178+ }
179+
180+ ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &irqc->intr_mask);
181+ if (ret < 0) {
182+ pr_warn("irq-xilinx: unable to read xlnx,kind-of-intr\n");
183+ irqc->intr_mask = 0;
184+ }
185+
186+ if (irqc->intr_mask >> nr_irq)
187+ pr_warn("irq-xilinx: mismatch in kind-of-intr param\n");
188+
189+ pr_info("irq-xilinx: %s: num_irq=%d, edge=0x%x\n",
190+ intc->full_name, nr_irq, irqc->intr_mask);
191+
192+
193+ /*
194+ * Disable all external interrupts until they are
195+ * explicity requested.
196+ */
197+ xintc_write(IER, 0);
198+
199+ /* Acknowledge any pending interrupts just in case. */
200+ xintc_write(IAR, 0xffffffff);
201+
202+ /* Turn on the Master Enable. */
203+ xintc_write(MER, MER_HIE | MER_ME);
204+ if (!(xintc_read(MER) & (MER_HIE | MER_ME))) {
205+ static_branch_enable(&xintc_is_be);
206+ xintc_write(MER, MER_HIE | MER_ME);
207+ }
208+
209+ irqc->root_domain = irq_domain_add_linear(intc, nr_irq,
210+ &xintc_irq_domain_ops, irqc);
211+ if (!irqc->root_domain) {
212+ pr_err("irq-xilinx: Unable to create IRQ domain\n");
213+ goto err_alloc;
214+ }
215+
216+ if (parent) {
217+ irq = irq_of_parse_and_map(intc, 0);
218+ if (irq) {
219+ irq_set_chained_handler_and_data(irq,
220+ xil_intc_irq_handler,
221+ irqc);
222+ } else {
223+ pr_err("irq-xilinx: interrupts property not in DT\n");
224+ ret = -EINVAL;
225+ goto err_alloc;
226+ }
227+ } else {
228+ irq_set_default_host(irqc->root_domain);
229+ }
230+
231+ return 0;
232+
233+err_alloc:
234+ xintc_irqc = NULL;
235+ kfree(irqc);
236+ return ret;
237+
238+}
239+
240+IRQCHIP_DECLARE(xilinx_intc_xps, "xlnx,xps-intc-1.00.a", xilinx_intc_of_init);
241+IRQCHIP_DECLARE(xilinx_intc_opb, "xlnx,opb-intc-1.00.c", xilinx_intc_of_init);
drivers/pci/msi.c+43−35
@@ -551,14 +551,14 @@ error_attrs: · 550 unmodified lines
551551 }
552552
553553 static struct msi_desc *
554−msi_setup_entry(struct pci_dev *dev, int nvec, bool affinity)
554+msi_setup_entry(struct pci_dev *dev, int nvec, const struct irq_affinity *affd)
555555 {
556556 struct cpumask *masks = NULL;
557557 struct msi_desc *entry;
558558 u16 control;
559559
560− if (affinity) {
561− masks = irq_create_affinity_masks(dev->irq_affinity, nvec);
560+ if (affd) {
561+ masks = irq_create_affinity_masks(nvec, affd);
562562 if (!masks)
563563 pr_err("Unable to allocate affinity masks, ignoring\n");
564564 }
@@ -618,7 +618,8 @@ static int msi_verify_entries(struct pci_dev *dev) · 53 unmodified lines
618618 * an error, and a positive return value indicates the number of interrupts
619619 * which could have been allocated.
620620 */
621−static int msi_capability_init(struct pci_dev *dev, int nvec, bool affinity)
621+static int msi_capability_init(struct pci_dev *dev, int nvec,
622+ const struct irq_affinity *affd)
622623 {
623624 struct msi_desc *entry;
624625 int ret;
@@ -626,7 +627,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec, bool affinity) · 1 unmodified line
626627
627628 pci_msi_set_enable(dev, 0); /* Disable MSI during set up */
628629
629− entry = msi_setup_entry(dev, nvec, affinity);
630+ entry = msi_setup_entry(dev, nvec, affd);
630631 if (!entry)
631632 return -ENOMEM;
632633
@@ -690,14 +691,14 @@ static void __iomem *msix_map_region(struct pci_dev *dev, unsigned nr_entries) · 57 unmodified lines
690691
691692 static int msix_setup_entries(struct pci_dev *dev, void __iomem *base,
692693 struct msix_entry *entries, int nvec,
693− bool affinity)
694+ const struct irq_affinity *affd)
694695 {
695696 struct cpumask *curmsk, *masks = NULL;
696697 struct msi_desc *entry;
697698 int ret, i;
698699
699− if (affinity) {
700− masks = irq_create_affinity_masks(dev->irq_affinity, nvec);
700+ if (affd) {
701+ masks = irq_create_affinity_masks(nvec, affd);
701702 if (!masks)
702703 pr_err("Unable to allocate affinity masks, ignoring\n");
703704 }
@@ -753,14 +754,14 @@ static void msix_program_entries(struct pci_dev *dev, · 49 unmodified lines
753754 * @dev: pointer to the pci_dev data structure of MSI-X device function
754755 * @entries: pointer to an array of struct msix_entry entries
755756 * @nvec: number of @entries
756− * @affinity: flag to indicate cpu irq affinity mask should be set
757+ * @affd: Optional pointer to enable automatic affinity assignement
757758 *
758759 * Setup the MSI-X capability structure of device function with a
759760 * single MSI-X irq. A return of zero indicates the successful setup of
760761 * requested MSI-X entries with allocated irqs or non-zero for otherwise.
761762 **/
762763 static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
763− int nvec, bool affinity)
764+ int nvec, const struct irq_affinity *affd)
764765 {
765766 int ret;
766767 u16 control;
@@ -775,7 +776,7 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, · 8 unmodified lines
775776 if (!base)
776777 return -ENOMEM;
777778
778− ret = msix_setup_entries(dev, base, entries, nvec, affinity);
779+ ret = msix_setup_entries(dev, base, entries, nvec, affd);
779780 if (ret)
780781 return ret;
781782
@@ -956,7 +957,7 @@ int pci_msix_vec_count(struct pci_dev *dev) · 174 unmodified lines
956957 EXPORT_SYMBOL(pci_msix_vec_count);
957958
958959 static int __pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries,
959− int nvec, bool affinity)
960+ int nvec, const struct irq_affinity *affd)
960961 {
961962 int nr_entries;
962963 int i, j;
@@ -988,7 +989,7 @@ static int __pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, · 25 unmodified lines
988989 dev_info(&dev->dev, "can't enable MSI-X (MSI IRQ already assigned)\n");
989990 return -EINVAL;
990991 }
991− return msix_capability_init(dev, entries, nvec, affinity);
992+ return msix_capability_init(dev, entries, nvec, affd);
992993 }
993994
994995 /**
@@ -1008,7 +1009,7 @@ static int __pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, · 13 unmodified lines
10081009 **/
10091010 int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
10101011 {
1011− return __pci_enable_msix(dev, entries, nvec, false);
1012+ return __pci_enable_msix(dev, entries, nvec, NULL);
10121013 }
10131014 EXPORT_SYMBOL(pci_enable_msix);
10141015
@@ -1059,9 +1060,8 @@ int pci_msi_enabled(void) · 44 unmodified lines
10591060 EXPORT_SYMBOL(pci_msi_enabled);
10601061
10611062 static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
1062− unsigned int flags)
1063+ const struct irq_affinity *affd)
10631064 {
1064− bool affinity = flags & PCI_IRQ_AFFINITY;
10651065 int nvec;
10661066 int rc;
10671067
@@ -1090,14 +1090,13 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, · 22 unmodified lines
10901090 nvec = maxvec;
10911091
10921092 for (;;) {
1093− if (affinity) {
1094− nvec = irq_calc_affinity_vectors(dev->irq_affinity,
1095− nvec);
1093+ if (affd) {
1094+ nvec = irq_calc_affinity_vectors(nvec, affd);
10961095 if (nvec < minvec)
10971096 return -ENOSPC;
10981097 }
10991098
1100− rc = msi_capability_init(dev, nvec, affinity);
1099+ rc = msi_capability_init(dev, nvec, affd);
11011100 if (rc == 0)
11021101 return nvec;
11031102
@@ -1124,29 +1123,27 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, · 20 unmodified lines
11241123 **/
11251124 int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
11261125 {
1127− return __pci_enable_msi_range(dev, minvec, maxvec, 0);
1126+ return __pci_enable_msi_range(dev, minvec, maxvec, NULL);
11281127 }
11291128 EXPORT_SYMBOL(pci_enable_msi_range);
11301129
11311130 static int __pci_enable_msix_range(struct pci_dev *dev,
1132− struct msix_entry *entries, int minvec, int maxvec,
1133− unsigned int flags)
1131+ struct msix_entry *entries, int minvec,
1132+ int maxvec, const struct irq_affinity *affd)
11341133 {
1135− bool affinity = flags & PCI_IRQ_AFFINITY;
11361134 int rc, nvec = maxvec;
11371135
11381136 if (maxvec < minvec)
11391137 return -ERANGE;
11401138
11411139 for (;;) {
1142− if (affinity) {
1143− nvec = irq_calc_affinity_vectors(dev->irq_affinity,
1144− nvec);
1140+ if (affd) {
1141+ nvec = irq_calc_affinity_vectors(nvec, affd);
11451142 if (nvec < minvec)
11461143 return -ENOSPC;
11471144 }
11481145
1149− rc = __pci_enable_msix(dev, entries, nvec, affinity);
1146+ rc = __pci_enable_msix(dev, entries, nvec, affd);
11501147 if (rc == 0)
11511148 return nvec;
11521149
@@ -1177,16 +1174,17 @@ static int __pci_enable_msix_range(struct pci_dev *dev, · 24 unmodified lines
11771174 int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
11781175 int minvec, int maxvec)
11791176 {
1180− return __pci_enable_msix_range(dev, entries, minvec, maxvec, 0);
1177+ return __pci_enable_msix_range(dev, entries, minvec, maxvec, NULL);
11811178 }
11821179 EXPORT_SYMBOL(pci_enable_msix_range);
11831180
11841181 /**
1185− * pci_alloc_irq_vectors - allocate multiple IRQs for a device
1182+ * pci_alloc_irq_vectors_affinity - allocate multiple IRQs for a device
11861183 * @dev: PCI device to operate on
11871184 * @min_vecs: minimum number of vectors required (must be >= 1)
11881185 * @max_vecs: maximum (desired) number of vectors
11891186 * @flags: flags or quirks for the allocation
1187+ * @affd: optional description of the affinity requirements
11901188 *
11911189 * Allocate up to @max_vecs interrupt vectors for @dev, using MSI-X or MSI
11921190 * vectors if available, and fall back to a single legacy vector
@@ -1198,20 +1196,30 @@ EXPORT_SYMBOL(pci_enable_msix_range); · 5 unmodified lines
11981196 * To get the Linux IRQ number used for a vector that can be passed to
11991197 * request_irq() use the pci_irq_vector() helper.
12001198 */
1201−int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,
1202− unsigned int max_vecs, unsigned int flags)
1199+int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,
1200+ unsigned int max_vecs, unsigned int flags,
1201+ const struct irq_affinity *affd)
12031202 {
1203+ static const struct irq_affinity msi_default_affd;
12041204 int vecs = -ENOSPC;
12051205
1206+ if (flags & PCI_IRQ_AFFINITY) {
1207+ if (!affd)
1208+ affd = &msi_default_affd;
1209+ } else {
1210+ if (WARN_ON(affd))
1211+ affd = NULL;
1212+ }
1213+
12061214 if (flags & PCI_IRQ_MSIX) {
12071215 vecs = __pci_enable_msix_range(dev, NULL, min_vecs, max_vecs,
1208− flags);
1216+ affd);
12091217 if (vecs > 0)
12101218 return vecs;
12111219 }
12121220
12131221 if (flags & PCI_IRQ_MSI) {
1214− vecs = __pci_enable_msi_range(dev, min_vecs, max_vecs, flags);
1222+ vecs = __pci_enable_msi_range(dev, min_vecs, max_vecs, affd);
12151223 if (vecs > 0)
12161224 return vecs;
12171225 }
@@ -1224,7 +1232,7 @@ int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, · 6 unmodified lines
12241232
12251233 return vecs;
12261234 }
1227−EXPORT_SYMBOL(pci_alloc_irq_vectors);
1235+EXPORT_SYMBOL(pci_alloc_irq_vectors_affinity);
12281236
12291237 /**
12301238 * pci_free_irq_vectors - free previously allocated IRQs for a device
include/linux/interrupt.h+16−4
@@ -232,6 +232,18 @@ struct irq_affinity_notify { · 231 unmodified lines
232232 void (*release)(struct kref *ref);
233233 };
234234
235+/**
236+ * struct irq_affinity - Description for automatic irq affinity assignements
237+ * @pre_vectors: Don't apply affinity to @pre_vectors at beginning of
238+ * the MSI(-X) vector space
239+ * @post_vectors: Don't apply affinity to @post_vectors at end of
240+ * the MSI(-X) vector space
241+ */
242+struct irq_affinity {
243+ int pre_vectors;
244+ int post_vectors;
245+};
246+
235247 #if defined(CONFIG_SMP)
236248
237249 extern cpumask_var_t irq_default_affinity;
@@ -278,8 +290,8 @@ extern int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m); · 40 unmodified lines
278290 extern int
279291 irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify);
280292
281−struct cpumask *irq_create_affinity_masks(const struct cpumask *affinity, int nvec);
282−int irq_calc_affinity_vectors(const struct cpumask *affinity, int maxvec);
293+struct cpumask *irq_create_affinity_masks(int nvec, const struct irq_affinity *affd);
294+int irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd);
283295
284296 #else /* CONFIG_SMP */
285297
@@ -313,13 +325,13 @@ irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify) · 27 unmodified lines
313325 }
314326
315327 static inline struct cpumask *
316−irq_create_affinity_masks(const struct cpumask *affinity, int nvec)
328+irq_create_affinity_masks(int nvec, const struct irq_affinity *affd)
317329 {
318330 return NULL;
319331 }
320332
321333 static inline int
322−irq_calc_affinity_vectors(const struct cpumask *affinity, int maxvec)
334+irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd)
323335 {
324336 return maxvec;
325337 }
include/linux/irqchip/arm-gic-v3.h+2−2
@@ -239,7 +239,7 @@ · 238 unmodified lines
239239 #define GITS_TYPER_PTA (1UL << 19)
240240 #define GITS_TYPER_HWCOLLCNT_SHIFT 24
241241
242−#define GITS_CBASER_VALID (1UL << 63)
242+#define GITS_CBASER_VALID (1ULL << 63)
243243 #define GITS_CBASER_SHAREABILITY_SHIFT (10)
244244 #define GITS_CBASER_INNER_CACHEABILITY_SHIFT (59)
245245 #define GITS_CBASER_OUTER_CACHEABILITY_SHIFT (53)
@@ -265,7 +265,7 @@ · 19 unmodified lines
265265
266266 #define GITS_BASER_NR_REGS 8
267267
268−#define GITS_BASER_VALID (1UL << 63)
268+#define GITS_BASER_VALID (1ULL << 63)
269269 #define GITS_BASER_INDIRECT (1ULL << 62)
270270
271271 #define GITS_BASER_INNER_CACHEABILITY_SHIFT (59)
include/linux/pci.h+19−6
@@ -244,6 +244,7 @@ struct pci_cap_saved_state { · 243 unmodified lines
244244 struct pci_cap_saved_data cap;
245245 };
246246
247+struct irq_affinity;
247248 struct pcie_link_state;
248249 struct pci_vpd;
249250 struct pci_sriov;
@@ -332,7 +333,6 @@ struct pci_dev { · 82 unmodified lines
332333 * directly, use the values stored here. They might be different!
333334 */
334335 unsigned int irq;
335− struct cpumask *irq_affinity;
336336 struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
337337
338338 bool match_driver; /* Skip attaching driver */
@@ -1310,8 +1310,10 @@ static inline int pci_enable_msix_exact(struct pci_dev *dev, · 971 unmodified lines
13101310 return rc;
13111311 return 0;
13121312 }
1313−int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,
1314− unsigned int max_vecs, unsigned int flags);
1313+int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,
1314+ unsigned int max_vecs, unsigned int flags,
1315+ const struct irq_affinity *affd);
1316+
13151317 void pci_free_irq_vectors(struct pci_dev *dev);
13161318 int pci_irq_vector(struct pci_dev *dev, unsigned int nr);
13171319 const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev, int vec);
@@ -1339,14 +1341,17 @@ static inline int pci_enable_msix_range(struct pci_dev *dev, · 21 unmodified lines
13391341 static inline int pci_enable_msix_exact(struct pci_dev *dev,
13401342 struct msix_entry *entries, int nvec)
13411343 { return -ENOSYS; }
1342−static inline int pci_alloc_irq_vectors(struct pci_dev *dev,
1343− unsigned int min_vecs, unsigned int max_vecs,
1344− unsigned int flags)
1344+
1345+static inline int
1346+pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs,
1347+ unsigned int max_vecs, unsigned int flags,
1348+ const struct irq_affinity *aff_desc)
13451349 {
13461350 if (min_vecs > 1)
13471351 return -EINVAL;
13481352 return 1;
13491353 }
1354+
13501355 static inline void pci_free_irq_vectors(struct pci_dev *dev)
13511356 {
13521357 }
@@ -1364,6 +1369,14 @@ static inline const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev, · 11 unmodified lines
13641369 }
13651370 #endif
13661371
1372+static inline int
1373+pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,
1374+ unsigned int max_vecs, unsigned int flags)
1375+{
1376+ return pci_alloc_irq_vectors_affinity(dev, min_vecs, max_vecs, flags,
1377+ NULL);
1378+}
1379+
13671380 #ifdef CONFIG_PCIEPORTBUS
13681381 extern bool pcie_ports_disabled;
13691382 extern bool pcie_ports_auto;
kernel/irq/affinity.c+37−35
@@ -51,16 +51,17 @@ static int get_nodes_in_cpumask(const struct cpumask *mask, nodemask_t *nodemsk) · 50 unmodified lines
5151
5252 /**
5353 * irq_create_affinity_masks - Create affinity masks for multiqueue spreading
54− * @affinity: The affinity mask to spread. If NULL cpu_online_mask
55− * is used
56− * @nvecs: The number of vectors
54+ * @nvecs: The total number of vectors
55+ * @affd: Description of the affinity requirements
5756 *
5857 * Returns the masks pointer or NULL if allocation failed.
5958 */
60−struct cpumask *irq_create_affinity_masks(const struct cpumask *affinity,
61− int nvec)
59+struct cpumask *
60+irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd)
6261 {
63− int n, nodes, vecs_per_node, cpus_per_vec, extra_vecs, curvec = 0;
62+ int n, nodes, vecs_per_node, cpus_per_vec, extra_vecs, curvec;
63+ int affv = nvecs - affd->pre_vectors - affd->post_vectors;
64+ int last_affv = affv + affd->pre_vectors;
6465 nodemask_t nodemsk = NODE_MASK_NONE;
6566 struct cpumask *masks;
6667 cpumask_var_t nmsk;
@@ -68,46 +69,47 @@ struct cpumask *irq_create_affinity_masks(const struct cpumask *affinity, · 1 unmodified line
6869 if (!zalloc_cpumask_var(&nmsk, GFP_KERNEL))
6970 return NULL;
7071
71− masks = kzalloc(nvec * sizeof(*masks), GFP_KERNEL);
72+ masks = kcalloc(nvecs, sizeof(*masks), GFP_KERNEL);
7273 if (!masks)
7374 goto out;
7475
76+ /* Fill out vectors at the beginning that don't need affinity */
77+ for (curvec = 0; curvec < affd->pre_vectors; curvec++)
78+ cpumask_copy(masks + curvec, irq_default_affinity);
79+
7580 /* Stabilize the cpumasks */
7681 get_online_cpus();
77− /* If the supplied affinity mask is NULL, use cpu online mask */
78− if (!affinity)
79− affinity = cpu_online_mask;
80−
81− nodes = get_nodes_in_cpumask(affinity, &nodemsk);
82+ nodes = get_nodes_in_cpumask(cpu_online_mask, &nodemsk);
8283
8384 /*
8485 * If the number of nodes in the mask is less than or equal the
8586 * number of vectors we just spread the vectors across the nodes.
8687 */
87− if (nvec <= nodes) {
88+ if (affv <= nodes) {
8889 for_each_node_mask(n, nodemsk) {
8990 cpumask_copy(masks + curvec, cpumask_of_node(n));
90− if (++curvec == nvec)
91+ if (++curvec == last_affv)
9192 break;
9293 }
93− goto outonl;
94+ goto done;
9495 }
9596
9697 /* Spread the vectors per node */
97− vecs_per_node = nvec / nodes;
98+ vecs_per_node = affv / nodes;
9899 /* Account for rounding errors */
99− extra_vecs = nvec - (nodes * vecs_per_node);
100+ extra_vecs = affv - (nodes * vecs_per_node);
100101
101102 for_each_node_mask(n, nodemsk) {
102103 int ncpus, v, vecs_to_assign = vecs_per_node;
103104
104105 /* Get the cpus on this node which are in the mask */
105− cpumask_and(nmsk, affinity, cpumask_of_node(n));
106+ cpumask_and(nmsk, cpu_online_mask, cpumask_of_node(n));
106107
107108 /* Calculate the number of cpus per vector */
108109 ncpus = cpumask_weight(nmsk);
109110
110− for (v = 0; curvec < nvec && v < vecs_to_assign; curvec++, v++) {
111+ for (v = 0; curvec < last_affv && v < vecs_to_assign;
112+ curvec++, v++) {
111113 cpus_per_vec = ncpus / vecs_to_assign;
112114
113115 /* Account for extra vectors to compensate rounding errors */
@@ -119,36 +121,36 @@ struct cpumask *irq_create_affinity_masks(const struct cpumask *affinity, · 5 unmodified lines
119121 irq_spread_init_one(masks + curvec, nmsk, cpus_per_vec);
120122 }
121123
122− if (curvec >= nvec)
124+ if (curvec >= last_affv)
123125 break;
124126 }
125127
126−outonl:
128+done:
127129 put_online_cpus();
130+
131+ /* Fill out vectors at the end that don't need affinity */
132+ for (; curvec < nvecs; curvec++)
133+ cpumask_copy(masks + curvec, irq_default_affinity);
128134 out:
129135 free_cpumask_var(nmsk);
130136 return masks;
131137 }
132138
133139 /**
134− * irq_calc_affinity_vectors - Calculate to optimal number of vectors for a given affinity mask
135− * @affinity: The affinity mask to spread. If NULL cpu_online_mask
136− * is used
137− * @maxvec: The maximum number of vectors available
140+ * irq_calc_affinity_vectors - Calculate the optimal number of vectors
141+ * @maxvec: The maximum number of vectors available
142+ * @affd: Description of the affinity requirements
138143 */
139−int irq_calc_affinity_vectors(const struct cpumask *affinity, int maxvec)
144+int irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd)
140145 {
141− int cpus, ret;
146+ int resv = affd->pre_vectors + affd->post_vectors;
147+ int vecs = maxvec - resv;
148+ int cpus;
142149
143150 /* Stabilize the cpumasks */
144151 get_online_cpus();
145− /* If the supplied affinity mask is NULL, use cpu online mask */
146− if (!affinity)
147− affinity = cpu_online_mask;
148−
149− cpus = cpumask_weight(affinity);
150− ret = (cpus < maxvec) ? cpus : maxvec;
151−
152+ cpus = cpumask_weight(cpu_online_mask);
152153 put_online_cpus();
153− return ret;
154+
155+ return min(cpus, vecs) + resv;
154156 }
kernel/irq/msi.c+1−3
@@ -14,9 +14,7 @@ · 13 unmodified lines
1414 #include <linux/irq.h>
1515 #include <linux/irqdomain.h>
1616 #include <linux/msi.h>
17−
18−/* Temparory solution for building, will be removed later */
19−#include <linux/pci.h>
17+#include <linux/slab.h>
2018
2119 /**
2220 * alloc_msi_entry - Allocate an initialize msi_entry