drivers/pci/controller/dwc/pcie-spacemit-k1.c
Source file repositories/reference/linux-study-clean/drivers/pci/controller/dwc/pcie-spacemit-k1.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/controller/dwc/pcie-spacemit-k1.c- Extension
.c- Size
- 9004 bytes
- Lines
- 358
- 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/clk.hlinux/delay.hlinux/device.hlinux/err.hlinux/gfp.hlinux/mfd/syscon.hlinux/mod_devicetable.hlinux/phy/phy.hlinux/platform_device.hlinux/regmap.hlinux/reset.hlinux/types.hpcie-designware.h
Detected Declarations
struct k1_pciefunction platform_get_drvdatafunction k1_pcie_enable_resourcesfunction k1_pcie_disable_resourcesfunction k1_pcie_disable_aspm_l1function k1_pcie_initfunction k1_pcie_deinitfunction k1_pcie_link_upfunction k1_pcie_start_linkfunction k1_pcie_stop_linkfunction k1_pcie_parse_portfunction k1_pcie_probefunction k1_pcie_remove
Annotated Snippet
struct k1_pcie {
struct dw_pcie pci;
struct phy *phy;
void __iomem *link;
struct regmap *pmu; /* Errors ignored; MMIO-backed regmap */
u32 pmu_off;
};
#define to_k1_pcie(dw_pcie) \
platform_get_drvdata(to_platform_device((dw_pcie)->dev))
static void k1_pcie_toggle_soft_reset(struct k1_pcie *k1)
{
u32 offset;
u32 val;
/*
* Write, then read back to guarantee it has reached the device
* before we start the delay.
*/
offset = k1->pmu_off + PCIE_CONTROL_LOGIC;
regmap_set_bits(k1->pmu, offset, PCIE_SOFT_RESET);
regmap_read(k1->pmu, offset, &val);
mdelay(2);
regmap_clear_bits(k1->pmu, offset, PCIE_SOFT_RESET);
}
/* Enable app clocks, deassert resets */
static int k1_pcie_enable_resources(struct k1_pcie *k1)
{
struct dw_pcie *pci = &k1->pci;
int ret;
ret = clk_bulk_prepare_enable(ARRAY_SIZE(pci->app_clks), pci->app_clks);
if (ret)
return ret;
ret = reset_control_bulk_deassert(ARRAY_SIZE(pci->app_rsts),
pci->app_rsts);
if (ret)
goto err_disable_clks;
return 0;
err_disable_clks:
clk_bulk_disable_unprepare(ARRAY_SIZE(pci->app_clks), pci->app_clks);
return ret;
}
/* Assert resets, disable app clocks */
static void k1_pcie_disable_resources(struct k1_pcie *k1)
{
struct dw_pcie *pci = &k1->pci;
reset_control_bulk_assert(ARRAY_SIZE(pci->app_rsts), pci->app_rsts);
clk_bulk_disable_unprepare(ARRAY_SIZE(pci->app_clks), pci->app_clks);
}
/* FIXME: Disable ASPM L1 to avoid errors reported on some NVMe drives */
static void k1_pcie_disable_aspm_l1(struct k1_pcie *k1)
{
struct dw_pcie *pci = &k1->pci;
u8 offset;
u32 val;
offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
offset += PCI_EXP_LNKCAP;
dw_pcie_dbi_ro_wr_en(pci);
val = dw_pcie_readl_dbi(pci, offset);
val &= ~PCI_EXP_LNKCAP_ASPM_L1;
dw_pcie_writel_dbi(pci, offset, val);
dw_pcie_dbi_ro_wr_dis(pci);
}
static int k1_pcie_init(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct k1_pcie *k1 = to_k1_pcie(pci);
u32 reset_ctrl;
u32 val;
int ret;
k1_pcie_toggle_soft_reset(k1);
ret = k1_pcie_enable_resources(k1);
if (ret)
Annotation
- Immediate include surface: `linux/clk.h`, `linux/delay.h`, `linux/device.h`, `linux/err.h`, `linux/gfp.h`, `linux/mfd/syscon.h`, `linux/mod_devicetable.h`, `linux/phy/phy.h`.
- Detected declarations: `struct k1_pcie`, `function platform_get_drvdata`, `function k1_pcie_enable_resources`, `function k1_pcie_disable_resources`, `function k1_pcie_disable_aspm_l1`, `function k1_pcie_init`, `function k1_pcie_deinit`, `function k1_pcie_link_up`, `function k1_pcie_start_link`, `function k1_pcie_stop_link`.
- 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.