aboutsummaryrefslogtreecommitdiff
path: root/kernel/ethosu_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/ethosu_buffer.c')
-rw-r--r--kernel/ethosu_buffer.c126
1 files changed, 37 insertions, 89 deletions
diff --git a/kernel/ethosu_buffer.c b/kernel/ethosu_buffer.c
index 07c8033..bf7d745 100644
--- a/kernel/ethosu_buffer.c
+++ b/kernel/ethosu_buffer.c
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
- *
*/
/****************************************************************************
@@ -45,17 +44,14 @@ static int ethosu_buffer_release(struct inode *inode,
static int ethosu_buffer_mmap(struct file *file,
struct vm_area_struct *vma);
-static long ethosu_buffer_ioctl(struct file *file,
- unsigned int cmd,
- unsigned long arg);
+static loff_t ethosu_buffer_llseek(struct file *file,
+ loff_t offset,
+ int whence);
static const struct file_operations ethosu_buffer_fops = {
- .release = &ethosu_buffer_release,
- .mmap = &ethosu_buffer_mmap,
- .unlocked_ioctl = &ethosu_buffer_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = &ethosu_buffer_ioctl,
-#endif
+ .release = &ethosu_buffer_release,
+ .mmap = &ethosu_buffer_mmap,
+ .llseek = &ethosu_buffer_llseek,
};
/****************************************************************************
@@ -75,8 +71,8 @@ static void ethosu_buffer_destroy(struct kref *kref)
dev_dbg(dev, "Buffer destroy. buf=0x%pK", buf);
- memset(buf->cpu_addr, 0, buf->capacity);
- dma_free_coherent(dev, buf->capacity, buf->cpu_addr,
+ memset(buf->cpu_addr, 0, buf->size);
+ dma_free_coherent(dev, buf->size, buf->cpu_addr,
buf->dma_addr);
memset(buf, 0, sizeof(*buf));
@@ -108,78 +104,43 @@ static int ethosu_buffer_mmap(struct file *file,
file, buf);
ret = dma_mmap_coherent(dev, vma, buf->cpu_addr,
- buf->dma_addr, buf->capacity);
+ buf->dma_addr, buf->size);
return ret;
}
-static long ethosu_buffer_ioctl(struct file *file,
- unsigned int cmd,
- unsigned long arg)
+static loff_t ethosu_buffer_llseek(struct file *file,
+ loff_t offset,
+ int whence)
{
struct ethosu_buffer *buf = file->private_data;
- struct device *dev = buf->dev;
- void __user *udata = (void __user *)arg;
- int ret;
-
- ret = device_lock_interruptible(dev);
- if (ret)
- return ret;
-
- switch (cmd) {
- case ETHOSU_IOCTL_BUFFER_SET: {
- struct ethosu_uapi_buffer uapi;
-
- if (copy_from_user(&uapi, udata, sizeof(uapi))) {
- ret = -EFAULT;
- break;
- }
-
- dev_dbg(dev,
- "Buffer ioctl: Buffer set. size=%u, offset=%u\n",
- uapi.size, uapi.offset);
- ret = ethosu_buffer_resize(buf, uapi.size, uapi.offset);
- break;
- }
- case ETHOSU_IOCTL_BUFFER_GET: {
- struct ethosu_uapi_buffer uapi = { 0 };
-
- uapi.size = buf->size;
- uapi.offset = buf->offset;
-
- dev_dbg(dev,
- "Buffer ioctl: Buffer get. size=%u, offset=%u\n",
- uapi.size, uapi.offset);
-
- if (copy_to_user(udata, &uapi, sizeof(uapi))) {
- ret = -EFAULT;
- break;
- }
+ if (offset != 0)
+ return -EINVAL;
- ret = 0;
- break;
- }
- default: {
- dev_err(dev, "Invalid ioctl. cmd=%u, arg=%lu",
- cmd, arg);
- ret = -ENOIOCTLCMD;
- break;
- }
+ /*
+ * SEEK_END and SEEK_SET is supported with a zero offset to allow buffer
+ * size discovery using seek functions e.g.
+ * size = lseek(buf_fd, 0, SEEK_END);
+ * lseek(buf_fd, 0, SEEK_SET);
+ */
+ switch (whence) {
+ case SEEK_END:
+ return buf->size;
+ case SEEK_SET:
+ return 0;
+ default:
+ return -EINVAL;
}
-
- device_unlock(dev);
-
- return ret;
}
int ethosu_buffer_create(struct device *dev,
- size_t capacity)
+ size_t size)
{
struct ethosu_buffer *buf;
int ret = -ENOMEM;
- if (!capacity)
+ if (!size)
return -EINVAL;
buf = devm_kzalloc(dev, sizeof(*buf), GFP_KERNEL);
@@ -187,13 +148,11 @@ int ethosu_buffer_create(struct device *dev,
return -ENOMEM;
buf->dev = dev;
- buf->capacity = capacity;
- buf->offset = 0;
- buf->size = 0;
+ buf->size = size;
kref_init(&buf->kref);
- buf->cpu_addr = dma_alloc_coherent(dev, capacity,
- &buf->dma_addr, GFP_KERNEL);
+ buf->cpu_addr = dma_alloc_coherent(dev, size, &buf->dma_addr,
+ GFP_KERNEL);
if (!buf->cpu_addr)
goto free_buf;
@@ -203,17 +162,19 @@ int ethosu_buffer_create(struct device *dev,
goto free_dma;
buf->file = fget(ret);
+ buf->file->f_mode |= FMODE_LSEEK;
+
fput(buf->file);
dev_dbg(dev,
- "Buffer create. file=0x%pK, fd=%d, buf=0x%pK, capacity=%zu, cpu_addr=0x%pK, dma_addr=0x%llx, phys_addr=0x%llx\n",
- buf->file, ret, buf, capacity, buf->cpu_addr, buf->dma_addr,
+ "Buffer create. file=0x%pK, fd=%d, buf=0x%pK, size=%zu, cpu_addr=0x%pK, dma_addr=0x%llx, phys_addr=0x%llx\n",
+ buf->file, ret, buf, size, buf->cpu_addr, buf->dma_addr,
virt_to_phys(buf->cpu_addr));
return ret;
free_dma:
- dma_free_coherent(dev, buf->capacity, buf->cpu_addr,
+ dma_free_coherent(dev, buf->size, buf->cpu_addr,
buf->dma_addr);
free_buf:
@@ -254,16 +215,3 @@ void ethosu_buffer_put(struct ethosu_buffer *buf)
{
kref_put(&buf->kref, ethosu_buffer_destroy);
}
-
-int ethosu_buffer_resize(struct ethosu_buffer *buf,
- size_t size,
- size_t offset)
-{
- if ((size + offset) > buf->capacity)
- return -EINVAL;
-
- buf->size = size;
- buf->offset = offset;
-
- return 0;
-}