Skip to content

Commit 7d189c7

Browse files
shivamurthyshastriKAGA-KOKO
authored andcommitted
PCI/MSI: Provide MSI_FLAG_PCI_MSI_MASK_PARENT
Most ARM(64) PCI/MSI domains mask and unmask in the parent domain after or before the PCI mask/unmask operation takes place. So there are more than a dozen of the same wrapper implementation all over the place. Don't make the same mistake with the new per device PCI/MSI domains and provide a new MSI feature flag, which lets the domain implementation enable this sequence in the PCI/MSI code. Signed-off-by: Shivamurthy Shastri <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Acked-by: Bjorn Helgaas <[email protected]> Link: https://lore.kernel.org/r/87ed8j34pj.ffs@tglx
1 parent 6dca724 commit 7d189c7

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

drivers/pci/msi/irqdomain.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,17 +148,35 @@ static void pci_device_domain_set_desc(msi_alloc_info_t *arg, struct msi_desc *d
148148
arg->hwirq = desc->msi_index;
149149
}
150150

151+
static __always_inline void cond_mask_parent(struct irq_data *data)
152+
{
153+
struct msi_domain_info *info = data->domain->host_data;
154+
155+
if (unlikely(info->flags & MSI_FLAG_PCI_MSI_MASK_PARENT))
156+
irq_chip_mask_parent(data);
157+
}
158+
159+
static __always_inline void cond_unmask_parent(struct irq_data *data)
160+
{
161+
struct msi_domain_info *info = data->domain->host_data;
162+
163+
if (unlikely(info->flags & MSI_FLAG_PCI_MSI_MASK_PARENT))
164+
irq_chip_unmask_parent(data);
165+
}
166+
151167
static void pci_irq_mask_msi(struct irq_data *data)
152168
{
153169
struct msi_desc *desc = irq_data_get_msi_desc(data);
154170

155171
pci_msi_mask(desc, BIT(data->irq - desc->irq));
172+
cond_mask_parent(data);
156173
}
157174

158175
static void pci_irq_unmask_msi(struct irq_data *data)
159176
{
160177
struct msi_desc *desc = irq_data_get_msi_desc(data);
161178

179+
cond_unmask_parent(data);
162180
pci_msi_unmask(desc, BIT(data->irq - desc->irq));
163181
}
164182

@@ -195,10 +213,12 @@ static const struct msi_domain_template pci_msi_template = {
195213
static void pci_irq_mask_msix(struct irq_data *data)
196214
{
197215
pci_msix_mask(irq_data_get_msi_desc(data));
216+
cond_mask_parent(data);
198217
}
199218

200219
static void pci_irq_unmask_msix(struct irq_data *data)
201220
{
221+
cond_unmask_parent(data);
202222
pci_msix_unmask(irq_data_get_msi_desc(data));
203223
}
204224

include/linux/msi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,8 @@ enum {
556556
MSI_FLAG_USE_DEV_FWNODE = (1 << 7),
557557
/* Set parent->dev into domain->pm_dev on device domain creation */
558558
MSI_FLAG_PARENT_PM_DEV = (1 << 8),
559+
/* Support for parent mask/unmask */
560+
MSI_FLAG_PCI_MSI_MASK_PARENT = (1 << 9),
559561

560562
/* Mask for the generic functionality */
561563
MSI_GENERIC_FLAGS_MASK = GENMASK(15, 0),

0 commit comments

Comments
 (0)