PageRenderTime 36ms CodeModel.GetById 21ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/arm/mach-fsm/qdsp5/evlog.h

https://bitbucket.org/sammyz/iscream_thunderc-2.6.35-rebase
C++ Header | 125 lines | 94 code | 15 blank | 16 comment | 7 complexity | 2440b122e22e6237a72815a225fd8f1e MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1/* arch/arm/mach-msm/qdsp5/evlog.h
  2 *
  3 * simple event log debugging facility
  4 *
  5 * Copyright (C) 2008 Google, Inc.
  6 *
  7 * This software is licensed under the terms of the GNU General Public
  8 * License version 2, as published by the Free Software Foundation, and
  9 * may be copied, distributed, and modified under those terms.
 10 *
 11 * This program is distributed in the hope that it will be useful,
 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14 * GNU General Public License for more details.
 15 *
 16 */
 17
 18#include <linux/fs.h>
 19#include <linux/hrtimer.h>
 20#include <linux/debugfs.h>
 21
 22#define EV_LOG_ENTRY_NAME(n) n##_entry
 23
 24#define DECLARE_LOG(_name, _size, _str) \
 25static struct ev_entry EV_LOG_ENTRY_NAME(_name)[_size]; \
 26static struct ev_log _name = { \
 27	.name = #_name, \
 28	.strings = _str, \
 29	.num_strings = ARRAY_SIZE(_str), \
 30	.entry = EV_LOG_ENTRY_NAME(_name), \
 31	.max = ARRAY_SIZE(EV_LOG_ENTRY_NAME(_name)), \
 32}
 33
 34struct ev_entry {
 35	ktime_t when;
 36	uint32_t id;
 37	uint32_t arg;
 38};
 39	
 40struct ev_log {
 41	struct ev_entry *entry;
 42	unsigned max;
 43	unsigned next;
 44	unsigned fault;
 45	const char **strings;
 46	unsigned num_strings;
 47	const char *name;
 48};
 49
 50static char ev_buf[4096];
 51
 52static ssize_t ev_log_read(struct file *file, char __user *buf,
 53			   size_t count, loff_t *ppos)
 54{
 55	struct ev_log *log = file->private_data;
 56	struct ev_entry *entry;
 57	unsigned long flags;
 58	int size = 0;
 59	unsigned n, id, max;
 60	ktime_t now, t;
 61	
 62	max = log->max;
 63	now = ktime_get();
 64	local_irq_save(flags);
 65	n = (log->next - 1) & (max - 1);
 66	entry = log->entry;
 67	while (n != log->next) {
 68		t = ktime_sub(now, entry[n].when);
 69		id = entry[n].id;
 70		if (id) {
 71			const char *str;
 72			if (id < log->num_strings)
 73				str = log->strings[id];
 74			else
 75				str = "UNKNOWN";
 76			size += scnprintf(ev_buf + size, 4096 - size,
 77					  "%8d.%03d %08x %s\n",
 78					  t.tv.sec, t.tv.nsec / 1000000,
 79					  entry[n].arg, str);
 80		}
 81		n = (n - 1) & (max - 1);
 82	}
 83	log->fault = 0;
 84	local_irq_restore(flags);
 85	return simple_read_from_buffer(buf, count, ppos, ev_buf, size);
 86}
 87
 88static void ev_log_write(struct ev_log *log, unsigned id, unsigned arg)
 89{
 90	struct ev_entry *entry;
 91	unsigned long flags;
 92	local_irq_save(flags);
 93
 94	if (log->fault) {
 95		if (log->fault == 1)
 96			goto done;
 97		log->fault--;
 98	}
 99
100	entry = log->entry + log->next;
101	entry->when = ktime_get();
102	entry->id = id;
103	entry->arg = arg;
104	log->next = (log->next + 1) & (log->max - 1);
105done:
106	local_irq_restore(flags);
107}
108
109static int ev_log_open(struct inode *inode, struct file *file)
110{
111	file->private_data = inode->i_private;
112	return 0;
113}
114
115static const struct file_operations ev_log_ops = {
116	.read = ev_log_read,
117	.open = ev_log_open,
118};
119
120static int ev_log_init(struct ev_log *log)
121{
122	debugfs_create_file(log->name, 0444, 0, log, &ev_log_ops);
123	return 0;
124}
125