aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/dream/qdsp5/evlog.h
diff options
context:
space:
mode:
authorIliyan Malchev <ibm@android.com>2009-07-17 13:10:30 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-15 12:01:43 -0700
commitcaff4caead44f6a1ed0bc8ca50d8607d01f69b78 (patch)
tree2fd9b777e509af1da825753e44c416f369f20660 /drivers/staging/dream/qdsp5/evlog.h
parentStaging: HTC Dream: add rpcrouter driver (diff)
downloadlinux-dev-caff4caead44f6a1ed0bc8ca50d8607d01f69b78.tar.xz
linux-dev-caff4caead44f6a1ed0bc8ca50d8607d01f69b78.zip
Staging: HTC Dream: add qdsp support
QDSP code is neccessarry for communication with some hardware components on HTC Dream, including camera hardware. It also drives DSP coproccessor. Signed-off-by: Pavel Machek <pavel@ucw.cz> Cc: Brian Swetland <swetland@google.com> Cc: Iliyan Malchev <ibm@android.com> Cc: San Mehat <san@android.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/dream/qdsp5/evlog.h')
-rw-r--r--drivers/staging/dream/qdsp5/evlog.h133
1 files changed, 133 insertions, 0 deletions
diff --git a/drivers/staging/dream/qdsp5/evlog.h b/drivers/staging/dream/qdsp5/evlog.h
new file mode 100644
index 000000000000..922ce670a32a
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/evlog.h
@@ -0,0 +1,133 @@
+/* arch/arm/mach-msm/qdsp5/evlog.h
+ *
+ * simple event log debugging facility
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/hrtimer.h>
+#include <linux/debugfs.h>
+
+#define EV_LOG_ENTRY_NAME(n) n##_entry
+
+#define DECLARE_LOG(_name, _size, _str) \
+static struct ev_entry EV_LOG_ENTRY_NAME(_name)[_size]; \
+static struct ev_log _name = { \
+ .name = #_name, \
+ .strings = _str, \
+ .num_strings = ARRAY_SIZE(_str), \
+ .entry = EV_LOG_ENTRY_NAME(_name), \
+ .max = ARRAY_SIZE(EV_LOG_ENTRY_NAME(_name)), \
+}
+
+struct ev_entry {
+ ktime_t when;
+ uint32_t id;
+ uint32_t arg;
+};
+
+struct ev_log {
+ struct ev_entry *entry;
+ unsigned max;
+ unsigned next;
+ unsigned fault;
+ const char **strings;
+ unsigned num_strings;
+ const char *name;
+};
+
+static char ev_buf[4096];
+
+static ssize_t ev_log_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct ev_log *log = file->private_data;
+ struct ev_entry *entry;
+ unsigned long flags;
+ int size = 0;
+ unsigned n, id, max;
+ ktime_t now, t;
+
+ max = log->max;
+ now = ktime_get();
+ local_irq_save(flags);
+ n = (log->next - 1) & (max - 1);
+ entry = log->entry;
+ while (n != log->next) {
+ t = ktime_sub(now, entry[n].when);
+ id = entry[n].id;
+ if (id) {
+ const char *str;
+ if (id < log->num_strings)
+ str = log->strings[id];
+ else
+ str = "UNKNOWN";
+ size += scnprintf(ev_buf + size, 4096 - size,
+ "%8d.%03d %08x %s\n",
+ t.tv.sec, t.tv.nsec / 1000000,
+ entry[n].arg, str);
+ }
+ n = (n - 1) & (max - 1);
+ }
+ log->fault = 0;
+ local_irq_restore(flags);
+ return simple_read_from_buffer(buf, count, ppos, ev_buf, size);
+}
+
+static void ev_log_write(struct ev_log *log, unsigned id, unsigned arg)
+{
+ struct ev_entry *entry;
+ unsigned long flags;
+ local_irq_save(flags);
+
+ if (log->fault) {
+ if (log->fault == 1)
+ goto done;
+ log->fault--;
+ }
+
+ entry = log->entry + log->next;
+ entry->when = ktime_get();
+ entry->id = id;
+ entry->arg = arg;
+ log->next = (log->next + 1) & (log->max - 1);
+done:
+ local_irq_restore(flags);
+}
+
+static void ev_log_freeze(struct ev_log *log, unsigned count)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ log->fault = count;
+ local_irq_restore(flags);
+}
+
+static int ev_log_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static const struct file_operations ev_log_ops = {
+ .read = ev_log_read,
+ .open = ev_log_open,
+};
+
+static int ev_log_init(struct ev_log *log)
+{
+ debugfs_create_file(log->name, 0444, 0, log, &ev_log_ops);
+ return 0;
+}
+