Commit 342d3c1c authored by Will Deacon's avatar Will Deacon
Browse files

Merge branch 'iommu/fwspec-ops-removal' into iommu/next

* iommu/fwspec-ops-removal:
  iommu: Remove iommu_fwspec ops
  OF: Simplify of_iommu_configure()
  ACPI: Retire acpi_iommu_fwspec_ops()
  iommu: Resolve fwspec ops automatically
  iommu/mediatek-v1: Clean up redundant fwspec checks

[will: Fixed conflict in drivers/iommu/tegra-smmu.c between fwspec ops
 removal and fwspec driver fix as per Robin and Jon]
parents c2b2e5c5 3e36c15f
Loading
Loading
Loading
Loading
+5 −14
Original line number Diff line number Diff line
@@ -1221,10 +1221,10 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
			    u32 streamid)
{
	const struct iommu_ops *ops;
	struct fwnode_handle *iort_fwnode;

	if (!node)
	/* If there's no SMMU driver at all, give up now */
	if (!node || !iort_iommu_driver_enabled(node->type))
		return -ENODEV;

	iort_fwnode = iort_get_fwnode(node);
@@ -1232,19 +1232,10 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
		return -ENODEV;

	/*
	 * If the ops look-up fails, this means that either
	 * the SMMU drivers have not been probed yet or that
	 * the SMMU drivers are not built in the kernel;
	 * Depending on whether the SMMU drivers are built-in
	 * in the kernel or not, defer the IOMMU configuration
	 * or just abort it.
	 * If the SMMU drivers are enabled but not loaded/probed
	 * yet, this will defer.
	 */
	ops = iommu_ops_from_fwnode(iort_fwnode);
	if (!ops)
		return iort_iommu_driver_enabled(node->type) ?
		       -EPROBE_DEFER : -ENODEV;

	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
	return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode);
}

struct iort_pci_alias_info {
+8 −28
Original line number Diff line number Diff line
@@ -1577,38 +1577,25 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)

#ifdef CONFIG_IOMMU_API
int acpi_iommu_fwspec_init(struct device *dev, u32 id,
			   struct fwnode_handle *fwnode,
			   const struct iommu_ops *ops)
			   struct fwnode_handle *fwnode)
{
	int ret;

	ret = iommu_fwspec_init(dev, fwnode, ops);
	ret = iommu_fwspec_init(dev, fwnode);
	if (ret)
		return ret;

	return iommu_fwspec_add_ids(dev, &id, 1);
}

static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
{
	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);

	return fwspec ? fwspec->ops : NULL;
}

static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
{
	int err;
	const struct iommu_ops *ops;

	/* Serialise to make dev->iommu stable under our potential fwspec */
	mutex_lock(&iommu_probe_device_lock);
	/*
	 * If we already translated the fwspec there is nothing left to do,
	 * return the iommu_ops.
	 */
	ops = acpi_iommu_fwspec_ops(dev);
	if (ops) {
	/* If we already translated the fwspec there is nothing left to do */
	if (dev_iommu_fwspec_get(dev)) {
		mutex_unlock(&iommu_probe_device_lock);
		return 0;
	}
@@ -1625,22 +1612,13 @@ static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
	if (!err && dev->bus)
		err = iommu_probe_device(dev);

	if (err == -EPROBE_DEFER)
	return err;
	if (err) {
		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
		return err;
	}
	if (!acpi_iommu_fwspec_ops(dev))
		return -ENODEV;
	return 0;
}

#else /* !CONFIG_IOMMU_API */

int acpi_iommu_fwspec_init(struct device *dev, u32 id,
			   struct fwnode_handle *fwnode,
			   const struct iommu_ops *ops)
			   struct fwnode_handle *fwnode)
{
	return -ENODEV;
}
@@ -1674,6 +1652,8 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
	ret = acpi_iommu_configure_id(dev, input_id);
	if (ret == -EPROBE_DEFER)
		return -EPROBE_DEFER;
	if (ret)
		dev_dbg(dev, "Adding to IOMMU failed: %d\n", ret);

	arch_setup_dma_ops(dev, attr == DEV_DMA_COHERENT);

+2 −9
Original line number Diff line number Diff line
@@ -307,21 +307,14 @@ void __init acpi_viot_init(void)
static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
			       u32 epid)
{
	const struct iommu_ops *ops;

	if (!viommu)
	if (!viommu || !IS_ENABLED(CONFIG_VIRTIO_IOMMU))
		return -ENODEV;

	/* We're not translating ourself */
	if (device_match_fwnode(dev, viommu->fwnode))
		return -EINVAL;

	ops = iommu_ops_from_fwnode(viommu->fwnode);
	if (!ops)
		return IS_ENABLED(CONFIG_VIRTIO_IOMMU) ?
			-EPROBE_DEFER : -ENODEV;

	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops);
	return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode);
}

static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
+1 −2
Original line number Diff line number Diff line
@@ -178,8 +178,7 @@ static int arm_smmu_register_legacy_master(struct device *dev,
		it.cur_count = 1;
	}

	err = iommu_fwspec_init(dev, &smmu_dev->of_node->fwnode,
				&arm_smmu_ops);
	err = iommu_fwspec_init(dev, NULL);
	if (err)
		return err;

+7 −0
Original line number Diff line number Diff line
@@ -17,6 +17,13 @@ static inline const struct iommu_ops *dev_iommu_ops(struct device *dev)
	return dev->iommu->iommu_dev->ops;
}

const struct iommu_ops *iommu_ops_from_fwnode(const struct fwnode_handle *fwnode);

static inline const struct iommu_ops *iommu_fwspec_ops(struct iommu_fwspec *fwspec)
{
	return iommu_ops_from_fwnode(fwspec ? fwspec->iommu_fwnode : NULL);
}

int iommu_group_replace_domain(struct iommu_group *group,
			       struct iommu_domain *new_domain);

Loading