[PATCH RFC 054/111] staging: etnaviv: move scatterlist creation to etnaviv_gem_get_pages()

Lucas Stach l.stach at pengutronix.de
Thu Apr 2 08:29:56 PDT 2015


From: Russell King <rmk+kernel at arm.linux.org.uk>

Move the scatterlist creation from etnaviv_gem_shmem_get_pages() into
etnaviv_gem_get_pages() as we always want a scatterlist internally for
the IOMMU code.  It makes little sense to have each get_pages() method
re-implement this code.

However, we still allow a get_pages() method to override this by doing
their own initialisation of the etnaviv_obj->sgt pointer.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/staging/etnaviv/etnaviv_gem.c | 47 +++++++++++++++++++++--------------
 1 file changed, 28 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/etnaviv/etnaviv_gem.c b/drivers/staging/etnaviv/etnaviv_gem.c
index ab7c6db4ec10..ad8fa71ea920 100644
--- a/drivers/staging/etnaviv/etnaviv_gem.c
+++ b/drivers/staging/etnaviv/etnaviv_gem.c
@@ -27,37 +27,21 @@
 static int etnaviv_gem_shmem_get_pages(struct etnaviv_gem_object *etnaviv_obj)
 {
 	struct drm_device *dev = etnaviv_obj->base.dev;
-	struct page **p;
-	int npages = etnaviv_obj->base.size >> PAGE_SHIFT;
+	struct page **p = drm_gem_get_pages(&etnaviv_obj->base);
 
-	p = drm_gem_get_pages(&etnaviv_obj->base);
 	if (IS_ERR(p)) {
 		dev_err(dev->dev, "could not get pages: %ld\n", PTR_ERR(p));
 		return PTR_ERR(p);
 	}
 
-	etnaviv_obj->sgt = drm_prime_pages_to_sg(p, npages);
-	if (IS_ERR(etnaviv_obj->sgt)) {
-		dev_err(dev->dev, "failed to allocate sgt\n");
-		drm_gem_put_pages(&etnaviv_obj->base, p, false, false);
-		return PTR_ERR(p);
-	}
-
 	etnaviv_obj->pages = p;
 
-	/* For non-cached buffers, ensure the new pages are clean
-	 * because display controller, GPU, etc. are not coherent:
-	 */
-	if (etnaviv_obj->flags & (ETNA_BO_WC|ETNA_BO_CACHED))
-		dma_map_sg(dev->dev, etnaviv_obj->sgt->sgl,
-			   etnaviv_obj->sgt->nents, DMA_BIDIRECTIONAL);
-
 	return 0;
 }
 
 static void put_pages(struct etnaviv_gem_object *etnaviv_obj)
 {
-	if (etnaviv_obj->pages) {
+	if (etnaviv_obj->sgt) {
 		struct drm_device *dev = etnaviv_obj->base.dev;
 
 		/*
@@ -81,7 +65,9 @@ static void put_pages(struct etnaviv_gem_object *etnaviv_obj)
 				     DMA_BIDIRECTIONAL);
 		sg_free_table(etnaviv_obj->sgt);
 		kfree(etnaviv_obj->sgt);
-
+		etnaviv_obj->sgt = NULL;
+	}
+	if (etnaviv_obj->pages) {
 		drm_gem_put_pages(&etnaviv_obj->base, etnaviv_obj->pages,
 				  true, false);
 
@@ -99,6 +85,29 @@ struct page **etnaviv_gem_get_pages(struct etnaviv_gem_object *etnaviv_obj)
 			return ERR_PTR(ret);
 	}
 
+	if (!etnaviv_obj->sgt) {
+		struct drm_device *dev = etnaviv_obj->base.dev;
+		int npages = etnaviv_obj->base.size >> PAGE_SHIFT;
+		struct sg_table *sgt;
+
+		sgt = drm_prime_pages_to_sg(etnaviv_obj->pages, npages);
+		if (IS_ERR(sgt)) {
+			dev_err(dev->dev, "failed to allocate sgt: %ld\n",
+				PTR_ERR(sgt));
+			return ERR_CAST(sgt);
+		}
+
+		etnaviv_obj->sgt = sgt;
+
+		/*
+		 * For non-cached buffers, ensure the new pages are clean
+		 * because display controller, GPU, etc. are not coherent.
+		 */
+		if (etnaviv_obj->flags & (ETNA_BO_WC|ETNA_BO_CACHED))
+			dma_map_sg(dev->dev, etnaviv_obj->sgt->sgl,
+				   etnaviv_obj->sgt->nents, DMA_BIDIRECTIONAL);
+	}
+
 	return etnaviv_obj->pages;
 }
 
-- 
2.1.4



More information about the dri-devel mailing list