raw_spinlock_t irq_lock;
        struct irq_domain *msi_domain;
        struct irq_domain *msi_inner_domain;
+       raw_spinlock_t msi_irq_lock;
        DECLARE_BITMAP(msi_used, MSI_IRQ_NUM);
        struct mutex msi_used_lock;
        u16 msi_msg;
        advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG);
        advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG);
 
-       /* Disable All ISR0/1 Sources */
+       /* Disable All ISR0/1 and MSI Sources */
        advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_MASK_REG);
        advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG);
-
-       /* Unmask all MSIs */
-       advk_writel(pcie, ~(u32)PCIE_MSI_ALL_MASK, PCIE_MSI_MASK_REG);
+       advk_writel(pcie, PCIE_MSI_ALL_MASK, PCIE_MSI_MASK_REG);
 
        /* Unmask summary MSI interrupt */
        reg = advk_readl(pcie, PCIE_ISR0_MASK_REG);
        return -EINVAL;
 }
 
+static void advk_msi_irq_mask(struct irq_data *d)
+{
+       struct advk_pcie *pcie = d->domain->host_data;
+       irq_hw_number_t hwirq = irqd_to_hwirq(d);
+       unsigned long flags;
+       u32 mask;
+
+       raw_spin_lock_irqsave(&pcie->msi_irq_lock, flags);
+       mask = advk_readl(pcie, PCIE_MSI_MASK_REG);
+       mask |= BIT(hwirq);
+       advk_writel(pcie, mask, PCIE_MSI_MASK_REG);
+       raw_spin_unlock_irqrestore(&pcie->msi_irq_lock, flags);
+}
+
+static void advk_msi_irq_unmask(struct irq_data *d)
+{
+       struct advk_pcie *pcie = d->domain->host_data;
+       irq_hw_number_t hwirq = irqd_to_hwirq(d);
+       unsigned long flags;
+       u32 mask;
+
+       raw_spin_lock_irqsave(&pcie->msi_irq_lock, flags);
+       mask = advk_readl(pcie, PCIE_MSI_MASK_REG);
+       mask &= ~BIT(hwirq);
+       advk_writel(pcie, mask, PCIE_MSI_MASK_REG);
+       raw_spin_unlock_irqrestore(&pcie->msi_irq_lock, flags);
+}
+
+static void advk_msi_top_irq_mask(struct irq_data *d)
+{
+       pci_msi_mask_irq(d);
+       irq_chip_mask_parent(d);
+}
+
+static void advk_msi_top_irq_unmask(struct irq_data *d)
+{
+       pci_msi_unmask_irq(d);
+       irq_chip_unmask_parent(d);
+}
+
 static struct irq_chip advk_msi_bottom_irq_chip = {
        .name                   = "MSI",
        .irq_compose_msi_msg    = advk_msi_irq_compose_msi_msg,
        .irq_set_affinity       = advk_msi_set_affinity,
+       .irq_mask               = advk_msi_irq_mask,
+       .irq_unmask             = advk_msi_irq_unmask,
 };
 
 static int advk_msi_irq_domain_alloc(struct irq_domain *domain,
 };
 
 static struct irq_chip advk_msi_irq_chip = {
-       .name = "advk-MSI",
+       .name           = "advk-MSI",
+       .irq_mask       = advk_msi_top_irq_mask,
+       .irq_unmask     = advk_msi_top_irq_unmask,
 };
 
 static struct msi_domain_info advk_msi_domain_info = {
        struct device *dev = &pcie->pdev->dev;
        phys_addr_t msi_msg_phys;
 
+       raw_spin_lock_init(&pcie->msi_irq_lock);
        mutex_init(&pcie->msi_used_lock);
 
        msi_msg_phys = virt_to_phys(&pcie->msi_msg);