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

Commit 0980131b authored by Patrick Daly's avatar Patrick Daly
Browse files

iommu: arm-smmu: Disable default DMA Domain support



The current upstream arm-smmu implementation supports a 'stub' default DMA
domain. This domain is automatically attached at bootup, but has no context
bank or stream-ids. A device may choose to attach a different domain with
other context bank/stream-id settings. When the device detaches from this
domain, the 'default domain' is again attached automatically. This behavior
conflicts with several qcom-added features.

Dynamic domains:

When a dynamic domain is detached, the stream-ids of the dynamic domain
must not be removed.

Power:

Qcom uses the attach_dev() and detach_dev() callbacks as a signal that
power to the iommu can be removed. But with a default domain, the iommu is
always attached.

Change-Id: I84ec42667b986e5abfdbb0b5b7956a38532cabaa
Signed-off-by: default avatarPatrick Daly <pdaly@codeaurora.org>
parent c190d93b
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -1313,7 +1313,8 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
{
	struct arm_smmu_domain *smmu_domain;

	if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
	/* Do not support DOMAIN_DMA for now */
	if (type != IOMMU_DOMAIN_UNMANAGED)
		return NULL;
	/*
	 * Allocate the domain and initialise some of its data structures.
@@ -1483,11 +1484,25 @@ static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain,
	arm_smmu_master_free_smrs(smmu, cfg);
}

static void arm_smmu_detach_dev(struct device *dev,
				struct arm_smmu_master_cfg *cfg)
static void arm_smmu_detach_dev(struct iommu_domain *domain,
				struct device *dev)
{
	struct iommu_domain *domain = dev->archdata.iommu;
	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
	struct arm_smmu_device *smmu = smmu_domain->smmu;
	struct arm_smmu_master_cfg *cfg;
	int dynamic = smmu_domain->attributes & (1 << DOMAIN_ATTR_DYNAMIC);

	if (dynamic)
		return;

	cfg = find_smmu_master_cfg(dev);
	if (!cfg)
		return;

	if (!smmu) {
		dev_err(dev, "Domain not attached; cannot detach!\n");
		return;
	}

	dev->archdata.iommu = NULL;
	arm_smmu_domain_remove_master(smmu_domain, cfg);
@@ -1533,7 +1548,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)

	/* Detach the dev from its current domain */
	if (dev->archdata.iommu)
		arm_smmu_detach_dev(dev, cfg);
		arm_smmu_detach_dev(dev->archdata.iommu, dev);

	ret = arm_smmu_domain_add_master(smmu_domain, cfg);
	if (!ret)
@@ -1939,6 +1954,7 @@ static struct iommu_ops arm_smmu_ops = {
	.domain_alloc		= arm_smmu_domain_alloc,
	.domain_free		= arm_smmu_domain_free,
	.attach_dev		= arm_smmu_attach_dev,
	.detach_dev		= arm_smmu_detach_dev,
	.map			= arm_smmu_map,
	.unmap			= arm_smmu_unmap,
	.map_sg			= default_iommu_map_sg,