blob: c961713e2f4fb0b13a6f17d73e6ef61fa6d6a39c [file] [log] [blame]
Pratik Patelef6da292012-09-17 17:37:19 -07001/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
Pratik Patel7831c082011-06-08 21:44:37 -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/kernel.h>
14#include <linux/module.h>
Pratik Patelcf418622011-09-22 11:15:11 -070015#include <linux/init.h>
16#include <linux/types.h>
17#include <linux/device.h>
Pratik Patel7831c082011-06-08 21:44:37 -070018#include <linux/platform_device.h>
19#include <linux/io.h>
20#include <linux/err.h>
21#include <linux/fs.h>
Pratik Patel7831c082011-06-08 21:44:37 -070022#include <linux/slab.h>
23#include <linux/delay.h>
24#include <linux/smp.h>
Pratik Patel7831c082011-06-08 21:44:37 -070025#include <linux/wakelock.h>
Pratik Patel6630ebe2012-03-06 16:44:22 -080026#include <linux/sysfs.h>
27#include <linux/stat.h>
Pratik Patel3b0ca882012-06-01 16:54:14 -070028#include <linux/mutex.h>
Pratik Patelf17b1472012-05-25 22:23:52 -070029#include <linux/clk.h>
Pratik Patel5f6d1af2012-06-13 15:48:13 -070030#include <linux/of_coresight.h>
Pratik Patel1746b8f2012-06-02 21:11:41 -070031#include <linux/coresight.h>
Pratik Pateld30deda2012-02-01 14:40:55 -080032#include <asm/sections.h>
Pratik Patel2d0c7b62012-02-24 19:04:37 -080033#include <mach/socinfo.h>
Pratik Patel26477792012-09-07 01:35:36 -070034#include <mach/msm_memory_dump.h>
Pratik Patel7831c082011-06-08 21:44:37 -070035
Pratik Patel1746b8f2012-06-02 21:11:41 -070036#include "coresight-priv.h"
Pratik Patel7831c082011-06-08 21:44:37 -070037
Pratik Patele6e41da2012-09-12 12:50:29 -070038#define etm_writel_mm(drvdata, val, off) \
Pratik Patel3b0ca882012-06-01 16:54:14 -070039 __raw_writel((val), drvdata->base + off)
Pratik Patele6e41da2012-09-12 12:50:29 -070040#define etm_readl_mm(drvdata, off) \
Pratik Patel3b0ca882012-06-01 16:54:14 -070041 __raw_readl(drvdata->base + off)
42
Pratik Patele6e41da2012-09-12 12:50:29 -070043#define etm_writel(drvdata, val, off) \
44({ \
45 if (cpu_is_krait_v3()) \
46 etm_writel_cp14(val, off); \
47 else \
48 etm_writel_mm(drvdata, val, off); \
49})
50#define etm_readl(drvdata, off) \
51({ \
52 uint32_t val; \
53 if (cpu_is_krait_v3()) \
54 val = etm_readl_cp14(off); \
55 else \
56 val = etm_readl_mm(drvdata, off); \
57 val; \
58})
59
Pratik Patel3b0ca882012-06-01 16:54:14 -070060#define ETM_LOCK(drvdata) \
61do { \
Pratik Patele6e41da2012-09-12 12:50:29 -070062 /* recommended by spec to ensure ETM writes are committed prior
63 * to resuming execution
64 */ \
Pratik Patel3b0ca882012-06-01 16:54:14 -070065 mb(); \
Pratik Patele6e41da2012-09-12 12:50:29 -070066 isb(); \
67 etm_writel_mm(drvdata, 0x0, CORESIGHT_LAR); \
Pratik Patel3b0ca882012-06-01 16:54:14 -070068} while (0)
69#define ETM_UNLOCK(drvdata) \
70do { \
Pratik Patele6e41da2012-09-12 12:50:29 -070071 etm_writel_mm(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR); \
72 /* ensure unlock and any pending writes are committed prior to
73 * programming ETM registers
74 */ \
Pratik Patel3b0ca882012-06-01 16:54:14 -070075 mb(); \
Pratik Patele6e41da2012-09-12 12:50:29 -070076 isb(); \
Pratik Patel3b0ca882012-06-01 16:54:14 -070077} while (0)
78
Pratik Patel7831c082011-06-08 21:44:37 -070079/*
80 * Device registers:
81 * 0x000 - 0x2FC: Trace registers
82 * 0x300 - 0x314: Management registers
83 * 0x318 - 0xEFC: Trace registers
84 *
85 * Coresight registers
86 * 0xF00 - 0xF9C: Management registers
87 * 0xFA0 - 0xFA4: Management registers in PFTv1.0
88 * Trace registers in PFTv1.1
89 * 0xFA8 - 0xFFC: Management registers
90 */
91
92/* Trace registers (0x000-0x2FC) */
93#define ETMCR (0x000)
94#define ETMCCR (0x004)
95#define ETMTRIGGER (0x008)
96#define ETMSR (0x010)
97#define ETMSCR (0x014)
98#define ETMTSSCR (0x018)
99#define ETMTEEVR (0x020)
100#define ETMTECR1 (0x024)
101#define ETMFFLR (0x02C)
102#define ETMACVRn(n) (0x040 + (n * 4))
103#define ETMACTRn(n) (0x080 + (n * 4))
104#define ETMCNTRLDVRn(n) (0x140 + (n * 4))
105#define ETMCNTENRn(n) (0x150 + (n * 4))
106#define ETMCNTRLDEVRn(n) (0x160 + (n * 4))
107#define ETMCNTVRn(n) (0x170 + (n * 4))
108#define ETMSQ12EVR (0x180)
109#define ETMSQ21EVR (0x184)
110#define ETMSQ23EVR (0x188)
Pratik Pateld5bbc762012-01-29 14:13:21 -0800111#define ETMSQ31EVR (0x18C)
112#define ETMSQ32EVR (0x190)
113#define ETMSQ13EVR (0x194)
Pratik Patel7831c082011-06-08 21:44:37 -0700114#define ETMSQR (0x19C)
115#define ETMEXTOUTEVRn(n) (0x1A0 + (n * 4))
116#define ETMCIDCVRn(n) (0x1B0 + (n * 4))
117#define ETMCIDCMR (0x1BC)
118#define ETMIMPSPEC0 (0x1C0)
119#define ETMIMPSPEC1 (0x1C4)
120#define ETMIMPSPEC2 (0x1C8)
121#define ETMIMPSPEC3 (0x1CC)
122#define ETMIMPSPEC4 (0x1D0)
123#define ETMIMPSPEC5 (0x1D4)
124#define ETMIMPSPEC6 (0x1D8)
125#define ETMIMPSPEC7 (0x1DC)
126#define ETMSYNCFR (0x1E0)
127#define ETMIDR (0x1E4)
128#define ETMCCER (0x1E8)
129#define ETMEXTINSELR (0x1EC)
130#define ETMTESSEICR (0x1F0)
131#define ETMEIBCR (0x1F4)
132#define ETMTSEVR (0x1F8)
133#define ETMAUXCR (0x1FC)
134#define ETMTRACEIDR (0x200)
Pratik Pateld5bbc762012-01-29 14:13:21 -0800135#define ETMVMIDCVR (0x240)
Pratik Patel7831c082011-06-08 21:44:37 -0700136/* Management registers (0x300-0x314) */
137#define ETMOSLAR (0x300)
138#define ETMOSLSR (0x304)
139#define ETMOSSRR (0x308)
140#define ETMPDCR (0x310)
141#define ETMPDSR (0x314)
142
Pratik Patel61de7302012-03-07 12:06:10 -0800143#define ETM_MAX_ADDR_CMP (16)
144#define ETM_MAX_CNTR (4)
145#define ETM_MAX_CTXID_CMP (3)
146
Pratik Patel6630ebe2012-03-06 16:44:22 -0800147#define ETM_MODE_EXCLUDE BIT(0)
148#define ETM_MODE_CYCACC BIT(1)
149#define ETM_MODE_STALL BIT(2)
150#define ETM_MODE_TIMESTAMP BIT(3)
151#define ETM_MODE_CTXID BIT(4)
152#define ETM_MODE_ALL (0x1F)
153
154#define ETM_EVENT_MASK (0x1FFFF)
155#define ETM_SYNC_MASK (0xFFF)
156#define ETM_ALL_MASK (0xFFFFFFFF)
157
158#define ETM_SEQ_STATE_MAX_VAL (0x2)
159
Pratik Patel26477792012-09-07 01:35:36 -0700160#define ETM_REG_DUMP_VER_OFF (4)
161#define ETM_REG_DUMP_VER (1)
162
Pratik Patel3b0ca882012-06-01 16:54:14 -0700163enum etm_addr_type {
Pratik Patel6630ebe2012-03-06 16:44:22 -0800164 ETM_ADDR_TYPE_NONE,
165 ETM_ADDR_TYPE_SINGLE,
166 ETM_ADDR_TYPE_RANGE,
167 ETM_ADDR_TYPE_START,
168 ETM_ADDR_TYPE_STOP,
169};
170
Pratik Patel29cba152012-01-03 11:40:26 -0800171#ifdef CONFIG_MSM_QDSS_ETM_DEFAULT_ENABLE
Pratik Patel3b0ca882012-06-01 16:54:14 -0700172static int boot_enable = 1;
Pratik Patel29cba152012-01-03 11:40:26 -0800173#else
Pratik Patel3b0ca882012-06-01 16:54:14 -0700174static int boot_enable;
Pratik Patel29cba152012-01-03 11:40:26 -0800175#endif
Pratik Patel7831c082011-06-08 21:44:37 -0700176module_param_named(
Pratik Patel3b0ca882012-06-01 16:54:14 -0700177 boot_enable, boot_enable, int, S_IRUGO
Pratik Patel7831c082011-06-08 21:44:37 -0700178);
179
Pratik Patel938e1ff2012-09-28 23:21:46 -0700180#ifdef CONFIG_MSM_QDSS_ETM_PCSAVE_DEFAULT_ENABLE
181static int boot_pcsave_enable = 1;
182#else
183static int boot_pcsave_enable;
184#endif
185module_param_named(
186 boot_pcsave_enable, boot_pcsave_enable, int, S_IRUGO
187);
188
Pratik Patel16aefdb2012-05-30 10:41:23 -0700189struct etm_drvdata {
Pratik Patel7831c082011-06-08 21:44:37 -0700190 void __iomem *base;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700191 struct device *dev;
192 struct coresight_device *csdev;
193 struct clk *clk;
194 struct mutex mutex;
Pratik Patel7831c082011-06-08 21:44:37 -0700195 struct wake_lock wake_lock;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700196 int cpu;
Pratik Patel61de7302012-03-07 12:06:10 -0800197 uint8_t arch;
Pratik Patelf3238df2012-10-19 16:19:12 -0700198 bool enable;
Pratik Patel61de7302012-03-07 12:06:10 -0800199 uint8_t nr_addr_cmp;
200 uint8_t nr_cntr;
201 uint8_t nr_ext_inp;
202 uint8_t nr_ext_out;
203 uint8_t nr_ctxid_cmp;
Pratik Pateld30deda2012-02-01 14:40:55 -0800204 uint8_t reset;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800205 uint32_t mode;
Pratik Patel61de7302012-03-07 12:06:10 -0800206 uint32_t ctrl;
207 uint32_t trigger_event;
208 uint32_t startstop_ctrl;
209 uint32_t enable_event;
210 uint32_t enable_ctrl1;
211 uint32_t fifofull_level;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800212 uint8_t addr_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800213 uint32_t addr_val[ETM_MAX_ADDR_CMP];
214 uint32_t addr_acctype[ETM_MAX_ADDR_CMP];
Pratik Patel6630ebe2012-03-06 16:44:22 -0800215 uint32_t addr_type[ETM_MAX_ADDR_CMP];
216 uint8_t cntr_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800217 uint32_t cntr_rld_val[ETM_MAX_CNTR];
218 uint32_t cntr_event[ETM_MAX_CNTR];
219 uint32_t cntr_rld_event[ETM_MAX_CNTR];
220 uint32_t cntr_val[ETM_MAX_CNTR];
221 uint32_t seq_12_event;
222 uint32_t seq_21_event;
223 uint32_t seq_23_event;
224 uint32_t seq_31_event;
225 uint32_t seq_32_event;
226 uint32_t seq_13_event;
227 uint32_t seq_curr_state;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800228 uint8_t ctxid_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800229 uint32_t ctxid_val[ETM_MAX_CTXID_CMP];
230 uint32_t ctxid_mask;
231 uint32_t sync_freq;
232 uint32_t timestamp_event;
Pratik Patel938e1ff2012-09-28 23:21:46 -0700233 bool pcsave_impl;
234 bool pcsave_enable;
Pratik Patel7831c082011-06-08 21:44:37 -0700235};
236
Pratik Patelc14b4df2012-09-05 18:07:59 -0700237static struct etm_drvdata *etm0drvdata;
238
Pratik Pateld1d65c92012-09-25 23:37:43 -0700239/*
240 * ETM clock is derived from the processor clock and gets enabled on a
241 * logical OR of below items on Krait (v2 onwards):
Pratik Patel17f3b822011-11-21 12:41:47 -0800242 * 1.CPMR[ETMCLKEN] is 1
243 * 2.ETMCR[PD] is 0
244 * 3.ETMPDCR[PU] is 1
245 * 4.Reset is asserted (core or debug)
246 * 5.APB memory mapped requests (eg. EDAP access)
247 *
248 * 1., 2. and 3. above are permanent enables whereas 4. and 5. are temporary
249 * enables
250 *
Pratik Pateld1d65c92012-09-25 23:37:43 -0700251 * We rely on 5. to be able to access ETMCR/ETMPDCR and then use 2./3. above
252 * for ETM clock vote in the driver and the save-restore code uses 1. above
Pratik Patel17f3b822011-11-21 12:41:47 -0800253 * for its vote
254 */
Pratik Pateld1d65c92012-09-25 23:37:43 -0700255static void etm_set_pwrdwn(struct etm_drvdata *drvdata)
256{
257 uint32_t etmcr;
258
259 /* ensure pending cp14 accesses complete before setting pwrdwn */
260 mb();
261 isb();
262 etmcr = etm_readl(drvdata, ETMCR);
263 etmcr |= BIT(0);
264 etm_writel(drvdata, etmcr, ETMCR);
265}
266
267static void etm_clr_pwrdwn(struct etm_drvdata *drvdata)
268{
269 uint32_t etmcr;
270
271 etmcr = etm_readl(drvdata, ETMCR);
272 etmcr &= ~BIT(0);
273 etm_writel(drvdata, etmcr, ETMCR);
274 /* ensure pwrup completes before subsequent cp14 accesses */
275 mb();
276 isb();
277}
278
Pratik Patelef6da292012-09-17 17:37:19 -0700279static void etm_set_pwrup(struct etm_drvdata *drvdata)
Pratik Patel7831c082011-06-08 21:44:37 -0700280{
Pratik Patelef6da292012-09-17 17:37:19 -0700281 uint32_t etmpdcr;
Pratik Patel7831c082011-06-08 21:44:37 -0700282
Pratik Patele6e41da2012-09-12 12:50:29 -0700283 etmpdcr = etm_readl_mm(drvdata, ETMPDCR);
Pratik Patelef6da292012-09-17 17:37:19 -0700284 etmpdcr |= BIT(3);
Pratik Patele6e41da2012-09-12 12:50:29 -0700285 etm_writel_mm(drvdata, etmpdcr, ETMPDCR);
286 /* ensure pwrup completes before subsequent cp14 accesses */
287 mb();
288 isb();
Pratik Patel7831c082011-06-08 21:44:37 -0700289}
290
Pratik Patelef6da292012-09-17 17:37:19 -0700291static void etm_clr_pwrup(struct etm_drvdata *drvdata)
Pratik Patel7831c082011-06-08 21:44:37 -0700292{
Pratik Patelef6da292012-09-17 17:37:19 -0700293 uint32_t etmpdcr;
Pratik Patel7831c082011-06-08 21:44:37 -0700294
Pratik Patele6e41da2012-09-12 12:50:29 -0700295 /* ensure pending cp14 accesses complete before clearing pwrup */
296 mb();
297 isb();
298 etmpdcr = etm_readl_mm(drvdata, ETMPDCR);
Pratik Patelef6da292012-09-17 17:37:19 -0700299 etmpdcr &= ~BIT(3);
Pratik Patele6e41da2012-09-12 12:50:29 -0700300 etm_writel_mm(drvdata, etmpdcr, ETMPDCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700301}
302
Pratik Patel3b0ca882012-06-01 16:54:14 -0700303static void etm_set_prog(struct etm_drvdata *drvdata)
Pratik Patel7831c082011-06-08 21:44:37 -0700304{
305 uint32_t etmcr;
306 int count;
307
Pratik Patel3b0ca882012-06-01 16:54:14 -0700308 etmcr = etm_readl(drvdata, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700309 etmcr |= BIT(10);
Pratik Patel3b0ca882012-06-01 16:54:14 -0700310 etm_writel(drvdata, etmcr, ETMCR);
Pratik Patele6e41da2012-09-12 12:50:29 -0700311 /* recommended by spec for cp14 accesses to ensure etmcr write is
312 * complete before polling etmsr
313 */
314 isb();
Pratik Patel3b0ca882012-06-01 16:54:14 -0700315 for (count = TIMEOUT_US; BVAL(etm_readl(drvdata, ETMSR), 1) != 1
Pratik Patel7831c082011-06-08 21:44:37 -0700316 && count > 0; count--)
317 udelay(1);
Pratik Patel61de7302012-03-07 12:06:10 -0800318 WARN(count == 0, "timeout while setting prog bit, ETMSR: %#x\n",
Pratik Patel3b0ca882012-06-01 16:54:14 -0700319 etm_readl(drvdata, ETMSR));
Pratik Patel7831c082011-06-08 21:44:37 -0700320}
321
Pratik Patel3b0ca882012-06-01 16:54:14 -0700322static void etm_clr_prog(struct etm_drvdata *drvdata)
Pratik Patel7831c082011-06-08 21:44:37 -0700323{
324 uint32_t etmcr;
325 int count;
326
Pratik Patel3b0ca882012-06-01 16:54:14 -0700327 etmcr = etm_readl(drvdata, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700328 etmcr &= ~BIT(10);
Pratik Patel3b0ca882012-06-01 16:54:14 -0700329 etm_writel(drvdata, etmcr, ETMCR);
Pratik Patele6e41da2012-09-12 12:50:29 -0700330 /* recommended by spec for cp14 accesses to ensure etmcr write is
331 * complete before polling etmsr
332 */
333 isb();
Pratik Patel3b0ca882012-06-01 16:54:14 -0700334 for (count = TIMEOUT_US; BVAL(etm_readl(drvdata, ETMSR), 1) != 0
Pratik Patel7831c082011-06-08 21:44:37 -0700335 && count > 0; count--)
336 udelay(1);
Pratik Patel61de7302012-03-07 12:06:10 -0800337 WARN(count == 0, "timeout while clearing prog bit, ETMSR: %#x\n",
Pratik Patel3b0ca882012-06-01 16:54:14 -0700338 etm_readl(drvdata, ETMSR));
Pratik Patel7831c082011-06-08 21:44:37 -0700339}
340
Pratik Patel938e1ff2012-09-28 23:21:46 -0700341static void etm_enable_pcsave(void *info)
342{
343 struct etm_drvdata *drvdata = info;
344
345 ETM_UNLOCK(drvdata);
346
Pratik Patel938e1ff2012-09-28 23:21:46 -0700347 /*
348 * ETMPDCR is only accessible via memory mapped interface and so use
349 * it first to enable power/clock to allow subsequent cp14 accesses.
350 */
351 etm_set_pwrup(drvdata);
352 etm_clr_pwrdwn(drvdata);
Pratik Patel938e1ff2012-09-28 23:21:46 -0700353
354 ETM_LOCK(drvdata);
355}
356
357static void etm_disable_pcsave(void *info)
358{
359 struct etm_drvdata *drvdata = info;
360
361 ETM_UNLOCK(drvdata);
362
Pratik Patelf3238df2012-10-19 16:19:12 -0700363 if (!drvdata->enable) {
364 etm_set_pwrdwn(drvdata);
365 etm_clr_pwrup(drvdata);
366 }
Pratik Patel938e1ff2012-09-28 23:21:46 -0700367
368 ETM_LOCK(drvdata);
369}
370
Pratik Patel66e1a412012-09-06 11:07:06 -0700371static void __etm_enable(void *info)
Pratik Patel7831c082011-06-08 21:44:37 -0700372{
Pratik Patel17f3b822011-11-21 12:41:47 -0800373 int i;
Pratik Pateld1d65c92012-09-25 23:37:43 -0700374 uint32_t etmcr;
Pratik Patel66e1a412012-09-06 11:07:06 -0700375 struct etm_drvdata *drvdata = info;
Pratik Patel7831c082011-06-08 21:44:37 -0700376
Pratik Patel3b0ca882012-06-01 16:54:14 -0700377 ETM_UNLOCK(drvdata);
Pratik Patel938e1ff2012-09-28 23:21:46 -0700378 /*
379 * Vote for ETM power/clock enable. ETMPDCR is only accessible via
380 * memory mapped interface and so use it first to enable power/clock
381 * to allow subsequent cp14 accesses.
382 */
Pratik Patelef6da292012-09-17 17:37:19 -0700383 etm_set_pwrup(drvdata);
Pratik Pateld1d65c92012-09-25 23:37:43 -0700384 /*
385 * Clear power down bit since when this bit is set writes to
Pratik Patelf3238df2012-10-19 16:19:12 -0700386 * certain registers might be ignored. This is also a pre-requisite
387 * for trace enable.
Pratik Pateld1d65c92012-09-25 23:37:43 -0700388 */
389 etm_clr_pwrdwn(drvdata);
Pratik Patel3b0ca882012-06-01 16:54:14 -0700390 etm_set_prog(drvdata);
Pratik Patel7831c082011-06-08 21:44:37 -0700391
Pratik Pateld1d65c92012-09-25 23:37:43 -0700392 etmcr = etm_readl(drvdata, ETMCR);
393 etmcr &= (BIT(10) | BIT(0));
394 etm_writel(drvdata, drvdata->ctrl | etmcr, ETMCR);
Pratik Patel3b0ca882012-06-01 16:54:14 -0700395 etm_writel(drvdata, drvdata->trigger_event, ETMTRIGGER);
396 etm_writel(drvdata, drvdata->startstop_ctrl, ETMTSSCR);
397 etm_writel(drvdata, drvdata->enable_event, ETMTEEVR);
398 etm_writel(drvdata, drvdata->enable_ctrl1, ETMTECR1);
399 etm_writel(drvdata, drvdata->fifofull_level, ETMFFLR);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700400 for (i = 0; i < drvdata->nr_addr_cmp; i++) {
Pratik Patel3b0ca882012-06-01 16:54:14 -0700401 etm_writel(drvdata, drvdata->addr_val[i], ETMACVRn(i));
402 etm_writel(drvdata, drvdata->addr_acctype[i], ETMACTRn(i));
Pratik Patel7831c082011-06-08 21:44:37 -0700403 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700404 for (i = 0; i < drvdata->nr_cntr; i++) {
Pratik Patel3b0ca882012-06-01 16:54:14 -0700405 etm_writel(drvdata, drvdata->cntr_rld_val[i], ETMCNTRLDVRn(i));
406 etm_writel(drvdata, drvdata->cntr_event[i], ETMCNTENRn(i));
407 etm_writel(drvdata, drvdata->cntr_rld_event[i],
Pratik Patel16aefdb2012-05-30 10:41:23 -0700408 ETMCNTRLDEVRn(i));
Pratik Patel3b0ca882012-06-01 16:54:14 -0700409 etm_writel(drvdata, drvdata->cntr_val[i], ETMCNTVRn(i));
Pratik Patel17f3b822011-11-21 12:41:47 -0800410 }
Pratik Patel3b0ca882012-06-01 16:54:14 -0700411 etm_writel(drvdata, drvdata->seq_12_event, ETMSQ12EVR);
412 etm_writel(drvdata, drvdata->seq_21_event, ETMSQ21EVR);
413 etm_writel(drvdata, drvdata->seq_23_event, ETMSQ23EVR);
414 etm_writel(drvdata, drvdata->seq_31_event, ETMSQ31EVR);
415 etm_writel(drvdata, drvdata->seq_32_event, ETMSQ32EVR);
416 etm_writel(drvdata, drvdata->seq_13_event, ETMSQ13EVR);
417 etm_writel(drvdata, drvdata->seq_curr_state, ETMSQR);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700418 for (i = 0; i < drvdata->nr_ext_out; i++)
Pratik Patel3b0ca882012-06-01 16:54:14 -0700419 etm_writel(drvdata, 0x0000406F, ETMEXTOUTEVRn(i));
Pratik Patel16aefdb2012-05-30 10:41:23 -0700420 for (i = 0; i < drvdata->nr_ctxid_cmp; i++)
Pratik Patel3b0ca882012-06-01 16:54:14 -0700421 etm_writel(drvdata, drvdata->ctxid_val[i], ETMCIDCVRn(i));
422 etm_writel(drvdata, drvdata->ctxid_mask, ETMCIDCMR);
423 etm_writel(drvdata, drvdata->sync_freq, ETMSYNCFR);
424 etm_writel(drvdata, 0x00000000, ETMEXTINSELR);
425 etm_writel(drvdata, drvdata->timestamp_event, ETMTSEVR);
426 etm_writel(drvdata, 0x00000000, ETMAUXCR);
427 etm_writel(drvdata, drvdata->cpu + 1, ETMTRACEIDR);
428 etm_writel(drvdata, 0x00000000, ETMVMIDCVR);
Pratik Patel17f3b822011-11-21 12:41:47 -0800429
Pratik Patel3b0ca882012-06-01 16:54:14 -0700430 etm_clr_prog(drvdata);
431 ETM_LOCK(drvdata);
Pratik Patel66e1a412012-09-06 11:07:06 -0700432
433 dev_dbg(drvdata->dev, "cpu: %d enable smp call done\n", drvdata->cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700434}
435
Pratik Patel3b0ca882012-06-01 16:54:14 -0700436static int etm_enable(struct coresight_device *csdev)
Pratik Patel7831c082011-06-08 21:44:37 -0700437{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700438 struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
439 int ret;
Pratik Patel61de7302012-03-07 12:06:10 -0800440
Pratik Patel16aefdb2012-05-30 10:41:23 -0700441 wake_lock(&drvdata->wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700442
Pratik Patel16aefdb2012-05-30 10:41:23 -0700443 ret = clk_prepare_enable(drvdata->clk);
Pratik Patelf17b1472012-05-25 22:23:52 -0700444 if (ret)
445 goto err_clk;
446
Pratik Patel3b0ca882012-06-01 16:54:14 -0700447 mutex_lock(&drvdata->mutex);
Pratik Patelf3238df2012-10-19 16:19:12 -0700448 /*
449 * Executing __etm_enable on the cpu whose ETM is being enabled
Pratik Patel66e1a412012-09-06 11:07:06 -0700450 * ensures that register writes occur when cpu is powered.
451 */
452 smp_call_function_single(drvdata->cpu, __etm_enable, drvdata, 1);
Pratik Patelf3238df2012-10-19 16:19:12 -0700453 drvdata->enable = true;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700454 mutex_unlock(&drvdata->mutex);
Pratik Patel7831c082011-06-08 21:44:37 -0700455
Pratik Patel16aefdb2012-05-30 10:41:23 -0700456 wake_unlock(&drvdata->wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700457
Pratik Patel16aefdb2012-05-30 10:41:23 -0700458 dev_info(drvdata->dev, "ETM tracing enabled\n");
Pratik Patel7831c082011-06-08 21:44:37 -0700459 return 0;
Pratik Patelf17b1472012-05-25 22:23:52 -0700460err_clk:
Pratik Patel16aefdb2012-05-30 10:41:23 -0700461 wake_unlock(&drvdata->wake_lock);
Pratik Patel61de7302012-03-07 12:06:10 -0800462 return ret;
Pratik Patel7831c082011-06-08 21:44:37 -0700463}
464
Pratik Patel66e1a412012-09-06 11:07:06 -0700465static void __etm_disable(void *info)
Pratik Patel7831c082011-06-08 21:44:37 -0700466{
Pratik Patel66e1a412012-09-06 11:07:06 -0700467 struct etm_drvdata *drvdata = info;
468
Pratik Patel3b0ca882012-06-01 16:54:14 -0700469 ETM_UNLOCK(drvdata);
470 etm_set_prog(drvdata);
Pratik Patel7831c082011-06-08 21:44:37 -0700471
Pratik Patel17f3b822011-11-21 12:41:47 -0800472 /* program trace enable to low by using always false event */
Pratik Patel3b0ca882012-06-01 16:54:14 -0700473 etm_writel(drvdata, 0x6F | BIT(14), ETMTEEVR);
Pratik Patel7831c082011-06-08 21:44:37 -0700474
Pratik Patelf3238df2012-10-19 16:19:12 -0700475 if (!drvdata->pcsave_enable) {
476 etm_set_pwrdwn(drvdata);
477 etm_clr_pwrup(drvdata);
478 }
Pratik Patel3b0ca882012-06-01 16:54:14 -0700479 ETM_LOCK(drvdata);
Pratik Patel66e1a412012-09-06 11:07:06 -0700480
481 dev_dbg(drvdata->dev, "cpu: %d disable smp call done\n", drvdata->cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700482}
483
Pratik Patel3b0ca882012-06-01 16:54:14 -0700484static void etm_disable(struct coresight_device *csdev)
Pratik Patel7831c082011-06-08 21:44:37 -0700485{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700486 struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
Pratik Patel17f3b822011-11-21 12:41:47 -0800487
Pratik Patel16aefdb2012-05-30 10:41:23 -0700488 wake_lock(&drvdata->wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700489
Pratik Patel3b0ca882012-06-01 16:54:14 -0700490 mutex_lock(&drvdata->mutex);
Pratik Patelf3238df2012-10-19 16:19:12 -0700491 /*
492 * Executing __etm_disable on the cpu whose ETM is being disabled
Pratik Patel66e1a412012-09-06 11:07:06 -0700493 * ensures that register writes occur when cpu is powered.
494 */
495 smp_call_function_single(drvdata->cpu, __etm_disable, drvdata, 1);
Pratik Patelf3238df2012-10-19 16:19:12 -0700496 drvdata->enable = false;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700497 mutex_unlock(&drvdata->mutex);
Pratik Patel7831c082011-06-08 21:44:37 -0700498
Pratik Patel16aefdb2012-05-30 10:41:23 -0700499 clk_disable_unprepare(drvdata->clk);
Pratik Patel7831c082011-06-08 21:44:37 -0700500
Pratik Patel16aefdb2012-05-30 10:41:23 -0700501 wake_unlock(&drvdata->wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700502
Pratik Patel16aefdb2012-05-30 10:41:23 -0700503 dev_info(drvdata->dev, "ETM tracing disabled\n");
Pratik Patel7831c082011-06-08 21:44:37 -0700504}
505
Pratik Patel3b0ca882012-06-01 16:54:14 -0700506static const struct coresight_ops_source etm_source_ops = {
507 .enable = etm_enable,
508 .disable = etm_disable,
509};
Pratik Patel17f3b822011-11-21 12:41:47 -0800510
Pratik Patel3b0ca882012-06-01 16:54:14 -0700511static const struct coresight_ops etm_cs_ops = {
512 .source_ops = &etm_source_ops,
513};
Pratik Patel6630ebe2012-03-06 16:44:22 -0800514
Pratik Patela9c0e062012-05-28 13:45:35 -0700515static ssize_t etm_show_nr_addr_cmp(struct device *dev,
516 struct device_attribute *attr, char *buf)
517{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700518 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700519 unsigned long val = drvdata->nr_addr_cmp;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700520
Pratik Patela9c0e062012-05-28 13:45:35 -0700521 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
522}
523static DEVICE_ATTR(nr_addr_cmp, S_IRUGO, etm_show_nr_addr_cmp, NULL);
524
525static ssize_t etm_show_nr_cntr(struct device *dev,
526 struct device_attribute *attr, char *buf)
527{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700528 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700529 unsigned long val = drvdata->nr_cntr;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700530
Pratik Patela9c0e062012-05-28 13:45:35 -0700531 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
532}
533static DEVICE_ATTR(nr_cntr, S_IRUGO, etm_show_nr_cntr, NULL);
534
535static ssize_t etm_show_nr_ctxid_cmp(struct device *dev,
536 struct device_attribute *attr, char *buf)
537{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700538 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700539 unsigned long val = drvdata->nr_ctxid_cmp;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700540
Pratik Patela9c0e062012-05-28 13:45:35 -0700541 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
542}
543static DEVICE_ATTR(nr_ctxid_cmp, S_IRUGO, etm_show_nr_ctxid_cmp, NULL);
544
545static ssize_t etm_show_reset(struct device *dev, struct device_attribute *attr,
546 char *buf)
547{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700548 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700549 unsigned long val = drvdata->reset;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700550
Pratik Patela9c0e062012-05-28 13:45:35 -0700551 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
552}
Pratik Patel6630ebe2012-03-06 16:44:22 -0800553
Pratik Pateld30deda2012-02-01 14:40:55 -0800554/* Reset to trace everything i.e. exclude nothing. */
Pratik Patela9c0e062012-05-28 13:45:35 -0700555static ssize_t etm_store_reset(struct device *dev,
556 struct device_attribute *attr, const char *buf,
557 size_t size)
Pratik Pateld30deda2012-02-01 14:40:55 -0800558{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700559 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Pateld30deda2012-02-01 14:40:55 -0800560 int i;
561 unsigned long val;
562
563 if (sscanf(buf, "%lx", &val) != 1)
564 return -EINVAL;
565
Pratik Patel16aefdb2012-05-30 10:41:23 -0700566 mutex_lock(&drvdata->mutex);
Pratik Pateld30deda2012-02-01 14:40:55 -0800567 if (val) {
Pratik Patel16aefdb2012-05-30 10:41:23 -0700568 drvdata->mode = ETM_MODE_EXCLUDE;
569 drvdata->ctrl = 0x0;
Pratik Patel2d0c7b62012-02-24 19:04:37 -0800570 if (cpu_is_krait_v1()) {
Pratik Patel16aefdb2012-05-30 10:41:23 -0700571 drvdata->mode |= ETM_MODE_CYCACC;
572 drvdata->ctrl |= BIT(12);
Pratik Patel2d0c7b62012-02-24 19:04:37 -0800573 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700574 drvdata->trigger_event = 0x406F;
575 drvdata->startstop_ctrl = 0x0;
576 drvdata->enable_event = 0x6F;
577 drvdata->enable_ctrl1 = 0x1000000;
578 drvdata->fifofull_level = 0x28;
579 drvdata->addr_idx = 0x0;
580 for (i = 0; i < drvdata->nr_addr_cmp; i++) {
581 drvdata->addr_val[i] = 0x0;
582 drvdata->addr_acctype[i] = 0x0;
583 drvdata->addr_type[i] = ETM_ADDR_TYPE_NONE;
Pratik Pateld30deda2012-02-01 14:40:55 -0800584 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700585 drvdata->cntr_idx = 0x0;
586 for (i = 0; i < drvdata->nr_cntr; i++) {
587 drvdata->cntr_rld_val[i] = 0x0;
588 drvdata->cntr_event[i] = 0x406F;
589 drvdata->cntr_rld_event[i] = 0x406F;
590 drvdata->cntr_val[i] = 0x0;
Pratik Pateld30deda2012-02-01 14:40:55 -0800591 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700592 drvdata->seq_12_event = 0x406F;
593 drvdata->seq_21_event = 0x406F;
594 drvdata->seq_23_event = 0x406F;
595 drvdata->seq_31_event = 0x406F;
596 drvdata->seq_32_event = 0x406F;
597 drvdata->seq_13_event = 0x406F;
598 drvdata->seq_curr_state = 0x0;
599 drvdata->ctxid_idx = 0x0;
600 for (i = 0; i < drvdata->nr_ctxid_cmp; i++)
601 drvdata->ctxid_val[i] = 0x0;
602 drvdata->ctxid_mask = 0x0;
Pratik Patel77b90632012-07-17 17:54:51 -0700603 /* Bits[7:0] of ETMSYNCFR are reserved on Krait pass3 onwards */
604 if (cpu_is_krait() && !cpu_is_krait_v1() && !cpu_is_krait_v2())
605 drvdata->sync_freq = 0x100;
606 else
607 drvdata->sync_freq = 0x80;
Pratik Patel16aefdb2012-05-30 10:41:23 -0700608 drvdata->timestamp_event = 0x406F;
Pratik Pateld30deda2012-02-01 14:40:55 -0800609 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700610 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700611 return size;
Pratik Pateld30deda2012-02-01 14:40:55 -0800612}
Pratik Patela9c0e062012-05-28 13:45:35 -0700613static DEVICE_ATTR(reset, S_IRUGO | S_IWUSR, etm_show_reset, etm_store_reset);
Pratik Pateld30deda2012-02-01 14:40:55 -0800614
Pratik Patela9c0e062012-05-28 13:45:35 -0700615static ssize_t etm_show_mode(struct device *dev, struct device_attribute *attr,
616 char *buf)
617{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700618 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700619 unsigned long val = drvdata->mode;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700620
Pratik Patela9c0e062012-05-28 13:45:35 -0700621 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
622}
623
624static ssize_t etm_store_mode(struct device *dev, struct device_attribute *attr,
625 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800626{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700627 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800628 unsigned long val;
629
630 if (sscanf(buf, "%lx", &val) != 1)
631 return -EINVAL;
632
Pratik Patel16aefdb2012-05-30 10:41:23 -0700633 mutex_lock(&drvdata->mutex);
634 drvdata->mode = val & ETM_MODE_ALL;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800635
Pratik Patel16aefdb2012-05-30 10:41:23 -0700636 if (drvdata->mode & ETM_MODE_EXCLUDE)
637 drvdata->enable_ctrl1 |= BIT(24);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800638 else
Pratik Patel16aefdb2012-05-30 10:41:23 -0700639 drvdata->enable_ctrl1 &= ~BIT(24);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800640
Pratik Patel16aefdb2012-05-30 10:41:23 -0700641 if (drvdata->mode & ETM_MODE_CYCACC)
642 drvdata->ctrl |= BIT(12);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800643 else
Pratik Patel16aefdb2012-05-30 10:41:23 -0700644 drvdata->ctrl &= ~BIT(12);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800645
Pratik Patel16aefdb2012-05-30 10:41:23 -0700646 if (drvdata->mode & ETM_MODE_STALL)
647 drvdata->ctrl |= BIT(7);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800648 else
Pratik Patel16aefdb2012-05-30 10:41:23 -0700649 drvdata->ctrl &= ~BIT(7);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800650
Pratik Patel16aefdb2012-05-30 10:41:23 -0700651 if (drvdata->mode & ETM_MODE_TIMESTAMP)
652 drvdata->ctrl |= BIT(28);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800653 else
Pratik Patel16aefdb2012-05-30 10:41:23 -0700654 drvdata->ctrl &= ~BIT(28);
Pratik Patel3b0ca882012-06-01 16:54:14 -0700655
Pratik Patel16aefdb2012-05-30 10:41:23 -0700656 if (drvdata->mode & ETM_MODE_CTXID)
657 drvdata->ctrl |= (BIT(14) | BIT(15));
Pratik Patel6630ebe2012-03-06 16:44:22 -0800658 else
Pratik Patel16aefdb2012-05-30 10:41:23 -0700659 drvdata->ctrl &= ~(BIT(14) | BIT(15));
660 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800661
Pratik Patela9c0e062012-05-28 13:45:35 -0700662 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800663}
Pratik Patela9c0e062012-05-28 13:45:35 -0700664static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, etm_show_mode, etm_store_mode);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800665
Pratik Patela9c0e062012-05-28 13:45:35 -0700666static ssize_t etm_show_trigger_event(struct device *dev,
667 struct device_attribute *attr, char *buf)
668{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700669 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700670 unsigned long val = drvdata->trigger_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700671
Pratik Patela9c0e062012-05-28 13:45:35 -0700672 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
673}
Pratik Patel6630ebe2012-03-06 16:44:22 -0800674
Pratik Patela9c0e062012-05-28 13:45:35 -0700675static ssize_t etm_store_trigger_event(struct device *dev,
676 struct device_attribute *attr,
677 const char *buf, size_t size)
678{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700679 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -0700680 unsigned long val;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800681
Pratik Patela9c0e062012-05-28 13:45:35 -0700682 if (sscanf(buf, "%lx", &val) != 1)
683 return -EINVAL;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800684
Pratik Patel16aefdb2012-05-30 10:41:23 -0700685 drvdata->trigger_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -0700686 return size;
687}
688static DEVICE_ATTR(trigger_event, S_IRUGO | S_IWUSR, etm_show_trigger_event,
689 etm_store_trigger_event);
690
691static ssize_t etm_show_enable_event(struct device *dev,
692 struct device_attribute *attr, char *buf)
693{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700694 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700695 unsigned long val = drvdata->enable_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700696
Pratik Patela9c0e062012-05-28 13:45:35 -0700697 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
698}
699
700static ssize_t etm_store_enable_event(struct device *dev,
701 struct device_attribute *attr,
702 const char *buf, size_t size)
703{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700704 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -0700705 unsigned long val;
706
707 if (sscanf(buf, "%lx", &val) != 1)
708 return -EINVAL;
709
Pratik Patel16aefdb2012-05-30 10:41:23 -0700710 drvdata->enable_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -0700711 return size;
712}
713static DEVICE_ATTR(enable_event, S_IRUGO | S_IWUSR, etm_show_enable_event,
714 etm_store_enable_event);
715
716static ssize_t etm_show_fifofull_level(struct device *dev,
717 struct device_attribute *attr, char *buf)
718{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700719 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700720 unsigned long val = drvdata->fifofull_level;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700721
Pratik Patela9c0e062012-05-28 13:45:35 -0700722 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
723}
724
725static ssize_t etm_store_fifofull_level(struct device *dev,
726 struct device_attribute *attr,
727 const char *buf, size_t size)
728{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700729 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -0700730 unsigned long val;
731
732 if (sscanf(buf, "%lx", &val) != 1)
733 return -EINVAL;
734
Pratik Patel16aefdb2012-05-30 10:41:23 -0700735 drvdata->fifofull_level = val;
Pratik Patela9c0e062012-05-28 13:45:35 -0700736 return size;
737}
738static DEVICE_ATTR(fifofull_level, S_IRUGO | S_IWUSR, etm_show_fifofull_level,
739 etm_store_fifofull_level);
740
741static ssize_t etm_show_addr_idx(struct device *dev,
742 struct device_attribute *attr, char *buf)
743{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700744 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700745 unsigned long val = drvdata->addr_idx;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700746
Pratik Patela9c0e062012-05-28 13:45:35 -0700747 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
748}
749
750static ssize_t etm_store_addr_idx(struct device *dev,
751 struct device_attribute *attr,
752 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800753{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700754 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800755 unsigned long val;
756
757 if (sscanf(buf, "%lx", &val) != 1)
758 return -EINVAL;
Pratik Patel16aefdb2012-05-30 10:41:23 -0700759 if (val >= drvdata->nr_addr_cmp)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800760 return -EINVAL;
761
762 /* Use mutex to ensure index doesn't change while it gets dereferenced
763 * multiple times within a mutex block elsewhere.
764 */
Pratik Patel16aefdb2012-05-30 10:41:23 -0700765 mutex_lock(&drvdata->mutex);
766 drvdata->addr_idx = val;
767 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700768 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800769}
Pratik Patela9c0e062012-05-28 13:45:35 -0700770static DEVICE_ATTR(addr_idx, S_IRUGO | S_IWUSR, etm_show_addr_idx,
771 etm_store_addr_idx);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800772
Pratik Patela9c0e062012-05-28 13:45:35 -0700773static ssize_t etm_show_addr_single(struct device *dev,
774 struct device_attribute *attr, char *buf)
775{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700776 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -0700777 unsigned long val;
778 uint8_t idx;
779
Pratik Patel16aefdb2012-05-30 10:41:23 -0700780 mutex_lock(&drvdata->mutex);
781 idx = drvdata->addr_idx;
782 if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
783 drvdata->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
784 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700785 return -EPERM;
786 }
787
Pratik Patel16aefdb2012-05-30 10:41:23 -0700788 val = drvdata->addr_val[idx];
789 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700790 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
791}
792
793static ssize_t etm_store_addr_single(struct device *dev,
794 struct device_attribute *attr,
795 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800796{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700797 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800798 unsigned long val;
799 uint8_t idx;
800
801 if (sscanf(buf, "%lx", &val) != 1)
802 return -EINVAL;
803
Pratik Patel16aefdb2012-05-30 10:41:23 -0700804 mutex_lock(&drvdata->mutex);
805 idx = drvdata->addr_idx;
806 if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
807 drvdata->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
808 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800809 return -EPERM;
810 }
811
Pratik Patel16aefdb2012-05-30 10:41:23 -0700812 drvdata->addr_val[idx] = val;
813 drvdata->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
814 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700815 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800816}
Pratik Patela9c0e062012-05-28 13:45:35 -0700817static DEVICE_ATTR(addr_single, S_IRUGO | S_IWUSR, etm_show_addr_single,
818 etm_store_addr_single);
819
820static ssize_t etm_show_addr_range(struct device *dev,
821 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800822{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700823 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -0700824 unsigned long val1, val2;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800825 uint8_t idx;
826
Pratik Patel16aefdb2012-05-30 10:41:23 -0700827 mutex_lock(&drvdata->mutex);
828 idx = drvdata->addr_idx;
Pratik Patela9c0e062012-05-28 13:45:35 -0700829 if (idx % 2 != 0) {
Pratik Patel16aefdb2012-05-30 10:41:23 -0700830 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700831 return -EPERM;
832 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700833 if (!((drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
834 drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
835 (drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
836 drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
837 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800838 return -EPERM;
839 }
840
Pratik Patel16aefdb2012-05-30 10:41:23 -0700841 val1 = drvdata->addr_val[idx];
842 val2 = drvdata->addr_val[idx + 1];
843 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700844 return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800845}
Pratik Patel6630ebe2012-03-06 16:44:22 -0800846
Pratik Patela9c0e062012-05-28 13:45:35 -0700847static ssize_t etm_store_addr_range(struct device *dev,
848 struct device_attribute *attr,
849 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800850{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700851 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800852 unsigned long val1, val2;
853 uint8_t idx;
854
855 if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
856 return -EINVAL;
857 /* lower address comparator cannot have a higher address value */
858 if (val1 > val2)
859 return -EINVAL;
860
Pratik Patel16aefdb2012-05-30 10:41:23 -0700861 mutex_lock(&drvdata->mutex);
862 idx = drvdata->addr_idx;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800863 if (idx % 2 != 0) {
Pratik Patel16aefdb2012-05-30 10:41:23 -0700864 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800865 return -EPERM;
866 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700867 if (!((drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
868 drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
869 (drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
870 drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
871 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800872 return -EPERM;
873 }
874
Pratik Patel16aefdb2012-05-30 10:41:23 -0700875 drvdata->addr_val[idx] = val1;
876 drvdata->addr_type[idx] = ETM_ADDR_TYPE_RANGE;
877 drvdata->addr_val[idx + 1] = val2;
878 drvdata->addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
879 drvdata->enable_ctrl1 |= (1 << (idx/2));
880 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700881 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800882}
Pratik Patela9c0e062012-05-28 13:45:35 -0700883static DEVICE_ATTR(addr_range, S_IRUGO | S_IWUSR, etm_show_addr_range,
884 etm_store_addr_range);
885
886static ssize_t etm_show_addr_start(struct device *dev,
887 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800888{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700889 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -0700890 unsigned long val;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800891 uint8_t idx;
892
Pratik Patel16aefdb2012-05-30 10:41:23 -0700893 mutex_lock(&drvdata->mutex);
894 idx = drvdata->addr_idx;
895 if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
896 drvdata->addr_type[idx] == ETM_ADDR_TYPE_START)) {
897 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800898 return -EPERM;
899 }
900
Pratik Patel16aefdb2012-05-30 10:41:23 -0700901 val = drvdata->addr_val[idx];
902 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700903 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800904}
Pratik Patel6630ebe2012-03-06 16:44:22 -0800905
Pratik Patela9c0e062012-05-28 13:45:35 -0700906static ssize_t etm_store_addr_start(struct device *dev,
907 struct device_attribute *attr,
908 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800909{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700910 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800911 unsigned long val;
912 uint8_t idx;
913
914 if (sscanf(buf, "%lx", &val) != 1)
915 return -EINVAL;
916
Pratik Patel16aefdb2012-05-30 10:41:23 -0700917 mutex_lock(&drvdata->mutex);
918 idx = drvdata->addr_idx;
919 if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
920 drvdata->addr_type[idx] == ETM_ADDR_TYPE_START)) {
921 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800922 return -EPERM;
923 }
924
Pratik Patel16aefdb2012-05-30 10:41:23 -0700925 drvdata->addr_val[idx] = val;
926 drvdata->addr_type[idx] = ETM_ADDR_TYPE_START;
927 drvdata->startstop_ctrl |= (1 << idx);
928 drvdata->enable_ctrl1 |= BIT(25);
929 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700930 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800931}
Pratik Patela9c0e062012-05-28 13:45:35 -0700932static DEVICE_ATTR(addr_start, S_IRUGO | S_IWUSR, etm_show_addr_start,
933 etm_store_addr_start);
934
935static ssize_t etm_show_addr_stop(struct device *dev,
936 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800937{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700938 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800939 unsigned long val;
940 uint8_t idx;
941
Pratik Patel16aefdb2012-05-30 10:41:23 -0700942 mutex_lock(&drvdata->mutex);
943 idx = drvdata->addr_idx;
944 if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
945 drvdata->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
946 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800947 return -EPERM;
948 }
949
Pratik Patel16aefdb2012-05-30 10:41:23 -0700950 val = drvdata->addr_val[idx];
951 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800952 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
953}
Pratik Patel6630ebe2012-03-06 16:44:22 -0800954
Pratik Patela9c0e062012-05-28 13:45:35 -0700955static ssize_t etm_store_addr_stop(struct device *dev,
956 struct device_attribute *attr,
957 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800958{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700959 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800960 unsigned long val;
961 uint8_t idx;
962
963 if (sscanf(buf, "%lx", &val) != 1)
964 return -EINVAL;
965
Pratik Patel16aefdb2012-05-30 10:41:23 -0700966 mutex_lock(&drvdata->mutex);
967 idx = drvdata->addr_idx;
968 if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
969 drvdata->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
970 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800971 return -EPERM;
972 }
973
Pratik Patel16aefdb2012-05-30 10:41:23 -0700974 drvdata->addr_val[idx] = val;
975 drvdata->addr_type[idx] = ETM_ADDR_TYPE_STOP;
976 drvdata->startstop_ctrl |= (1 << (idx + 16));
977 drvdata->enable_ctrl1 |= BIT(25);
978 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700979 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800980}
Pratik Patela9c0e062012-05-28 13:45:35 -0700981static DEVICE_ATTR(addr_stop, S_IRUGO | S_IWUSR, etm_show_addr_stop,
982 etm_store_addr_stop);
983
984static ssize_t etm_show_addr_acctype(struct device *dev,
985 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800986{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700987 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800988 unsigned long val;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800989
Pratik Patel16aefdb2012-05-30 10:41:23 -0700990 mutex_lock(&drvdata->mutex);
991 val = drvdata->addr_acctype[drvdata->addr_idx];
992 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800993 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
994}
Pratik Patel6630ebe2012-03-06 16:44:22 -0800995
Pratik Patela9c0e062012-05-28 13:45:35 -0700996static ssize_t etm_store_addr_acctype(struct device *dev,
997 struct device_attribute *attr,
998 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800999{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001000 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001001 unsigned long val;
1002
1003 if (sscanf(buf, "%lx", &val) != 1)
1004 return -EINVAL;
1005
Pratik Patel16aefdb2012-05-30 10:41:23 -07001006 mutex_lock(&drvdata->mutex);
1007 drvdata->addr_acctype[drvdata->addr_idx] = val;
1008 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001009 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001010}
Pratik Patela9c0e062012-05-28 13:45:35 -07001011static DEVICE_ATTR(addr_acctype, S_IRUGO | S_IWUSR, etm_show_addr_acctype,
1012 etm_store_addr_acctype);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001013
Pratik Patela9c0e062012-05-28 13:45:35 -07001014static ssize_t etm_show_cntr_idx(struct device *dev,
1015 struct device_attribute *attr, char *buf)
1016{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001017 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001018 unsigned long val = drvdata->addr_idx;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001019
Pratik Patel6630ebe2012-03-06 16:44:22 -08001020 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1021}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001022
Pratik Patela9c0e062012-05-28 13:45:35 -07001023static ssize_t etm_store_cntr_idx(struct device *dev,
1024 struct device_attribute *attr,
1025 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001026{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001027 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001028 unsigned long val;
1029
1030 if (sscanf(buf, "%lx", &val) != 1)
1031 return -EINVAL;
Pratik Patel16aefdb2012-05-30 10:41:23 -07001032 if (val >= drvdata->nr_cntr)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001033 return -EINVAL;
1034
1035 /* Use mutex to ensure index doesn't change while it gets dereferenced
1036 * multiple times within a mutex block elsewhere.
1037 */
Pratik Patel16aefdb2012-05-30 10:41:23 -07001038 mutex_lock(&drvdata->mutex);
1039 drvdata->cntr_idx = val;
1040 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001041 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001042}
Pratik Patela9c0e062012-05-28 13:45:35 -07001043static DEVICE_ATTR(cntr_idx, S_IRUGO | S_IWUSR, etm_show_cntr_idx,
1044 etm_store_cntr_idx);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001045
Pratik Patela9c0e062012-05-28 13:45:35 -07001046static ssize_t etm_show_cntr_rld_val(struct device *dev,
1047 struct device_attribute *attr, char *buf)
1048{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001049 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001050 unsigned long val;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001051
Pratik Patel16aefdb2012-05-30 10:41:23 -07001052 mutex_lock(&drvdata->mutex);
1053 val = drvdata->cntr_rld_val[drvdata->cntr_idx];
1054 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001055 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1056}
1057
1058static ssize_t etm_store_cntr_rld_val(struct device *dev,
1059 struct device_attribute *attr,
1060 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001061{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001062 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001063 unsigned long val;
1064
1065 if (sscanf(buf, "%lx", &val) != 1)
1066 return -EINVAL;
1067
Pratik Patel16aefdb2012-05-30 10:41:23 -07001068 mutex_lock(&drvdata->mutex);
1069 drvdata->cntr_rld_val[drvdata->cntr_idx] = val;
1070 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001071 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001072}
Pratik Patela9c0e062012-05-28 13:45:35 -07001073static DEVICE_ATTR(cntr_rld_val, S_IRUGO | S_IWUSR, etm_show_cntr_rld_val,
1074 etm_store_cntr_rld_val);
1075
1076static ssize_t etm_show_cntr_event(struct device *dev,
1077 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001078{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001079 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001080 unsigned long val;
Pratik Patela9c0e062012-05-28 13:45:35 -07001081
Pratik Patel16aefdb2012-05-30 10:41:23 -07001082 mutex_lock(&drvdata->mutex);
1083 val = drvdata->cntr_event[drvdata->cntr_idx];
1084 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001085 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1086}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001087
Pratik Patela9c0e062012-05-28 13:45:35 -07001088static ssize_t etm_store_cntr_event(struct device *dev,
1089 struct device_attribute *attr,
1090 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001091{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001092 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001093 unsigned long val;
1094
1095 if (sscanf(buf, "%lx", &val) != 1)
1096 return -EINVAL;
1097
Pratik Patel16aefdb2012-05-30 10:41:23 -07001098 mutex_lock(&drvdata->mutex);
1099 drvdata->cntr_event[drvdata->cntr_idx] = val & ETM_EVENT_MASK;
1100 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001101 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001102}
Pratik Patela9c0e062012-05-28 13:45:35 -07001103static DEVICE_ATTR(cntr_event, S_IRUGO | S_IWUSR, etm_show_cntr_event,
1104 etm_store_cntr_event);
1105
1106static ssize_t etm_show_cntr_rld_event(struct device *dev,
1107 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001108{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001109 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001110 unsigned long val;
1111
Pratik Patel16aefdb2012-05-30 10:41:23 -07001112 mutex_lock(&drvdata->mutex);
1113 val = drvdata->cntr_rld_event[drvdata->cntr_idx];
1114 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001115 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1116}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001117
Pratik Patela9c0e062012-05-28 13:45:35 -07001118static ssize_t etm_store_cntr_rld_event(struct device *dev,
1119 struct device_attribute *attr,
1120 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001121{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001122 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001123 unsigned long val;
1124
1125 if (sscanf(buf, "%lx", &val) != 1)
1126 return -EINVAL;
1127
Pratik Patel16aefdb2012-05-30 10:41:23 -07001128 mutex_lock(&drvdata->mutex);
1129 drvdata->cntr_rld_event[drvdata->cntr_idx] = val & ETM_EVENT_MASK;
1130 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001131 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001132}
Pratik Patela9c0e062012-05-28 13:45:35 -07001133static DEVICE_ATTR(cntr_rld_event, S_IRUGO | S_IWUSR, etm_show_cntr_rld_event,
1134 etm_store_cntr_rld_event);
1135
1136static ssize_t etm_show_cntr_val(struct device *dev,
1137 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001138{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001139 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001140 unsigned long val;
1141
Pratik Patel16aefdb2012-05-30 10:41:23 -07001142 mutex_lock(&drvdata->mutex);
1143 val = drvdata->cntr_val[drvdata->cntr_idx];
1144 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001145 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1146}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001147
Pratik Patela9c0e062012-05-28 13:45:35 -07001148static ssize_t etm_store_cntr_val(struct device *dev,
1149 struct device_attribute *attr,
1150 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001151{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001152 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001153 unsigned long val;
1154
1155 if (sscanf(buf, "%lx", &val) != 1)
1156 return -EINVAL;
1157
Pratik Patel16aefdb2012-05-30 10:41:23 -07001158 mutex_lock(&drvdata->mutex);
1159 drvdata->cntr_val[drvdata->cntr_idx] = val;
1160 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001161 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001162}
Pratik Patela9c0e062012-05-28 13:45:35 -07001163static DEVICE_ATTR(cntr_val, S_IRUGO | S_IWUSR, etm_show_cntr_val,
1164 etm_store_cntr_val);
1165
1166static ssize_t etm_show_seq_12_event(struct device *dev,
1167 struct device_attribute *attr, char *buf)
1168{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001169 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001170 unsigned long val = drvdata->seq_12_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001171
Pratik Patela9c0e062012-05-28 13:45:35 -07001172 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1173}
1174
1175static ssize_t etm_store_seq_12_event(struct device *dev,
1176 struct device_attribute *attr,
1177 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001178{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001179 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001180 unsigned long val;
1181
Pratik Patela9c0e062012-05-28 13:45:35 -07001182 if (sscanf(buf, "%lx", &val) != 1)
1183 return -EINVAL;
1184
Pratik Patel16aefdb2012-05-30 10:41:23 -07001185 drvdata->seq_12_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001186 return size;
1187}
1188static DEVICE_ATTR(seq_12_event, S_IRUGO | S_IWUSR, etm_show_seq_12_event,
1189 etm_store_seq_12_event);
1190
1191static ssize_t etm_show_seq_21_event(struct device *dev,
1192 struct device_attribute *attr, char *buf)
1193{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001194 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001195 unsigned long val = drvdata->seq_21_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001196
Pratik Patel6630ebe2012-03-06 16:44:22 -08001197 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1198}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001199
Pratik Patela9c0e062012-05-28 13:45:35 -07001200static ssize_t etm_store_seq_21_event(struct device *dev,
1201 struct device_attribute *attr,
1202 const char *buf, size_t size)
1203{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001204 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001205 unsigned long val;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001206
Pratik Patela9c0e062012-05-28 13:45:35 -07001207 if (sscanf(buf, "%lx", &val) != 1)
1208 return -EINVAL;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001209
Pratik Patel16aefdb2012-05-30 10:41:23 -07001210 drvdata->seq_21_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001211 return size;
1212}
1213static DEVICE_ATTR(seq_21_event, S_IRUGO | S_IWUSR, etm_show_seq_21_event,
1214 etm_store_seq_21_event);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001215
Pratik Patela9c0e062012-05-28 13:45:35 -07001216static ssize_t etm_show_seq_23_event(struct device *dev,
1217 struct device_attribute *attr, char *buf)
1218{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001219 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001220 unsigned long val = drvdata->seq_23_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001221
Pratik Patela9c0e062012-05-28 13:45:35 -07001222 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1223}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001224
Pratik Patela9c0e062012-05-28 13:45:35 -07001225static ssize_t etm_store_seq_23_event(struct device *dev,
1226 struct device_attribute *attr,
1227 const char *buf, size_t size)
1228{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001229 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001230 unsigned long val;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001231
Pratik Patela9c0e062012-05-28 13:45:35 -07001232 if (sscanf(buf, "%lx", &val) != 1)
1233 return -EINVAL;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001234
Pratik Patel16aefdb2012-05-30 10:41:23 -07001235 drvdata->seq_23_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001236 return size;
1237}
1238static DEVICE_ATTR(seq_23_event, S_IRUGO | S_IWUSR, etm_show_seq_23_event,
1239 etm_store_seq_23_event);
1240
1241static ssize_t etm_show_seq_31_event(struct device *dev,
1242 struct device_attribute *attr, char *buf)
1243{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001244 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001245 unsigned long val = drvdata->seq_31_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001246
Pratik Patela9c0e062012-05-28 13:45:35 -07001247 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1248}
1249
1250static ssize_t etm_store_seq_31_event(struct device *dev,
1251 struct device_attribute *attr,
1252 const char *buf, size_t size)
1253{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001254 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001255 unsigned long val;
1256
1257 if (sscanf(buf, "%lx", &val) != 1)
1258 return -EINVAL;
1259
Pratik Patel16aefdb2012-05-30 10:41:23 -07001260 drvdata->seq_31_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001261 return size;
1262}
1263static DEVICE_ATTR(seq_31_event, S_IRUGO | S_IWUSR, etm_show_seq_31_event,
1264 etm_store_seq_31_event);
1265
1266static ssize_t etm_show_seq_32_event(struct device *dev,
1267 struct device_attribute *attr, char *buf)
1268{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001269 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001270 unsigned long val = drvdata->seq_32_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001271
Pratik Patela9c0e062012-05-28 13:45:35 -07001272 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1273}
1274
1275static ssize_t etm_store_seq_32_event(struct device *dev,
1276 struct device_attribute *attr,
1277 const char *buf, size_t size)
1278{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001279 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001280 unsigned long val;
1281
1282 if (sscanf(buf, "%lx", &val) != 1)
1283 return -EINVAL;
1284
Pratik Patel16aefdb2012-05-30 10:41:23 -07001285 drvdata->seq_32_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001286 return size;
1287}
1288static DEVICE_ATTR(seq_32_event, S_IRUGO | S_IWUSR, etm_show_seq_32_event,
1289 etm_store_seq_32_event);
1290
1291static ssize_t etm_show_seq_13_event(struct device *dev,
1292 struct device_attribute *attr, char *buf)
1293{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001294 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001295 unsigned long val = drvdata->seq_13_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001296
Pratik Patela9c0e062012-05-28 13:45:35 -07001297 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1298}
1299
1300static ssize_t etm_store_seq_13_event(struct device *dev,
1301 struct device_attribute *attr,
1302 const char *buf, size_t size)
1303{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001304 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001305 unsigned long val;
1306
1307 if (sscanf(buf, "%lx", &val) != 1)
1308 return -EINVAL;
1309
Pratik Patel16aefdb2012-05-30 10:41:23 -07001310 drvdata->seq_13_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001311 return size;
1312}
1313static DEVICE_ATTR(seq_13_event, S_IRUGO | S_IWUSR, etm_show_seq_13_event,
1314 etm_store_seq_13_event);
1315
1316static ssize_t etm_show_seq_curr_state(struct device *dev,
1317 struct device_attribute *attr, char *buf)
1318{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001319 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001320 unsigned long val = drvdata->seq_curr_state;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001321
Pratik Patela9c0e062012-05-28 13:45:35 -07001322 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1323}
1324
1325static ssize_t etm_store_seq_curr_state(struct device *dev,
1326 struct device_attribute *attr,
1327 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001328{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001329 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001330 unsigned long val;
1331
1332 if (sscanf(buf, "%lx", &val) != 1)
1333 return -EINVAL;
1334 if (val > ETM_SEQ_STATE_MAX_VAL)
1335 return -EINVAL;
1336
Pratik Patel16aefdb2012-05-30 10:41:23 -07001337 drvdata->seq_curr_state = val;
Pratik Patela9c0e062012-05-28 13:45:35 -07001338 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001339}
Pratik Patela9c0e062012-05-28 13:45:35 -07001340static DEVICE_ATTR(seq_curr_state, S_IRUGO | S_IWUSR, etm_show_seq_curr_state,
1341 etm_store_seq_curr_state);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001342
Pratik Patela9c0e062012-05-28 13:45:35 -07001343static ssize_t etm_show_ctxid_idx(struct device *dev,
1344 struct device_attribute *attr, char *buf)
1345{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001346 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001347 unsigned long val = drvdata->ctxid_idx;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001348
Pratik Patela9c0e062012-05-28 13:45:35 -07001349 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1350}
1351
1352static ssize_t etm_store_ctxid_idx(struct device *dev,
1353 struct device_attribute *attr,
1354 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001355{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001356 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001357 unsigned long val;
1358
1359 if (sscanf(buf, "%lx", &val) != 1)
1360 return -EINVAL;
Pratik Patel16aefdb2012-05-30 10:41:23 -07001361 if (val >= drvdata->nr_ctxid_cmp)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001362 return -EINVAL;
1363
1364 /* Use mutex to ensure index doesn't change while it gets dereferenced
1365 * multiple times within a mutex block elsewhere.
1366 */
Pratik Patel16aefdb2012-05-30 10:41:23 -07001367 mutex_lock(&drvdata->mutex);
1368 drvdata->ctxid_idx = val;
1369 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001370 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001371}
Pratik Patela9c0e062012-05-28 13:45:35 -07001372static DEVICE_ATTR(ctxid_idx, S_IRUGO | S_IWUSR, etm_show_ctxid_idx,
1373 etm_store_ctxid_idx);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001374
Pratik Patela9c0e062012-05-28 13:45:35 -07001375static ssize_t etm_show_ctxid_val(struct device *dev,
1376 struct device_attribute *attr, char *buf)
1377{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001378 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001379 unsigned long val;
1380
Pratik Patel16aefdb2012-05-30 10:41:23 -07001381 mutex_lock(&drvdata->mutex);
1382 val = drvdata->ctxid_val[drvdata->ctxid_idx];
1383 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001384 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1385}
1386
1387static ssize_t etm_store_ctxid_val(struct device *dev,
1388 struct device_attribute *attr,
1389 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001390{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001391 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001392 unsigned long val;
1393
1394 if (sscanf(buf, "%lx", &val) != 1)
1395 return -EINVAL;
1396
Pratik Patel16aefdb2012-05-30 10:41:23 -07001397 mutex_lock(&drvdata->mutex);
1398 drvdata->ctxid_val[drvdata->ctxid_idx] = val;
1399 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001400 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001401}
Pratik Patela9c0e062012-05-28 13:45:35 -07001402static DEVICE_ATTR(ctxid_val, S_IRUGO | S_IWUSR, etm_show_ctxid_val,
1403 etm_store_ctxid_val);
1404
1405static ssize_t etm_show_ctxid_mask(struct device *dev,
1406 struct device_attribute *attr, char *buf)
1407{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001408 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001409 unsigned long val = drvdata->ctxid_mask;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001410
Pratik Patela9c0e062012-05-28 13:45:35 -07001411 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1412}
1413
1414static ssize_t etm_store_ctxid_mask(struct device *dev,
1415 struct device_attribute *attr,
1416 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001417{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001418 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001419 unsigned long val;
1420
Pratik Patela9c0e062012-05-28 13:45:35 -07001421 if (sscanf(buf, "%lx", &val) != 1)
1422 return -EINVAL;
1423
Pratik Patel16aefdb2012-05-30 10:41:23 -07001424 drvdata->ctxid_mask = val;
Pratik Patela9c0e062012-05-28 13:45:35 -07001425 return size;
1426}
1427static DEVICE_ATTR(ctxid_mask, S_IRUGO | S_IWUSR, etm_show_ctxid_mask,
1428 etm_store_ctxid_mask);
1429
1430static ssize_t etm_show_sync_freq(struct device *dev,
1431 struct device_attribute *attr, char *buf)
1432{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001433 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001434 unsigned long val = drvdata->sync_freq;
Pratik Patel938e1ff2012-09-28 23:21:46 -07001435
Pratik Patel6630ebe2012-03-06 16:44:22 -08001436 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1437}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001438
Pratik Patela9c0e062012-05-28 13:45:35 -07001439static ssize_t etm_store_sync_freq(struct device *dev,
1440 struct device_attribute *attr,
1441 const char *buf, size_t size)
1442{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001443 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001444 unsigned long val;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001445
Pratik Patela9c0e062012-05-28 13:45:35 -07001446 if (sscanf(buf, "%lx", &val) != 1)
1447 return -EINVAL;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001448
Pratik Patel16aefdb2012-05-30 10:41:23 -07001449 drvdata->sync_freq = val & ETM_SYNC_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001450 return size;
1451}
1452static DEVICE_ATTR(sync_freq, S_IRUGO | S_IWUSR, etm_show_sync_freq,
1453 etm_store_sync_freq);
1454
1455static ssize_t etm_show_timestamp_event(struct device *dev,
1456 struct device_attribute *attr,
1457 char *buf)
1458{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001459 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001460 unsigned long val = drvdata->timestamp_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001461
Pratik Patela9c0e062012-05-28 13:45:35 -07001462 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1463}
1464
1465static ssize_t etm_store_timestamp_event(struct device *dev,
1466 struct device_attribute *attr,
1467 const char *buf, size_t size)
1468{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001469 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001470 unsigned long val;
1471
1472 if (sscanf(buf, "%lx", &val) != 1)
1473 return -EINVAL;
1474
Pratik Patel16aefdb2012-05-30 10:41:23 -07001475 drvdata->timestamp_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001476 return size;
1477}
1478static DEVICE_ATTR(timestamp_event, S_IRUGO | S_IWUSR, etm_show_timestamp_event,
1479 etm_store_timestamp_event);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001480
Pratik Patel938e1ff2012-09-28 23:21:46 -07001481static ssize_t etm_show_pcsave(struct device *dev,
1482 struct device_attribute *attr, char *buf)
1483{
1484 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1485 unsigned long val;
1486
1487 val = drvdata->pcsave_enable;
1488 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1489}
1490
1491static int __etm_store_pcsave(struct etm_drvdata *drvdata, unsigned long val)
1492{
1493 int ret;
1494
1495 ret = clk_prepare_enable(drvdata->clk);
1496 if (ret)
1497 return ret;
1498
1499 mutex_lock(&drvdata->mutex);
1500 if (val) {
1501 smp_call_function_single(drvdata->cpu, etm_enable_pcsave,
1502 drvdata, 1);
1503 drvdata->pcsave_enable = true;
1504 } else {
1505 smp_call_function_single(drvdata->cpu, etm_disable_pcsave,
1506 drvdata, 1);
1507 drvdata->pcsave_enable = false;
1508 }
1509 mutex_unlock(&drvdata->mutex);
1510
1511 clk_disable_unprepare(drvdata->clk);
1512 return 0;
1513}
1514
1515static ssize_t etm_store_pcsave(struct device *dev,
1516 struct device_attribute *attr,
1517 const char *buf, size_t size)
1518{
1519 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1520 unsigned long val;
1521 int ret;
1522
1523 if (sscanf(buf, "%lx", &val) != 1)
1524 return -EINVAL;
1525
1526 ret = __etm_store_pcsave(drvdata, val);
1527 if (ret)
1528 return ret;
1529
1530 return size;
1531}
1532static DEVICE_ATTR(pcsave, S_IRUGO | S_IWUSR, etm_show_pcsave,
1533 etm_store_pcsave);
1534
Pratik Patel6630ebe2012-03-06 16:44:22 -08001535static struct attribute *etm_attrs[] = {
Pratik Patela9c0e062012-05-28 13:45:35 -07001536 &dev_attr_nr_addr_cmp.attr,
1537 &dev_attr_nr_cntr.attr,
1538 &dev_attr_nr_ctxid_cmp.attr,
1539 &dev_attr_reset.attr,
1540 &dev_attr_mode.attr,
1541 &dev_attr_trigger_event.attr,
1542 &dev_attr_enable_event.attr,
1543 &dev_attr_fifofull_level.attr,
1544 &dev_attr_addr_idx.attr,
1545 &dev_attr_addr_single.attr,
1546 &dev_attr_addr_range.attr,
1547 &dev_attr_addr_start.attr,
1548 &dev_attr_addr_stop.attr,
1549 &dev_attr_addr_acctype.attr,
1550 &dev_attr_cntr_idx.attr,
1551 &dev_attr_cntr_rld_val.attr,
1552 &dev_attr_cntr_event.attr,
1553 &dev_attr_cntr_rld_event.attr,
1554 &dev_attr_cntr_val.attr,
1555 &dev_attr_seq_12_event.attr,
1556 &dev_attr_seq_21_event.attr,
1557 &dev_attr_seq_23_event.attr,
1558 &dev_attr_seq_31_event.attr,
1559 &dev_attr_seq_32_event.attr,
1560 &dev_attr_seq_13_event.attr,
1561 &dev_attr_seq_curr_state.attr,
1562 &dev_attr_ctxid_idx.attr,
1563 &dev_attr_ctxid_val.attr,
1564 &dev_attr_ctxid_mask.attr,
1565 &dev_attr_sync_freq.attr,
1566 &dev_attr_timestamp_event.attr,
Pratik Patel6630ebe2012-03-06 16:44:22 -08001567 NULL,
1568};
1569
1570static struct attribute_group etm_attr_grp = {
1571 .attrs = etm_attrs,
1572};
1573
Pratik Patel3b0ca882012-06-01 16:54:14 -07001574static const struct attribute_group *etm_attr_grps[] = {
1575 &etm_attr_grp,
1576 NULL,
1577};
1578
1579/* Memory mapped writes to clear os lock not supported */
1580static void etm_os_unlock(void *unused)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001581{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001582 unsigned long value = 0x0;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001583
Pratik Patel3b0ca882012-06-01 16:54:14 -07001584 asm("mcr p14, 1, %0, c1, c0, 4\n\t" : : "r" (value));
1585 asm("isb\n\t");
Pratik Patel6630ebe2012-03-06 16:44:22 -08001586}
1587
Stephen Boyda9510502012-04-24 16:23:34 -07001588static bool __devinit etm_arch_supported(uint8_t arch)
Pratik Patel7831c082011-06-08 21:44:37 -07001589{
Pratik Patel61de7302012-03-07 12:06:10 -08001590 switch (arch) {
1591 case PFT_ARCH_V1_1:
1592 break;
1593 default:
1594 return false;
1595 }
1596 return true;
1597}
1598
Pratik Patele6e41da2012-09-12 12:50:29 -07001599static void __devinit etm_prepare_arch(struct etm_drvdata *drvdata)
1600{
1601 /* Unlock OS lock first to allow memory mapped reads and writes. This
1602 * is required for Krait pass1
1603 * */
1604 etm_os_unlock(NULL);
1605 smp_call_function(etm_os_unlock, NULL, 1);
1606}
1607
1608static void __devinit etm_init_arch_data(void *info)
Pratik Patel61de7302012-03-07 12:06:10 -08001609{
Pratik Patel61de7302012-03-07 12:06:10 -08001610 uint32_t etmidr;
1611 uint32_t etmccr;
Pratik Patele6e41da2012-09-12 12:50:29 -07001612 struct etm_drvdata *drvdata = info;
Pratik Patel7831c082011-06-08 21:44:37 -07001613
Pratik Patel3b0ca882012-06-01 16:54:14 -07001614 ETM_UNLOCK(drvdata);
Pratik Patel938e1ff2012-09-28 23:21:46 -07001615 /*
1616 * Vote for ETM power/clock enable. ETMPDCR is only accessible via
1617 * memory mapped interface and so use it first to enable power/clock
1618 * to allow subsequent cp14 accesses.
1619 */
Pratik Patelef6da292012-09-17 17:37:19 -07001620 etm_set_pwrup(drvdata);
Pratik Pateld1d65c92012-09-25 23:37:43 -07001621 /*
1622 * Clear power down bit since when this bit is set writes to
1623 * certain registers might be ignored.
1624 */
1625 etm_clr_pwrdwn(drvdata);
Pratik Patel61de7302012-03-07 12:06:10 -08001626 /* Set prog bit. It will be set from reset but this is included to
1627 * ensure it is set
1628 */
Pratik Patel3b0ca882012-06-01 16:54:14 -07001629 etm_set_prog(drvdata);
Pratik Patel7831c082011-06-08 21:44:37 -07001630
1631 /* find all capabilities */
Pratik Patel3b0ca882012-06-01 16:54:14 -07001632 etmidr = etm_readl(drvdata, ETMIDR);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001633 drvdata->arch = BMVAL(etmidr, 4, 11);
Pratik Patel7831c082011-06-08 21:44:37 -07001634
Pratik Patel3b0ca882012-06-01 16:54:14 -07001635 etmccr = etm_readl(drvdata, ETMCCR);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001636 drvdata->nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
1637 drvdata->nr_cntr = BMVAL(etmccr, 13, 15);
1638 drvdata->nr_ext_inp = BMVAL(etmccr, 17, 19);
1639 drvdata->nr_ext_out = BMVAL(etmccr, 20, 22);
1640 drvdata->nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
Pratik Patel2d0c7b62012-02-24 19:04:37 -08001641
Pratik Pateld1d65c92012-09-25 23:37:43 -07001642 etm_set_pwrdwn(drvdata);
Pratik Patelef6da292012-09-17 17:37:19 -07001643 etm_clr_pwrup(drvdata);
Pratik Patel3b0ca882012-06-01 16:54:14 -07001644 ETM_LOCK(drvdata);
Pratik Patel7831c082011-06-08 21:44:37 -07001645}
1646
Pratik Patelc14b4df2012-09-05 18:07:59 -07001647static void __devinit etm_copy_arch_data(struct etm_drvdata *drvdata)
1648{
1649 drvdata->arch = etm0drvdata->arch;
1650 drvdata->nr_addr_cmp = etm0drvdata->nr_addr_cmp;
1651 drvdata->nr_cntr = etm0drvdata->nr_cntr;
1652 drvdata->nr_ext_inp = etm0drvdata->nr_ext_inp;
1653 drvdata->nr_ext_out = etm0drvdata->nr_ext_out;
1654 drvdata->nr_ctxid_cmp = etm0drvdata->nr_ctxid_cmp;
1655}
1656
Pratik Patel3b0ca882012-06-01 16:54:14 -07001657static void __devinit etm_init_default_data(struct etm_drvdata *drvdata)
Pratik Patel16aefdb2012-05-30 10:41:23 -07001658{
1659 int i;
1660
1661 drvdata->trigger_event = 0x406F;
1662 drvdata->enable_event = 0x6F;
1663 drvdata->enable_ctrl1 = 0x1;
1664 drvdata->fifofull_level = 0x28;
1665 if (drvdata->nr_addr_cmp >= 2) {
1666 drvdata->addr_val[0] = (uint32_t) _stext;
1667 drvdata->addr_val[1] = (uint32_t) _etext;
1668 drvdata->addr_type[0] = ETM_ADDR_TYPE_RANGE;
1669 drvdata->addr_type[1] = ETM_ADDR_TYPE_RANGE;
1670 }
1671 for (i = 0; i < drvdata->nr_cntr; i++) {
1672 drvdata->cntr_event[i] = 0x406F;
1673 drvdata->cntr_rld_event[i] = 0x406F;
1674 }
1675 drvdata->seq_12_event = 0x406F;
1676 drvdata->seq_21_event = 0x406F;
1677 drvdata->seq_23_event = 0x406F;
1678 drvdata->seq_31_event = 0x406F;
1679 drvdata->seq_32_event = 0x406F;
1680 drvdata->seq_13_event = 0x406F;
Pratik Patel77b90632012-07-17 17:54:51 -07001681 /* Bits[7:0] of ETMSYNCFR are reserved on Krait pass3 onwards */
1682 if (cpu_is_krait() && !cpu_is_krait_v1() && !cpu_is_krait_v2())
1683 drvdata->sync_freq = 0x100;
1684 else
1685 drvdata->sync_freq = 0x80;
Pratik Patel16aefdb2012-05-30 10:41:23 -07001686 drvdata->timestamp_event = 0x406F;
1687
1688 /* Overrides for Krait pass1 */
1689 if (cpu_is_krait_v1()) {
1690 /* Krait pass1 doesn't support include filtering and non-cycle
1691 * accurate tracing
1692 */
1693 drvdata->mode = (ETM_MODE_EXCLUDE | ETM_MODE_CYCACC);
1694 drvdata->ctrl = 0x1000;
1695 drvdata->enable_ctrl1 = 0x1000000;
1696 for (i = 0; i < drvdata->nr_addr_cmp; i++) {
1697 drvdata->addr_val[i] = 0x0;
1698 drvdata->addr_acctype[i] = 0x0;
1699 drvdata->addr_type[i] = ETM_ADDR_TYPE_NONE;
1700 }
1701 }
1702}
1703
Pratik Patel492b3012012-03-06 14:22:30 -08001704static int __devinit etm_probe(struct platform_device *pdev)
Pratik Patel7831c082011-06-08 21:44:37 -07001705{
Pratik Patele5771792011-09-17 18:33:54 -07001706 int ret;
Pratik Patel4a1b2522012-06-17 15:31:15 -07001707 struct device *dev = &pdev->dev;
Pratik Patel5f6d1af2012-06-13 15:48:13 -07001708 struct coresight_platform_data *pdata;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001709 struct etm_drvdata *drvdata;
Pratik Patel7831c082011-06-08 21:44:37 -07001710 struct resource *res;
Pratik Patel26477792012-09-07 01:35:36 -07001711 uint32_t reg_size;
1712 static int count;
1713 void *baddr;
1714 struct msm_client_dump dump;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001715 struct coresight_desc *desc;
Pratik Patel7831c082011-06-08 21:44:37 -07001716
Pratik Patel5f6d1af2012-06-13 15:48:13 -07001717 if (pdev->dev.of_node) {
1718 pdata = of_get_coresight_platform_data(dev, pdev->dev.of_node);
1719 if (IS_ERR(pdata))
1720 return PTR_ERR(pdata);
1721 pdev->dev.platform_data = pdata;
1722 }
1723
Pratik Patel4a1b2522012-06-17 15:31:15 -07001724 drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
1725 if (!drvdata)
1726 return -ENOMEM;
Pratik Patel16aefdb2012-05-30 10:41:23 -07001727 drvdata->dev = &pdev->dev;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001728 platform_set_drvdata(pdev, drvdata);
Pratik Patel7831c082011-06-08 21:44:37 -07001729
Pratik Patel4a1b2522012-06-17 15:31:15 -07001730 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1731 if (!res)
1732 return -ENODEV;
Pratik Patel26477792012-09-07 01:35:36 -07001733 reg_size = resource_size(res);
Pratik Patel2c09b762012-07-21 15:54:54 -07001734
Pratik Patel4a1b2522012-06-17 15:31:15 -07001735 drvdata->base = devm_ioremap(dev, res->start, resource_size(res));
1736 if (!drvdata->base)
1737 return -ENOMEM;
1738
Pratik Patel16aefdb2012-05-30 10:41:23 -07001739 mutex_init(&drvdata->mutex);
Pratik Patel3b0ca882012-06-01 16:54:14 -07001740 wake_lock_init(&drvdata->wake_lock, WAKE_LOCK_SUSPEND, "coresight-etm");
Pratik Patele10a77c2012-03-20 10:35:16 -07001741
Pratik Patel4a1b2522012-06-17 15:31:15 -07001742 drvdata->clk = devm_clk_get(dev, "core_clk");
Pratik Patel16aefdb2012-05-30 10:41:23 -07001743 if (IS_ERR(drvdata->clk)) {
1744 ret = PTR_ERR(drvdata->clk);
Pratik Patel4a1b2522012-06-17 15:31:15 -07001745 goto err0;
Pratik Patelf17b1472012-05-25 22:23:52 -07001746 }
Pratik Patel2c09b762012-07-21 15:54:54 -07001747
Pratik Patel6fb38342012-06-03 14:51:38 -07001748 ret = clk_set_rate(drvdata->clk, CORESIGHT_CLK_RATE_TRACE);
Pratik Patel7831c082011-06-08 21:44:37 -07001749 if (ret)
Pratik Patel4a1b2522012-06-17 15:31:15 -07001750 goto err0;
1751
Pratik Patel26477792012-09-07 01:35:36 -07001752 drvdata->cpu = count++;
Pratik Patel4a1b2522012-06-17 15:31:15 -07001753
Pratik Patel16aefdb2012-05-30 10:41:23 -07001754 ret = clk_prepare_enable(drvdata->clk);
Pratik Patelf17b1472012-05-25 22:23:52 -07001755 if (ret)
Pratik Patel4a1b2522012-06-17 15:31:15 -07001756 goto err0;
Pratik Patel2c09b762012-07-21 15:54:54 -07001757
Pratik Patelc14b4df2012-09-05 18:07:59 -07001758 /* Use CPU0 to populate read-only configuration data for ETM0. For other
1759 * ETMs copy it over from ETM0.
1760 */
1761 if (drvdata->cpu == 0) {
Pratik Patele6e41da2012-09-12 12:50:29 -07001762 etm_prepare_arch(drvdata);
1763 smp_call_function_single(drvdata->cpu, etm_init_arch_data,
1764 drvdata, 1);
Pratik Patelc14b4df2012-09-05 18:07:59 -07001765 etm0drvdata = drvdata;
1766 } else {
Pratik Pateldc3a0a42012-09-11 17:48:23 -07001767 etm_copy_arch_data(drvdata);
1768 }
1769 if (etm_arch_supported(drvdata->arch) == false) {
1770 ret = -EINVAL;
1771 goto err1;
Pratik Patelc14b4df2012-09-05 18:07:59 -07001772 }
Pratik Patel3b0ca882012-06-01 16:54:14 -07001773 etm_init_default_data(drvdata);
Pratik Patel2c09b762012-07-21 15:54:54 -07001774
Pratik Patel16aefdb2012-05-30 10:41:23 -07001775 clk_disable_unprepare(drvdata->clk);
Pratik Patel7831c082011-06-08 21:44:37 -07001776
Pratik Patel26477792012-09-07 01:35:36 -07001777 baddr = devm_kzalloc(dev, PAGE_SIZE + reg_size, GFP_KERNEL);
1778 if (baddr) {
1779 *(uint32_t *)(baddr + ETM_REG_DUMP_VER_OFF) = ETM_REG_DUMP_VER;
1780 dump.id = MSM_ETM0_REG + drvdata->cpu;
1781 dump.start_addr = virt_to_phys(baddr);
1782 dump.end_addr = dump.start_addr + PAGE_SIZE + reg_size;
1783 ret = msm_dump_table_register(&dump);
1784 if (ret) {
1785 devm_kfree(dev, baddr);
1786 dev_err(dev, "ETM REG dump setup failed\n");
1787 }
1788 } else {
1789 dev_err(dev, "ETM REG dump space allocation failed\n");
1790 }
1791
Pratik Patel4a1b2522012-06-17 15:31:15 -07001792 desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
Pratik Patel3b0ca882012-06-01 16:54:14 -07001793 if (!desc) {
1794 ret = -ENOMEM;
Pratik Patel4a1b2522012-06-17 15:31:15 -07001795 goto err0;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001796 }
1797 desc->type = CORESIGHT_DEV_TYPE_SOURCE;
1798 desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC;
1799 desc->ops = &etm_cs_ops;
1800 desc->pdata = pdev->dev.platform_data;
1801 desc->dev = &pdev->dev;
1802 desc->groups = etm_attr_grps;
1803 desc->owner = THIS_MODULE;
1804 drvdata->csdev = coresight_register(desc);
1805 if (IS_ERR(drvdata->csdev)) {
1806 ret = PTR_ERR(drvdata->csdev);
Pratik Patel4a1b2522012-06-17 15:31:15 -07001807 goto err0;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001808 }
Pratik Patel3b0ca882012-06-01 16:54:14 -07001809
Pratik Patel938e1ff2012-09-28 23:21:46 -07001810 if (pdev->dev.of_node)
1811 drvdata->pcsave_impl = of_property_read_bool(pdev->dev.of_node,
1812 "qcom,pc-save");
1813 if (drvdata->pcsave_impl) {
1814 ret = device_create_file(&drvdata->csdev->dev,
1815 &dev_attr_pcsave);
1816 if (ret)
1817 dev_err(dev, "ETM pcsave dev node creation failed\n");
1818 }
1819
Pratik Patel4a1b2522012-06-17 15:31:15 -07001820 dev_info(dev, "ETM initialized\n");
Pratik Patel7831c082011-06-08 21:44:37 -07001821
Pratik Patel3b0ca882012-06-01 16:54:14 -07001822 if (boot_enable)
1823 coresight_enable(drvdata->csdev);
Pratik Patel7831c082011-06-08 21:44:37 -07001824
Pratik Patel938e1ff2012-09-28 23:21:46 -07001825 if (drvdata->pcsave_impl && boot_pcsave_enable)
1826 __etm_store_pcsave(drvdata, true);
1827
Pratik Patel7831c082011-06-08 21:44:37 -07001828 return 0;
Pratik Patel4a1b2522012-06-17 15:31:15 -07001829err1:
Pratik Patel16aefdb2012-05-30 10:41:23 -07001830 clk_disable_unprepare(drvdata->clk);
Pratik Patel4a1b2522012-06-17 15:31:15 -07001831err0:
Pratik Patel16aefdb2012-05-30 10:41:23 -07001832 wake_lock_destroy(&drvdata->wake_lock);
1833 mutex_destroy(&drvdata->mutex);
Pratik Patel7831c082011-06-08 21:44:37 -07001834 return ret;
1835}
1836
Pratik Patelf6fe9182012-03-20 14:04:18 -07001837static int __devexit etm_remove(struct platform_device *pdev)
Pratik Patel7831c082011-06-08 21:44:37 -07001838{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001839 struct etm_drvdata *drvdata = platform_get_drvdata(pdev);
1840
Pratik Patel938e1ff2012-09-28 23:21:46 -07001841 device_remove_file(&drvdata->csdev->dev, &dev_attr_pcsave);
Pratik Patel3b0ca882012-06-01 16:54:14 -07001842 coresight_unregister(drvdata->csdev);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001843 wake_lock_destroy(&drvdata->wake_lock);
1844 mutex_destroy(&drvdata->mutex);
Pratik Patel7831c082011-06-08 21:44:37 -07001845 return 0;
1846}
1847
Pratik Patel9eae4822012-05-14 17:34:53 -07001848static struct of_device_id etm_match[] = {
Pratik Patel5f6d1af2012-06-13 15:48:13 -07001849 {.compatible = "arm,coresight-etm"},
Pratik Patel9eae4822012-05-14 17:34:53 -07001850 {}
1851};
1852
Pratik Patel492b3012012-03-06 14:22:30 -08001853static struct platform_driver etm_driver = {
1854 .probe = etm_probe,
Pratik Patelf6fe9182012-03-20 14:04:18 -07001855 .remove = __devexit_p(etm_remove),
Pratik Patel7831c082011-06-08 21:44:37 -07001856 .driver = {
Pratik Patel3b0ca882012-06-01 16:54:14 -07001857 .name = "coresight-etm",
Pratik Patel9eae4822012-05-14 17:34:53 -07001858 .owner = THIS_MODULE,
1859 .of_match_table = etm_match,
Pratik Patel7831c082011-06-08 21:44:37 -07001860 },
1861};
1862
Pratik Patel492b3012012-03-06 14:22:30 -08001863int __init etm_init(void)
Pratik Patel7831c082011-06-08 21:44:37 -07001864{
Pratik Patel492b3012012-03-06 14:22:30 -08001865 return platform_driver_register(&etm_driver);
Pratik Patel7831c082011-06-08 21:44:37 -07001866}
Pratik Patelf6fe9182012-03-20 14:04:18 -07001867module_init(etm_init);
Pratik Patel7831c082011-06-08 21:44:37 -07001868
Pratik Patelf6fe9182012-03-20 14:04:18 -07001869void __exit etm_exit(void)
Pratik Patel7831c082011-06-08 21:44:37 -07001870{
Pratik Patel492b3012012-03-06 14:22:30 -08001871 platform_driver_unregister(&etm_driver);
Pratik Patel7831c082011-06-08 21:44:37 -07001872}
Pratik Patelf6fe9182012-03-20 14:04:18 -07001873module_exit(etm_exit);
1874
1875MODULE_LICENSE("GPL v2");
1876MODULE_DESCRIPTION("CoreSight Program Flow Trace driver");