drivers/pci/controller/cadence/pci-sky1.c

Source file repositories/reference/linux-study-clean/drivers/pci/controller/cadence/pci-sky1.c

File Facts

System
Linux kernel
Corpus path
drivers/pci/controller/cadence/pci-sky1.c
Extension
.c
Size
6328 bytes
Lines
241
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct sky1_pcie {
	struct cdns_pcie *cdns_pcie;
	struct cdns_pcie_rc *cdns_pcie_rc;

	struct resource *cfg_res;
	struct resource *msg_res;
	struct pci_config_window *cfg;
	void __iomem *strap_base;
	void __iomem *status_base;
	void __iomem *reg_base;
	void __iomem *cfg_base;
	void __iomem *msg_base;
};

static int sky1_pcie_resource_get(struct platform_device *pdev,
				  struct sky1_pcie *pcie)
{
	struct device *dev = &pdev->dev;
	struct resource *res;
	void __iomem *base;

	base = devm_platform_ioremap_resource_byname(pdev, "reg");
	if (IS_ERR(base))
		return dev_err_probe(dev, PTR_ERR(base),
				     "unable to find \"reg\" registers\n");
	pcie->reg_base = base;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
	if (!res)
		return dev_err_probe(dev, -ENODEV, "unable to get \"cfg\" resource\n");
	pcie->cfg_res = res;

	base = devm_platform_ioremap_resource_byname(pdev, "rcsu_strap");
	if (IS_ERR(base))
		return dev_err_probe(dev, PTR_ERR(base),
				     "unable to find \"rcsu_strap\" registers\n");
	pcie->strap_base = base;

	base = devm_platform_ioremap_resource_byname(pdev, "rcsu_status");
	if (IS_ERR(base))
		return dev_err_probe(dev, PTR_ERR(base),
				     "unable to find \"rcsu_status\" registers\n");
	pcie->status_base = base;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "msg");
	if (!res)
		return dev_err_probe(dev, -ENODEV, "unable to get \"msg\" resource\n");
	pcie->msg_res = res;
	pcie->msg_base = devm_ioremap_resource(dev, res);
	if (IS_ERR(pcie->msg_base)) {
		return dev_err_probe(dev, PTR_ERR(pcie->msg_base),
				     "unable to ioremap msg resource\n");
	}

	return 0;
}

static int sky1_pcie_start_link(struct cdns_pcie *cdns_pcie)
{
	struct sky1_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
	u32 val;

	val = readl(pcie->strap_base + STRAP_REG(1));
	val |= LINK_TRAINING_ENABLE;
	writel(val, pcie->strap_base + STRAP_REG(1));

	return 0;
}

static void sky1_pcie_stop_link(struct cdns_pcie *cdns_pcie)
{
	struct sky1_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
	u32 val;

	val = readl(pcie->strap_base + STRAP_REG(1));
	val &= ~LINK_TRAINING_ENABLE;
	writel(val, pcie->strap_base + STRAP_REG(1));
}

static bool sky1_pcie_link_up(struct cdns_pcie *cdns_pcie)
{
	u32 val;

	val = cdns_pcie_hpa_readl(cdns_pcie, REG_BANK_IP_REG,
				  IP_REG_I_DBG_STS_0);
	return val & LINK_COMPLETE;
}

static const struct cdns_pcie_ops sky1_pcie_ops = {
	.start_link = sky1_pcie_start_link,

Annotation

Implementation Notes