Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 179145e6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'iommu-fixes-v4.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu

Pull IOMMU fixes from Joerg Roedel:

 - another compile-fix for my header cleanup

 - a couple of fixes for the recently merged IOMMU probe deferal code

 - fixes for ACPI/IORT code necessary with IOMMU probe deferal

* tag 'iommu-fixes-v4.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
  arm: dma-mapping: Reset the device's dma_ops
  ACPI/IORT: Move the check to get iommu_ops from translated fwspec
  ARM: dma-mapping: Don't tear down third-party mappings
  ACPI/IORT: Ignore all errors except EPROBE_DEFER
  iommu/of: Ignore all errors except EPROBE_DEFER
  iommu/of: Fix check for returning EPROBE_DEFER
  iommu/dma: Fix function declaration
parents c7a1aefc d3e01c51
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -19,7 +19,8 @@ struct dev_archdata {
#ifdef CONFIG_XEN
	const struct dma_map_ops *dev_dma_ops;
#endif
	bool dma_coherent;
	unsigned int dma_coherent:1;
	unsigned int dma_ops_setup:1;
};

struct omap_device;
+14 −15
Original line number Diff line number Diff line
@@ -2311,7 +2311,14 @@ int arm_iommu_attach_device(struct device *dev,
}
EXPORT_SYMBOL_GPL(arm_iommu_attach_device);

static void __arm_iommu_detach_device(struct device *dev)
/**
 * arm_iommu_detach_device
 * @dev: valid struct device pointer
 *
 * Detaches the provided device from a previously attached map.
 * This voids the dma operations (dma_map_ops pointer)
 */
void arm_iommu_detach_device(struct device *dev)
{
	struct dma_iommu_mapping *mapping;

@@ -2324,22 +2331,10 @@ static void __arm_iommu_detach_device(struct device *dev)
	iommu_detach_device(mapping->domain, dev);
	kref_put(&mapping->kref, release_iommu_mapping);
	to_dma_iommu_mapping(dev) = NULL;
	set_dma_ops(dev, NULL);

	pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev));
}

/**
 * arm_iommu_detach_device
 * @dev: valid struct device pointer
 *
 * Detaches the provided device from a previously attached map.
 * This voids the dma operations (dma_map_ops pointer)
 */
void arm_iommu_detach_device(struct device *dev)
{
	__arm_iommu_detach_device(dev);
	set_dma_ops(dev, NULL);
}
EXPORT_SYMBOL_GPL(arm_iommu_detach_device);

static const struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
@@ -2379,7 +2374,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
	if (!mapping)
		return;

	__arm_iommu_detach_device(dev);
	arm_iommu_detach_device(dev);
	arm_iommu_release_mapping(mapping);
}

@@ -2430,9 +2425,13 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
		dev->dma_ops = xen_dma_ops;
	}
#endif
	dev->archdata.dma_ops_setup = true;
}

void arch_teardown_dma_ops(struct device *dev)
{
	if (!dev->archdata.dma_ops_setup)
		return;

	arm_teardown_iommu_dma_ops(dev);
}
+14 −8
Original line number Diff line number Diff line
@@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
	int ret = -ENODEV;
	struct fwnode_handle *iort_fwnode;

	/*
	 * If we already translated the fwspec there
	 * is nothing left to do, return the iommu_ops.
	 */
	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
	if (ops)
		return ops;

	if (node) {
		iort_fwnode = iort_get_fwnode(node);
		if (!iort_fwnode)
@@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
	u32 streamid = 0;
	int err;

	/*
	 * If we already translated the fwspec there
	 * is nothing left to do, return the iommu_ops.
	 */
	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
	if (ops)
		return ops;

	if (dev_is_pci(dev)) {
		struct pci_bus *bus = to_pci_dev(dev)->bus;
		u32 rid;
@@ -782,6 +782,12 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
	if (err)
		ops = ERR_PTR(err);

	/* Ignore all other errors apart from EPROBE_DEFER */
	if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
		dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
		ops = NULL;
	}

	return ops;
}

+2 −2
Original line number Diff line number Diff line
@@ -1371,8 +1371,8 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
	iort_set_dma_mask(dev);

	iommu = iort_iommu_configure(dev);
	if (IS_ERR(iommu))
		return PTR_ERR(iommu);
	if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
		return -EPROBE_DEFER;

	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
	/*
+7 −0
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ static const struct iommu_ops

	ops = iommu_ops_from_fwnode(fwnode);
	if ((ops && !ops->of_xlate) ||
	    !of_device_is_available(iommu_spec->np) ||
	    (!ops && !of_iommu_driver_present(iommu_spec->np)))
		return NULL;

@@ -236,6 +237,12 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
			ops = ERR_PTR(err);
	}

	/* Ignore all other errors apart from EPROBE_DEFER */
	if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
		dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
		ops = NULL;
	}

	return ops;
}

Loading