[PATCH v2 1/1] irqchip/riscv-aplic: Retrigger MSI interrupt on source configuration
Anup Patel
anup at brainfault.org
Fri Aug 9 00:40:41 PDT 2024
On Fri, Aug 9, 2024 at 12:40 PM Yong-Xuan Wang <yongxuan.wang at sifive.com> wrote:
>
> 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 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 if it
> was already asserted.
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang at sifive.com>
> Reviewed-by: Vincent Chen <vincent.chen at sifive.com>
LGTM.
Reviewed-by: Anup Patel <anup at brainfault.org>
Regards,
Anup
> ---
> v2:
> - update commit message (Anup, Thomas)
> - rename aplic_retrigger_asserting_irq() to aplic_msi_irq_retrigger_level()
> and make it as a static function since only APLIC MSI mode require it.
> (Anup, Thomas)
>
> ---
> drivers/irqchip/irq-riscv-aplic-msi.c | 35 +++++++++++++++++++++------
> 1 file changed, 28 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/irqchip/irq-riscv-aplic-msi.c b/drivers/irqchip/irq-riscv-aplic-msi.c
> index 028444af48bd..9d63dc37dea5 100644
> --- a/drivers/irqchip/irq-riscv-aplic-msi.c
> +++ b/drivers/irqchip/irq-riscv-aplic-msi.c
> @@ -32,15 +32,10 @@ static void aplic_msi_irq_unmask(struct irq_data *d)
> aplic_irq_unmask(d);
> }
>
> -static void aplic_msi_irq_eoi(struct irq_data *d)
> +static void aplic_msi_irq_retrigger_level(struct irq_data *d)
> {
> struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
>
> - /*
> - * EOI handling is required only for level-triggered interrupts
> - * when APLIC is in MSI mode.
> - */
> -
> switch (irqd_get_trigger_type(d)) {
> case IRQ_TYPE_LEVEL_LOW:
> case IRQ_TYPE_LEVEL_HIGH:
> @@ -59,6 +54,32 @@ static void aplic_msi_irq_eoi(struct irq_data *d)
> }
> }
>
> +static void aplic_msi_irq_eoi(struct irq_data *d)
> +{
> + /*
> + * EOI handling is required only for level-triggered interrupts
> + * when APLIC is in MSI mode.
> + */
> +
> + aplic_msi_irq_retrigger_level(d);
> +}
> +
> +static int aplic_msi_irq_set_type(struct irq_data *d, unsigned int type)
> +{
> + int rc;
> +
> + rc = aplic_irq_set_type(d, type);
> + if (rc)
> + return rc;
> +
> + /*
> + * Updating sourcecfg register for level-triggered interrupts
> + * requires interrupt retriggering when APLIC is in MSI mode.
> + */
> + aplic_msi_irq_retrigger_level(d);
> + return 0;
> +}
> +
> static void aplic_msi_write_msg(struct irq_data *d, struct msi_msg *msg)
> {
> unsigned int group_index, hart_index, guest_index, val;
> @@ -130,7 +151,7 @@ static const struct msi_domain_template aplic_msi_template = {
> .name = "APLIC-MSI",
> .irq_mask = aplic_msi_irq_mask,
> .irq_unmask = aplic_msi_irq_unmask,
> - .irq_set_type = aplic_irq_set_type,
> + .irq_set_type = aplic_msi_irq_set_type,
> .irq_eoi = aplic_msi_irq_eoi,
> #ifdef CONFIG_SMP
> .irq_set_affinity = irq_chip_set_affinity_parent,
> --
> 2.17.1
>
More information about the linux-riscv
mailing list