All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Osipenko <digetx@gmail.com>
To: Thierry Reding <thierry.reding@gmail.com>
Cc: linux-tegra@vger.kernel.org, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 4/4] drm/tegra: Refactor IOMMU attach/detach
Date: Fri, 4 May 2018 17:23:42 +0300	[thread overview]
Message-ID: <60550738-6a93-ddc3-0376-fe9676b85c42@gmail.com> (raw)
In-Reply-To: <20180504133707.22451-4-thierry.reding@gmail.com>

On 04.05.2018 16:37, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
> 
> Attaching to and detaching from an IOMMU uses the same code sequence in
> every driver, so factor it out into separate helpers.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/gpu/drm/tegra/dc.c   | 42 ++++++------------------------------
>  drivers/gpu/drm/tegra/drm.c  | 42 ++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/tegra/drm.h  |  4 ++++
>  drivers/gpu/drm/tegra/gr2d.c | 32 +++++++--------------------
>  drivers/gpu/drm/tegra/gr3d.c | 31 ++++++--------------------
>  5 files changed, 68 insertions(+), 83 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
> index c843f11043db..3e7ec3937346 100644
> --- a/drivers/gpu/drm/tegra/dc.c
> +++ b/drivers/gpu/drm/tegra/dc.c
> @@ -1837,21 +1837,11 @@ static int tegra_dc_init(struct host1x_client *client)
>  	if (!dc->syncpt)
>  		dev_warn(dc->dev, "failed to allocate syncpoint\n");
>  
> -	if (tegra->domain) {
> -		dc->group = iommu_group_get(client->dev);
> -
> -		if (dc->group && dc->group != tegra->group) {
> -			err = iommu_attach_group(tegra->domain, dc->group);
> -			if (err < 0) {
> -				dev_err(dc->dev,
> -					"failed to attach to domain: %d\n",
> -					err);
> -				iommu_group_put(dc->group);
> -				return err;
> -			}
> -
> -			tegra->group = dc->group;
> -		}
> +	dc->group = host1x_client_iommu_attach(client, true);
> +	if (IS_ERR(dc->group)) {
> +		err = PTR_ERR(dc->group);
> +		dev_err(client->dev, "failed to attach to domain: %d\n", err);
> +		return err;
>  	}
>  
>  	if (dc->soc->wgrps)
> @@ -1916,15 +1906,7 @@ static int tegra_dc_init(struct host1x_client *client)
>  	if (!IS_ERR(primary))
>  		drm_plane_cleanup(primary);
>  
> -	if (dc->group) {
> -		if (dc->group == tegra->group) {
> -			iommu_detach_group(tegra->domain, dc->group);
> -			tegra->group = NULL;
> -		}
> -
> -		iommu_group_put(dc->group);
> -	}
> -
> +	host1x_client_iommu_detach(client, dc->group);
>  	host1x_syncpt_free(dc->syncpt);
>  
>  	return err;
> @@ -1932,9 +1914,7 @@ static int tegra_dc_init(struct host1x_client *client)
>  
>  static int tegra_dc_exit(struct host1x_client *client)
>  {
> -	struct drm_device *drm = dev_get_drvdata(client->parent);
>  	struct tegra_dc *dc = host1x_client_to_dc(client);
> -	struct tegra_drm *tegra = drm->dev_private;
>  	int err;
>  
>  	devm_free_irq(dc->dev, dc->irq, dc);
> @@ -1945,15 +1925,7 @@ static int tegra_dc_exit(struct host1x_client *client)
>  		return err;
>  	}
>  
> -	if (dc->group) {
> -		if (dc->group == tegra->group) {
> -			iommu_detach_group(tegra->domain, dc->group);
> -			tegra->group = NULL;
> -		}
> -
> -		iommu_group_put(dc->group);
> -	}
> -
> +	host1x_client_iommu_detach(client, dc->group);
>  	host1x_syncpt_free(dc->syncpt);
>  
>  	return 0;
> diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
> index 7afe2f635f74..bc1008305e1e 100644
> --- a/drivers/gpu/drm/tegra/drm.c
> +++ b/drivers/gpu/drm/tegra/drm.c
> @@ -1114,6 +1114,48 @@ int tegra_drm_unregister_client(struct tegra_drm *tegra,
>  	return 0;
>  }
>  
> +struct iommu_group *host1x_client_iommu_attach(struct host1x_client *client,
> +					       bool shared)
> +{
> +	struct drm_device *drm = dev_get_drvdata(client->parent);
> +	struct tegra_drm *tegra = drm->dev_private;
> +	struct iommu_group *group = NULL;
> +	int err;
> +
> +	if (tegra->domain) {
> +		group = iommu_group_get(client->dev);
> +
> +		if (group && (!shared || (shared && (group != tegra->group)))) {
> +			err = iommu_attach_group(tegra->domain, group);
> +			if (err < 0) {
> +				iommu_group_put(group);
> +				return ERR_PTR(err);
> +			}
> +
> +			if (shared && !tegra->group)
> +				tegra->group = group;
> +		}
> +	}
> +
> +	return group;
> +}
> +
> +void host1x_client_iommu_detach(struct host1x_client *client,
> +				struct iommu_group *group)
> +{
> +	struct drm_device *drm = dev_get_drvdata(client->parent);
> +	struct tegra_drm *tegra = drm->dev_private;
> +
> +	if (group) {
> +		if (group == tegra->group) {
> +			iommu_detach_group(tegra->domain, group);
> +			tegra->group = NULL;
> +		}
> +
> +		iommu_group_put(group);
> +	}
> +}
> +
>  void *tegra_drm_alloc(struct tegra_drm *tegra, size_t size, dma_addr_t *dma)
>  {
>  	struct iova *alloc;
> diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
> index 4f41aaec8530..fe263cf58f34 100644
> --- a/drivers/gpu/drm/tegra/drm.h
> +++ b/drivers/gpu/drm/tegra/drm.h
> @@ -110,6 +110,10 @@ int tegra_drm_register_client(struct tegra_drm *tegra,
>  			      struct tegra_drm_client *client);
>  int tegra_drm_unregister_client(struct tegra_drm *tegra,
>  				struct tegra_drm_client *client);
> +struct iommu_group *host1x_client_iommu_attach(struct host1x_client *client,
> +					       bool shared);
> +void host1x_client_iommu_detach(struct host1x_client *client,
> +				struct iommu_group *group);
>  
>  int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm);
>  int tegra_drm_exit(struct tegra_drm *tegra);
> diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
> index 0b42e99da8ad..2cd0f66c8aa9 100644
> --- a/drivers/gpu/drm/tegra/gr2d.c
> +++ b/drivers/gpu/drm/tegra/gr2d.c
> @@ -32,7 +32,6 @@ static int gr2d_init(struct host1x_client *client)
>  	struct tegra_drm_client *drm = host1x_to_drm_client(client);
>  	struct drm_device *dev = dev_get_drvdata(client->parent);
>  	unsigned long flags = HOST1X_SYNCPT_HAS_BASE;
> -	struct tegra_drm *tegra = dev->dev_private;
>  	struct gr2d *gr2d = to_gr2d(drm);
>  	int err;
>  
> @@ -47,22 +46,14 @@ static int gr2d_init(struct host1x_client *client)
>  		goto put;
>  	}
>  
> -	if (tegra->domain) {
> -		gr2d->group = iommu_group_get(client->dev);
> -
> -		if (gr2d->group) {
> -			err = iommu_attach_group(tegra->domain, gr2d->group);
> -			if (err < 0) {
> -				dev_err(client->dev,
> -					"failed to attach to domain: %d\n",
> -					err);
> -				iommu_group_put(gr2d->group);
> -				goto free;
> -			}
> -		}
> +	gr2d->group = host1x_client_iommu_attach(client, false);
> +	if (IS_ERR(gr2d->group)) {
> +		err = PTR_ERR(gr2d->group);
> +		dev_err(client->dev, "failed to attach to domain: %d\n", err);
> +		goto free;
>  	}
>  
> -	err = tegra_drm_register_client(tegra, drm);
> +	err = tegra_drm_register_client(dev->dev_private, drm);
>  	if (err < 0) {
>  		dev_err(client->dev, "failed to register client: %d\n", err);
>  		goto detach;
> @@ -71,10 +62,7 @@ static int gr2d_init(struct host1x_client *client)
>  	return 0;
>  
>  detach:
> -	if (gr2d->group) {
> -		iommu_detach_group(tegra->domain, gr2d->group);
> -		iommu_group_put(gr2d->group);
> -	}
> +	host1x_client_iommu_detach(client, gr2d->group);
>  free:
>  	host1x_syncpt_free(client->syncpts[0]);
>  put:
> @@ -94,14 +82,10 @@ static int gr2d_exit(struct host1x_client *client)
>  	if (err < 0)
>  		return err;
>  
> +	host1x_client_iommu_detach(client, gr2d->group);
>  	host1x_syncpt_free(client->syncpts[0]);
>  	host1x_channel_put(gr2d->channel);
>  
> -	if (gr2d->group) {
> -		iommu_detach_group(tegra->domain, gr2d->group);
> -		iommu_group_put(gr2d->group);
> -	}
> -
>  	return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c
> index e129f1afff33..98e3c67d0fb5 100644
> --- a/drivers/gpu/drm/tegra/gr3d.c
> +++ b/drivers/gpu/drm/tegra/gr3d.c
> @@ -42,7 +42,6 @@ static int gr3d_init(struct host1x_client *client)
>  	struct tegra_drm_client *drm = host1x_to_drm_client(client);
>  	struct drm_device *dev = dev_get_drvdata(client->parent);
>  	unsigned long flags = HOST1X_SYNCPT_HAS_BASE;
> -	struct tegra_drm *tegra = dev->dev_private;
>  	struct gr3d *gr3d = to_gr3d(drm);
>  	int err;
>  
> @@ -56,19 +55,11 @@ static int gr3d_init(struct host1x_client *client)
>  		goto put;
>  	}
>  
> -	if (tegra->domain) {
> -		gr3d->group = iommu_group_get(client->dev);
> -
> -		if (gr3d->group) {
> -			err = iommu_attach_group(tegra->domain, gr3d->group);
> -			if (err < 0) {
> -				dev_err(client->dev,
> -					"failed to attach to domain: %d\n",
> -					err);
> -				iommu_group_put(gr3d->group);
> -				goto free;
> -			}
> -		}
> +	gr3d->group = host1x_client_iommu_attach(client, false);
> +	if (IS_ERR(gr3d->group)) {
> +		err = PTR_ERR(gr3d->group);
> +		dev_err(client->dev, "failed to attach to domain: %d\n", err);
> +		goto free;
>  	}
>  
>  	err = tegra_drm_register_client(dev->dev_private, drm);
> @@ -80,10 +71,7 @@ static int gr3d_init(struct host1x_client *client)
>  	return 0;
>  
>  detach:
> -	if (gr3d->group) {
> -		iommu_detach_group(tegra->domain, gr3d->group);
> -		iommu_group_put(gr3d->group);
> -	}
> +	host1x_client_iommu_detach(client, gr3d->group);
>  free:
>  	host1x_syncpt_free(client->syncpts[0]);
>  put:
> @@ -95,7 +83,6 @@ static int gr3d_exit(struct host1x_client *client)
>  {
>  	struct tegra_drm_client *drm = host1x_to_drm_client(client);
>  	struct drm_device *dev = dev_get_drvdata(client->parent);
> -	struct tegra_drm *tegra = dev->dev_private;
>  	struct gr3d *gr3d = to_gr3d(drm);
>  	int err;
>  
> @@ -103,14 +90,10 @@ static int gr3d_exit(struct host1x_client *client)
>  	if (err < 0)
>  		return err;
>  
> +	host1x_client_iommu_detach(client, gr3d->group);
>  	host1x_syncpt_free(client->syncpts[0]);
>  	host1x_channel_put(gr3d->channel);
>  
> -	if (gr3d->group) {
> -		iommu_detach_group(tegra->domain, gr3d->group);
> -		iommu_group_put(gr3d->group);
> -	}
> -
>  	return 0;
>  }
>  
> 

Reviewed-by: Dmitry Osipenko <digetx@gmail.com>

Though I'd prefer to have tegra->group renamed, maybe to 'shared_dc_group'.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2018-05-04 14:23 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-04 13:37 [PATCH 1/4] drm/tegra: dc: Free syncpoint on errors Thierry Reding
2018-05-04 13:37 ` [PATCH 2/4] drm/tegra: gr2d: Properly clean up resources Thierry Reding
2018-05-04 14:16   ` Dmitry Osipenko
2018-05-07 20:57   ` Dmitry Osipenko
2018-05-04 13:37 ` [PATCH 3/4] drm/tegra: gr3d: " Thierry Reding
2018-05-04 14:16   ` Dmitry Osipenko
2018-05-04 13:37 ` [PATCH 4/4] drm/tegra: Refactor IOMMU attach/detach Thierry Reding
2018-05-04 14:23   ` Dmitry Osipenko [this message]
2018-05-04 15:10     ` Thierry Reding
2018-05-04 15:17       ` Dmitry Osipenko
2018-05-04 15:25         ` Thierry Reding
2018-05-10 23:42   ` Dmitry Osipenko
2018-05-04 14:14 ` [PATCH 1/4] drm/tegra: dc: Free syncpoint on errors Dmitry Osipenko
2018-05-04 15:16 ` Thierry Reding

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=60550738-6a93-ddc3-0376-fe9676b85c42@gmail.com \
    --to=digetx@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=thierry.reding@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.