diff options
author | vdumpa <vdumpa@nvidia.com> | 2011-05-15 19:31:15 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:45:04 -0800 |
commit | 546fb49a3cf459dc5de4c015987390ed221412eb (patch) | |
tree | 3982b86ca987b201fe9fb22c7fbab759024387f6 /drivers/video/tegra/nvmap/nvmap.c | |
parent | 91985ba2716065d11974e6140b1febf4f93f0f55 (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.c | 47 |
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)); |