Skip to content

Commit e77d9c9

Browse files
paliLorenzo Pieralisi
authored andcommitted
PCI: aardvark: Add support for masking MSI interrupts
We should not unmask MSIs at setup, but only when kernel asks for them to be unmasked. At setup, mask all MSIs, and implement IRQ chip callbacks for masking and unmasking particular MSIs. Link: https://lore.kernel.org/r/20220110015018.26359-11-kabel@kernel.org Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Marek Behún <kabel@kernel.org> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
1 parent 4689c09 commit e77d9c9

1 file changed

Lines changed: 49 additions & 5 deletions

File tree

drivers/pci/controller/pci-aardvark.c

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ struct advk_pcie {
274274
raw_spinlock_t irq_lock;
275275
struct irq_domain *msi_domain;
276276
struct irq_domain *msi_inner_domain;
277+
raw_spinlock_t msi_irq_lock;
277278
DECLARE_BITMAP(msi_used, MSI_IRQ_NUM);
278279
struct mutex msi_used_lock;
279280
u16 msi_msg;
@@ -570,12 +571,10 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
570571
advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG);
571572
advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG);
572573

573-
/* Disable All ISR0/1 Sources */
574+
/* Disable All ISR0/1 and MSI Sources */
574575
advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_MASK_REG);
575576
advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG);
576-
577-
/* Unmask all MSIs */
578-
advk_writel(pcie, ~(u32)PCIE_MSI_ALL_MASK, PCIE_MSI_MASK_REG);
577+
advk_writel(pcie, PCIE_MSI_ALL_MASK, PCIE_MSI_MASK_REG);
579578

580579
/* Unmask summary MSI interrupt */
581580
reg = advk_readl(pcie, PCIE_ISR0_MASK_REG);
@@ -1189,10 +1188,52 @@ static int advk_msi_set_affinity(struct irq_data *irq_data,
11891188
return -EINVAL;
11901189
}
11911190

1191+
static void advk_msi_irq_mask(struct irq_data *d)
1192+
{
1193+
struct advk_pcie *pcie = d->domain->host_data;
1194+
irq_hw_number_t hwirq = irqd_to_hwirq(d);
1195+
unsigned long flags;
1196+
u32 mask;
1197+
1198+
raw_spin_lock_irqsave(&pcie->msi_irq_lock, flags);
1199+
mask = advk_readl(pcie, PCIE_MSI_MASK_REG);
1200+
mask |= BIT(hwirq);
1201+
advk_writel(pcie, mask, PCIE_MSI_MASK_REG);
1202+
raw_spin_unlock_irqrestore(&pcie->msi_irq_lock, flags);
1203+
}
1204+
1205+
static void advk_msi_irq_unmask(struct irq_data *d)
1206+
{
1207+
struct advk_pcie *pcie = d->domain->host_data;
1208+
irq_hw_number_t hwirq = irqd_to_hwirq(d);
1209+
unsigned long flags;
1210+
u32 mask;
1211+
1212+
raw_spin_lock_irqsave(&pcie->msi_irq_lock, flags);
1213+
mask = advk_readl(pcie, PCIE_MSI_MASK_REG);
1214+
mask &= ~BIT(hwirq);
1215+
advk_writel(pcie, mask, PCIE_MSI_MASK_REG);
1216+
raw_spin_unlock_irqrestore(&pcie->msi_irq_lock, flags);
1217+
}
1218+
1219+
static void advk_msi_top_irq_mask(struct irq_data *d)
1220+
{
1221+
pci_msi_mask_irq(d);
1222+
irq_chip_mask_parent(d);
1223+
}
1224+
1225+
static void advk_msi_top_irq_unmask(struct irq_data *d)
1226+
{
1227+
pci_msi_unmask_irq(d);
1228+
irq_chip_unmask_parent(d);
1229+
}
1230+
11921231
static struct irq_chip advk_msi_bottom_irq_chip = {
11931232
.name = "MSI",
11941233
.irq_compose_msi_msg = advk_msi_irq_compose_msi_msg,
11951234
.irq_set_affinity = advk_msi_set_affinity,
1235+
.irq_mask = advk_msi_irq_mask,
1236+
.irq_unmask = advk_msi_irq_unmask,
11961237
};
11971238

11981239
static int advk_msi_irq_domain_alloc(struct irq_domain *domain,
@@ -1282,7 +1323,9 @@ static const struct irq_domain_ops advk_pcie_irq_domain_ops = {
12821323
};
12831324

12841325
static struct irq_chip advk_msi_irq_chip = {
1285-
.name = "advk-MSI",
1326+
.name = "advk-MSI",
1327+
.irq_mask = advk_msi_top_irq_mask,
1328+
.irq_unmask = advk_msi_top_irq_unmask,
12861329
};
12871330

12881331
static struct msi_domain_info advk_msi_domain_info = {
@@ -1296,6 +1339,7 @@ static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
12961339
struct device *dev = &pcie->pdev->dev;
12971340
phys_addr_t msi_msg_phys;
12981341

1342+
raw_spin_lock_init(&pcie->msi_irq_lock);
12991343
mutex_init(&pcie->msi_used_lock);
13001344

13011345
msi_msg_phys = virt_to_phys(&pcie->msi_msg);

0 commit comments

Comments
 (0)