summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/nvmap/nvmap.c
diff options
context:
space:
mode:
authorvdumpa <vdumpa@nvidia.com>2011-05-15 19:31:15 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:45:04 -0800
commit546fb49a3cf459dc5de4c015987390ed221412eb (patch)
tree3982b86ca987b201fe9fb22c7fbab759024387f6 /drivers/video/tegra/nvmap/nvmap.c
parent91985ba2716065d11974e6140b1febf4f93f0f55 (diff)
video: tegra: nvmap: Add support to allocate specific IOVM
Original-Change-Id: I95cdf71e74947d4394e0cfd272a29c47562d4059 Reviewed-on: http://git-master/r/31648 Reviewed-by: Niket Sirsi <nsirsi@nvidia.com> Tested-by: Niket Sirsi <nsirsi@nvidia.com> Rebase-Id: Rb8c6f92bdfd0bf124a878800a793828fa61c0043
Diffstat (limited to 'drivers/video/tegra/nvmap/nvmap.c')
-rw-r--r--drivers/video/tegra/nvmap/nvmap.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/video/tegra/nvmap/nvmap.c b/drivers/video/tegra/nvmap/nvmap.c
index 09627145ec82..06ce0767e3ee 100644
--- a/drivers/video/tegra/nvmap/nvmap.c
+++ b/drivers/video/tegra/nvmap/nvmap.c
@@ -725,6 +725,53 @@ struct nvmap_handle_ref *nvmap_alloc(struct nvmap_client *client, size_t size,
return r;
}
+/* allocates memory with specifed iovm_start address. */
+struct nvmap_handle_ref *nvmap_alloc_iovm(struct nvmap_client *client,
+ size_t size, size_t align, unsigned int flags, unsigned int iovm_start)
+{
+ int err;
+ struct nvmap_handle *h;
+ struct nvmap_handle_ref *r;
+ const unsigned int default_heap = NVMAP_HEAP_IOVMM;
+
+ /* size need to be more than one page.
+ * otherwise heap preference would change to system heap.
+ */
+ if (size <= PAGE_SIZE)
+ size = PAGE_SIZE << 1;
+ r = nvmap_create_handle(client, size);
+ if (IS_ERR_OR_NULL(r))
+ return r;
+
+ h = r->handle;
+ h->pgalloc.iovm_addr = iovm_start;
+ err = nvmap_alloc_handle_id(client, nvmap_ref_to_id(r),
+ default_heap, align, flags);
+ if (err)
+ goto fail;
+
+ err = mutex_lock_interruptible(&client->share->pin_lock);
+ if (WARN_ON(err))
+ goto fail;
+ err = pin_locked(client, h);
+ mutex_unlock(&client->share->pin_lock);
+ if (err)
+ goto fail;
+ return r;
+
+fail:
+ nvmap_free_handle_id(client, nvmap_ref_to_id(r));
+ return ERR_PTR(err);
+}
+
+void nvmap_free_iovm(struct nvmap_client *client, struct nvmap_handle_ref *r)
+{
+ unsigned long ref_id = nvmap_ref_to_id(r);
+
+ nvmap_unpin_ids(client, 1, &ref_id);
+ nvmap_free_handle_id(client, ref_id);
+}
+
void nvmap_free(struct nvmap_client *client, struct nvmap_handle_ref *r)
{
nvmap_free_handle_id(client, nvmap_ref_to_id(r));