etnaviv: add API to create etna_device from private dup() fd

Like etna_device_new() but creates it's own private dup() of the fd
which is close()d when the device is finalized.

Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Acked-by: Eric Anholt <eric@anholt.net>
diff --git a/etnaviv/etnaviv-symbol-check b/etnaviv/etnaviv-symbol-check
index 378e073..72f2bc5 100755
--- a/etnaviv/etnaviv-symbol-check
+++ b/etnaviv/etnaviv-symbol-check
@@ -11,6 +11,7 @@
 _fini
 _init
 etna_device_new
+etna_device_new_dup
 etna_device_ref
 etna_device_del
 etna_device_fd
diff --git a/etnaviv/etnaviv_device.c b/etnaviv/etnaviv_device.c
index b716360..3ce9203 100644
--- a/etnaviv/etnaviv_device.c
+++ b/etnaviv/etnaviv_device.c
@@ -61,6 +61,21 @@
 	return dev;
 }
 
+/* like etna_device_new() but creates it's own private dup() of the fd
+ * which is close()d when the device is finalized. */
+struct etna_device *etna_device_new_dup(int fd)
+{
+	int dup_fd = dup(fd);
+	struct etna_device *dev = etna_device_new(dup_fd);
+
+	if (dev)
+		dev->closefd = 1;
+	else
+		close(dup_fd);
+
+	return dev;
+}
+
 struct etna_device *etna_device_ref(struct etna_device *dev)
 {
 	atomic_inc(&dev->refcnt);
@@ -74,6 +89,9 @@
 	drmHashDestroy(dev->handle_table);
 	drmHashDestroy(dev->name_table);
 
+	if (dev->closefd)
+		close(dev->fd);
+
 	free(dev);
 }
 
diff --git a/etnaviv/etnaviv_drmif.h b/etnaviv/etnaviv_drmif.h
index 3a5cb51..fe9d5db 100644
--- a/etnaviv/etnaviv_drmif.h
+++ b/etnaviv/etnaviv_drmif.h
@@ -84,6 +84,7 @@
  */
 
 struct etna_device *etna_device_new(int fd);
+struct etna_device *etna_device_new_dup(int fd);
 struct etna_device *etna_device_ref(struct etna_device *dev);
 void etna_device_del(struct etna_device *dev);
 int etna_device_fd(struct etna_device *dev);
diff --git a/etnaviv/etnaviv_priv.h b/etnaviv/etnaviv_priv.h
index 6bb0c8d..eb62ed3 100644
--- a/etnaviv/etnaviv_priv.h
+++ b/etnaviv/etnaviv_priv.h
@@ -93,6 +93,8 @@
 	void *handle_table, *name_table;
 
 	struct etna_bo_cache bo_cache;
+
+	int closefd;        /* call close(fd) upon destruction */
 };
 
 drm_private void etna_bo_cache_init(struct etna_bo_cache *cache);