gator: ARM DS-5.6 Streamline gator driver
[android-sdk/arm-ds5-gator.git] / gator_events_mmaped.c
1 /*
2  * Example events provider
3  *
4  * Copyright (C) ARM Limited 2010-2011. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * Similar entires must be present in events.xml file:
11  *
12  * <counter_set name="mmaped_cntX">
13  *   <counter name="mmaped_cnt0"/>
14  *   <counter name="mmaped_cnt1"/>
15  * </counter_set>
16  * <category name="mmaped" counter_set="mmaped_cntX" per_cpu="no">
17  *   <event event="0x0" title="Simulated" name="Sine" description="Sort-of-sine"/>
18  *   <event event="0x1" title="Simulated" name="Triangle" description="Triangular wave"/>
19  *   <event event="0x2" title="Simulated" name="PWM" description="PWM Signal"/>
20  * </category>
21  */
23 #include <linux/init.h>
24 #include <linux/io.h>
25 #include <linux/ratelimit.h>
27 #include "gator.h"
29 #define MMAPED_COUNTERS_NUM 3
31 static struct {
32         unsigned long enabled;
33         unsigned long event;
34         unsigned long key;
35 } mmaped_counters[MMAPED_COUNTERS_NUM];
37 static int mmaped_buffer[MMAPED_COUNTERS_NUM * 2];
39 #ifdef TODO
40 static void __iomem *mmaped_base;
41 #endif
43 /* Adds mmaped_cntX directories and enabled, event, and key files to /dev/gator/events */
44 static int gator_events_mmaped_create_files(struct super_block *sb,
45                 struct dentry *root)
46 {
47         int i;
49         for (i = 0; i < MMAPED_COUNTERS_NUM; i++) {
50                 char buf[16];
51                 struct dentry *dir;
53                 snprintf(buf, sizeof(buf), "mmaped_cnt%d", i);
54                 dir = gatorfs_mkdir(sb, root, buf);
55                 if (WARN_ON(!dir))
56                         return -1;
57                 gatorfs_create_ulong(sb, dir, "enabled",
58                                 &mmaped_counters[i].enabled);
59                 gatorfs_create_ulong(sb, dir, "event",
60                                 &mmaped_counters[i].event);
61                 gatorfs_create_ro_ulong(sb, dir, "key",
62                                 &mmaped_counters[i].key);
63         }
65         return 0;
66 }
68 static int gator_events_mmaped_start(void)
69 {
70 #ifdef TODO
71         for (i = 0; i < MMAPED_COUNTERS_NUM; i++)
72                 writel(mmaped_counters[i].event,
73                                 mmaped_base + COUNTERS_CONFIG_OFFSET[i]);
75         writel(ENABLED, COUNTERS_CONTROL_OFFSET);
76 #endif
78         return 0;
79 }
81 static void gator_events_mmaped_stop(void)
82 {
83 #ifdef TODO
84         writel(DISABLED, COUNTERS_CONTROL_OFFSET);
85 #endif
86 }
88 #ifndef TODO
89 /* This function "simulates" counters, generating values of fancy
90  * functions like sine or triangle... */
91 static int mmaped_simulate(int counter)
92 {
93         int result = 0;
95         switch (counter) {
96         case 0: /* sort-of-sine */
97                 {
98                         static int t;
99                         int x;
101                         if (t % 1024 < 512)
102                                 x = 512 - (t % 512);
103                         else
104                                 x = t % 512;
106                         result = 32 * x / 512;
107                         result = result * result;
109                         if (t < 1024)
110                                 result = 1922 - result;
112                         t = (t + 1) % 2048;
113                 }
114                 break;
115         case 1: /* triangle */
116                 {
117                         static int v, d = 1;
119                         v += d;
120                         if (v % 2000 == 0)
121                                 d = -d;
123                         result = v;
124                 }
125                 break;
126         case 2: /* PWM signal */
127                 {
128                         static int t, dc;
130                         t = (t + 1) % 2000;
131                         if (t % 100)
132                                 dc = (dc + 200) % 2000;
133                         
134                         result = t < dc ? 0 : 2000;
135                 }
136                 break;
137         }
139         return result;
141 #endif
143 static int gator_events_mmaped_read(int **buffer)
145         int i;
146         int len = 0;
148         /* System wide counters - read from one core only */
149         if (smp_processor_id())
150                 return 0;
152         for (i = 0; i < MMAPED_COUNTERS_NUM; i++) {
153                 if (mmaped_counters[i].enabled) {
154                         mmaped_buffer[len++] = mmaped_counters[i].key;
155 #ifdef TODO
156                         mmaped_buffer[len++] = readl(mmaped_base +
157                                         COUNTERS_VALUE_OFFSET[i]);
158 #else
159                         mmaped_buffer[len++] = mmaped_simulate(
160                                         mmaped_counters[i].event);
161 #endif
162                 }
163         }
164         
165         if (buffer)
166                 *buffer = mmaped_buffer;
168         return len;
171 static struct gator_interface gator_events_mmaped_interface = {
172         .create_files = gator_events_mmaped_create_files,
173         .start = gator_events_mmaped_start,
174         .stop = gator_events_mmaped_stop,
175         .read = gator_events_mmaped_read,
176 };
178 /* Must not be static! */
179 int __init gator_events_mmaped_init(void)
181         int i;
183 #ifdef TODO
184         mmaped_base = ioremap(COUNTERS_PHYS_ADDR, SZ_4K);
185         if (!mmaped_base)
186                 return -ENOMEM; 
187 #endif
189         for (i = 0; i < MMAPED_COUNTERS_NUM; i++) {
190                 mmaped_counters[i].enabled = 0;
191                 mmaped_counters[i].key = gator_events_get_key();
192         }
194         return gator_events_install(&gator_events_mmaped_interface);
196 gator_events_init(gator_events_mmaped_init);