misc: tegra-profiler: add poll support
Igor Nabirushkin [Tue, 24 Sep 2013 13:11:06 +0000 (17:11 +0400)]
Tegra Profiler misc driver: add poll support

Bug 1374312

Change-Id: Id0844b3b329f348763f22b831fc73ac64f04fd9b
Signed-off-by: Igor Nabirushkin <inabirushkin@nvidia.com>
Reviewed-on: http://git-master/r/298729
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Tested-by: Maxim Morin <mmorin@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>

drivers/misc/tegra-profiler/comm.c
drivers/misc/tegra-profiler/comm.h
drivers/misc/tegra-profiler/main.c
drivers/misc/tegra-profiler/quadd_proc.c
drivers/misc/tegra-profiler/version.h

index 9273d8a..51a4abe 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/vmalloc.h>
 #include <linux/miscdevice.h>
 #include <linux/sched.h>
+#include <linux/poll.h>
 
 #include <linux/tegra_profiler.h>
 
@@ -92,6 +93,18 @@ static int rb_is_empty(struct quadd_ring_buffer *rb)
        return rb->fill_count == 0;
 }
 
+static int rb_is_empty_lock(struct quadd_ring_buffer *rb)
+{
+       int res;
+       unsigned long flags;
+
+       spin_lock_irqsave(&rb->lock, flags);
+       res = rb->fill_count == 0;
+       spin_unlock_irqrestore(&rb->lock, flags);
+
+       return res;
+}
+
 static size_t
 rb_get_free_space(struct quadd_ring_buffer *rb)
 {
@@ -231,6 +244,8 @@ write_sample(struct quadd_record_data *sample, void *extra_data,
                rb->max_fill_count = rb->fill_count;
 
        spin_unlock_irqrestore(&rb->lock, flags);
+
+       wake_up_interruptible(&comm_ctx.read_wait);
 }
 
 static int read_sample(char __user *buffer, size_t max_length)
@@ -405,6 +420,23 @@ static int device_release(struct inode *inode, struct file *file)
        return 0;
 }
 
+static unsigned int
+device_poll(struct file *file, poll_table *wait)
+{
+       unsigned int mask = 0;
+       struct quadd_ring_buffer *rb = &comm_ctx.rb;
+
+       poll_wait(file, &comm_ctx.read_wait, wait);
+
+       if (!rb_is_empty_lock(rb))
+               mask |= POLLIN | POLLRDNORM;
+
+       if (!atomic_read(&comm_ctx.active))
+               mask |= POLLHUP;
+
+       return mask;
+}
+
 static ssize_t
 device_read(struct file *filp,
            char __user *buffer,
@@ -588,6 +620,7 @@ device_ioctl(struct file *file,
        case IOCTL_STOP:
                if (atomic_cmpxchg(&comm_ctx.active, 1, 0)) {
                        comm_ctx.control->stop();
+                       wake_up_interruptible(&comm_ctx.read_wait);
                        rb_deinit(&comm_ctx.rb);
                        pr_info("Stop profiling success\n");
                }
@@ -617,6 +650,7 @@ static void free_ctx(void)
 
 static const struct file_operations qm_fops = {
        .read           = device_read,
+       .poll           = device_poll,
        .open           = device_open,
        .release        = device_release,
        .unlocked_ioctl = device_ioctl
@@ -651,6 +685,8 @@ static int comm_init(void)
        comm_ctx.process_pid = 0;
        comm_ctx.nr_users = 0;
 
+       init_waitqueue_head(&comm_ctx.read_wait);
+
        return 0;
 }
 
index f519f17..956e44b 100644 (file)
@@ -67,6 +67,8 @@ struct quadd_comm_ctx {
        pid_t process_pid;
        uid_t debug_app_uid;
 
+       wait_queue_head_t read_wait;
+
        struct miscdevice *misc_dev;
 };
 
index cf7997e..96e364c 100644 (file)
@@ -356,7 +356,7 @@ static void get_capabilities(struct quadd_comm_cap *cap)
 
        cap->tegra_lp_cluster = quadd_is_cpu_with_lp_cluster();
        cap->power_rate = 1;
-       cap->blocked_read = 0;
+       cap->blocked_read = 1;
 }
 
 static void get_state(struct quadd_module_state *state)
index 649c2d7..02b4cb0 100644 (file)
@@ -71,6 +71,9 @@ static int show_capabilities(struct seq_file *f, void *offset)
                           YES_NO(cap->l2_multiple_events));
        }
 
+       seq_printf(f, "support polling mode:   %s\n",
+                  YES_NO(cap->blocked_read));
+
        seq_printf(f, "\n");
        seq_printf(f, "Supported events:\n");
        seq_printf(f, "cpu_cycles:             %s\n",
index 2d55c51..91fade5 100644 (file)
@@ -18,7 +18,7 @@
 #ifndef __QUADD_VERSION_H
 #define __QUADD_VERSION_H
 
-#define QUADD_MODULE_VERSION           "1.32"
+#define QUADD_MODULE_VERSION           "1.33"
 #define QUADD_MODULE_BRANCH            "Dev"
 
 #endif /* __QUADD_VERSION_H */