From: Kumar Abhishek <[email protected]>

Signed-off-by: Kumar Abhishek <[email protected]>
---
 drivers/remoteproc/beaglelogic.c | 134 ++++++++++++++++++++++++++++++---------
 1 file changed, 103 insertions(+), 31 deletions(-)

diff --git a/drivers/remoteproc/beaglelogic.c b/drivers/remoteproc/beaglelogic.c
index 11da9f9..391f9be 100644
--- a/drivers/remoteproc/beaglelogic.c
+++ b/drivers/remoteproc/beaglelogic.c
@@ -18,6 +18,7 @@
 #include <linux/kernel.h> 
 #include <linux/init.h>
 #include <linux/wait.h>
+#include <linux/poll.h>
 
 #include <linux/platform_device.h>
 #include <linux/miscdevice.h>
@@ -130,8 +131,8 @@ struct beaglelogicdev {
        ccontext *cxt_pru;
 
        /* Device capabilities */
-       u32 bufunitsize;        /* Size of 1 Allocation unit */
        u32 maxbufcount;        /* Max buffer count supported by the PRU FW */
+       u32 bufunitsize;        /* Size of 1 Allocation unit */
        u32 samplerate;         /* Sample rate = 100 / n MHz, n = 2+ (int) */
        u32 triggerflags;       /* bit 0 : 1shot/!continuous */
        u32 sampleunit;         /* 0:8bits, 1:16bits */
@@ -153,7 +154,7 @@ typedef struct bufreader {
                struct beaglelogicdev, miscdev)
 
 #define DRV_NAME       "beaglelogic"
-#define DRV_VERSION    "1.0"
+#define DRV_VERSION    "1.1"
 
 /* Begin Buffer Management section */
 static int bufunitsize = 4 * 1024 * 1024;
@@ -348,7 +349,7 @@ u32 beaglelogic_get_samplerate(struct device *dev)
 int beaglelogic_set_samplerate(struct device *dev, u32 samplerate)
 {
        struct beaglelogicdev *bldev = dev_get_drvdata(dev);
-       if (samplerate > bldev->coreclockfreq / 2 || samplerate < 100000)
+       if (samplerate > bldev->coreclockfreq / 2 || samplerate < 1)
                return -EINVAL;
 
        if (mutex_trylock(&bldev->mutex)) {
@@ -527,14 +528,17 @@ static int beaglelogic_f_open(struct inode *inode, struct 
file *filp)
 
        filp->private_data = reader;
 
-       /* Map and submit all the buffers */
-       if (beaglelogic_map_and_submit_all_buffers(dev))
+       /* The buffers will be mapped/resubmitted at the time of allocation
+        * Here, we just map the first buffer */
+       if (!bldev->buffers)
                return -ENOMEM;
 
+       beaglelogic_map_buffer(dev, &bldev->buffers[0]);
+
        return 0;
 }
 
-/* Read the sample (ring) buffer. TODO Implement Nonblock */
+/* Read the sample (ring) buffer. */
 ssize_t beaglelogic_f_read (struct file *filp, char __user *buf,
                           size_t sz, loff_t *offset)
 {
@@ -546,47 +550,56 @@ ssize_t beaglelogic_f_read (struct file *filp, char 
__user *buf,
        if (bldev->state == STATE_BL_ERROR)
                return -EIO;
 
-       if (reader->remaining > 0)
+       if (reader->pos > 0)
                goto perform_copy;
 
-       if (reader->buf) {
-               if (bldev->state == STATE_BL_INITIALIZED &&
-                               bldev->lastbufready == reader->buf)
-                       return 0;
+       if (reader->buf == NULL) {
+               /* First time init */
+               reader->buf = &reader->bldev->buffers[0];
+               reader->remaining = reader->buf->size;
 
-               reader->buf = reader->buf->next;
-       }
-       else {
-               /* (re)trigger */
-               if (beaglelogic_start(dev))
-                       return -ENOEXEC;
-
-               reader->buf = &bldev->buffers[0];
+               if (bldev->state != STATE_BL_RUNNING) {
+                       /* Start the capture */
+                       if (beaglelogic_start(dev))
+                               return -ENOEXEC;
+               }
+       } else {
+               /* EOF Condition, back to buffer 0 and stopped */
+               if (reader->buf == bldev->buffers &&
+                               bldev->state == STATE_BL_INITIALIZED)
+                       return 0;
        }
-       reader->pos = 0;
-       reader->remaining = reader->buf->size;
 
-       dev_dbg(dev, "waiting for IRQ\n");
-       wait_event_interruptible(bldev->wait,
-                       reader->buf->state == STATE_BL_BUF_UNMAPPED);
-       dev_dbg(dev, "got IRQ\n");
+       if (filp->f_flags & O_NONBLOCK) {
+               if (reader->buf->state != STATE_BL_BUF_UNMAPPED)
+                       return -EAGAIN;
+       } else
+               wait_event_interruptible(bldev->wait,
+                               reader->buf->state == STATE_BL_BUF_UNMAPPED);
 perform_copy:
        count = min(reader->remaining, sz);
 
+       if (copy_to_user(buf, reader->buf->buf + reader->pos, count))
+               return -EFAULT;
+
        /* Detect buffer drop */
        if (reader->buf->state == STATE_BL_BUF_MAPPED) {
-               dev_warn(dev, "buffer dropped at index %d \n",
+               dev_warn(dev, "buffer may be dropped at index %d \n",
                                reader->buf->index);
                reader->buf->state = STATE_BL_BUF_DROPPED;
                bldev->lasterror = 0x10000 | reader->buf->index;
        }
 
-       if (copy_to_user(buf, reader->buf->buf + reader->pos, count))
-               return -EFAULT;
-
        reader->pos += count;
        reader->remaining -= count;
 
+       if (reader->remaining == 0) {
+               /* Change the buffer */
+               reader->buf = reader->buf->next;
+               reader->pos = 0;
+               reader->remaining = reader->buf->size;
+       }
+
        return count;
 }
 
@@ -626,7 +639,7 @@ static long beaglelogic_f_ioctl(struct file *filp, unsigned 
int cmd,
 
        u32 val;
 
-       dev_info(dev, "BeagleLogic: IOCTL called cmd = %08X, "\
+       dev_dbg(dev, "BeagleLogic: IOCTL called cmd = %08X, "\
                        "arg = %08lX\n", cmd, arg);
 
        switch (cmd) {
@@ -710,6 +723,11 @@ static long beaglelogic_f_ioctl(struct file *filp, 
unsigned int cmd,
                        return 0;
 
                case IOCTL_BL_START:
+                       /* Reset and reconfigure the reader object and then 
start */
+                       reader->buf = &bldev->buffers[0];
+                       reader->pos = 0;
+                       reader->remaining = reader->buf->size;
+
                        beaglelogic_start(dev);
                        return 0;
 
@@ -725,7 +743,36 @@ static long beaglelogic_f_ioctl(struct file *filp, 
unsigned int cmd,
 static loff_t beaglelogic_f_llseek(struct file *filp, loff_t offset, int 
whence)
 {
        logic_buffer_reader *reader = filp->private_data;
-       struct device *dev = reader->bldev->miscdev.this_device;
+       struct beaglelogicdev *bldev = reader->bldev;
+       struct device *dev = bldev->miscdev.this_device;
+
+       loff_t i = offset;
+       u32 j;
+
+       if (whence == SEEK_CUR) {
+               while (i > 0) {
+                       if (reader->buf->state == STATE_BL_BUF_MAPPED) {
+                               dev_warn(dev, "buffer may be dropped at index 
%d \n",
+                                               reader->buf->index);
+                               reader->buf->state = STATE_BL_BUF_DROPPED;
+                               bldev->lasterror = 0x10000 | reader->buf->index;
+                       }
+
+                       j = min((u32)i, reader->remaining);
+                       reader->pos += j;
+
+                       if ((reader->remaining -= j) == 0) {
+                               /* Change the buffer */
+                               reader->buf = reader->buf->next;
+                               reader->pos = 0;
+                               reader->remaining = reader->buf->size;
+                       }
+
+                       i -= j;
+               }
+               return offset;
+       }
+
        if (whence == SEEK_SET && offset == 0) {
                /* The next read triggers the LA */
                reader->buf = NULL;
@@ -735,10 +782,34 @@ static loff_t beaglelogic_f_llseek(struct file *filp, 
loff_t offset, int whence)
                /* Stop and map the first buffer */
                beaglelogic_stop(dev);
                beaglelogic_map_buffer(dev, &reader->bldev->buffers[0]);
+
+               return 0;
        }
+
        return -EINVAL;
 }
 
+/* Poll the file descriptor */
+unsigned int beaglelogic_f_poll(struct file *filp,
+               struct poll_table_struct *tbl)
+{
+       logic_buffer_reader *reader = filp->private_data;
+       struct beaglelogicdev *bldev = reader->bldev;
+       logic_buffer *buf;
+
+       /* Raise an error if polled without starting the LA first */
+       if (reader->buf == NULL && bldev->state != STATE_BL_RUNNING)
+               return -ENOEXEC;
+
+       buf = reader->buf;
+       if (buf->state == STATE_BL_BUF_UNMAPPED)
+               return (POLLIN | POLLRDNORM);
+
+       poll_wait(filp, &bldev->wait, tbl);
+
+       return 0;
+}
+
 /* Device file close handler */
 static int beaglelogic_f_release(struct inode *inode, struct file *filp)
 {
@@ -761,6 +832,7 @@ static const struct file_operations pru_beaglelogic_fops = {
        .read = beaglelogic_f_read,
        .llseek = beaglelogic_f_llseek,
        .mmap = beaglelogic_f_mmap,
+       .poll = beaglelogic_f_poll,
        .release = beaglelogic_f_release,
 };
 /* fops */
-- 
1.9.1

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to