Skip to content

Commit 03f9885

Browse files
yong-xuanKAGA-KOKO
authored andcommitted
irqchip/riscv-aplic: Retrigger MSI interrupt on source configuration
The section 4.5.2 of the RISC-V AIA specification says that "any write to a sourcecfg register of an APLIC might (or might not) cause the corresponding interrupt-pending bit to be set to one if the rectified input value is high (= 1) under the new source mode." When the interrupt type is changed in the sourcecfg register, the APLIC device might not set the corresponding pending bit, so the interrupt might never become pending. To handle sourcecfg register changes for level-triggered interrupts in MSI mode, manually set the pending bit for retriggering interrupt so it gets retriggered if it was already asserted. Fixes: ca8df97 ("irqchip/riscv-aplic: Add support for MSI-mode") Signed-off-by: Yong-Xuan Wang <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Vincent Chen <[email protected]> Reviewed-by: Anup Patel <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/all/[email protected]
1 parent d73f0f4 commit 03f9885

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

drivers/irqchip/irq-riscv-aplic-msi.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,10 @@ static void aplic_msi_irq_unmask(struct irq_data *d)
3232
aplic_irq_unmask(d);
3333
}
3434

35-
static void aplic_msi_irq_eoi(struct irq_data *d)
35+
static void aplic_msi_irq_retrigger_level(struct irq_data *d)
3636
{
3737
struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
3838

39-
/*
40-
* EOI handling is required only for level-triggered interrupts
41-
* when APLIC is in MSI mode.
42-
*/
43-
4439
switch (irqd_get_trigger_type(d)) {
4540
case IRQ_TYPE_LEVEL_LOW:
4641
case IRQ_TYPE_LEVEL_HIGH:
@@ -59,6 +54,29 @@ static void aplic_msi_irq_eoi(struct irq_data *d)
5954
}
6055
}
6156

57+
static void aplic_msi_irq_eoi(struct irq_data *d)
58+
{
59+
/*
60+
* EOI handling is required only for level-triggered interrupts
61+
* when APLIC is in MSI mode.
62+
*/
63+
aplic_msi_irq_retrigger_level(d);
64+
}
65+
66+
static int aplic_msi_irq_set_type(struct irq_data *d, unsigned int type)
67+
{
68+
int rc = aplic_irq_set_type(d, type);
69+
70+
if (rc)
71+
return rc;
72+
/*
73+
* Updating sourcecfg register for level-triggered interrupts
74+
* requires interrupt retriggering when APLIC is in MSI mode.
75+
*/
76+
aplic_msi_irq_retrigger_level(d);
77+
return 0;
78+
}
79+
6280
static void aplic_msi_write_msg(struct irq_data *d, struct msi_msg *msg)
6381
{
6482
unsigned int group_index, hart_index, guest_index, val;
@@ -130,7 +148,7 @@ static const struct msi_domain_template aplic_msi_template = {
130148
.name = "APLIC-MSI",
131149
.irq_mask = aplic_msi_irq_mask,
132150
.irq_unmask = aplic_msi_irq_unmask,
133-
.irq_set_type = aplic_irq_set_type,
151+
.irq_set_type = aplic_msi_irq_set_type,
134152
.irq_eoi = aplic_msi_irq_eoi,
135153
#ifdef CONFIG_SMP
136154
.irq_set_affinity = irq_chip_set_affinity_parent,

0 commit comments

Comments
 (0)