mirror of https://github.com/OpenIPC/firmware.git
170 lines
3.8 KiB
Diff
170 lines
3.8 KiB
Diff
diff -drupN a/drivers/misc/rmem.c b/drivers/misc/rmem.c
|
|
--- a/drivers/misc/rmem.c 1970-01-01 03:00:00.000000000 +0300
|
|
+++ b/drivers/misc/rmem.c 2022-06-09 05:02:30.000000000 +0300
|
|
@@ -0,0 +1,165 @@
|
|
+/*
|
|
+ * rmem.c - Reserved memory driver for libimp.
|
|
+ *
|
|
+ * Copyright (C) 2012 Ingenic Semiconductor Co., Ltd.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License version 2 as
|
|
+ * published by the Free Software Foundation.
|
|
+ */
|
|
+
|
|
+#include <linux/errno.h>
|
|
+#include <linux/slab.h>
|
|
+#include <linux/delay.h>
|
|
+#include <linux/miscdevice.h>
|
|
+#include <linux/platform_device.h>
|
|
+#include <linux/dma-mapping.h>
|
|
+#include <linux/fs.h>
|
|
+#include <linux/file.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/mm.h>
|
|
+#include <linux/syscalls.h>
|
|
+
|
|
+#define RMEM_MAGIC 'r'
|
|
+#define RMEM_CMD_FLUSH_CACHE _IOWR(RMEM_MAGIC, 0, struct rmem_flush_cache_info)
|
|
+#define RMEM_CMD_RMEM_INFO _IOWR(RMEM_MAGIC, 1, struct rmem_info)
|
|
+
|
|
+struct rmem_info {
|
|
+ unsigned int vaddr;
|
|
+ unsigned int paddr;
|
|
+};
|
|
+static struct rmem_info rmem_addr;
|
|
+
|
|
+
|
|
+static struct miscdevice mdev;
|
|
+
|
|
+struct rmem_flush_cache_info {
|
|
+ unsigned int addr;
|
|
+ unsigned int len;
|
|
+ unsigned int dir;
|
|
+};
|
|
+
|
|
+static int rmem_open(struct inode *inode, struct file *filp)
|
|
+{
|
|
+ pr_debug("[%d:%d] %s\n", current->tgid, current->pid, __func__);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int rmem_release(struct inode *inode, struct file *filp)
|
|
+{
|
|
+ pr_debug("[%d:%d] %s\n", current->tgid, current->pid, __func__);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static long rmem_cmd_flush_cache(long arg)
|
|
+{
|
|
+ struct rmem_flush_cache_info info;
|
|
+ long ret = 0;
|
|
+ if (copy_from_user(&info, (void *)arg, sizeof(info))) {
|
|
+ return -EFAULT;
|
|
+ }
|
|
+
|
|
+ dma_cache_sync(NULL, (void *)info.addr, info.len, info.dir);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static long rmem_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|
+{
|
|
+ switch (cmd) {
|
|
+ case RMEM_CMD_FLUSH_CACHE:
|
|
+ return rmem_cmd_flush_cache(arg);
|
|
+ case RMEM_CMD_RMEM_INFO:
|
|
+ if (copy_to_user((void *)arg, &rmem_addr, sizeof(struct rmem_info))) {
|
|
+ return -EFAULT;
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ pr_err("Unknown ioctl: 0x%.8X\n", cmd);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+}
|
|
+
|
|
+static int rmem_mmap(struct file *file, struct vm_area_struct *vma)
|
|
+{
|
|
+ vma->vm_flags |= VM_IO;
|
|
+
|
|
+ pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
|
|
+ pgprot_val(vma->vm_page_prot) |= _CACHE_CACHABLE_NONCOHERENT;
|
|
+
|
|
+ if (io_remap_pfn_range(vma,vma->vm_start,
|
|
+ vma->vm_pgoff,
|
|
+ vma->vm_end - vma->vm_start,
|
|
+ vma->vm_page_prot))
|
|
+ return -EAGAIN;
|
|
+ rmem_addr.vaddr = vma->vm_start;
|
|
+ rmem_addr.paddr = vma->vm_pgoff * PAGE_SIZE;
|
|
+
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static struct file_operations rmem_misc_fops = {
|
|
+ .open = rmem_open,
|
|
+ .release = rmem_release,
|
|
+ .unlocked_ioctl = rmem_ioctl,
|
|
+ .mmap = rmem_mmap,
|
|
+};
|
|
+
|
|
+static int rmem_probe(struct platform_device *pdev)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+
|
|
+ mdev.minor = MISC_DYNAMIC_MINOR;
|
|
+ mdev.name = "rmem";
|
|
+ mdev.fops = &rmem_misc_fops;
|
|
+
|
|
+ ret = misc_register(&mdev);
|
|
+ if (ret < 0) {
|
|
+ pr_err("rmem register failed\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ rmem_addr.vaddr = 0;
|
|
+ rmem_addr.paddr = 0;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int rmem_remove(struct platform_device *dev)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static struct platform_driver rmem_driver = {
|
|
+ .probe = rmem_probe,
|
|
+ .remove = rmem_remove,
|
|
+ .driver = {
|
|
+ .name = "rmem",
|
|
+ },
|
|
+};
|
|
+
|
|
+struct platform_device rmem_device = {
|
|
+ .name = "rmem",
|
|
+ .id = -1,
|
|
+ .resource = NULL,
|
|
+ .num_resources = 0,
|
|
+};
|
|
+
|
|
+static int __init rmem_init(void)
|
|
+{
|
|
+ platform_device_register(&rmem_device);
|
|
+ return platform_driver_register(&rmem_driver);
|
|
+}
|
|
+
|
|
+static void __exit rmem_exit(void)
|
|
+{
|
|
+ platform_device_unregister(&rmem_device);
|
|
+ platform_driver_unregister(&rmem_driver);
|
|
+}
|
|
+
|
|
+module_init(rmem_init);
|
|
+module_exit(rmem_exit);
|
|
+
|
|
+MODULE_LICENSE("GPL v2");
|