drivers/ssb/driver_pcicore.c
Source file repositories/reference/linux-study-clean/drivers/ssb/driver_pcicore.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/ssb/driver_pcicore.c- Extension
.c- Size
- 19243 bytes
- Lines
- 743
- Domain
- Driver Families
- Bucket
- drivers/ssb
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
ssb_private.hlinux/ssb/ssb.hlinux/pci.hlinux/export.hlinux/delay.hlinux/ssb/ssb_embedded.hasm/paccess.h
Detected Declarations
function pcicore_read32function pcicore_write32function pcicore_read16function pcicore_write16function get_cfgspace_addrfunction ssb_extpci_read_configfunction ssb_extpci_write_configfunction ssb_pcicore_read_configfunction ssb_pcicore_write_configfunction ssb_pcicore_plat_dev_initfunction ssb_pcicore_fixup_pcibridgefunction ssb_pcicore_pcibios_map_irqfunction ssb_pcicore_init_hostmodefunction pcicore_is_in_hostmodefunction ssb_pcicore_fix_sprom_core_indexfunction ssb_pcicore_polarity_workaroundfunction ssb_pcicore_serdes_workaroundfunction ssb_pcicore_pci_setup_workaroundsfunction ssb_pcicore_pcie_setup_workaroundsfunction ssb_pcicore_init_clientmodefunction ssb_pcicore_initfunction ssb_pcie_readfunction ssb_pcie_writefunction ssb_pcie_mdio_set_phyfunction ssb_pcie_mdio_readfunction ssb_pcie_mdio_writefunction ssb_pcicore_dev_irqvecs_enableexport ssb_pcicore_dev_irqvecs_enable
Annotated Snippet
if (v & 0x100 /* Trans complete */) {
udelay(10);
ret = pcicore_read32(pc, mdio_data);
break;
}
msleep(1);
}
pcicore_write32(pc, mdio_control, 0);
return ret;
}
static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
u8 address, u16 data)
{
const u16 mdio_control = 0x128;
const u16 mdio_data = 0x12C;
int max_retries = 10;
u32 v;
int i;
v = 0x80; /* Enable Preamble Sequence */
v |= 0x2; /* MDIO Clock Divisor */
pcicore_write32(pc, mdio_control, v);
if (pc->dev->id.revision >= 10) {
max_retries = 200;
ssb_pcie_mdio_set_phy(pc, device);
}
v = (1 << 30); /* Start of Transaction */
v |= (1 << 28); /* Write Transaction */
v |= (1 << 17); /* Turnaround */
if (pc->dev->id.revision < 10)
v |= (u32)device << 22;
v |= (u32)address << 18;
v |= data;
pcicore_write32(pc, mdio_data, v);
/* Wait for the device to complete the transaction */
udelay(10);
for (i = 0; i < max_retries; i++) {
v = pcicore_read32(pc, mdio_control);
if (v & 0x100 /* Trans complete */)
break;
msleep(1);
}
pcicore_write32(pc, mdio_control, 0);
}
int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
struct ssb_device *dev)
{
struct ssb_device *pdev = pc->dev;
struct ssb_bus *bus;
int err = 0;
u32 tmp;
if (dev->bus->bustype != SSB_BUSTYPE_PCI) {
/* This SSB device is not on a PCI host-bus. So the IRQs are
* not routed through the PCI core.
* So we must not enable routing through the PCI core.
*/
goto out;
}
if (!pdev)
goto out;
bus = pdev->bus;
might_sleep_if(pdev->id.coreid != SSB_DEV_PCI);
/* Enable interrupts for this device. */
if ((pdev->id.revision >= 6) || (pdev->id.coreid == SSB_DEV_PCIE)) {
u32 coremask;
/* Calculate the "coremask" for the device. */
coremask = (1 << dev->core_index);
WARN_ON(bus->bustype != SSB_BUSTYPE_PCI);
err = pci_read_config_dword(bus->host_pci, SSB_PCI_IRQMASK, &tmp);
if (err)
goto out;
tmp |= coremask << 8;
err = pci_write_config_dword(bus->host_pci, SSB_PCI_IRQMASK, tmp);
if (err)
goto out;
} else {
u32 intvec;
intvec = ssb_read32(pdev, SSB_INTVEC);
tmp = ssb_read32(dev, SSB_TPSFLAG);
Annotation
- Immediate include surface: `ssb_private.h`, `linux/ssb/ssb.h`, `linux/pci.h`, `linux/export.h`, `linux/delay.h`, `linux/ssb/ssb_embedded.h`, `asm/paccess.h`.
- Detected declarations: `function pcicore_read32`, `function pcicore_write32`, `function pcicore_read16`, `function pcicore_write16`, `function get_cfgspace_addr`, `function ssb_extpci_read_config`, `function ssb_extpci_write_config`, `function ssb_pcicore_read_config`, `function ssb_pcicore_write_config`, `function ssb_pcicore_plat_dev_init`.
- Atlas domain: Driver Families / drivers/ssb.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.