History

irqchip/gic-v3: Add ESPI range support

Add the required support for the ESPI range, which behave exactly like the SPIs of old, only with new funky INTIDs.

Marc Zyngier committed 7 years ago

Commit 211bddd1 parent 86624652 files · +85 −17Browse files

Unified · Split

2 files
  1. drivers/irqchip/irq-gic-v3.c +69 −16
  2. include/linux/irqchip/arm-gic-v3.h +16 −1
drivers/irqchip/irq-gic-v3.c+69−16
@@ -51,13 +51,16 @@ struct gic_chip_data { · 50 unmodified lines
5151 u32 nr_redist_regions;
5252 u64 flags;
5353 bool has_rss;
54− unsigned int irq_nr;
5554 struct partition_desc *ppi_descs[16];
5655 };
5756
5857 static struct gic_chip_data gic_data __read_mostly;
5958 static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
6059
60+#define GIC_ID_NR (1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer))
61+#define GIC_LINE_NR max(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)
62+#define GIC_ESPI_NR GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
63+
6164 /*
6265 * The behaviours of RPR and PMR registers differ depending on the value of
6366 * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the
@@ -100,6 +103,7 @@ static DEFINE_PER_CPU(bool, has_rss); · 36 unmodified lines
100103 enum gic_intid_range {
101104 PPI_RANGE,
102105 SPI_RANGE,
106+ ESPI_RANGE,
103107 LPI_RANGE,
104108 __INVALID_RANGE__
105109 };
@@ -111,6 +115,8 @@ static enum gic_intid_range __get_intid_range(irq_hw_number_t hwirq) · 5 unmodified lines
111115 return PPI_RANGE;
112116 case 32 ... 1019:
113117 return SPI_RANGE;
118+ case ESPI_BASE_INTID ... (ESPI_BASE_INTID + 1023):
119+ return ESPI_RANGE;
114120 case 8192 ... GENMASK(23, 0):
115121 return LPI_RANGE;
116122 default:
@@ -141,6 +147,7 @@ static inline void __iomem *gic_dist_base(struct irq_data *d) · 24 unmodified lines
141147 return gic_data_rdist_sgi_base();
142148
143149 case SPI_RANGE:
150+ case ESPI_RANGE:
144151 /* SPI -> dist_base */
145152 return gic_data.dist_base;
146153
@@ -234,6 +241,31 @@ static u32 convert_offset_index(struct irq_data *d, u32 offset, u32 *index) · 87 unmodified lines
234241 case SPI_RANGE:
235242 *index = d->hwirq;
236243 return offset;
244+ case ESPI_RANGE:
245+ *index = d->hwirq - ESPI_BASE_INTID;
246+ switch (offset) {
247+ case GICD_ISENABLER:
248+ return GICD_ISENABLERnE;
249+ case GICD_ICENABLER:
250+ return GICD_ICENABLERnE;
251+ case GICD_ISPENDR:
252+ return GICD_ISPENDRnE;
253+ case GICD_ICPENDR:
254+ return GICD_ICPENDRnE;
255+ case GICD_ISACTIVER:
256+ return GICD_ISACTIVERnE;
257+ case GICD_ICACTIVER:
258+ return GICD_ICACTIVERnE;
259+ case GICD_IPRIORITYR:
260+ return GICD_IPRIORITYRnE;
261+ case GICD_ICFGR:
262+ return GICD_ICFGRnE;
263+ case GICD_IROUTER:
264+ return GICD_IROUTERnE;
265+ default:
266+ break;
267+ }
268+ break;
237269 default:
238270 break;
239271 }
@@ -316,7 +348,7 @@ static int gic_irq_set_irqchip_state(struct irq_data *d, · 76 unmodified lines
316348 {
317349 u32 reg;
318350
319− if (d->hwirq >= gic_data.irq_nr) /* PPI/SPI only */
351+ if (d->hwirq >= 8192) /* PPI/SPI only */
320352 return -EINVAL;
321353
322354 switch (which) {
@@ -343,7 +375,7 @@ static int gic_irq_set_irqchip_state(struct irq_data *d, · 20 unmodified lines
343375 static int gic_irq_get_irqchip_state(struct irq_data *d,
344376 enum irqchip_irq_state which, bool *val)
345377 {
346− if (d->hwirq >= gic_data.irq_nr) /* PPI/SPI only */
378+ if (d->hwirq >= 8192) /* PPI/SPI only */
347379 return -EINVAL;
348380
349381 switch (which) {
@@ -567,7 +599,12 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs · 217 unmodified lines
567599 gic_arch_enable_irqs();
568600 }
569601
570− if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
602+ /* Check for special IDs first */
603+ if ((irqnr >= 1020 && irqnr <= 1023))
604+ return;
605+
606+ /* Treat anything but SGIs in a uniform way */
607+ if (likely(irqnr > 15)) {
571608 int err;
572609
573610 if (static_branch_likely(&supports_deactivate_key))
@@ -655,10 +692,26 @@ static void __init gic_dist_init(void) · 81 unmodified lines
655692 * do the right thing if the kernel is running in secure mode,
656693 * but that's not the intended use case anyway.
657694 */
658− for (i = 32; i < gic_data.irq_nr; i += 32)
695+ for (i = 32; i < GIC_LINE_NR; i += 32)
659696 writel_relaxed(~0, base + GICD_IGROUPR + i / 8);
660697
661− gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp);
698+ /* Extended SPI range, not handled by the GICv2/GICv3 common code */
699+ for (i = 0; i < GIC_ESPI_NR; i += 32) {
700+ writel_relaxed(~0U, base + GICD_ICENABLERnE + i / 8);
701+ writel_relaxed(~0U, base + GICD_ICACTIVERnE + i / 8);
702+ }
703+
704+ for (i = 0; i < GIC_ESPI_NR; i += 32)
705+ writel_relaxed(~0U, base + GICD_IGROUPRnE + i / 8);
706+
707+ for (i = 0; i < GIC_ESPI_NR; i += 16)
708+ writel_relaxed(0, base + GICD_ICFGRnE + i / 4);
709+
710+ for (i = 0; i < GIC_ESPI_NR; i += 4)
711+ writel_relaxed(GICD_INT_DEF_PRI_X4, base + GICD_IPRIORITYRnE + i);
712+
713+ /* Now do the common stuff, and wait for the distributor to drain */
714+ gic_dist_config(base, GIC_LINE_NR, gic_dist_wait_for_rwp);
662715
663716 /* Enable distributor with ARE, Group1 */
664717 writel_relaxed(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1,
@@ -669,8 +722,11 @@ static void __init gic_dist_init(void) · 4 unmodified lines
669722 * enabled.
670723 */
671724 affinity = gic_mpidr_to_affinity(cpu_logical_map(smp_processor_id()));
672− for (i = 32; i < gic_data.irq_nr; i++)
725+ for (i = 32; i < GIC_LINE_NR; i++)
673726 gic_write_irouter(affinity, base + GICD_IROUTER + i * 8);
727+
728+ for (i = 0; i < GIC_ESPI_NR; i++)
729+ gic_write_irouter(affinity, base + GICD_IROUTERnE + i * 8);
674730 }
675731
676732 static int gic_iterate_rdists(int (*fn)(struct redist_region *, void __iomem *))
@@ -1134,8 +1190,6 @@ static struct irq_chip gic_eoimode1_chip = { · 457 unmodified lines
11341190 IRQCHIP_MASK_ON_SUSPEND,
11351191 };
11361192
1137−#define GIC_ID_NR (1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer))
1138−
11391193 static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
11401194 irq_hw_number_t hw)
11411195 {
@@ -1153,6 +1207,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, · 11 unmodified lines
11531207 break;
11541208
11551209 case SPI_RANGE:
1210+ case ESPI_RANGE:
11561211 irq_domain_set_info(d, irq, hw, chip, d->host_data,
11571212 handle_fasteoi_irq, NULL, NULL);
11581213 irq_set_probe(irq);
@@ -1192,6 +1247,9 @@ static int gic_irq_domain_translate(struct irq_domain *d, · 33 unmodified lines
11921247 case GIC_IRQ_TYPE_PARTITION:
11931248 *hwirq = fwspec->param[1] + 16;
11941249 break;
1250+ case 2: /* ESPI */
1251+ *hwirq = fwspec->param[1] + ESPI_BASE_INTID;
1252+ break;
11951253 case GIC_IRQ_TYPE_LPI: /* LPI */
11961254 *hwirq = fwspec->param[1];
11971255 break;
@@ -1346,7 +1404,6 @@ static int __init gic_init_bases(void __iomem *dist_base, · 148 unmodified lines
13461404 struct fwnode_handle *handle)
13471405 {
13481406 u32 typer;
1349− int gic_irqs;
13501407 int err;
13511408
13521409 if (!is_hyp_mode_available())
@@ -1363,15 +1420,11 @@ static int __init gic_init_bases(void __iomem *dist_base, · 10 unmodified lines
13631420
13641421 /*
13651422 * Find out how many interrupts are supported.
1366− * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)
13671423 */
13681424 typer = readl_relaxed(gic_data.dist_base + GICD_TYPER);
13691425 gic_data.rdists.gicd_typer = typer;
1370− gic_irqs = GICD_TYPER_IRQS(typer);
1371− if (gic_irqs > 1020)
1372− gic_irqs = 1020;
1373− gic_data.irq_nr = gic_irqs;
1374−
1426+ pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32);
1427+ pr_info("%d Extended SPIs implemented\n", GIC_ESPI_NR);
13751428 gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops,
13761429 &gic_data);
13771430 irq_domain_update_bus_token(gic_data.domain, DOMAIN_BUS_WIRED);
include/linux/irqchip/arm-gic-v3.h+16−1
@@ -30,10 +30,22 @@ · 29 unmodified lines
3030 #define GICD_ICFGR 0x0C00
3131 #define GICD_IGRPMODR 0x0D00
3232 #define GICD_NSACR 0x0E00
33+#define GICD_IGROUPRnE 0x1000
34+#define GICD_ISENABLERnE 0x1200
35+#define GICD_ICENABLERnE 0x1400
36+#define GICD_ISPENDRnE 0x1600
37+#define GICD_ICPENDRnE 0x1800
38+#define GICD_ISACTIVERnE 0x1A00
39+#define GICD_ICACTIVERnE 0x1C00
40+#define GICD_IPRIORITYRnE 0x2000
41+#define GICD_ICFGRnE 0x3000
3342 #define GICD_IROUTER 0x6000
43+#define GICD_IROUTERnE 0x8000
3444 #define GICD_IDREGS 0xFFD0
3545 #define GICD_PIDR2 0xFFE8
3646
47+#define ESPI_BASE_INTID 4096
48+
3749 /*
3850 * Those registers are actually from GICv2, but the spec demands that they
3951 * are implemented as RES0 if ARE is 1 (which we do in KVM's emulated GICv3).
@@ -69,10 +81,13 @@ · 29 unmodified lines
6981 #define GICD_TYPER_RSS (1U << 26)
7082 #define GICD_TYPER_LPIS (1U << 17)
7183 #define GICD_TYPER_MBIS (1U << 16)
84+#define GICD_TYPER_ESPI (1U << 8)
7285
7386 #define GICD_TYPER_ID_BITS(typer) ((((typer) >> 19) & 0x1f) + 1)
7487 #define GICD_TYPER_NUM_LPIS(typer) ((((typer) >> 11) & 0x1f) + 1)
75−#define GICD_TYPER_IRQS(typer) ((((typer) & 0x1f) + 1) * 32)
88+#define GICD_TYPER_SPIS(typer) ((((typer) & 0x1f) + 1) * 32)
89+#define GICD_TYPER_ESPIS(typer) \
90+ (((typer) & GICD_TYPER_ESPI) ? GICD_TYPER_SPIS((typer) >> 27) : 0)
7691
7792 #define GICD_IROUTER_SPI_MODE_ONE (0U << 31)
7893 #define GICD_IROUTER_SPI_MODE_ANY (1U << 31)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t