drivers/pci/controller/pci-thunder-pem.c
Source file repositories/reference/linux-study-clean/drivers/pci/controller/pci-thunder-pem.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/controller/pci-thunder-pem.c- Extension
.c- Size
- 12512 bytes
- Lines
- 482
- 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/bitfield.hlinux/kernel.hlinux/init.hlinux/pci.hlinux/of_address.hlinux/of_pci.hlinux/pci-acpi.hlinux/pci-ecam.hlinux/platform_device.hlinux/io-64-nonatomic-lo-hi.h../pci.hpci-host-common.h
Detected Declarations
struct thunder_pem_pcifunction thunder_pem_bridge_readfunction thunder_pem_config_readfunction thunder_pem_bridge_w1c_bitsfunction thunder_pem_bridge_w1_bitsfunction thunder_pem_bridge_writefunction thunder_pem_config_writefunction thunder_pem_initfunction thunder_pem_reserve_rangefunction thunder_pem_legacy_fwfunction thunder_pem_acpi_initfunction thunder_pem_platform_init
Annotated Snippet
struct thunder_pem_pci {
u32 ea_entry[3];
void __iomem *pem_reg_base;
};
static int thunder_pem_bridge_read(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
u64 read_val, tmp_val;
struct pci_config_window *cfg = bus->sysdata;
struct thunder_pem_pci *pem_pci = (struct thunder_pem_pci *)cfg->priv;
if (devfn != 0 || where >= 2048)
return PCIBIOS_DEVICE_NOT_FOUND;
/*
* 32-bit accesses only. Write the address to the low order
* bits of PEM_CFG_RD, then trigger the read by reading back.
* The config data lands in the upper 32-bits of PEM_CFG_RD.
*/
read_val = where & ~3ull;
writeq(read_val, pem_pci->pem_reg_base + PEM_CFG_RD);
read_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD);
read_val >>= 32;
/*
* The config space contains some garbage, fix it up. Also
* synthesize an EA capability for the BAR used by MSI-X.
*/
switch (where & ~3) {
case 0x40:
read_val &= 0xffff00ff;
read_val |= 0x00007000; /* Skip MSI CAP */
break;
case 0x70: /* Express Cap */
/*
* Change PME interrupt to vector 2 on T88 where it
* reads as 0, else leave it alone.
*/
if (!(read_val & (0x1f << 25)))
read_val |= (2u << 25);
break;
case 0xb0: /* MSI-X Cap */
/* TableSize=2 or 4, Next Cap is EA */
read_val &= 0xc00000ff;
/*
* If Express Cap(0x70) raw PME vector reads as 0 we are on
* T88 and TableSize is reported as 4, else TableSize
* is 2.
*/
writeq(0x70, pem_pci->pem_reg_base + PEM_CFG_RD);
tmp_val = readq(pem_pci->pem_reg_base + PEM_CFG_RD);
tmp_val >>= 32;
if (!(tmp_val & (0x1f << 25)))
read_val |= 0x0003bc00;
else
read_val |= 0x0001bc00;
break;
case 0xb4:
/* Table offset=0, BIR=0 */
read_val = 0x00000000;
break;
case 0xb8:
/* BPA offset=0xf0000, BIR=0 */
read_val = 0x000f0000;
break;
case 0xbc:
/* EA, 1 entry, no next Cap */
read_val = 0x00010014;
break;
case 0xc0:
/* DW2 for type-1 */
read_val = 0x00000000;
break;
case 0xc4:
/* Entry BEI=0, PP=0x00, SP=0xff, ES=3 */
read_val = 0x80ff0003;
break;
case 0xc8:
read_val = pem_pci->ea_entry[0];
break;
case 0xcc:
read_val = pem_pci->ea_entry[1];
break;
case 0xd0:
read_val = pem_pci->ea_entry[2];
break;
default:
break;
}
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/kernel.h`, `linux/init.h`, `linux/pci.h`, `linux/of_address.h`, `linux/of_pci.h`, `linux/pci-acpi.h`, `linux/pci-ecam.h`.
- Detected declarations: `struct thunder_pem_pci`, `function thunder_pem_bridge_read`, `function thunder_pem_config_read`, `function thunder_pem_bridge_w1c_bits`, `function thunder_pem_bridge_w1_bits`, `function thunder_pem_bridge_write`, `function thunder_pem_config_write`, `function thunder_pem_init`, `function thunder_pem_reserve_range`, `function thunder_pem_legacy_fw`.
- 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.