drivers/pci/controller/dwc/pci-meson.c

Source file repositories/reference/linux-study-clean/drivers/pci/controller/dwc/pci-meson.c

File Facts

System
Linux kernel
Corpus path
drivers/pci/controller/dwc/pci-meson.c
Extension
.c
Size
11058 bytes
Lines
478
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 meson_pcie_clk_res {
	struct clk *clk;
	struct clk *port_clk;
	struct clk *general_clk;
};

struct meson_pcie_rc_reset {
	struct reset_control *port;
	struct reset_control *apb;
};

struct meson_pcie {
	struct dw_pcie pci;
	void __iomem *cfg_base;
	struct meson_pcie_clk_res clk_res;
	struct meson_pcie_rc_reset mrst;
	struct gpio_desc *reset_gpio;
	struct phy *phy;
};

static struct reset_control *meson_pcie_get_reset(struct meson_pcie *mp,
						  const char *id,
						  u32 reset_type)
{
	struct device *dev = mp->pci.dev;
	struct reset_control *reset;

	if (reset_type == PCIE_SHARED_RESET)
		reset = devm_reset_control_get_shared(dev, id);
	else
		reset = devm_reset_control_get(dev, id);

	return reset;
}

static int meson_pcie_get_resets(struct meson_pcie *mp)
{
	struct meson_pcie_rc_reset *mrst = &mp->mrst;

	mrst->port = meson_pcie_get_reset(mp, "port", PCIE_NORMAL_RESET);
	if (IS_ERR(mrst->port))
		return PTR_ERR(mrst->port);
	reset_control_deassert(mrst->port);

	mrst->apb = meson_pcie_get_reset(mp, "apb", PCIE_SHARED_RESET);
	if (IS_ERR(mrst->apb))
		return PTR_ERR(mrst->apb);
	reset_control_deassert(mrst->apb);

	return 0;
}

static int meson_pcie_get_mems(struct platform_device *pdev,
			       struct meson_pcie *mp)
{
	struct dw_pcie *pci = &mp->pci;
	struct resource *res;

	/*
	 * For the broken DTs that supply 'dbi' as 'elbi', parse the 'elbi'
	 * region and assign it to both 'pci->elbi_base' and 'pci->dbi_space' so
	 * that the DWC core can skip parsing both regions.
	 */
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi");
	if (res) {
		pci->elbi_base = devm_pci_remap_cfg_resource(pci->dev, res);
		if (IS_ERR(pci->elbi_base))
			return PTR_ERR(pci->elbi_base);

		pci->dbi_base = pci->elbi_base;
		pci->dbi_phys_addr = res->start;
	}

	mp->cfg_base = devm_platform_ioremap_resource_byname(pdev, "cfg");
	if (IS_ERR(mp->cfg_base))
		return PTR_ERR(mp->cfg_base);

	return 0;
}

static int meson_pcie_power_on(struct meson_pcie *mp)
{
	int ret = 0;

	ret = phy_init(mp->phy);
	if (ret)
		return ret;

	ret = phy_power_on(mp->phy);
	if (ret) {

Annotation

Implementation Notes