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

Commit 5f4d6ef9 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: move SMMU devices as separate devices"

parents 564f198f b4006c3c
Loading
Loading
Loading
Loading
+91 −19
Original line number Diff line number Diff line
@@ -31,10 +31,12 @@

struct msm_smmu_client {
	struct device *dev;
	const char *compat;
	struct iommu_domain *domain;
	const struct dma_map_ops *dma_ops;
	bool domain_attached;
	bool secure;
	struct list_head smmu_list;
};

struct msm_smmu {
@@ -51,6 +53,12 @@ struct msm_smmu_domain {
#define to_msm_smmu(x) container_of(x, struct msm_smmu, base)
#define msm_smmu_to_client(smmu) (smmu->client)

/* Serialization lock for smmu_list */
static DEFINE_MUTEX(smmu_list_lock);

/* List of all smmu devices installed */
static LIST_HEAD(sde_smmu_list);

static int msm_smmu_attach(struct msm_mmu *mmu, const char * const *names,
		int cnt)
{
@@ -335,12 +343,36 @@ static const struct of_device_id msm_smmu_dt_match[] = {
};
MODULE_DEVICE_TABLE(of, msm_smmu_dt_match);

static struct device *msm_smmu_device_create(struct device *dev,
static struct msm_smmu_client *msm_smmu_get_smmu(const char *compat)
{
	struct msm_smmu_client *curr = NULL;
	bool found = false;

	if (!compat) {
		pr_err("invalid param\n");
		return ERR_PTR(-EINVAL);
	}

	mutex_lock(&smmu_list_lock);
	list_for_each_entry(curr, &sde_smmu_list, smmu_list) {
		if (of_compat_cmp(compat, curr->compat, strlen(compat)) == 0) {
			DRM_DEBUG("found msm_smmu_client for %s\n", compat);
			found = true;
			break;
		}
	}
	mutex_unlock(&smmu_list_lock);

	if (!found)
		return ERR_PTR(-ENODEV);

	return curr;
}

static struct device *msm_smmu_device_add(struct device *dev,
		enum msm_mmu_domain_type domain,
		struct msm_smmu *smmu)
{
	struct device_node *child;
	struct platform_device *pdev;
	int i;
	const char *compat = NULL;

@@ -357,22 +389,14 @@ static struct device *msm_smmu_device_create(struct device *dev,
	}
	DRM_DEBUG("found domain %d compat: %s\n", domain, compat);

	child = of_find_compatible_node(dev->of_node, NULL, compat);
	if (!child) {
		DRM_DEBUG("unable to find compatible node for %s\n", compat);
		return ERR_PTR(-ENODEV);
	}

	pdev = of_platform_device_create(child, NULL, dev);
	if (!pdev) {
		DRM_ERROR("unable to create smmu platform dev for domain %d\n",
				domain);
	smmu->client = msm_smmu_get_smmu(compat);
	if (IS_ERR_OR_NULL(smmu->client)) {
		DRM_ERROR("unable to find domain %d compat: %s\n", domain,
				compat);
		return ERR_PTR(-ENODEV);
	}

	smmu->client = platform_get_drvdata(pdev);

	return &pdev->dev;
	return smmu->client->dev;
}

struct msm_mmu *msm_smmu_new(struct device *dev,
@@ -385,8 +409,8 @@ struct msm_mmu *msm_smmu_new(struct device *dev,
	if (!smmu)
		return ERR_PTR(-ENOMEM);

	client_dev = msm_smmu_device_create(dev, domain, smmu);
	if (IS_ERR(client_dev)) {
	client_dev = msm_smmu_device_add(dev, domain, smmu);
	if (IS_ERR_OR_NULL(client_dev)) {
		kfree(smmu);
		return (void *)client_dev ? : ERR_PTR(-ENODEV);
	}
@@ -423,6 +447,34 @@ static int msm_smmu_fault_handler(struct iommu_domain *domain,
	return rc;
}

/**
 * msm_smmu_bind - bind smmu device with controlling device
 * @dev:        Pointer to base of platform device
 * @master:     Pointer to container of drm device
 * @data:       Pointer to private data
 * Returns:     Zero on success
 */
static int msm_smmu_bind(struct device *dev, struct device *master, void *data)
{
	return 0;
}

/**
 * msm_smmu_unbind - unbind msm_smmu from controlling device
 * @dev:        Pointer to base of platform device
 * @master:     Pointer to container of drm device
 * @data:       Pointer to private data
 */
static void msm_smmu_unbind(struct device *dev,
		struct device *master, void *data)
{
}

static const struct component_ops msm_smmu_comp_ops = {
	.bind = msm_smmu_bind,
	.unbind = msm_smmu_unbind,
};

/**
 * msm_smmu_probe()
 * @pdev: platform device
@@ -437,6 +489,7 @@ static int msm_smmu_probe(struct platform_device *pdev)
	const struct of_device_id *match;
	struct msm_smmu_client *client;
	const struct msm_smmu_domain *domain;
	int ret;

	match = of_match_device(msm_smmu_dt_match, &pdev->dev);
	if (!match || !match->data) {
@@ -462,6 +515,7 @@ static int msm_smmu_probe(struct platform_device *pdev)
		dev_err(&pdev->dev, "iommu get domain for dev failed\n");
		return -EINVAL;
	}
	client->compat = match->compatible;
	client->secure = domain->secure;
	client->domain_attached = true;

@@ -479,16 +533,34 @@ static int msm_smmu_probe(struct platform_device *pdev)

	platform_set_drvdata(pdev, client);

	return 0;
	mutex_lock(&smmu_list_lock);
	list_add(&client->smmu_list, &sde_smmu_list);
	mutex_unlock(&smmu_list_lock);

	ret = component_add(&pdev->dev, &msm_smmu_comp_ops);
	if (ret)
		pr_err("component add failed\n");

	return ret;
}

static int msm_smmu_remove(struct platform_device *pdev)
{
	struct msm_smmu_client *client;
	struct msm_smmu_client *curr, *next;

	client = platform_get_drvdata(pdev);
	client->domain_attached = false;

	mutex_lock(&smmu_list_lock);
	list_for_each_entry_safe(curr, next, &sde_smmu_list, smmu_list) {
		if (curr == client) {
			list_del(&client->smmu_list);
			break;
		}
	}
	mutex_unlock(&smmu_list_lock);

	return 0;
}