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

Commit 63c2ccb9 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "arm64: dma-mapping: Clean up arm_iommu_attach_device() call flow"

parents 58a2b3e6 121a9a11
Loading
Loading
Loading
Loading
+18 −24
Original line number Original line Diff line number Diff line
@@ -1979,26 +1979,18 @@ static int upstream_iommu_init_mapping(struct device *dev,
					struct dma_iommu_mapping *mapping)
					struct dma_iommu_mapping *mapping)
{
{
	struct iommu_domain *domain = mapping->domain;
	struct iommu_domain *domain = mapping->domain;
	struct iommu_group *group = dev->iommu_group;
	dma_addr_t base = mapping->base;
	dma_addr_t base = mapping->base;
	u64 size = mapping->bits << PAGE_SHIFT;
	u64 size = mapping->bits << PAGE_SHIFT;


	if (iommu_get_dma_cookie(domain))
	if (iommu_get_dma_cookie(domain))
		return -EINVAL;
		return -EINVAL;


	/* Need to attach to get geometry */
	if (iommu_attach_group(domain, group))
		goto out_put_cookie;

	if (iommu_dma_init_domain(domain, base, size, dev))
	if (iommu_dma_init_domain(domain, base, size, dev))
		goto out_detach_group;
		goto out_put_cookie;


	mapping->ops = &iommu_dma_ops;
	mapping->ops = &iommu_dma_ops;
	iommu_detach_group(domain, group);
	return 0;
	return 0;


out_detach_group:
	iommu_detach_group(domain, group);
out_put_cookie:
out_put_cookie:
	iommu_put_dma_cookie(domain);
	iommu_put_dma_cookie(domain);
	return -EINVAL;
	return -EINVAL;
@@ -2060,20 +2052,8 @@ static int arm_iommu_init_mapping(struct device *dev,
{
{
	int err = -EINVAL;
	int err = -EINVAL;
	int s1_bypass = 0, is_fast = 0, is_upstream = 0;
	int s1_bypass = 0, is_fast = 0, is_upstream = 0;
	struct iommu_group *group;
	dma_addr_t iova_end;
	dma_addr_t iova_end;


	group = dev->iommu_group;
	if (!group) {
		dev_err(dev, "No iommu associated with device\n");
		return -EINVAL;
	}

	if (iommu_get_domain_for_dev(dev)) {
		dev_err(dev, "Device already attached to other iommu_domain\n");
		return -EINVAL;
	}

	if (mapping->init) {
	if (mapping->init) {
		kref_get(&mapping->kref);
		kref_get(&mapping->kref);
		return 0;
		return 0;
@@ -2128,14 +2108,28 @@ int arm_iommu_attach_device(struct device *dev,
			    struct dma_iommu_mapping *mapping)
			    struct dma_iommu_mapping *mapping)
{
{
	int err;
	int err;
	struct iommu_domain *domain = mapping->domain;
	struct iommu_group *group = dev->iommu_group;


	err = arm_iommu_init_mapping(dev, mapping);
	if (!group) {
		dev_err(dev, "No iommu associated with device\n");
		return -EINVAL;
	}

	if (iommu_get_domain_for_dev(dev)) {
		dev_err(dev, "Device already attached to other iommu_domain\n");
		return -EINVAL;
	}

	err = iommu_attach_group(domain, group);
	if (err)
	if (err)
		return err;
		return err;


	err = iommu_attach_group(mapping->domain, dev->iommu_group);
	err = arm_iommu_init_mapping(dev, mapping);
	if (err)
	if (err) {
		iommu_detach_group(domain, group);
		return err;
		return err;
	}


	dev->archdata.mapping = mapping;
	dev->archdata.mapping = mapping;
	set_dma_ops(dev, mapping->ops);
	set_dma_ops(dev, mapping->ops);
+4 −29
Original line number Original line Diff line number Diff line
@@ -434,7 +434,8 @@ static int fast_smmu_map_sg(struct device *dev, struct scatterlist *sg,
			    int nents, enum dma_data_direction dir,
			    int nents, enum dma_data_direction dir,
			    unsigned long attrs)
			    unsigned long attrs)
{
{
	return -EINVAL;
	/* 0 indicates error */
	return 0;
}
}


static void fast_smmu_unmap_sg(struct device *dev,
static void fast_smmu_unmap_sg(struct device *dev,
@@ -869,7 +870,6 @@ int fast_smmu_init_mapping(struct device *dev,
{
{
	int err;
	int err;
	struct iommu_domain *domain = mapping->domain;
	struct iommu_domain *domain = mapping->domain;
	struct iommu_group *group;
	struct iommu_pgtbl_info info;
	struct iommu_pgtbl_info info;
	u64 size = (u64)mapping->bits << PAGE_SHIFT;
	u64 size = (u64)mapping->bits << PAGE_SHIFT;


@@ -886,51 +886,26 @@ int fast_smmu_init_mapping(struct device *dev,


	fast_smmu_reserve_pci_windows(dev, mapping->fast);
	fast_smmu_reserve_pci_windows(dev, mapping->fast);


	group = dev->iommu_group;
	if (!group) {
		dev_err(dev, "No iommu associated with device\n");
		err = -ENODEV;
		goto release_mapping;
	}

	if (iommu_get_domain_for_dev(dev)) {
		dev_err(dev, "Device already attached to other iommu_domain\n");
		err = -EINVAL;
		goto release_mapping;
	}

	/*
	 * Need to attach prior to calling DOMAIN_ATTR_PGTBL_INFO and then
	 * detach to be in the expected state. Its a bit messy.
	 */
	if (iommu_attach_group(mapping->domain, group)) {
		err = -EINVAL;
		goto release_mapping;
	}

	if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PGTBL_INFO,
	if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PGTBL_INFO,
				  &info)) {
				  &info)) {
		dev_err(dev, "Couldn't get page table info\n");
		dev_err(dev, "Couldn't get page table info\n");
		err = -EINVAL;
		err = -EINVAL;
		goto detach_group;
		goto release_mapping;
	}
	}
	mapping->fast->pgtbl_pmds = info.pmds;
	mapping->fast->pgtbl_pmds = info.pmds;


	if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT,
	if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT,
				  &mapping->fast->is_smmu_pt_coherent)) {
				  &mapping->fast->is_smmu_pt_coherent)) {
		err = -EINVAL;
		err = -EINVAL;
		goto detach_group;
		goto release_mapping;
	}
	}


	mapping->fast->notifier.notifier_call = fast_smmu_notify;
	mapping->fast->notifier.notifier_call = fast_smmu_notify;
	av8l_register_notify(&mapping->fast->notifier);
	av8l_register_notify(&mapping->fast->notifier);


	iommu_detach_group(mapping->domain, group);
	mapping->ops = &fast_smmu_dma_ops;
	mapping->ops = &fast_smmu_dma_ops;
	return 0;
	return 0;


detach_group:
	iommu_detach_group(mapping->domain, group);
release_mapping:
release_mapping:
	kfree(mapping->fast->bitmap);
	kfree(mapping->fast->bitmap);
	kfree(mapping->fast);
	kfree(mapping->fast);