drivers/pci/controller/dwc/pci-layerscape-ep.c
Source file repositories/reference/linux-study-clean/drivers/pci/controller/dwc/pci-layerscape-ep.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/controller/dwc/pci-layerscape-ep.c- Extension
.c- Size
- 7690 bytes
- Lines
- 296
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: implementation source
- Status
- source 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/init.hlinux/of_pci.hlinux/of_platform.hlinux/of_address.hlinux/pci.hlinux/platform_device.hlinux/resource.hpcie-designware.h
Detected Declarations
struct ls_pcie_ep_drvdatastruct ls_pcie_epfunction ls_pcie_pf_lut_readlfunction ls_pcie_pf_lut_writelfunction ls_pcie_ep_event_handlerfunction ls_pcie_ep_interrupt_initfunction ls_pcie_ep_get_featuresfunction ls_pcie_ep_initfunction ls_pcie_ep_raise_irqfunction ls_pcie_ep_get_dbi_offsetfunction ls_pcie_ep_probe
Annotated Snippet
struct ls_pcie_ep_drvdata {
u32 func_offset;
const struct dw_pcie_ep_ops *ops;
const struct dw_pcie_ops *dw_pcie_ops;
};
struct ls_pcie_ep {
struct dw_pcie *pci;
struct pci_epc_features *ls_epc;
const struct ls_pcie_ep_drvdata *drvdata;
int irq;
u32 lnkcap;
bool big_endian;
};
static u32 ls_pcie_pf_lut_readl(struct ls_pcie_ep *pcie, u32 offset)
{
struct dw_pcie *pci = pcie->pci;
if (pcie->big_endian)
return ioread32be(pci->dbi_base + offset);
else
return ioread32(pci->dbi_base + offset);
}
static void ls_pcie_pf_lut_writel(struct ls_pcie_ep *pcie, u32 offset, u32 value)
{
struct dw_pcie *pci = pcie->pci;
if (pcie->big_endian)
iowrite32be(value, pci->dbi_base + offset);
else
iowrite32(value, pci->dbi_base + offset);
}
static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id)
{
struct ls_pcie_ep *pcie = dev_id;
struct dw_pcie *pci = pcie->pci;
u32 val, cfg;
u8 offset;
val = ls_pcie_pf_lut_readl(pcie, PEX_PF0_PME_MES_DR);
ls_pcie_pf_lut_writel(pcie, PEX_PF0_PME_MES_DR, val);
if (!val)
return IRQ_NONE;
if (val & PEX_PF0_PME_MES_DR_LUD) {
offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
/*
* The values of the Maximum Link Width and Supported Link
* Speed from the Link Capabilities Register will be lost
* during link down or hot reset. Restore initial value
* that configured by the Reset Configuration Word (RCW).
*/
dw_pcie_dbi_ro_wr_en(pci);
dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, pcie->lnkcap);
dw_pcie_dbi_ro_wr_dis(pci);
cfg = ls_pcie_pf_lut_readl(pcie, PEX_PF0_CONFIG);
cfg |= PEX_PF0_CFG_READY;
ls_pcie_pf_lut_writel(pcie, PEX_PF0_CONFIG, cfg);
dw_pcie_ep_linkup(&pci->ep);
dev_dbg(pci->dev, "Link up\n");
} else if (val & PEX_PF0_PME_MES_DR_LDD) {
dev_dbg(pci->dev, "Link down\n");
dw_pcie_ep_linkdown(&pci->ep);
} else if (val & PEX_PF0_PME_MES_DR_HRD) {
dev_dbg(pci->dev, "Hot reset\n");
}
return IRQ_HANDLED;
}
static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
struct platform_device *pdev)
{
u32 val;
int ret;
pcie->irq = platform_get_irq_byname(pdev, "pme");
if (pcie->irq < 0)
return pcie->irq;
ret = devm_request_irq(&pdev->dev, pcie->irq, ls_pcie_ep_event_handler,
IRQF_SHARED, pdev->name, pcie);
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/init.h`, `linux/of_pci.h`, `linux/of_platform.h`, `linux/of_address.h`, `linux/pci.h`, `linux/platform_device.h`, `linux/resource.h`.
- Detected declarations: `struct ls_pcie_ep_drvdata`, `struct ls_pcie_ep`, `function ls_pcie_pf_lut_readl`, `function ls_pcie_pf_lut_writel`, `function ls_pcie_ep_event_handler`, `function ls_pcie_ep_interrupt_init`, `function ls_pcie_ep_get_features`, `function ls_pcie_ep_init`, `function ls_pcie_ep_raise_irq`, `function ls_pcie_ep_get_dbi_offset`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: source 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.