Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5264159d authored by Nikhilesh Reddy's avatar Nikhilesh Reddy
Browse files

uio: msm_sharedmem: Add custom mmap



Uio's default mmap for physical memory uses
pgprot_noncached which is strongly ordered.

Using pgprot_writecombine would allow for
unalligned access.

Add a custom mmap function when registering uio
to allow unalligned access to the mmaped
region.

Change-Id: If314eade4913bafd53d2b4abc6b205385e29dfd3
Signed-off-by: default avatarNikhilesh Reddy <reddyn@codeaurora.org>
parent dbd2b72e
Loading
Loading
Loading
Loading
+52 −4
Original line number Diff line number Diff line
@@ -23,6 +23,53 @@

#define CLIENT_ID_PROP "qcom,client-id"

static int uio_get_mem_index(struct uio_info *info, struct vm_area_struct *vma)
{
	if (vma->vm_pgoff >= MAX_UIO_MAPS)
		return -EINVAL;

	if (info->mem[vma->vm_pgoff].size == 0)
		return -EINVAL;

	return (int)vma->vm_pgoff;
}

static int sharedmem_mmap(struct uio_info *info, struct vm_area_struct *vma)
{
	int result;
	struct uio_mem *mem;
	int mem_index = uio_get_mem_index(info, vma);

	if (mem_index < 0) {
		pr_err("mem_index is invalid errno %d\n", mem_index);
		return mem_index;
	}

	mem = info->mem + mem_index;

	if (vma->vm_end - vma->vm_start > mem->size) {
		pr_err("vm_end[%lu] - vm_start[%lu] [%lu] > mem->size[%lu]\n",
			vma->vm_end, vma->vm_start,
			(vma->vm_end - vma->vm_start), mem->size);
		return -EINVAL;
	}
	pr_debug("Attempting to setup mmap.\n");

	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);

	result = remap_pfn_range(vma,
				 vma->vm_start,
				 mem->addr >> PAGE_SHIFT,
				 vma->vm_end - vma->vm_start,
				 vma->vm_page_prot);
	if (result != 0)
		pr_err("mmap Failed with errno %d\n", result);
	else
		pr_debug("mmap success\n");

	return result;
}

static int msm_sharedmem_probe(struct platform_device *pdev)
{
	int ret = 0;
@@ -62,7 +109,7 @@ static int msm_sharedmem_probe(struct platform_device *pdev)
	shared_mem_pyhsical = clnt_res->start;

	if (shared_mem_size == 0) {
		pr_err("Shared memory size is zero");
		pr_err("Shared memory size is zero\n");
		return -EINVAL;
	}

@@ -78,6 +125,7 @@ static int msm_sharedmem_probe(struct platform_device *pdev)
	}

	/* Setup device */
	info->mmap = sharedmem_mmap; /* Custom mmap function. */
	info->name = clnt_res->name;
	info->version = "1.0";
	info->mem[0].addr = shared_mem_pyhsical;
@@ -86,7 +134,7 @@ static int msm_sharedmem_probe(struct platform_device *pdev)

	ret = uio_register_device(&pdev->dev, info);
	if (ret) {
		pr_err("uio register failed ret=%d", ret);
		pr_err("uio register failed ret=%d\n", ret);
		goto out;
	}
	dev_set_drvdata(&pdev->dev, info);
@@ -134,13 +182,13 @@ static int __init msm_sharedmem_init(void)
	int result;
	result = sharedmem_qmi_init();
	if (result < 0) {
		pr_err("sharedmem_qmi_init failed result = %d", result);
		pr_err("sharedmem_qmi_init failed result = %d\n", result);
		return result;
	}

	result = platform_driver_register(&msm_sharedmem_driver);
	if (result != 0) {
		pr_err("Platform driver registration failed");
		pr_err("Platform driver registration failed\n");
		return result;
	}
	return 0;
+8 −8
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ static int get_buffer_for_client(u32 id, u32 size, u64 *address)
				list_entry->entry.request_count++;
				result = 0;
			} else {
				pr_err("Shared mem req too large for id=%u",
				pr_err("Shared mem req too large for id=%u\n",
					id);
				result = -ENOMEM;
			}
@@ -129,7 +129,7 @@ static int get_buffer_for_client(u32 id, u32 size, u64 *address)
	up_read(&sharedmem_list_lock);

	if (client_found != 1) {
		pr_err("Unknown client id %u", id);
		pr_err("Unknown client id %u\n", id);
		result = -ENOENT;
	}
	return result;
@@ -152,7 +152,7 @@ static int sharedmem_qmi_get_buffer(void *conn_h, void *req_handle, void *req)
		return result;

	if (address == 0) {
		pr_err("Entry found for client id = 0x%X but address is zero",
		pr_err("Entry found for client id= 0x%X but address is zero\n",
			get_buffer_req->client_id);
		return -ENOMEM;
	}
@@ -323,25 +323,25 @@ static void debugfs_init(void)

	dir_ent = debugfs_create_dir("rmt_storage", NULL);
	if (IS_ERR(dir_ent)) {
		pr_err("Failed to create debug_fs directory");
		pr_err("Failed to create debug_fs directory\n");
		return;
	}

	f_ent = debugfs_create_file("info", 0400, dir_ent, NULL, &debug_ops);
	if (IS_ERR(f_ent)) {
		pr_err("Failed to create debug_fs info file");
		pr_err("Failed to create debug_fs info file\n");
		return;
	}

	f_ent = debugfs_create_file("rfsa", 0200, dir_ent, NULL, &rfsa_fops);
	if (IS_ERR(f_ent)) {
		pr_err("Failed to create debug_fs rfsa file");
		pr_err("Failed to create debug_fs rfsa file\n");
		return;
	}

	f_ent = debugfs_create_file("rmts", 0200, dir_ent, NULL, &rmts_fops);
	if (IS_ERR(f_ent)) {
		pr_err("Failed to create debug_fs rmts file");
		pr_err("Failed to create debug_fs rmts file\n");
		return;
	}
}
@@ -356,7 +356,7 @@ static void sharedmem_qmi_svc_recv_msg(struct work_struct *work)
	int rc;

	do {
		pr_debug("%s: Notified about a Receive Event", __func__);
		pr_debug("Notified about a Receive Event\n");
	} while ((rc = qmi_recv_msg(sharedmem_qmi_svc_handle)) == 0);

	if (rc != -ENOMSG)