static int __init iommu_init_pci()

in amd/init.c [1798:1898]


static int __init iommu_init_pci(struct amd_iommu *iommu)
{
	int cap_ptr = iommu->cap_ptr;
	int ret;

	iommu->dev = pci_get_domain_bus_and_slot(0, PCI_BUS_NUM(iommu->devid),
						 iommu->devid & 0xff);
	if (!iommu->dev)
		return -ENODEV;

	/* Prevent binding other PCI device drivers to IOMMU devices */
	iommu->dev->match_driver = false;

	pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET,
			      &iommu->cap);

	if (!(iommu->cap & (1 << IOMMU_CAP_IOTLB)))
		amd_iommu_iotlb_sup = false;

	late_iommu_features_init(iommu);

	if (iommu_feature(iommu, FEATURE_GT)) {
		int glxval;
		u32 max_pasid;
		u64 pasmax;

		pasmax = iommu->features & FEATURE_PASID_MASK;
		pasmax >>= FEATURE_PASID_SHIFT;
		max_pasid  = (1 << (pasmax + 1)) - 1;

		amd_iommu_max_pasid = min(amd_iommu_max_pasid, max_pasid);

		BUG_ON(amd_iommu_max_pasid & ~PASID_MASK);

		glxval   = iommu->features & FEATURE_GLXVAL_MASK;
		glxval >>= FEATURE_GLXVAL_SHIFT;

		if (amd_iommu_max_glx_val == -1)
			amd_iommu_max_glx_val = glxval;
		else
			amd_iommu_max_glx_val = min(amd_iommu_max_glx_val, glxval);
	}

	if (iommu_feature(iommu, FEATURE_GT) &&
	    iommu_feature(iommu, FEATURE_PPR)) {
		iommu->is_iommu_v2   = true;
		amd_iommu_v2_present = true;
	}

	if (iommu_feature(iommu, FEATURE_PPR) && alloc_ppr_log(iommu))
		return -ENOMEM;

	ret = iommu_init_ga_log(iommu);
	if (ret)
		return ret;

	if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE)) {
		pr_info("Using strict mode due to virtualization\n");
		iommu_set_dma_strict();
		amd_iommu_np_cache = true;
	}

	init_iommu_perf_ctr(iommu);

	if (is_rd890_iommu(iommu->dev)) {
		int i, j;

		iommu->root_pdev =
			pci_get_domain_bus_and_slot(0, iommu->dev->bus->number,
						    PCI_DEVFN(0, 0));

		/*
		 * Some rd890 systems may not be fully reconfigured by the
		 * BIOS, so it's necessary for us to store this information so
		 * it can be reprogrammed on resume
		 */
		pci_read_config_dword(iommu->dev, iommu->cap_ptr + 4,
				&iommu->stored_addr_lo);
		pci_read_config_dword(iommu->dev, iommu->cap_ptr + 8,
				&iommu->stored_addr_hi);

		/* Low bit locks writes to configuration space */
		iommu->stored_addr_lo &= ~1;

		for (i = 0; i < 6; i++)
			for (j = 0; j < 0x12; j++)
				iommu->stored_l1[i][j] = iommu_read_l1(iommu, i, j);

		for (i = 0; i < 0x83; i++)
			iommu->stored_l2[i] = iommu_read_l2(iommu, i);
	}

	amd_iommu_erratum_746_workaround(iommu);
	amd_iommu_ats_write_check_workaround(iommu);

	iommu_device_sysfs_add(&iommu->iommu, &iommu->dev->dev,
			       amd_iommu_groups, "ivhd%d", iommu->index);
	iommu_device_register(&iommu->iommu, &amd_iommu_ops, NULL);

	return pci_enable_device(iommu->dev);
}