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:
        }
 }
 
+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 = 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;
                .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,