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