blob: ae427335139daf00d3fb734657cc0c66f4fe67b3 [file] [log] [blame]
Pratik Patelbb6e9e572012-09-19 13:21:31 -07001/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/fs.h>
16#include <linux/slab.h>
17#include <linux/miscdevice.h>
18#include <linux/cpu.h>
19#include <linux/smp.h>
20#include <linux/percpu.h>
21#include <linux/io.h>
22#include <linux/uaccess.h>
23#include <linux/wakelock.h>
Steve Mucklef132c6c2012-06-06 18:30:57 -070024#include <linux/pm_qos.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070025
26#include <asm/atomic.h>
Pratik Patelbb6e9e572012-09-19 13:21:31 -070027#include <asm/hardware/cp14.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070028
29#define LOG_BUF_LEN 32768
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070030/* each slot is 4 bytes, 8kb total */
31#define ETB_RAM_SLOTS 2048
32
33#define DATALOG_SYNC 0xB5C7
34#define ETM_DUMP_MSG_ID 0x000A6960
35#define ETB_DUMP_MSG_ID 0x000A6961
36
Pratik Patel17f3b822011-11-21 12:41:47 -080037/* ETB Registers */
38#define ETB_REG_CONTROL ETMIMPSPEC1
39#define ETB_REG_STATUS ETMIMPSPEC2
40#define ETB_REG_COUNT ETMIMPSPEC3
41#define ETB_REG_ADDRESS ETMIMPSPEC4
42#define ETB_REG_DATA ETMIMPSPEC5
43
44/* Having etb macro accessors allows macro expansion for ETB reg defines */
45#define etb_read(reg) etm_read(reg)
46#define etb_write(val, reg) etm_write(val, reg)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070047
48/* Bitmasks for the ETM control register */
49#define ETM_CONTROL_POWERDOWN 0x00000001
50#define ETM_CONTROL_PROGRAM 0x00000400
51
52/* Bitmasks for the ETM status register */
53#define ETM_STATUS_PROGRAMMING 0x00000002
54
55/* ETB Status Register bit definitions */
56#define OV 0x00200000
57
58/* ETB Control Register bit definitions */
59#define AIR 0x00000008
60#define AIW 0x00000004
61#define CPTM 0x00000002
62#define CPTEN 0x00000001
63
64/* Bitmasks for the swconfig field of ETM_CONFIG
65 * ETM trigger propagated to ETM instances on all cores
66 */
67#define TRIGGER_ALL 0x00000002
68
69#define PROG_TIMEOUT_MS 500
70
71static int trace_enabled;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070072static int cpu_to_dump;
73static int next_cpu_to_dump;
74static struct wake_lock etm_wake_lock;
Steve Mucklef132c6c2012-06-06 18:30:57 -070075static struct pm_qos_request etm_qos_req;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070076static int trace_on_boot;
77module_param_named(
78 trace_on_boot, trace_on_boot, int, S_IRUGO
79);
80
81struct b {
82 uint8_t etm_log_buf[LOG_BUF_LEN];
83 uint32_t log_end;
84};
85
86static struct b buf[NR_CPUS];
87static struct b __percpu * *alloc_b;
88static atomic_t etm_dev_in_use;
89
90/* These default settings will be used to configure the ETM/ETB
91 * when the driver loads. */
92struct etm_config_struct {
93 uint32_t etm_00_control;
94 uint32_t etm_02_trigger_event;
95 uint32_t etm_06_te_start_stop;
96 uint32_t etm_07_te_single_addr_comp;
97 uint32_t etm_08_te_event;
98 uint32_t etm_09_te_control;
99 uint32_t etm_0a_fifofull_region;
100 uint32_t etm_0b_fifofull_level;
101 uint32_t etm_0c_vd_event;
102 uint32_t etm_0d_vd_single_addr_comp;
103 uint32_t etm_0e_vd_mmd;
104 uint32_t etm_0f_vd_control;
105 uint32_t etm_addr_comp_value[8]; /* 10 to 17 */
106 uint32_t etm_addr_access_type[8]; /* 20 to 27 */
107 uint32_t etm_data_comp_value[2]; /* 30 and 32 */
108 uint32_t etm_data_comp_mask[2]; /* 40 and 42 */
109 uint32_t etm_counter_reload_value[2]; /* 50 to 51 */
110 uint32_t etm_counter_enable[2]; /* 54 to 55 */
111 uint32_t etm_counter_reload_event[2]; /* 58 to 59 */
112 uint32_t etm_60_seq_event_1_to_2;
113 uint32_t etm_61_seq_event_2_to_1;
114 uint32_t etm_62_seq_event_2_to_3;
115 uint32_t etm_63_seq_event_3_to_1;
116 uint32_t etm_64_seq_event_3_to_2;
117 uint32_t etm_65_seq_event_1_to_3;
118 uint32_t etm_6c_cid_comp_value_1;
119 uint32_t etm_6f_cid_comp_mask;
120 uint32_t etm_78_sync_freq;
121 uint32_t swconfig;
122 uint32_t etb_trig_cnt;
123 uint32_t etb_init_ptr;
124};
125
126static struct etm_config_struct etm_config = {
127 /* etm_00_control 0x0000D84E: 32-bit CID, cycle-accurate,
128 * monitorCPRT */
129 .etm_00_control = 0x0000D84E,
130 /* etm_02_trigger_event 0x00000000: address comparator 0 matches */
131 .etm_02_trigger_event = 0x00000000,
132 .etm_06_te_start_stop = 0x00000000,
133 .etm_07_te_single_addr_comp = 0x00000000,
134 /* etm_08_te_event 0x0000006F: always true */
135 .etm_08_te_event = 0x0000006F,
136 /* etm_09_te_control 0x01000000: exclude none */
137 .etm_09_te_control = 0x01000000,
138 .etm_0a_fifofull_region = 0x00000000,
139 .etm_0b_fifofull_level = 0x00000000,
140 /* etm_0c_vd_event 0x0000006F: always true */
141 .etm_0c_vd_event = 0x0000006F,
142 .etm_0d_vd_single_addr_comp = 0x00000000,
143 .etm_0e_vd_mmd = 0x00000000,
144 /* etm_0f_vd_control 0x00010000: exclude none */
145 .etm_0f_vd_control = 0x00010000,
146 .etm_addr_comp_value[0] = 0x00000000,
147 .etm_addr_comp_value[1] = 0x00000000,
148 .etm_addr_comp_value[2] = 0x00000000,
149 .etm_addr_comp_value[3] = 0x00000000,
150 .etm_addr_comp_value[4] = 0x00000000,
151 .etm_addr_comp_value[5] = 0x00000000,
152 .etm_addr_comp_value[6] = 0x00000000,
153 .etm_addr_comp_value[7] = 0x00000000,
154 .etm_addr_access_type[0] = 0x00000000,
155 .etm_addr_access_type[1] = 0x00000000,
156 .etm_addr_access_type[2] = 0x00000000,
157 .etm_addr_access_type[3] = 0x00000000,
158 .etm_addr_access_type[4] = 0x00000000,
159 .etm_addr_access_type[5] = 0x00000000,
160 .etm_addr_access_type[6] = 0x00000000,
161 .etm_addr_access_type[7] = 0x00000000,
162 .etm_data_comp_value[0] = 0x00000000,
163 .etm_data_comp_value[1] = 0x00000000,
164 .etm_data_comp_mask[0] = 0x00000000,
165 .etm_data_comp_mask[1] = 0x00000000,
166 .etm_counter_reload_value[0] = 0x00000000,
167 .etm_counter_reload_value[1] = 0x00000000,
168 .etm_counter_enable[0] = 0x0002406F,
169 .etm_counter_enable[1] = 0x0002406F,
170 .etm_counter_reload_event[0] = 0x0000406F,
171 .etm_counter_reload_event[1] = 0x0000406F,
172 .etm_60_seq_event_1_to_2 = 0x0000406F,
173 .etm_61_seq_event_2_to_1 = 0x0000406F,
174 .etm_62_seq_event_2_to_3 = 0x0000406F,
175 .etm_63_seq_event_3_to_1 = 0x0000406F,
176 .etm_64_seq_event_3_to_2 = 0x0000406F,
177 .etm_65_seq_event_1_to_3 = 0x0000406F,
178 .etm_6c_cid_comp_value_1 = 0x00000000,
179 .etm_6f_cid_comp_mask = 0x00000000,
180 .etm_78_sync_freq = 0x00000400,
181 .swconfig = 0x00000002,
182 /* etb_trig_cnt 0x00000000: ignore trigger */
183 .etb_trig_cnt = 0x00000000,
184 /* etb_init_ptr 0x00000010: 16 marker bytes */
185 .etb_init_ptr = 0x00000010,
186};
187
Pratik Patel17f3b822011-11-21 12:41:47 -0800188/* ETM clock is derived from the processor clock and gets enabled on a
189 * logical OR of below items on Scorpion:
190 * 1.CPMR[ETMCLKEN] is set
191 * 2.ETM is not idle. Also means ETMCR[PD] is 0
192 * 3.Reset is asserted (core or debug)
193 * 4.MRC/MCR to ETM reg (CP14 access)
194 * 5.Debugger access to a ETM register in the core power domain
195 *
196 * 1. and 2. above are permanent enables whereas 3., 4. and 5. are
197 * temporary enables
198 *
199 * We rely on 4. to be able to access ETMCR and then use 2. above for ETM
200 * clock vote in the driver and the save-restore code uses 1. above
201 * for its vote.
202 */
203static inline void __cpu_set_etm_pwrdwn(void)
204{
205 uint32_t etm_control;
206
207 isb();
208 etm_control = etm_read(ETMCR);
209 etm_control |= ETM_CONTROL_POWERDOWN;
210 etm_write(etm_control, ETMCR);
211}
212
213static inline void __cpu_clear_etm_pwrdwn(void)
214{
215 uint32_t etm_control;
216
217 etm_control = etm_read(ETMCR);
218 etm_control &= ~ETM_CONTROL_POWERDOWN;
219 etm_write(etm_control, ETMCR);
220 isb();
221}
222
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700223static void emit_log_char(uint8_t c)
224{
225 int this_cpu = get_cpu();
226 struct b *mybuf = *per_cpu_ptr(alloc_b, this_cpu);
227 char *log_buf = mybuf->etm_log_buf;
228 int index = (mybuf->log_end)++ & (LOG_BUF_LEN - 1);
229 log_buf[index] = c;
230 put_cpu();
231}
232
233static void emit_log_word(uint32_t word)
234{
235 emit_log_char(word >> 24);
236 emit_log_char(word >> 16);
237 emit_log_char(word >> 8);
238 emit_log_char(word >> 0);
239}
240
241static void __cpu_enable_etb(void)
242{
243 uint32_t etb_control;
244 uint32_t i;
245
246 /* enable auto-increment on reads and writes */
247 etb_control = AIR | AIW;
Pratik Patel17f3b822011-11-21 12:41:47 -0800248 etb_write(etb_control, ETB_REG_CONTROL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700249
250 /* write tags to the slots before the write pointer so we can
251 * detect overflow */
Pratik Patel17f3b822011-11-21 12:41:47 -0800252 etb_write(0x00000000, ETB_REG_ADDRESS);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700253 for (i = 0; i < (etm_config.etb_init_ptr >> 2); i++)
Pratik Patel17f3b822011-11-21 12:41:47 -0800254 etb_write(0xDEADBEEF, ETB_REG_DATA);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700255
Pratik Patel17f3b822011-11-21 12:41:47 -0800256 etb_write(0x00000000, ETB_REG_STATUS);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700257
258 /* initialize write pointer */
Pratik Patel17f3b822011-11-21 12:41:47 -0800259 etb_write(etm_config.etb_init_ptr, ETB_REG_ADDRESS);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700260
261 /* multiple of 16 */
Pratik Patel17f3b822011-11-21 12:41:47 -0800262 etb_write(etm_config.etb_trig_cnt & 0xFFFFFFF0, ETB_REG_COUNT);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700263
264 /* Enable ETB and enable the trigger counter as appropriate. A
265 * trigger count of 0 will be used to signify that the user wants to
266 * ignore the trigger (just keep writing to the ETB and overwriting
267 * the oldest data). For "trace before trigger" captures the user
268 * should set the trigger count to a small number. */
269
270 etb_control |= CPTEN;
271 if (etm_config.etb_trig_cnt)
272 etb_control |= CPTM;
Pratik Patel17f3b822011-11-21 12:41:47 -0800273 etb_write(etb_control, ETB_REG_CONTROL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700274}
275
276static void __cpu_disable_etb(void)
277{
278 uint32_t etb_control;
Pratik Patel17f3b822011-11-21 12:41:47 -0800279 etb_control = etb_read(ETB_REG_CONTROL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700280 etb_control &= ~CPTEN;
Pratik Patel17f3b822011-11-21 12:41:47 -0800281 etb_write(etb_control, ETB_REG_CONTROL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700282}
283
284static void __cpu_enable_etm(void)
285{
286 uint32_t etm_control;
287 unsigned long timeout = jiffies + msecs_to_jiffies(PROG_TIMEOUT_MS);
288
Pratik Patel17f3b822011-11-21 12:41:47 -0800289 etm_control = etm_read(ETMCR);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700290 etm_control &= ~ETM_CONTROL_PROGRAM;
Pratik Patel17f3b822011-11-21 12:41:47 -0800291 etm_write(etm_control, ETMCR);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700292
Pratik Patel17f3b822011-11-21 12:41:47 -0800293 while ((etm_read(ETMSR) & ETM_STATUS_PROGRAMMING) == 1) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700294 cpu_relax();
295 if (time_after(jiffies, timeout)) {
296 pr_err("etm: timeout while clearing prog bit\n");
297 break;
298 }
299 }
300}
301
302static void __cpu_disable_etm(void)
303{
304 uint32_t etm_control;
305 unsigned long timeout = jiffies + msecs_to_jiffies(PROG_TIMEOUT_MS);
306
Pratik Patel17f3b822011-11-21 12:41:47 -0800307 etm_control = etm_read(ETMCR);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700308 etm_control |= ETM_CONTROL_PROGRAM;
Pratik Patel17f3b822011-11-21 12:41:47 -0800309 etm_write(etm_control, ETMCR);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700310
Pratik Patel17f3b822011-11-21 12:41:47 -0800311 while ((etm_read(ETMSR) & ETM_STATUS_PROGRAMMING) == 0) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700312 cpu_relax();
313 if (time_after(jiffies, timeout)) {
314 pr_err("etm: timeout while setting prog bit\n");
315 break;
316 }
317 }
318}
319
320static void __cpu_enable_trace(void *unused)
321{
322 uint32_t etm_control;
323 uint32_t etm_trigger;
324 uint32_t etm_external_output;
325
326 get_cpu();
327
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700328 __cpu_disable_etb();
Pratik Patel17f3b822011-11-21 12:41:47 -0800329 /* vote for ETM power/clock enable */
330 __cpu_clear_etm_pwrdwn();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700331 __cpu_disable_etm();
332
333 etm_control = (etm_config.etm_00_control & ~ETM_CONTROL_POWERDOWN)
334 | ETM_CONTROL_PROGRAM;
Pratik Patel17f3b822011-11-21 12:41:47 -0800335 etm_write(etm_control, ETMCR);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700336
337 etm_trigger = etm_config.etm_02_trigger_event;
338 etm_external_output = 0x406F; /* always FALSE */
339
340 if (etm_config.swconfig & TRIGGER_ALL) {
341 uint32_t function = 0x5; /* A OR B */
342 uint32_t resource_b = 0x60; /* external input 1 */
343
344 etm_trigger &= 0x7F; /* keep resource A, clear function and
345 * resource B */
346 etm_trigger |= (function << 14);
347 etm_trigger |= (resource_b << 7);
348 etm_external_output = etm_trigger;
349 }
350
Pratik Patel17f3b822011-11-21 12:41:47 -0800351 etm_write(etm_trigger, ETMTRIGGER);
352 etm_write(etm_config.etm_06_te_start_stop, ETMTSSCR);
353 etm_write(etm_config.etm_07_te_single_addr_comp, ETMTECR2);
354 etm_write(etm_config.etm_08_te_event, ETMTEEVR);
355 etm_write(etm_config.etm_09_te_control, ETMTECR1);
356 etm_write(etm_config.etm_0a_fifofull_region, ETMFFRR);
357 etm_write(etm_config.etm_0b_fifofull_level, ETMFFLR);
358 etm_write(etm_config.etm_0c_vd_event, ETMVDEVR);
359 etm_write(etm_config.etm_0d_vd_single_addr_comp, ETMVDCR1);
360 etm_write(etm_config.etm_0e_vd_mmd, ETMVDCR2);
361 etm_write(etm_config.etm_0f_vd_control, ETMVDCR3);
362 etm_write(etm_config.etm_addr_comp_value[0], ETMACVR0);
363 etm_write(etm_config.etm_addr_comp_value[1], ETMACVR1);
364 etm_write(etm_config.etm_addr_comp_value[2], ETMACVR2);
365 etm_write(etm_config.etm_addr_comp_value[3], ETMACVR3);
366 etm_write(etm_config.etm_addr_comp_value[4], ETMACVR4);
367 etm_write(etm_config.etm_addr_comp_value[5], ETMACVR5);
368 etm_write(etm_config.etm_addr_comp_value[6], ETMACVR6);
369 etm_write(etm_config.etm_addr_comp_value[7], ETMACVR7);
370 etm_write(etm_config.etm_addr_access_type[0], ETMACTR0);
371 etm_write(etm_config.etm_addr_access_type[1], ETMACTR1);
372 etm_write(etm_config.etm_addr_access_type[2], ETMACTR2);
373 etm_write(etm_config.etm_addr_access_type[3], ETMACTR3);
374 etm_write(etm_config.etm_addr_access_type[4], ETMACTR4);
375 etm_write(etm_config.etm_addr_access_type[5], ETMACTR5);
376 etm_write(etm_config.etm_addr_access_type[6], ETMACTR6);
377 etm_write(etm_config.etm_addr_access_type[7], ETMACTR7);
378 etm_write(etm_config.etm_data_comp_value[0], ETMDCVR0);
Pratik Pateld5bbc762012-01-29 14:13:21 -0800379 etm_write(etm_config.etm_data_comp_value[1], ETMDCVR2);
Pratik Patel17f3b822011-11-21 12:41:47 -0800380 etm_write(etm_config.etm_data_comp_mask[0], ETMDCMR0);
Pratik Pateld5bbc762012-01-29 14:13:21 -0800381 etm_write(etm_config.etm_data_comp_mask[1], ETMDCMR2);
Pratik Patel17f3b822011-11-21 12:41:47 -0800382 etm_write(etm_config.etm_counter_reload_value[0], ETMCNTRLDVR0);
383 etm_write(etm_config.etm_counter_reload_value[1], ETMCNTRLDVR1);
384 etm_write(etm_config.etm_counter_enable[0], ETMCNTENR0);
385 etm_write(etm_config.etm_counter_enable[1], ETMCNTENR1);
386 etm_write(etm_config.etm_counter_reload_event[0], ETMCNTRLDEVR0);
387 etm_write(etm_config.etm_counter_reload_event[1], ETMCNTRLDEVR1);
388 etm_write(etm_config.etm_60_seq_event_1_to_2, ETMSQ12EVR);
389 etm_write(etm_config.etm_61_seq_event_2_to_1, ETMSQ21EVR);
390 etm_write(etm_config.etm_62_seq_event_2_to_3, ETMSQ23EVR);
391 etm_write(etm_config.etm_63_seq_event_3_to_1, ETMSQ31EVR);
392 etm_write(etm_config.etm_64_seq_event_3_to_2, ETMSQ32EVR);
393 etm_write(etm_config.etm_65_seq_event_1_to_3, ETMSQ13EVR);
394 etm_write(etm_external_output, ETMEXTOUTEVR0);
395 etm_write(etm_config.etm_6c_cid_comp_value_1, ETMCIDCVR0);
396 etm_write(etm_config.etm_6f_cid_comp_mask, ETMCIDCMR);
397 etm_write(etm_config.etm_78_sync_freq, ETMSYNCFR);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700398
399 /* Note that we must enable the ETB before we enable the ETM if we
400 * want to capture the "always true" trigger event. */
401
402 __cpu_enable_etb();
403 __cpu_enable_etm();
404
405 put_cpu();
406}
407
408static void __cpu_disable_trace(void *unused)
409{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700410 get_cpu();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700411
412 __cpu_disable_etm();
413
414 /* program trace enable to be low by using always false event */
Pratik Patel17f3b822011-11-21 12:41:47 -0800415 etm_write(0x6F | BIT(14), ETMTEEVR);
416 /* vote for ETM power/clock disable */
417 __cpu_set_etm_pwrdwn();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700418
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700419 __cpu_disable_etb();
420
421 put_cpu();
422}
423
424static void enable_trace(void)
425{
426 wake_lock(&etm_wake_lock);
427 pm_qos_update_request(&etm_qos_req, 0);
428
429 if (etm_config.swconfig & TRIGGER_ALL) {
430 /* This register is accessible from either core.
431 * CPU1_extout[0] -> CPU0_extin[0]
432 * CPU_extout[0] -> CPU1_extin[0] */
Pratik Patel17f3b822011-11-21 12:41:47 -0800433 asm volatile("mcr p15, 3, %0, c15, c5, 2" : : "r" (0x1));
434 asm volatile("isb");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700435 }
436
437 get_cpu();
438 __cpu_enable_trace(NULL);
439 smp_call_function(__cpu_enable_trace, NULL, 1);
440 put_cpu();
441
Pratik Patele5771792011-09-17 18:33:54 -0700442 /* 1. causes all online cpus to come out of idle PC
443 * 2. prevents idle PC until save restore flag is enabled atomically
444 *
445 * we rely on the user to prevent hotplug on/off racing with this
446 * operation and to ensure cores where trace is expected to be turned
447 * on are already hotplugged on
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700448 */
449 trace_enabled = 1;
450
451 pm_qos_update_request(&etm_qos_req, PM_QOS_DEFAULT_VALUE);
452 wake_unlock(&etm_wake_lock);
453}
454
455static void disable_trace(void)
456{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700457 wake_lock(&etm_wake_lock);
458 pm_qos_update_request(&etm_qos_req, 0);
459
460 get_cpu();
461 __cpu_disable_trace(NULL);
462 smp_call_function(__cpu_disable_trace, NULL, 1);
463 put_cpu();
464
Pratik Patele5771792011-09-17 18:33:54 -0700465 /* 1. causes all online cpus to come out of idle PC
466 * 2. prevents idle PC until save restore flag is disabled atomically
467 *
468 * we rely on the user to prevent hotplug on/off racing with this
469 * operation and to ensure cores where trace is expected to be turned
470 * off are already hotplugged on
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700471 */
472 trace_enabled = 0;
473
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700474 cpu_to_dump = next_cpu_to_dump = 0;
475
476 pm_qos_update_request(&etm_qos_req, PM_QOS_DEFAULT_VALUE);
477 wake_unlock(&etm_wake_lock);
478}
479
480static void generate_etb_dump(void)
481{
482 uint32_t i;
483 uint32_t full_slots;
484 uint32_t etb_control;
485 uint32_t prim_len;
486 uint32_t uptime = 0;
487
Pratik Patel17f3b822011-11-21 12:41:47 -0800488 etb_control = etb_read(ETB_REG_CONTROL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700489 etb_control |= AIR;
Pratik Patel17f3b822011-11-21 12:41:47 -0800490 etb_write(etb_control, ETB_REG_CONTROL);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700491
Pratik Patel17f3b822011-11-21 12:41:47 -0800492 if (etb_read(ETB_REG_STATUS) & OV)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700493 full_slots = ETB_RAM_SLOTS;
494 else
Pratik Patel17f3b822011-11-21 12:41:47 -0800495 full_slots = etb_read(ETB_REG_ADDRESS) >> 2;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700496
497 prim_len = 28 + (full_slots * 4);
498
499 emit_log_char((DATALOG_SYNC >> 8) & 0xFF);
500 emit_log_char((DATALOG_SYNC >> 0) & 0xFF);
501 emit_log_char((prim_len >> 8) & 0xFF);
502 emit_log_char((prim_len >> 0) & 0xFF);
503 emit_log_word(uptime);
504 emit_log_word(ETB_DUMP_MSG_ID);
Pratik Patel17f3b822011-11-21 12:41:47 -0800505 emit_log_word(etm_read(ETMCR));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700506 emit_log_word(etm_config.etb_init_ptr >> 2);
Pratik Patel17f3b822011-11-21 12:41:47 -0800507 emit_log_word(etb_read(ETB_REG_ADDRESS) >> 2);
508 emit_log_word((etb_read(ETB_REG_STATUS) & OV) >> 21);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700509
Pratik Patel17f3b822011-11-21 12:41:47 -0800510 etb_write(0x00000000, ETB_REG_ADDRESS);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700511 for (i = 0; i < full_slots; i++)
Pratik Patel17f3b822011-11-21 12:41:47 -0800512 emit_log_word(etb_read(ETB_REG_DATA));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700513}
514
Pratik Patel17f3b822011-11-21 12:41:47 -0800515/* This should match the number of ETM registers being dumped below */
516#define ETM_NUM_REGS_TO_DUMP 54
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700517static void generate_etm_dump(void)
518{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700519 uint32_t prim_len;
520 uint32_t uptime = 0;
521
Pratik Patel17f3b822011-11-21 12:41:47 -0800522 prim_len = 12 + (4 * ETM_NUM_REGS_TO_DUMP);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700523
524 emit_log_char((DATALOG_SYNC >> 8) & 0xFF);
525 emit_log_char((DATALOG_SYNC >> 0) & 0xFF);
526 emit_log_char((prim_len >> 8) & 0xFF);
527 emit_log_char((prim_len >> 0) & 0xFF);
528 emit_log_word(uptime);
529 emit_log_word(ETM_DUMP_MSG_ID);
530
Pratik Patel17f3b822011-11-21 12:41:47 -0800531 emit_log_word(etm_read(ETMCR));
532 emit_log_word(etm_read(ETMSR));
533 emit_log_word(etb_read(ETB_REG_CONTROL));
534 emit_log_word(etb_read(ETB_REG_STATUS));
535 emit_log_word(etb_read(ETB_REG_COUNT));
536 emit_log_word(etb_read(ETB_REG_ADDRESS));
537 emit_log_word(0); /* don't read ETB_REG_DATA, changes ETB_REG_ADDRESS */
538 emit_log_word(etm_read(ETMTRIGGER));
539 emit_log_word(etm_read(ETMTSSCR));
540 emit_log_word(etm_read(ETMTECR2));
541 emit_log_word(etm_read(ETMTEEVR));
542 emit_log_word(etm_read(ETMTECR1));
543 emit_log_word(etm_read(ETMFFRR));
544 emit_log_word(etm_read(ETMFFLR));
545 emit_log_word(etm_read(ETMVDEVR));
546 emit_log_word(etm_read(ETMVDCR1));
547 emit_log_word(etm_read(ETMVDCR2));
548 emit_log_word(etm_read(ETMVDCR3));
549 emit_log_word(etm_read(ETMACVR0));
550 emit_log_word(etm_read(ETMACVR1));
551 emit_log_word(etm_read(ETMACVR2));
552 emit_log_word(etm_read(ETMACVR3));
553 emit_log_word(etm_read(ETMACVR4));
554 emit_log_word(etm_read(ETMACVR5));
555 emit_log_word(etm_read(ETMACVR6));
556 emit_log_word(etm_read(ETMACVR7));
557 emit_log_word(etm_read(ETMACTR0));
558 emit_log_word(etm_read(ETMACTR1));
559 emit_log_word(etm_read(ETMACTR2));
560 emit_log_word(etm_read(ETMACTR3));
561 emit_log_word(etm_read(ETMACTR4));
562 emit_log_word(etm_read(ETMACTR5));
563 emit_log_word(etm_read(ETMACTR6));
564 emit_log_word(etm_read(ETMACTR7));
565 emit_log_word(etm_read(ETMDCVR0));
Pratik Pateld5bbc762012-01-29 14:13:21 -0800566 emit_log_word(etm_read(ETMDCVR2));
Pratik Patel17f3b822011-11-21 12:41:47 -0800567 emit_log_word(etm_read(ETMDCMR0));
Pratik Pateld5bbc762012-01-29 14:13:21 -0800568 emit_log_word(etm_read(ETMDCMR2));
Pratik Patel17f3b822011-11-21 12:41:47 -0800569 emit_log_word(etm_read(ETMCNTRLDVR0));
570 emit_log_word(etm_read(ETMCNTRLDVR1));
571 emit_log_word(etm_read(ETMCNTENR0));
572 emit_log_word(etm_read(ETMCNTENR1));
573 emit_log_word(etm_read(ETMCNTRLDEVR0));
574 emit_log_word(etm_read(ETMCNTRLDEVR1));
575 emit_log_word(etm_read(ETMSQ12EVR));
576 emit_log_word(etm_read(ETMSQ21EVR));
577 emit_log_word(etm_read(ETMSQ23EVR));
578 emit_log_word(etm_read(ETMSQ31EVR));
579 emit_log_word(etm_read(ETMSQ32EVR));
580 emit_log_word(etm_read(ETMSQ13EVR));
581 emit_log_word(etm_read(ETMEXTOUTEVR0));
582 emit_log_word(etm_read(ETMCIDCVR0));
583 emit_log_word(etm_read(ETMCIDCMR));
584 emit_log_word(etm_read(ETMSYNCFR));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700585}
586
587static void dump_all(void *unused)
588{
589 get_cpu();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700590 __cpu_disable_etb();
591 generate_etm_dump();
592 generate_etb_dump();
593 if (trace_enabled)
594 __cpu_enable_etb();
595 put_cpu();
596}
597
598static void dump_trace(void)
599{
600 get_cpu();
601 dump_all(NULL);
602 smp_call_function(dump_all, NULL, 1);
603 put_cpu();
604}
605
606static int bytes_to_dump;
607static uint8_t *etm_buf_ptr;
608
609static int etm_dev_open(struct inode *inode, struct file *file)
610{
611 if (atomic_cmpxchg(&etm_dev_in_use, 0, 1))
612 return -EBUSY;
613
614 pr_debug("%s: successfully opened\n", __func__);
615 return 0;
616}
617
618static ssize_t etm_dev_read(struct file *file, char __user *data,
619 size_t len, loff_t *ppos)
620{
621 if (cpu_to_dump == next_cpu_to_dump) {
622 if (cpu_to_dump == 0)
623 dump_trace();
624 bytes_to_dump = buf[cpu_to_dump].log_end;
625 buf[cpu_to_dump].log_end = 0;
626 etm_buf_ptr = buf[cpu_to_dump].etm_log_buf;
627 next_cpu_to_dump++;
628 if (next_cpu_to_dump >= num_possible_cpus())
629 next_cpu_to_dump = 0;
630 }
631
632 if (len > bytes_to_dump)
633 len = bytes_to_dump;
634
635 if (copy_to_user(data, etm_buf_ptr, len)) {
636 pr_debug("%s: copy_to_user failed\n", __func__);
637 return -EFAULT;
638 }
639
640 bytes_to_dump -= len;
641 etm_buf_ptr += len;
642
643 pr_debug("%s: %d bytes copied, %d bytes left (cpu %d)\n",
644 __func__, len, bytes_to_dump, next_cpu_to_dump);
645 return len;
646}
647
648static void setup_range_filter(char addr_type, char range, uint32_t reg1,
649 uint32_t addr1, uint32_t reg2, uint32_t addr2)
650{
651 etm_config.etm_addr_comp_value[reg1] = addr1;
652 etm_config.etm_addr_comp_value[reg2] = addr2;
653
654 etm_config.etm_07_te_single_addr_comp |= (1 << reg1);
655 etm_config.etm_07_te_single_addr_comp |= (1 << reg2);
656
657 etm_config.etm_09_te_control |= (1 << (reg1/2));
658 if (range == 'i')
659 etm_config.etm_09_te_control &= ~(1 << 24);
660 else if (range == 'e')
661 etm_config.etm_09_te_control |= (1 << 24);
662
663 if (addr_type == 'i') {
664 etm_config.etm_addr_access_type[reg1] = 0x99;
665 etm_config.etm_addr_access_type[reg2] = 0x99;
666 } else if (addr_type == 'd') {
667 etm_config.etm_addr_access_type[reg1] = 0x9C;
668 etm_config.etm_addr_access_type[reg2] = 0x9C;
669 }
670}
671
672static void setup_start_stop_filter(char addr_type, char start_stop,
673 uint32_t reg, uint32_t addr)
674{
675 etm_config.etm_addr_comp_value[reg] = addr;
676
677 if (start_stop == 's')
678 etm_config.etm_06_te_start_stop |= (1 << reg);
679 else if (start_stop == 't')
680 etm_config.etm_06_te_start_stop |= (1 << (reg + 16));
681
682 etm_config.etm_09_te_control |= (1 << 25);
683
684 if (addr_type == 'i')
685 etm_config.etm_addr_access_type[reg] = 0x99;
686 else if (addr_type == 'd')
687 etm_config.etm_addr_access_type[reg] = 0x9C;
688}
689
690static void setup_viewdata_range_filter(char range, uint32_t reg1,
691 uint32_t addr1, uint32_t reg2, uint32_t addr2)
692{
693 etm_config.etm_addr_comp_value[reg1] = addr1;
694 etm_config.etm_addr_comp_value[reg2] = addr2;
695
696 if (range == 'i') {
697 etm_config.etm_0d_vd_single_addr_comp |= (1 << reg1);
698 etm_config.etm_0d_vd_single_addr_comp |= (1 << reg2);
699 etm_config.etm_0f_vd_control |= (1 << (reg1/2));
700 } else if (range == 'e') {
701 etm_config.etm_0d_vd_single_addr_comp |= (1 << (reg1 + 16));
702 etm_config.etm_0d_vd_single_addr_comp |= (1 << (reg2 + 16));
703 etm_config.etm_0f_vd_control |= (1 << ((reg1/2) + 8));
704 }
705 etm_config.etm_0f_vd_control &= ~(1 << 16);
706
707 etm_config.etm_addr_access_type[reg1] = 0x9C;
708 etm_config.etm_addr_access_type[reg2] = 0x9C;
709}
710
711static void setup_viewdata_start_stop_filter(char start_stop, uint32_t reg,
712 uint32_t addr)
713{
714 etm_config.etm_addr_comp_value[reg] = addr;
715
716 if (start_stop == 's')
717 etm_config.etm_06_te_start_stop |= (1 << reg);
718 else if (start_stop == 't')
719 etm_config.etm_06_te_start_stop |= (1 << (reg + 16));
720
721 etm_config.etm_addr_access_type[reg] = 0x9C;
722}
723
724static void setup_access_type(uint32_t reg, uint32_t value)
725{
726 etm_config.etm_addr_access_type[reg] &= 0xFFFFFFF8;
727 value &= 0x7;
728 etm_config.etm_addr_access_type[reg] |= value;
729}
730
731static void reset_filter(void)
732{
733 etm_config.etm_00_control = 0x0000D84E;
734 /* etm_02_trigger_event 0x00000000: address comparator 0 matches */
735 etm_config.etm_02_trigger_event = 0x00000000;
736 etm_config.etm_06_te_start_stop = 0x00000000;
737 etm_config.etm_07_te_single_addr_comp = 0x00000000;
738 /* etm_08_te_event 0x0000006F: always true */
739 etm_config.etm_08_te_event = 0x0000006F;
740 /* etm_09_te_control 0x01000000: exclude none */
741 etm_config.etm_09_te_control = 0x01000000;
742 etm_config.etm_0a_fifofull_region = 0x00000000;
743 etm_config.etm_0b_fifofull_level = 0x00000000;
744 /* etm_0c_vd_event 0x0000006F: always true */
745 etm_config.etm_0c_vd_event = 0x0000006F;
746 etm_config.etm_0d_vd_single_addr_comp = 0x00000000;
747 etm_config.etm_0e_vd_mmd = 0x00000000;
748 /* etm_0f_vd_control 0x00010000: exclude none */
749 etm_config.etm_0f_vd_control = 0x00010000;
750 etm_config.etm_addr_comp_value[0] = 0x00000000;
751 etm_config.etm_addr_comp_value[1] = 0x00000000;
752 etm_config.etm_addr_comp_value[2] = 0x00000000;
753 etm_config.etm_addr_comp_value[3] = 0x00000000;
754 etm_config.etm_addr_comp_value[4] = 0x00000000;
755 etm_config.etm_addr_comp_value[5] = 0x00000000;
756 etm_config.etm_addr_comp_value[6] = 0x00000000;
757 etm_config.etm_addr_comp_value[7] = 0x00000000;
758 etm_config.etm_addr_access_type[0] = 0x00000000;
759 etm_config.etm_addr_access_type[1] = 0x00000000;
760 etm_config.etm_addr_access_type[2] = 0x00000000;
761 etm_config.etm_addr_access_type[3] = 0x00000000;
762 etm_config.etm_addr_access_type[4] = 0x00000000;
763 etm_config.etm_addr_access_type[5] = 0x00000000;
764 etm_config.etm_addr_access_type[6] = 0x00000000;
765 etm_config.etm_addr_access_type[7] = 0x00000000;
766 etm_config.etm_data_comp_value[0] = 0x00000000;
767 etm_config.etm_data_comp_value[1] = 0x00000000;
768 etm_config.etm_data_comp_mask[0] = 0x00000000;
769 etm_config.etm_data_comp_mask[1] = 0x00000000;
770 etm_config.etm_counter_reload_value[0] = 0x00000000;
771 etm_config.etm_counter_reload_value[1] = 0x00000000;
772 etm_config.etm_counter_enable[0] = 0x0002406F;
773 etm_config.etm_counter_enable[1] = 0x0002406F;
774 etm_config.etm_counter_reload_event[0] = 0x0000406F;
775 etm_config.etm_counter_reload_event[1] = 0x0000406F;
776 etm_config.etm_60_seq_event_1_to_2 = 0x0000406F;
777 etm_config.etm_61_seq_event_2_to_1 = 0x0000406F;
778 etm_config.etm_62_seq_event_2_to_3 = 0x0000406F;
779 etm_config.etm_63_seq_event_3_to_1 = 0x0000406F;
780 etm_config.etm_64_seq_event_3_to_2 = 0x0000406F;
781 etm_config.etm_65_seq_event_1_to_3 = 0x0000406F;
782 etm_config.etm_6c_cid_comp_value_1 = 0x00000000;
783 etm_config.etm_6f_cid_comp_mask = 0x00000000;
784 etm_config.etm_78_sync_freq = 0x00000400;
785 etm_config.swconfig = 0x00000002;
786 /* etb_trig_cnt 0x00000020: ignore trigger */
787 etm_config.etb_trig_cnt = 0x00000000;
788 /* etb_init_ptr 0x00000010: 16 marker bytes */
789 etm_config.etb_init_ptr = 0x00000010;
790}
791
792#define MAX_COMMAND_STRLEN 40
793static ssize_t etm_dev_write(struct file *file, const char __user *data,
794 size_t len, loff_t *ppos)
795{
796 char command[MAX_COMMAND_STRLEN];
797 int strlen;
798 unsigned long value;
799 unsigned long reg1, reg2;
800 unsigned long addr1, addr2;
801
802 strlen = strnlen_user(data, MAX_COMMAND_STRLEN);
803 pr_debug("etm: string length: %d", strlen);
804 if (strlen == 0 || strlen == (MAX_COMMAND_STRLEN+1)) {
805 pr_err("etm: error in strlen: %d", strlen);
806 return -EFAULT;
807 }
808 /* includes the null character */
809 if (copy_from_user(command, data, strlen)) {
810 pr_err("etm: error in copy_from_user: %d", strlen);
811 return -EFAULT;
812 }
813
814 pr_debug("etm: input = %s", command);
815
816 switch (command[0]) {
817 case '0':
818 if (trace_enabled) {
819 disable_trace();
820 pr_info("etm: tracing disabled\n");
821 }
822 break;
823 case '1':
824 if (!trace_enabled) {
825 enable_trace();
826 pr_info("etm: tracing enabled\n");
827 }
828 break;
829 case 'f':
830 switch (command[2]) {
831 case 'i':
832 case 'd':
833 switch (command[4]) {
834 case 'i':
835 if (sscanf(&command[6], "%lx:%lx:%lx:%lx\\0",
836 &reg1, &addr1, &reg2, &addr2) != 4)
837 goto err_out;
838 if (reg1 > 7 || reg2 > 7 || (reg1 % 2))
839 goto err_out;
840 setup_range_filter(command[2], 'i',
841 reg1, addr1, reg2, addr2);
842 break;
843 case 'e':
844 if (sscanf(&command[6], "%lx:%lx:%lx:%lx\\0",
845 &reg1, &addr1, &reg2, &addr2) != 4)
846 goto err_out;
847 if (reg1 > 7 || reg2 > 7 || (reg1 % 2)
848 || command[2] == 'd')
849 goto err_out;
850 setup_range_filter(command[2], 'e',
851 reg1, addr1, reg2, addr2);
852 break;
853 case 's':
854 if (sscanf(&command[6], "%lx:%lx\\0",
855 &reg1, &addr1) != 2)
856 goto err_out;
857 if (reg1 > 7)
858 goto err_out;
859 setup_start_stop_filter(command[2], 's',
860 reg1, addr1);
861 break;
862 case 't':
863 if (sscanf(&command[6], "%lx:%lx\\0",
864 &reg1, &addr1) != 2)
865 goto err_out;
866 if (reg1 > 7)
867 goto err_out;
868 setup_start_stop_filter(command[2], 't',
869 reg1, addr1);
870 break;
871 default:
872 goto err_out;
873 }
874 break;
875 case 'r':
876 reset_filter();
877 break;
878 default:
879 goto err_out;
880 }
881 break;
882 case 'v':
883 switch (command[2]) {
884 case 'd':
885 switch (command[4]) {
886 case 'i':
887 if (sscanf(&command[6], "%lx:%lx:%lx:%lx\\0",
888 &reg1, &addr1, &reg2, &addr2) != 4)
889 goto err_out;
890 if (reg1 > 7 || reg2 > 7 || (reg1 % 2))
891 goto err_out;
892 setup_viewdata_range_filter('i',
893 reg1, addr1, reg2, addr2);
894 break;
895 case 'e':
896 if (sscanf(&command[6], "%lx:%lx:%lx:%lx\\0",
897 &reg1, &addr1, &reg2, &addr2) != 4)
898 goto err_out;
899 if (reg1 > 7 || reg2 > 7 || (reg1 % 2))
900 goto err_out;
901 setup_viewdata_range_filter('e',
902 reg1, addr1, reg2, addr2);
903 break;
904 case 's':
905 if (sscanf(&command[6], "%lx:%lx\\0",
906 &reg1, &addr1) != 2)
907 goto err_out;
908 if (reg1 > 7)
909 goto err_out;
910 setup_viewdata_start_stop_filter('s',
911 reg1, addr1);
912 break;
913 case 't':
914 if (sscanf(&command[6], "%lx:%lx\\0",
915 &reg1, &addr1) != 2)
916 goto err_out;
917 if (reg1 > 7)
918 goto err_out;
919 setup_viewdata_start_stop_filter('t',
920 reg1, addr1);
921 break;
922 default:
923 goto err_out;
924 }
925 break;
926 default:
927 goto err_out;
928 }
929 break;
930 case 'a':
931 switch (command[2]) {
932 case 't':
933 if (sscanf(&command[4], "%lx:%lx\\0",
934 &reg1, &value) != 2)
935 goto err_out;
936 if (reg1 > 7 || value > 6)
937 goto err_out;
938 setup_access_type(reg1, value);
939 break;
940 default:
941 goto err_out;
942 }
943 break;
944 default:
945 goto err_out;
946 }
947
948 return len;
949
950err_out:
951 return -EFAULT;
952}
953
954static int etm_dev_release(struct inode *inode, struct file *file)
955{
956 if (cpu_to_dump == next_cpu_to_dump)
957 next_cpu_to_dump = 0;
958 cpu_to_dump = next_cpu_to_dump;
959
960 atomic_set(&etm_dev_in_use, 0);
961 pr_debug("%s: released\n", __func__);
962 return 0;
963}
964
965static const struct file_operations etm_dev_fops = {
966 .owner = THIS_MODULE,
967 .open = etm_dev_open,
968 .read = etm_dev_read,
969 .write = etm_dev_write,
970 .release = etm_dev_release,
971};
972
973static struct miscdevice etm_dev = {
974 .name = "msm_etm",
975 .minor = MISC_DYNAMIC_MINOR,
976 .fops = &etm_dev_fops,
977};
978
Pratik Patel17f3b822011-11-21 12:41:47 -0800979static void __cpu_clear_sticky(void *unused)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700980{
Pratik Patel17f3b822011-11-21 12:41:47 -0800981 etm_read(ETMPDSR); /* clear sticky bit in PDSR */
982 isb();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700983}
984
985static int __init etm_init(void)
986{
987 int ret, cpu;
988
989 ret = misc_register(&etm_dev);
990 if (ret)
991 return -ENODEV;
992
993 alloc_b = alloc_percpu(typeof(*alloc_b));
994 if (!alloc_b)
995 goto err1;
996
997 for_each_possible_cpu(cpu)
998 *per_cpu_ptr(alloc_b, cpu) = &buf[cpu];
999
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001000 wake_lock_init(&etm_wake_lock, WAKE_LOCK_SUSPEND, "msm_etm");
1001 pm_qos_add_request(&etm_qos_req, PM_QOS_CPU_DMA_LATENCY,
1002 PM_QOS_DEFAULT_VALUE);
1003
Pratik Patel17f3b822011-11-21 12:41:47 -08001004 /* No need to explicity turn on ETM clock since CP14 access go
1005 * through via the autoclock turn on/off
1006 */
1007 __cpu_clear_sticky(NULL);
1008 smp_call_function(__cpu_clear_sticky, NULL, 1);
1009
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001010 cpu_to_dump = next_cpu_to_dump = 0;
1011
1012 pr_info("ETM/ETB intialized.\n");
1013
1014 if (trace_on_boot)
1015 enable_trace();
1016
1017 return 0;
1018
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001019err1:
1020 misc_deregister(&etm_dev);
1021 return -ENOMEM;
1022}
Pratik Patele5771792011-09-17 18:33:54 -07001023module_init(etm_init);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001024
1025static void __exit etm_exit(void)
1026{
1027 disable_trace();
1028 pm_qos_remove_request(&etm_qos_req);
1029 wake_lock_destroy(&etm_wake_lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001030 free_percpu(alloc_b);
1031 misc_deregister(&etm_dev);
1032}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001033module_exit(etm_exit);
Pratik Patele5771792011-09-17 18:33:54 -07001034
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001035MODULE_LICENSE("GPL v2");
1036MODULE_DESCRIPTION("embedded trace driver");