iommu_completion_wait(iommu);
}
--- -void amd_iommu_dev_flush_pasid_all(struct iommu_dev_data *dev_data,
--- - ioasid_t pasid)
+++ +static void dev_flush_pasid_all(struct iommu_dev_data *dev_data,
+++ + ioasid_t pasid)
{
---- amd_iommu_dev_flush_pasid_pages(dev_data, 0,
---- CMD_INV_IOMMU_ALL_PAGES_ADDRESS, pasid);
-- -}
-- -
-- -void amd_iommu_domain_flush_complete(struct protection_domain *domain)
-- -{
-- - int i;
-- -
-- - for (i = 0; i < amd_iommu_get_num_iommus(); ++i) {
-- - if (domain && !domain->dev_iommu[i])
-- - continue;
-- -
-- - /*
-- - * Devices of this domain are behind this IOMMU
-- - * We need to wait for completion of all commands.
-- - */
-- - iommu_completion_wait(amd_iommus[i]);
-- - }
++++ amd_iommu_dev_flush_pasid_pages(dev_data, pasid, 0,
++++ CMD_INV_IOMMU_ALL_PAGES_ADDRESS);
}
- void amd_iommu_domain_flush_complete(struct protection_domain *domain)
- {
- int i;
-
- for (i = 0; i < amd_iommu_get_num_iommus(); ++i) {
- if (domain && !domain->dev_iommu[i])
- continue;
-
- /*
- * Devices of this domain are behind this IOMMU
- * We need to wait for completion of all commands.
- */
- iommu_completion_wait(amd_iommus[i]);
- }
- }
-
/* Flush the not present cache if it exists */
static void domain_flush_np_cache(struct protection_domain *domain,
dma_addr_t iova, size_t size)
pci_max_pasids(to_pci_dev(dev)));
}
+++ +out_err:
iommu_completion_wait(iommu);
++++ if (dev_is_pci(dev))
++++ pci_prepare_ats(to_pci_dev(dev), PAGE_SHIFT);
++++
return iommu_dev;
}
}
#ifdef CONFIG_ACPI
- ---static void acpi_smmu_get_options(u32 model, struct arm_smmu_device *smmu)
+ +++#ifdef CONFIG_TEGRA241_CMDQV
+ +++static void acpi_smmu_dsdt_probe_tegra241_cmdqv(struct acpi_iort_node *node,
+ +++ struct arm_smmu_device *smmu)
+ +++{
+ +++ const char *uid = kasprintf(GFP_KERNEL, "%u", node->identifier);
+ +++ struct acpi_device *adev;
+ +++
+ +++ /* Look for an NVDA200C node whose _UID matches the SMMU node ID */
+ +++ adev = acpi_dev_get_first_match_dev("NVDA200C", uid, -1);
+ +++ if (adev) {
+ +++ /* Tegra241 CMDQV driver is responsible for put_device() */
+ +++ smmu->impl_dev = &adev->dev;
+ +++ smmu->options |= ARM_SMMU_OPT_TEGRA241_CMDQV;
+ +++ dev_info(smmu->dev, "found companion CMDQV device: %s\n",
+ +++ dev_name(smmu->impl_dev));
+ +++ }
+ +++ kfree(uid);
+ +++}
+ +++#else
+ +++static void acpi_smmu_dsdt_probe_tegra241_cmdqv(struct acpi_iort_node *node,
+ +++ struct arm_smmu_device *smmu)
+ ++ {
- switch (model) {
+ +++}
+ +++#endif
+ +++
+ +++static int acpi_smmu_iort_probe_model(struct acpi_iort_node *node,
+ +++ struct arm_smmu_device *smmu)
+{
- -- switch (model) {
+ +++ struct acpi_iort_smmu_v3 *iort_smmu =
+ +++ (struct acpi_iort_smmu_v3 *)node->node_data;
+ +++
+ +++ switch (iort_smmu->model) {
case ACPI_IORT_SMMU_V3_CAVIUM_CN99XX:
smmu->options |= ARM_SMMU_OPT_PAGE0_REGS_ONLY;
break;