Commit 8565915e authored by Jason Gunthorpe's avatar Jason Gunthorpe Committed by Joerg Roedel
Browse files

iommu/fsl_pamu: Implement a PLATFORM domain



This driver is nonsensical. To not block migrating the core API away from
NULL default_domains give it a hacky of a PLATFORM domain that keeps it
working exactly as it always did.

Leave some comments around to warn away any future people looking at this.

Reviewed-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: default avatarJerry Snitselaar <jsnitsel@redhat.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/5-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com


Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent e04c7487
Loading
Loading
Loading
Loading
+38 −3
Original line number Diff line number Diff line
@@ -196,6 +196,13 @@ static struct iommu_domain *fsl_pamu_domain_alloc(unsigned type)
{
	struct fsl_dma_domain *dma_domain;

	/*
	 * FIXME: This isn't creating an unmanaged domain since the
	 * default_domain_ops do not have any map/unmap function it doesn't meet
	 * the requirements for __IOMMU_DOMAIN_PAGING. The only purpose seems to
	 * allow drivers/soc/fsl/qbman/qman_portal.c to do
	 * fsl_pamu_configure_l1_stash()
	 */
	if (type != IOMMU_DOMAIN_UNMANAGED)
		return NULL;

@@ -283,15 +290,33 @@ static int fsl_pamu_attach_device(struct iommu_domain *domain,
	return ret;
}

static void fsl_pamu_set_platform_dma(struct device *dev)
/*
 * FIXME: fsl/pamu is completely broken in terms of how it works with the iommu
 * API. Immediately after probe the HW is left in an IDENTITY translation and
 * the driver provides a non-working UNMANAGED domain that it can switch over
 * to. However it cannot switch back to an IDENTITY translation, instead it
 * switches to what looks like BLOCKING.
 */
static int fsl_pamu_platform_attach(struct iommu_domain *platform_domain,
				    struct device *dev)
{
	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
	struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
	struct fsl_dma_domain *dma_domain;
	const u32 *prop;
	int len;
	struct pci_dev *pdev = NULL;
	struct pci_controller *pci_ctl;

	/*
	 * Hack to keep things working as they always have, only leaving an
	 * UNMANAGED domain makes it BLOCKING.
	 */
	if (domain == platform_domain || !domain ||
	    domain->type != IOMMU_DOMAIN_UNMANAGED)
		return 0;

	dma_domain = to_fsl_dma_domain(domain);

	/*
	 * Use LIODN of the PCI controller while detaching a
	 * PCI device.
@@ -312,8 +337,18 @@ static void fsl_pamu_set_platform_dma(struct device *dev)
		detach_device(dev, dma_domain);
	else
		pr_debug("missing fsl,liodn property at %pOF\n", dev->of_node);
	return 0;
}

static struct iommu_domain_ops fsl_pamu_platform_ops = {
	.attach_dev = fsl_pamu_platform_attach,
};

static struct iommu_domain fsl_pamu_platform_domain = {
	.type = IOMMU_DOMAIN_PLATFORM,
	.ops = &fsl_pamu_platform_ops,
};

/* Set the domain stash attribute */
int fsl_pamu_configure_l1_stash(struct iommu_domain *domain, u32 cpu)
{
@@ -395,11 +430,11 @@ static struct iommu_device *fsl_pamu_probe_device(struct device *dev)
}

static const struct iommu_ops fsl_pamu_ops = {
	.default_domain = &fsl_pamu_platform_domain,
	.capable	= fsl_pamu_capable,
	.domain_alloc	= fsl_pamu_domain_alloc,
	.probe_device	= fsl_pamu_probe_device,
	.device_group   = fsl_pamu_device_group,
	.set_platform_dma_ops = fsl_pamu_set_platform_dma,
	.default_domain_ops = &(const struct iommu_domain_ops) {
		.attach_dev	= fsl_pamu_attach_device,
		.iova_to_phys	= fsl_pamu_iova_to_phys,