diff options
author | Igor Nabirushkin <inabirushkin@nvidia.com> | 2013-09-24 17:11:06 +0400 |
---|---|---|
committer | Riham Haidar <rhaidar@nvidia.com> | 2013-11-07 12:11:56 -0800 |
commit | 1f15e805f697b97bdbf5225f9fcce07fe1058c29 (patch) | |
tree | d1d6c98af057dca0b1e4f52a7c7db1f5725fb3e5 | |
parent | e35f1b96133d71434ef7d6910b730f85fe05d2d5 (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/309634
(cherry picked from commit d8e347f4e5636fd6face6fae3db572d64d6727f0)
Reviewed-on: http://git-master/r/325990
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Tested-by: Maxim Morin <mmorin@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r-- | drivers/misc/tegra-profiler/comm.c | 36 | ||||
-rw-r--r-- | drivers/misc/tegra-profiler/comm.h | 2 | ||||
-rw-r--r-- | drivers/misc/tegra-profiler/main.c | 2 | ||||
-rw-r--r-- | drivers/misc/tegra-profiler/quadd_proc.c | 3 | ||||
-rw-r--r-- | drivers/misc/tegra-profiler/version.h | 2 |
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 */ |