drivers/pci/msi/irqdomain.c
Source file repositories/reference/linux-study-clean/drivers/pci/msi/irqdomain.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/msi/irqdomain.c- Extension
.c- Size
- 12516 bytes
- Lines
- 432
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/acpi_iort.hlinux/irqdomain.hlinux/of_irq.hmsi.h
Detected Declarations
function Interruptfunction pci_msi_teardown_msi_irqsfunction pci_msi_domain_write_msgfunction pci_device_domain_set_descfunction cond_shutdown_parentfunction cond_startup_parentfunction pci_irq_shutdown_msifunction pci_irq_startup_msifunction pci_irq_mask_msifunction pci_irq_unmask_msifunction pci_irq_shutdown_msixfunction pci_irq_startup_msixfunction pci_irq_mask_msixfunction pci_irq_unmask_msixfunction pci_msix_prepare_descfunction pci_match_device_domainfunction pci_create_device_domainfunction pci_setup_msi_device_domainfunction pci_setup_msix_device_domainfunction pci_msi_domain_supportsfunction get_msi_id_cbfunction pci_msi_domain_get_msi_ridfunction pci_msi_map_rid_ctlr_nodeexport pci_msix_prepare_desc
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0
/*
* PCI Message Signaled Interrupt (MSI) - irqdomain support
*/
#include <linux/acpi_iort.h>
#include <linux/irqdomain.h>
#include <linux/of_irq.h>
#include "msi.h"
int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct irq_domain *domain;
domain = dev_get_msi_domain(&dev->dev);
if (domain && irq_domain_is_hierarchy(domain))
return msi_domain_alloc_irqs_all_locked(&dev->dev, MSI_DEFAULT_DOMAIN, nvec);
return pci_msi_legacy_setup_msi_irqs(dev, nvec, type);
}
void pci_msi_teardown_msi_irqs(struct pci_dev *dev)
{
struct irq_domain *domain;
domain = dev_get_msi_domain(&dev->dev);
if (domain && irq_domain_is_hierarchy(domain)) {
msi_domain_free_irqs_all_locked(&dev->dev, MSI_DEFAULT_DOMAIN);
} else {
pci_msi_legacy_teardown_msi_irqs(dev);
msi_free_msi_descs(&dev->dev);
}
}
/**
* pci_msi_domain_write_msg - Helper to write MSI message to PCI config space
* @irq_data: Pointer to interrupt data of the MSI interrupt
* @msg: Pointer to the message
*/
static void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg)
{
struct msi_desc *desc = irq_data_get_msi_desc(irq_data);
/*
* For MSI-X desc->irq is always equal to irq_data->irq. For
* MSI only the first interrupt of MULTI MSI passes the test.
*/
if (desc->irq == irq_data->irq)
__pci_write_msi_msg(desc, msg);
}
/*
* Per device MSI[-X] domain functionality
*/
static void pci_device_domain_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
{
arg->desc = desc;
arg->hwirq = desc->msi_index;
}
static void cond_shutdown_parent(struct irq_data *data)
{
struct msi_domain_info *info = data->domain->host_data;
if (unlikely(info->flags & MSI_FLAG_PCI_MSI_STARTUP_PARENT))
irq_chip_shutdown_parent(data);
else if (unlikely(info->flags & MSI_FLAG_PCI_MSI_MASK_PARENT))
irq_chip_mask_parent(data);
}
static unsigned int cond_startup_parent(struct irq_data *data)
{
struct msi_domain_info *info = data->domain->host_data;
if (unlikely(info->flags & MSI_FLAG_PCI_MSI_STARTUP_PARENT))
return irq_chip_startup_parent(data);
else if (unlikely(info->flags & MSI_FLAG_PCI_MSI_MASK_PARENT))
irq_chip_unmask_parent(data);
return 0;
}
static void pci_irq_shutdown_msi(struct irq_data *data)
{
struct msi_desc *desc = irq_data_get_msi_desc(data);
pci_msi_mask(desc, BIT(data->irq - desc->irq));
cond_shutdown_parent(data);
}
Annotation
- Immediate include surface: `linux/acpi_iort.h`, `linux/irqdomain.h`, `linux/of_irq.h`, `msi.h`.
- Detected declarations: `function Interrupt`, `function pci_msi_teardown_msi_irqs`, `function pci_msi_domain_write_msg`, `function pci_device_domain_set_desc`, `function cond_shutdown_parent`, `function cond_startup_parent`, `function pci_irq_shutdown_msi`, `function pci_irq_startup_msi`, `function pci_irq_mask_msi`, `function pci_irq_unmask_msi`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: integration implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.