drivers/platform/x86/amd/pmc/mp2_stb.c

Source file repositories/reference/linux-study-clean/drivers/platform/x86/amd/pmc/mp2_stb.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/x86/amd/pmc/mp2_stb.c
Extension
.c
Size
5947 bytes
Lines
281
Domain
Driver Families
Bucket
drivers/platform
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations amd_mp2_stb_debugfs_fops = {
	.owner = THIS_MODULE,
	.open = amd_mp2_stb_debugfs_open,
	.read = amd_mp2_stb_debugfs_read,
};

static void amd_mp2_dbgfs_register(struct amd_pmc_dev *dev)
{
	if (!dev->dbgfs_dir)
		return;

	debugfs_create_file("stb_read_previous_boot", 0644, dev->dbgfs_dir, dev,
			    &amd_mp2_stb_debugfs_fops);
}

void amd_mp2_stb_deinit(struct amd_pmc_dev *dev)
{
	struct amd_mp2_dev *mp2 = dev->mp2;
	struct pci_dev *pdev;

	if (mp2 && mp2->pdev) {
		pdev = mp2->pdev;

		if (mp2->mmio)
			pci_clear_master(pdev);

		pci_dev_put(pdev);

		if (mp2->devres_gid)
			devres_release_group(&pdev->dev, mp2->devres_gid);

		dev->mp2 = NULL;
	}
}

void amd_mp2_stb_init(struct amd_pmc_dev *dev)
{
	struct amd_mp2_dev *mp2 = NULL;
	struct pci_dev *pdev;
	int rc;

	mp2 = devm_kzalloc(dev->dev, sizeof(*mp2), GFP_KERNEL);
	if (!mp2)
		return;

	pdev = pci_get_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MP2_STB, NULL);
	if (!pdev)
		return;

	dev->mp2 = mp2;
	mp2->pdev = pdev;

	mp2->devres_gid = devres_open_group(&pdev->dev, NULL, GFP_KERNEL);
	if (!mp2->devres_gid) {
		dev_err(&pdev->dev, "devres_open_group failed\n");
		goto mp2_error;
	}

	rc = pcim_enable_device(pdev);
	if (rc) {
		dev_err(&pdev->dev, "pcim_enable_device failed\n");
		goto mp2_error;
	}

	rc = pcim_iomap_regions(pdev, BIT(MP2_MMIO_BAR), "mp2 stb");
	if (rc) {
		dev_err(&pdev->dev, "pcim_iomap_regions failed\n");
		goto mp2_error;
	}

	mp2->mmio = pcim_iomap_table(pdev)[MP2_MMIO_BAR];
	if (!mp2->mmio) {
		dev_err(&pdev->dev, "pcim_iomap_table failed\n");
		goto mp2_error;
	}

	pci_set_master(pdev);

	rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
	if (rc) {
		dev_err(&pdev->dev, "failed to set DMA mask\n");
		goto mp2_error;
	}

	amd_mp2_dbgfs_register(dev);

	return;

mp2_error:
	amd_mp2_stb_deinit(dev);

Annotation

Implementation Notes