Skip to content

Commit a6156e7

Browse files
mrutland-armctmarinas
authored andcommitted
irqchip/gic-v3: Make distributor priorities variables
In subsequent patches the GICv3 driver will choose the regular interrupt priority at boot time. In preparation for using dynamic priorities, place the priorities in variables and update the code to pass these as parameters. Users of GICD_INT_DEF_PRI_X4 are modified to replicate the priority byte using REPEAT_BYTE_U32(). There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland <[email protected]> Cc: Alexandru Elisei <[email protected]> Cc: Marc Zyngier <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Will Deacon <[email protected]> Reviewed-by: Marc Zyngier <[email protected]> Tested-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]> Acked-by: Thomas Gleixner <[email protected]>
1 parent e95c64a commit a6156e7

File tree

8 files changed

+32
-30
lines changed

8 files changed

+32
-30
lines changed

drivers/irqchip/irq-gic-common.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/io.h>
88
#include <linux/irq.h>
99
#include <linux/irqchip/arm-gic.h>
10+
#include <linux/kernel.h>
1011

1112
#include "irq-gic-common.h"
1213

@@ -87,7 +88,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
8788
return ret;
8889
}
8990

90-
void gic_dist_config(void __iomem *base, int gic_irqs)
91+
void gic_dist_config(void __iomem *base, int gic_irqs, u8 priority)
9192
{
9293
unsigned int i;
9394

@@ -102,7 +103,8 @@ void gic_dist_config(void __iomem *base, int gic_irqs)
102103
* Set priority on all global interrupts.
103104
*/
104105
for (i = 32; i < gic_irqs; i += 4)
105-
writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i);
106+
writel_relaxed(REPEAT_BYTE_U32(priority),
107+
base + GIC_DIST_PRI + i);
106108

107109
/*
108110
* Deactivate and disable all SPIs. Leave the PPI and SGIs
@@ -116,7 +118,7 @@ void gic_dist_config(void __iomem *base, int gic_irqs)
116118
}
117119
}
118120

119-
void gic_cpu_config(void __iomem *base, int nr)
121+
void gic_cpu_config(void __iomem *base, int nr, u8 priority)
120122
{
121123
int i;
122124

@@ -135,6 +137,6 @@ void gic_cpu_config(void __iomem *base, int nr)
135137
* Set priority on PPI and SGI interrupts
136138
*/
137139
for (i = 0; i < nr; i += 4)
138-
writel_relaxed(GICD_INT_DEF_PRI_X4,
140+
writel_relaxed(REPEAT_BYTE_U32(priority),
139141
base + GIC_DIST_PRI + i * 4 / 4);
140142
}

drivers/irqchip/irq-gic-common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ struct gic_quirk {
2121

2222
int gic_configure_irq(unsigned int irq, unsigned int type,
2323
void __iomem *base);
24-
void gic_dist_config(void __iomem *base, int gic_irqs);
25-
void gic_cpu_config(void __iomem *base, int nr);
24+
void gic_dist_config(void __iomem *base, int gic_irqs, u8 priority);
25+
void gic_cpu_config(void __iomem *base, int nr, u8 priority);
2626
void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
2727
void *data);
2828
void gic_enable_of_quirks(const struct device_node *np,

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static u32 lpi_id_bits;
5959
#define LPI_PROPBASE_SZ ALIGN(BIT(LPI_NRBITS), SZ_64K)
6060
#define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K)
6161

62-
#define LPI_PROP_DEFAULT_PRIO GICD_INT_DEF_PRI
62+
static u8 __ro_after_init lpi_prop_prio;
6363

6464
/*
6565
* Collection structure - just an ID, and a redistributor address to
@@ -1926,7 +1926,7 @@ static int its_vlpi_unmap(struct irq_data *d)
19261926
/* and restore the physical one */
19271927
irqd_clr_forwarded_to_vcpu(d);
19281928
its_send_mapti(its_dev, d->hwirq, event);
1929-
lpi_update_config(d, 0xff, (LPI_PROP_DEFAULT_PRIO |
1929+
lpi_update_config(d, 0xff, (lpi_prop_prio |
19301930
LPI_PROP_ENABLED |
19311931
LPI_PROP_GROUP1));
19321932

@@ -2181,8 +2181,8 @@ static void its_lpi_free(unsigned long *bitmap, u32 base, u32 nr_ids)
21812181

21822182
static void gic_reset_prop_table(void *va)
21832183
{
2184-
/* Priority 0xa0, Group-1, disabled */
2185-
memset(va, LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1, LPI_PROPBASE_SZ);
2184+
/* Regular IRQ priority, Group-1, disabled */
2185+
memset(va, lpi_prop_prio | LPI_PROP_GROUP1, LPI_PROPBASE_SZ);
21862186

21872187
/* Make sure the GIC will observe the written configuration */
21882188
gic_flush_dcache_to_poc(va, LPI_PROPBASE_SZ);
@@ -5650,7 +5650,7 @@ int __init its_lpi_memreserve_init(void)
56505650
}
56515651

56525652
int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
5653-
struct irq_domain *parent_domain)
5653+
struct irq_domain *parent_domain, u8 irq_prio)
56545654
{
56555655
struct device_node *of_node;
56565656
struct its_node *its;
@@ -5660,6 +5660,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
56605660

56615661
gic_rdists = rdists;
56625662

5663+
lpi_prop_prio = irq_prio;
56635664
its_parent = parent_domain;
56645665
of_node = to_of_node(handle);
56655666
if (of_node)

drivers/irqchip/irq-gic-v3.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/delay.h>
1313
#include <linux/interrupt.h>
1414
#include <linux/irqdomain.h>
15+
#include <linux/kernel.h>
1516
#include <linux/kstrtox.h>
1617
#include <linux/of.h>
1718
#include <linux/of_address.h>
@@ -36,7 +37,8 @@
3637

3738
#include "irq-gic-common.h"
3839

39-
#define GICD_INT_NMI_PRI (GICD_INT_DEF_PRI & ~0x80)
40+
static u8 dist_prio_irq __ro_after_init = GICD_INT_DEF_PRI;
41+
static u8 dist_prio_nmi __ro_after_init = GICD_INT_DEF_PRI & ~0x80;
4042

4143
#define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0)
4244
#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1)
@@ -556,7 +558,7 @@ static int gic_irq_nmi_setup(struct irq_data *d)
556558
desc->handle_irq = handle_fasteoi_nmi;
557559
}
558560

559-
gic_irq_set_prio(d, GICD_INT_NMI_PRI);
561+
gic_irq_set_prio(d, dist_prio_nmi);
560562

561563
return 0;
562564
}
@@ -591,7 +593,7 @@ static void gic_irq_nmi_teardown(struct irq_data *d)
591593
desc->handle_irq = handle_fasteoi_irq;
592594
}
593595

594-
gic_irq_set_prio(d, GICD_INT_DEF_PRI);
596+
gic_irq_set_prio(d, dist_prio_irq);
595597
}
596598

597599
static bool gic_arm64_erratum_2941627_needed(struct irq_data *d)
@@ -753,7 +755,7 @@ static bool gic_rpr_is_nmi_prio(void)
753755
if (!gic_supports_nmi())
754756
return false;
755757

756-
return unlikely(gic_read_rpr() == GICD_INT_RPR_PRI(GICD_INT_NMI_PRI));
758+
return unlikely(gic_read_rpr() == GICD_INT_RPR_PRI(dist_prio_nmi));
757759
}
758760

759761
static bool gic_irqnr_is_special(u32 irqnr)
@@ -937,10 +939,11 @@ static void __init gic_dist_init(void)
937939
writel_relaxed(0, base + GICD_ICFGRnE + i / 4);
938940

939941
for (i = 0; i < GIC_ESPI_NR; i += 4)
940-
writel_relaxed(GICD_INT_DEF_PRI_X4, base + GICD_IPRIORITYRnE + i);
942+
writel_relaxed(REPEAT_BYTE_U32(dist_prio_irq),
943+
base + GICD_IPRIORITYRnE + i);
941944

942945
/* Now do the common stuff */
943-
gic_dist_config(base, GIC_LINE_NR);
946+
gic_dist_config(base, GIC_LINE_NR, dist_prio_irq);
944947

945948
val = GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1;
946949
if (gic_data.rdists.gicd_typer2 & GICD_TYPER2_nASSGIcap) {
@@ -1282,7 +1285,7 @@ static void gic_cpu_init(void)
12821285
for (i = 0; i < gic_data.ppi_nr + SGI_NR; i += 32)
12831286
writel_relaxed(~0, rbase + GICR_IGROUPR0 + i / 8);
12841287

1285-
gic_cpu_config(rbase, gic_data.ppi_nr + SGI_NR);
1288+
gic_cpu_config(rbase, gic_data.ppi_nr + SGI_NR, dist_prio_irq);
12861289
gic_redist_wait_for_rwp();
12871290

12881291
/* initialise system registers */
@@ -2066,7 +2069,7 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
20662069
gic_cpu_pm_init();
20672070

20682071
if (gic_dist_supports_lpis()) {
2069-
its_init(handle, &gic_data.rdists, gic_data.domain);
2072+
its_init(handle, &gic_data.rdists, gic_data.domain, dist_prio_irq);
20702073
its_cpu_init();
20712074
its_lpi_memreserve_init();
20722075
} else {

drivers/irqchip/irq-gic.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ static void gic_dist_init(struct gic_chip_data *gic)
479479
for (i = 32; i < gic_irqs; i += 4)
480480
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
481481

482-
gic_dist_config(base, gic_irqs);
482+
gic_dist_config(base, gic_irqs, GICD_INT_DEF_PRI);
483483

484484
writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL);
485485
}
@@ -516,7 +516,7 @@ static int gic_cpu_init(struct gic_chip_data *gic)
516516
gic_cpu_map[i] &= ~cpu_mask;
517517
}
518518

519-
gic_cpu_config(dist_base, 32);
519+
gic_cpu_config(dist_base, 32, GICD_INT_DEF_PRI);
520520

521521
writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK);
522522
gic_cpu_if_up(gic);
@@ -608,7 +608,7 @@ void gic_dist_restore(struct gic_chip_data *gic)
608608
dist_base + GIC_DIST_CONFIG + i * 4);
609609

610610
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
611-
writel_relaxed(GICD_INT_DEF_PRI_X4,
611+
writel_relaxed(REPEAT_BYTE_U32(GICD_INT_DEF_PRI),
612612
dist_base + GIC_DIST_PRI + i * 4);
613613

614614
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
@@ -697,7 +697,7 @@ void gic_cpu_restore(struct gic_chip_data *gic)
697697
writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
698698

699699
for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
700-
writel_relaxed(GICD_INT_DEF_PRI_X4,
700+
writel_relaxed(REPEAT_BYTE_U32(GICD_INT_DEF_PRI),
701701
dist_base + GIC_DIST_PRI + i * 4);
702702

703703
writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK);

drivers/irqchip/irq-hip04.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ static void __init hip04_irq_dist_init(struct hip04_irq_data *intc)
260260
for (i = 32; i < nr_irqs; i += 2)
261261
writel_relaxed(cpumask, base + GIC_DIST_TARGET + ((i * 2) & ~3));
262262

263-
gic_dist_config(base, nr_irqs);
263+
gic_dist_config(base, nr_irqs, GICD_INT_DEF_PRI);
264264

265265
writel_relaxed(1, base + GIC_DIST_CTRL);
266266
}
@@ -287,7 +287,7 @@ static void hip04_irq_cpu_init(struct hip04_irq_data *intc)
287287
if (i != cpu)
288288
hip04_cpu_map[i] &= ~cpu_mask;
289289

290-
gic_cpu_config(dist_base, 32);
290+
gic_cpu_config(dist_base, 32, GICD_INT_DEF_PRI);
291291

292292
writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
293293
writel_relaxed(1, base + GIC_CPU_CTRL);

include/linux/irqchip/arm-gic-common.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@
1010
#include <linux/irqchip/arm-vgic-info.h>
1111

1212
#define GICD_INT_DEF_PRI 0xa0
13-
#define GICD_INT_DEF_PRI_X4 ((GICD_INT_DEF_PRI << 24) |\
14-
(GICD_INT_DEF_PRI << 16) |\
15-
(GICD_INT_DEF_PRI << 8) |\
16-
GICD_INT_DEF_PRI)
1713

1814
struct irq_domain;
1915
struct fwnode_handle;

include/linux/irqchip/arm-gic-v3.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ struct fwnode_handle;
638638
int __init its_lpi_memreserve_init(void);
639639
int its_cpu_init(void);
640640
int its_init(struct fwnode_handle *handle, struct rdists *rdists,
641-
struct irq_domain *domain);
641+
struct irq_domain *domain, u8 irq_prio);
642642
int mbi_init(struct fwnode_handle *fwnode, struct irq_domain *parent);
643643

644644
static inline bool gic_enable_sre(void)

0 commit comments

Comments
 (0)