Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <shivamurthy.shastri@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://lore.kernel.org/r/87ed8j34pj.ffs@tglx

authored by

Shivamurthy Shastri and committed by
Thomas Gleixner
7d189c77 6dca724d

+22
+20
drivers/pci/msi/irqdomain.c
··· 148 148 arg->hwirq = desc->msi_index; 149 149 } 150 150 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 + 151 167 static void pci_irq_mask_msi(struct irq_data *data) 152 168 { 153 169 struct msi_desc *desc = irq_data_get_msi_desc(data); 154 170 155 171 pci_msi_mask(desc, BIT(data->irq - desc->irq)); 172 + cond_mask_parent(data); 156 173 } 157 174 158 175 static void pci_irq_unmask_msi(struct irq_data *data) 159 176 { 160 177 struct msi_desc *desc = irq_data_get_msi_desc(data); 161 178 179 + cond_unmask_parent(data); 162 180 pci_msi_unmask(desc, BIT(data->irq - desc->irq)); 163 181 } 164 182 ··· 213 195 static void pci_irq_mask_msix(struct irq_data *data) 214 196 { 215 197 pci_msix_mask(irq_data_get_msi_desc(data)); 198 + cond_mask_parent(data); 216 199 } 217 200 218 201 static void pci_irq_unmask_msix(struct irq_data *data) 219 202 { 203 + cond_unmask_parent(data); 220 204 pci_msix_unmask(irq_data_get_msi_desc(data)); 221 205 } 222 206
+2
include/linux/msi.h
··· 556 556 MSI_FLAG_USE_DEV_FWNODE = (1 << 7), 557 557 /* Set parent->dev into domain->pm_dev on device domain creation */ 558 558 MSI_FLAG_PARENT_PM_DEV = (1 << 8), 559 + /* Support for parent mask/unmask */ 560 + MSI_FLAG_PCI_MSI_MASK_PARENT = (1 << 9), 559 561 560 562 /* Mask for the generic functionality */ 561 563 MSI_GENERIC_FLAGS_MASK = GENMASK(15, 0),