/** * This is the irqcontrol callback to be registered to uio_info. * It can be used to disable/enable interrupt from user space processes. * * @param info * pointer to uio_info. * @param irq_state * state value. 1 to enable interrupt, 0 to disable interrupt. * * @return * - On success, 0. * - On failure, a negative value. */ static int igbuio_pci_irqcontrol(struct uio_info *info, s32 irq_state) { struct rte_uio_pci_dev *udev = info->priv; struct pci_dev *pdev = udev->pdev; #ifdef HAVE_PCI_MSI_MASK_IRQ struct irq_data *irq = irq_get_irq_data(udev->info.irq); #endif pci_cfg_access_lock(pdev); if (udev->mode == RTE_INTR_MODE_MSIX || udev->mode == RTE_INTR_MODE_MSI) { #ifdef HAVE_PCI_MSI_MASK_IRQ if (irq_state == 1) pci_msi_unmask_irq(irq); else pci_msi_mask_irq(irq); #else igbuio_mask_irq(pdev, udev->mode, irq_state); #endif } if (udev->mode == RTE_INTR_MODE_LEGACY) pci_intx(pdev, !!irq_state); pci_cfg_access_unlock(pdev); return 0; }
/* * XLP8XX/4XX/3XX/2XX: * The MSI-X interrupt handling is different from MSI, there are 32 MSI-X * interrupts generated by the PIC and each of these correspond to a MSI-X * vector (0-31) that can be assigned. * * We divide the MSI-X vectors to 8 per link and do a per-link allocation * * XLP9XX: * 32 MSI-X vectors are available per link, and the interrupts are not routed * thru the PIC. PIC ack not needed. * * Enable and disable done using standard MSI functions. */ static void xlp_msix_mask_ack(struct irq_data *d) { struct xlp_msi_data *md; int link, msixvec; uint32_t status_reg, bit; msixvec = nlm_irq_msixvec(d->irq); link = nlm_irq_msixlink(msixvec); pci_msi_mask_irq(d); md = irq_data_get_irq_handler_data(d); /* Ack MSI on bridge */ if (cpu_is_xlp9xx()) { status_reg = PCIE_9XX_MSIX_STATUSX(link); bit = msixvec % XLP_MSIXVEC_PER_LINK; } else { status_reg = PCIE_MSIX_STATUS; bit = msixvec; } nlm_write_reg(md->lnkbase, status_reg, 1u << bit); if (!cpu_is_xlp9xx()) nlm_pic_ack(md->node->picbase, PIC_IRT_PCIE_MSIX_INDEX(msixvec)); }
static void ks_dw_pcie_msi_irq_mask(struct irq_data *d) { struct keystone_pcie *ks_pcie; unsigned int irq = d->irq; struct msi_desc *msi; struct pcie_port *pp; u32 offset; msi = irq_get_msi_desc(irq); pp = sys_to_pcie(msi->dev->bus->sysdata); ks_pcie = to_keystone_pcie(pp); offset = irq - irq_linear_revmap(pp->irq_domain, 0); /* Mask the end point if PVM implemented */ if (IS_ENABLED(CONFIG_PCI_MSI)) { if (msi->msi_attrib.maskbit) pci_msi_mask_irq(d); } ks_dw_pcie_msi_clear_irq(pp, offset); }
static void its_mask_msi_irq(struct irq_data *d) { pci_msi_mask_irq(d); irq_chip_mask_parent(d); }