summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Nabirushkin <inabirushkin@nvidia.com>2013-09-24 17:11:06 +0400
committerHarry Hong <hhong@nvidia.com>2013-12-10 16:21:48 -0800
commitc593b1898f2bb6b5dac3e9cccafebad2c97c9f85 (patch)
tree63c2ce39deb5ebe708bd318848de69eeea01243f
parent6a1f8af7c5fe956aca1a03f5d35d9e8894bd93dc (diff)
misc: tegra-profiler: add poll support
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/324078 (cherry picked from commit 5cf6aad33faf73a32d01aa9f4d064410c5a677b3) Reviewed-on: http://git-master/r/340010 Reviewed-by: Harry Hong <hhong@nvidia.com> Tested-by: Harry Hong <hhong@nvidia.com>
-rw-r--r--drivers/misc/tegra-profiler/comm.c36
-rw-r--r--drivers/misc/tegra-profiler/comm.h2
-rw-r--r--drivers/misc/tegra-profiler/main.c2
-rw-r--r--drivers/misc/tegra-profiler/quadd_proc.c3
-rw-r--r--drivers/misc/tegra-profiler/version.h2
5 files changed, 43 insertions, 2 deletions
diff --git a/drivers/misc/tegra-profiler/comm.c b/drivers/misc/tegra-profiler/comm.c
index 9273d8ad8991..51a4abe9d566 100644
--- a/drivers/misc/tegra-profiler/comm.c
+++ b/drivers/misc/tegra-profiler/comm.c
@@ -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;
}
diff --git a/drivers/misc/tegra-profiler/comm.h b/drivers/misc/tegra-profiler/comm.h
index f519f17b317c..956e44be90c3 100644
--- a/drivers/misc/tegra-profiler/comm.h
+++ b/drivers/misc/tegra-profiler/comm.h
@@ -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;
};
diff --git a/drivers/misc/tegra-profiler/main.c b/drivers/misc/tegra-profiler/main.c
index 2b84dd036d81..f5238bb55eeb 100644
--- a/drivers/misc/tegra-profiler/main.c
+++ b/drivers/misc/tegra-profiler/main.c
@@ -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)
diff --git a/drivers/misc/tegra-profiler/quadd_proc.c b/drivers/misc/tegra-profiler/quadd_proc.c
index 649c2d7065d5..02b4cb0e3fce 100644
--- a/drivers/misc/tegra-profiler/quadd_proc.c
+++ b/drivers/misc/tegra-profiler/quadd_proc.c
@@ -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",
diff --git a/drivers/misc/tegra-profiler/version.h b/drivers/misc/tegra-profiler/version.h
index 2d55c518b506..91fade52fa57 100644
--- a/drivers/misc/tegra-profiler/version.h
+++ b/drivers/misc/tegra-profiler/version.h
@@ -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 */