blob: e03c0c36ac98b20d6187935cce81d52c47ebf54b [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 Patel9dbfa372012-10-23 22:36:40 -070030#include <linux/cpu.h>
Pratik Patel5f6d1af2012-06-13 15:48:13 -070031#include <linux/of_coresight.h>
Pratik Patel1746b8f2012-06-02 21:11:41 -070032#include <linux/coresight.h>
Pratik Pateld30deda2012-02-01 14:40:55 -080033#include <asm/sections.h>
Pratik Patel2d0c7b62012-02-24 19:04:37 -080034#include <mach/socinfo.h>
Pratik Patel26477792012-09-07 01:35:36 -070035#include <mach/msm_memory_dump.h>
Pratik Patel7831c082011-06-08 21:44:37 -070036
Pratik Patel1746b8f2012-06-02 21:11:41 -070037#include "coresight-priv.h"
Pratik Patel7831c082011-06-08 21:44:37 -070038
Pratik Patele6e41da2012-09-12 12:50:29 -070039#define etm_writel_mm(drvdata, val, off) \
Pratik Patel3b0ca882012-06-01 16:54:14 -070040 __raw_writel((val), drvdata->base + off)
Pratik Patele6e41da2012-09-12 12:50:29 -070041#define etm_readl_mm(drvdata, off) \
Pratik Patel3b0ca882012-06-01 16:54:14 -070042 __raw_readl(drvdata->base + off)
43
Pratik Patele6e41da2012-09-12 12:50:29 -070044#define etm_writel(drvdata, val, off) \
45({ \
46 if (cpu_is_krait_v3()) \
47 etm_writel_cp14(val, off); \
48 else \
49 etm_writel_mm(drvdata, val, off); \
50})
51#define etm_readl(drvdata, off) \
52({ \
53 uint32_t val; \
54 if (cpu_is_krait_v3()) \
55 val = etm_readl_cp14(off); \
56 else \
57 val = etm_readl_mm(drvdata, off); \
58 val; \
59})
60
Pratik Patel3b0ca882012-06-01 16:54:14 -070061#define ETM_LOCK(drvdata) \
62do { \
Pratik Patele6e41da2012-09-12 12:50:29 -070063 /* recommended by spec to ensure ETM writes are committed prior
64 * to resuming execution
65 */ \
Pratik Patel3b0ca882012-06-01 16:54:14 -070066 mb(); \
Pratik Patele6e41da2012-09-12 12:50:29 -070067 isb(); \
68 etm_writel_mm(drvdata, 0x0, CORESIGHT_LAR); \
Pratik Patel3b0ca882012-06-01 16:54:14 -070069} while (0)
70#define ETM_UNLOCK(drvdata) \
71do { \
Pratik Patele6e41da2012-09-12 12:50:29 -070072 etm_writel_mm(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR); \
73 /* ensure unlock and any pending writes are committed prior to
74 * programming ETM registers
75 */ \
Pratik Patel3b0ca882012-06-01 16:54:14 -070076 mb(); \
Pratik Patele6e41da2012-09-12 12:50:29 -070077 isb(); \
Pratik Patel3b0ca882012-06-01 16:54:14 -070078} while (0)
79
Pratik Patel7831c082011-06-08 21:44:37 -070080/*
81 * Device registers:
82 * 0x000 - 0x2FC: Trace registers
83 * 0x300 - 0x314: Management registers
84 * 0x318 - 0xEFC: Trace registers
85 *
86 * Coresight registers
87 * 0xF00 - 0xF9C: Management registers
88 * 0xFA0 - 0xFA4: Management registers in PFTv1.0
89 * Trace registers in PFTv1.1
90 * 0xFA8 - 0xFFC: Management registers
91 */
92
93/* Trace registers (0x000-0x2FC) */
94#define ETMCR (0x000)
95#define ETMCCR (0x004)
96#define ETMTRIGGER (0x008)
97#define ETMSR (0x010)
98#define ETMSCR (0x014)
99#define ETMTSSCR (0x018)
100#define ETMTEEVR (0x020)
101#define ETMTECR1 (0x024)
102#define ETMFFLR (0x02C)
103#define ETMACVRn(n) (0x040 + (n * 4))
104#define ETMACTRn(n) (0x080 + (n * 4))
105#define ETMCNTRLDVRn(n) (0x140 + (n * 4))
106#define ETMCNTENRn(n) (0x150 + (n * 4))
107#define ETMCNTRLDEVRn(n) (0x160 + (n * 4))
108#define ETMCNTVRn(n) (0x170 + (n * 4))
109#define ETMSQ12EVR (0x180)
110#define ETMSQ21EVR (0x184)
111#define ETMSQ23EVR (0x188)
Pratik Pateld5bbc762012-01-29 14:13:21 -0800112#define ETMSQ31EVR (0x18C)
113#define ETMSQ32EVR (0x190)
114#define ETMSQ13EVR (0x194)
Pratik Patel7831c082011-06-08 21:44:37 -0700115#define ETMSQR (0x19C)
116#define ETMEXTOUTEVRn(n) (0x1A0 + (n * 4))
117#define ETMCIDCVRn(n) (0x1B0 + (n * 4))
118#define ETMCIDCMR (0x1BC)
119#define ETMIMPSPEC0 (0x1C0)
120#define ETMIMPSPEC1 (0x1C4)
121#define ETMIMPSPEC2 (0x1C8)
122#define ETMIMPSPEC3 (0x1CC)
123#define ETMIMPSPEC4 (0x1D0)
124#define ETMIMPSPEC5 (0x1D4)
125#define ETMIMPSPEC6 (0x1D8)
126#define ETMIMPSPEC7 (0x1DC)
127#define ETMSYNCFR (0x1E0)
128#define ETMIDR (0x1E4)
129#define ETMCCER (0x1E8)
130#define ETMEXTINSELR (0x1EC)
131#define ETMTESSEICR (0x1F0)
132#define ETMEIBCR (0x1F4)
133#define ETMTSEVR (0x1F8)
134#define ETMAUXCR (0x1FC)
135#define ETMTRACEIDR (0x200)
Pratik Pateld5bbc762012-01-29 14:13:21 -0800136#define ETMVMIDCVR (0x240)
Pratik Patel7831c082011-06-08 21:44:37 -0700137/* Management registers (0x300-0x314) */
138#define ETMOSLAR (0x300)
139#define ETMOSLSR (0x304)
140#define ETMOSSRR (0x308)
141#define ETMPDCR (0x310)
142#define ETMPDSR (0x314)
143
Pratik Patel61de7302012-03-07 12:06:10 -0800144#define ETM_MAX_ADDR_CMP (16)
145#define ETM_MAX_CNTR (4)
146#define ETM_MAX_CTXID_CMP (3)
147
Pratik Patel6630ebe2012-03-06 16:44:22 -0800148#define ETM_MODE_EXCLUDE BIT(0)
149#define ETM_MODE_CYCACC BIT(1)
150#define ETM_MODE_STALL BIT(2)
151#define ETM_MODE_TIMESTAMP BIT(3)
152#define ETM_MODE_CTXID BIT(4)
153#define ETM_MODE_ALL (0x1F)
154
155#define ETM_EVENT_MASK (0x1FFFF)
156#define ETM_SYNC_MASK (0xFFF)
157#define ETM_ALL_MASK (0xFFFFFFFF)
158
159#define ETM_SEQ_STATE_MAX_VAL (0x2)
160
Pratik Patel26477792012-09-07 01:35:36 -0700161#define ETM_REG_DUMP_VER_OFF (4)
162#define ETM_REG_DUMP_VER (1)
163
Pratik Patel3b0ca882012-06-01 16:54:14 -0700164enum etm_addr_type {
Pratik Patel6630ebe2012-03-06 16:44:22 -0800165 ETM_ADDR_TYPE_NONE,
166 ETM_ADDR_TYPE_SINGLE,
167 ETM_ADDR_TYPE_RANGE,
168 ETM_ADDR_TYPE_START,
169 ETM_ADDR_TYPE_STOP,
170};
171
Pratik Patel29cba152012-01-03 11:40:26 -0800172#ifdef CONFIG_MSM_QDSS_ETM_DEFAULT_ENABLE
Pratik Patel3b0ca882012-06-01 16:54:14 -0700173static int boot_enable = 1;
Pratik Patel29cba152012-01-03 11:40:26 -0800174#else
Pratik Patel3b0ca882012-06-01 16:54:14 -0700175static int boot_enable;
Pratik Patel29cba152012-01-03 11:40:26 -0800176#endif
Pratik Patel7831c082011-06-08 21:44:37 -0700177module_param_named(
Pratik Patel3b0ca882012-06-01 16:54:14 -0700178 boot_enable, boot_enable, int, S_IRUGO
Pratik Patel7831c082011-06-08 21:44:37 -0700179);
180
Pratik Patel938e1ff2012-09-28 23:21:46 -0700181#ifdef CONFIG_MSM_QDSS_ETM_PCSAVE_DEFAULT_ENABLE
182static int boot_pcsave_enable = 1;
183#else
184static int boot_pcsave_enable;
185#endif
186module_param_named(
187 boot_pcsave_enable, boot_pcsave_enable, int, S_IRUGO
188);
189
Pratik Patel16aefdb2012-05-30 10:41:23 -0700190struct etm_drvdata {
Pratik Patel7831c082011-06-08 21:44:37 -0700191 void __iomem *base;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700192 struct device *dev;
193 struct coresight_device *csdev;
194 struct clk *clk;
195 struct mutex mutex;
Pratik Patel7831c082011-06-08 21:44:37 -0700196 struct wake_lock wake_lock;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700197 int cpu;
Pratik Patel61de7302012-03-07 12:06:10 -0800198 uint8_t arch;
Pratik Patelf3238df2012-10-19 16:19:12 -0700199 bool enable;
Pratik Patel61de7302012-03-07 12:06:10 -0800200 uint8_t nr_addr_cmp;
201 uint8_t nr_cntr;
202 uint8_t nr_ext_inp;
203 uint8_t nr_ext_out;
204 uint8_t nr_ctxid_cmp;
Pratik Pateld30deda2012-02-01 14:40:55 -0800205 uint8_t reset;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800206 uint32_t mode;
Pratik Patel61de7302012-03-07 12:06:10 -0800207 uint32_t ctrl;
208 uint32_t trigger_event;
209 uint32_t startstop_ctrl;
210 uint32_t enable_event;
211 uint32_t enable_ctrl1;
212 uint32_t fifofull_level;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800213 uint8_t addr_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800214 uint32_t addr_val[ETM_MAX_ADDR_CMP];
215 uint32_t addr_acctype[ETM_MAX_ADDR_CMP];
Pratik Patel6630ebe2012-03-06 16:44:22 -0800216 uint32_t addr_type[ETM_MAX_ADDR_CMP];
217 uint8_t cntr_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800218 uint32_t cntr_rld_val[ETM_MAX_CNTR];
219 uint32_t cntr_event[ETM_MAX_CNTR];
220 uint32_t cntr_rld_event[ETM_MAX_CNTR];
221 uint32_t cntr_val[ETM_MAX_CNTR];
222 uint32_t seq_12_event;
223 uint32_t seq_21_event;
224 uint32_t seq_23_event;
225 uint32_t seq_31_event;
226 uint32_t seq_32_event;
227 uint32_t seq_13_event;
228 uint32_t seq_curr_state;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800229 uint8_t ctxid_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800230 uint32_t ctxid_val[ETM_MAX_CTXID_CMP];
231 uint32_t ctxid_mask;
232 uint32_t sync_freq;
233 uint32_t timestamp_event;
Pratik Patel938e1ff2012-09-28 23:21:46 -0700234 bool pcsave_impl;
235 bool pcsave_enable;
Pratik Patel7831c082011-06-08 21:44:37 -0700236};
237
Pratik Patelc14b4df2012-09-05 18:07:59 -0700238static struct etm_drvdata *etm0drvdata;
239
Pratik Pateld1d65c92012-09-25 23:37:43 -0700240/*
241 * ETM clock is derived from the processor clock and gets enabled on a
242 * logical OR of below items on Krait (v2 onwards):
Pratik Patel17f3b822011-11-21 12:41:47 -0800243 * 1.CPMR[ETMCLKEN] is 1
244 * 2.ETMCR[PD] is 0
245 * 3.ETMPDCR[PU] is 1
246 * 4.Reset is asserted (core or debug)
247 * 5.APB memory mapped requests (eg. EDAP access)
248 *
249 * 1., 2. and 3. above are permanent enables whereas 4. and 5. are temporary
250 * enables
251 *
Pratik Pateld1d65c92012-09-25 23:37:43 -0700252 * We rely on 5. to be able to access ETMCR/ETMPDCR and then use 2./3. above
253 * for ETM clock vote in the driver and the save-restore code uses 1. above
Pratik Patel17f3b822011-11-21 12:41:47 -0800254 * for its vote
255 */
Pratik Pateld1d65c92012-09-25 23:37:43 -0700256static void etm_set_pwrdwn(struct etm_drvdata *drvdata)
257{
258 uint32_t etmcr;
259
260 /* ensure pending cp14 accesses complete before setting pwrdwn */
261 mb();
262 isb();
263 etmcr = etm_readl(drvdata, ETMCR);
264 etmcr |= BIT(0);
265 etm_writel(drvdata, etmcr, ETMCR);
266}
267
268static void etm_clr_pwrdwn(struct etm_drvdata *drvdata)
269{
270 uint32_t etmcr;
271
272 etmcr = etm_readl(drvdata, ETMCR);
273 etmcr &= ~BIT(0);
274 etm_writel(drvdata, etmcr, ETMCR);
275 /* ensure pwrup completes before subsequent cp14 accesses */
276 mb();
277 isb();
278}
279
Pratik Patelef6da292012-09-17 17:37:19 -0700280static void etm_set_pwrup(struct etm_drvdata *drvdata)
Pratik Patel7831c082011-06-08 21:44:37 -0700281{
Pratik Patelef6da292012-09-17 17:37:19 -0700282 uint32_t etmpdcr;
Pratik Patel7831c082011-06-08 21:44:37 -0700283
Pratik Patele6e41da2012-09-12 12:50:29 -0700284 etmpdcr = etm_readl_mm(drvdata, ETMPDCR);
Pratik Patelef6da292012-09-17 17:37:19 -0700285 etmpdcr |= BIT(3);
Pratik Patele6e41da2012-09-12 12:50:29 -0700286 etm_writel_mm(drvdata, etmpdcr, ETMPDCR);
287 /* ensure pwrup completes before subsequent cp14 accesses */
288 mb();
289 isb();
Pratik Patel7831c082011-06-08 21:44:37 -0700290}
291
Pratik Patelef6da292012-09-17 17:37:19 -0700292static void etm_clr_pwrup(struct etm_drvdata *drvdata)
Pratik Patel7831c082011-06-08 21:44:37 -0700293{
Pratik Patelef6da292012-09-17 17:37:19 -0700294 uint32_t etmpdcr;
Pratik Patel7831c082011-06-08 21:44:37 -0700295
Pratik Patele6e41da2012-09-12 12:50:29 -0700296 /* ensure pending cp14 accesses complete before clearing pwrup */
297 mb();
298 isb();
299 etmpdcr = etm_readl_mm(drvdata, ETMPDCR);
Pratik Patelef6da292012-09-17 17:37:19 -0700300 etmpdcr &= ~BIT(3);
Pratik Patele6e41da2012-09-12 12:50:29 -0700301 etm_writel_mm(drvdata, etmpdcr, ETMPDCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700302}
303
Pratik Patel3b0ca882012-06-01 16:54:14 -0700304static void etm_set_prog(struct etm_drvdata *drvdata)
Pratik Patel7831c082011-06-08 21:44:37 -0700305{
306 uint32_t etmcr;
307 int count;
308
Pratik Patel3b0ca882012-06-01 16:54:14 -0700309 etmcr = etm_readl(drvdata, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700310 etmcr |= BIT(10);
Pratik Patel3b0ca882012-06-01 16:54:14 -0700311 etm_writel(drvdata, etmcr, ETMCR);
Pratik Patele6e41da2012-09-12 12:50:29 -0700312 /* recommended by spec for cp14 accesses to ensure etmcr write is
313 * complete before polling etmsr
314 */
315 isb();
Pratik Patel3b0ca882012-06-01 16:54:14 -0700316 for (count = TIMEOUT_US; BVAL(etm_readl(drvdata, ETMSR), 1) != 1
Pratik Patel7831c082011-06-08 21:44:37 -0700317 && count > 0; count--)
318 udelay(1);
Pratik Patel61de7302012-03-07 12:06:10 -0800319 WARN(count == 0, "timeout while setting prog bit, ETMSR: %#x\n",
Pratik Patel3b0ca882012-06-01 16:54:14 -0700320 etm_readl(drvdata, ETMSR));
Pratik Patel7831c082011-06-08 21:44:37 -0700321}
322
Pratik Patel3b0ca882012-06-01 16:54:14 -0700323static void etm_clr_prog(struct etm_drvdata *drvdata)
Pratik Patel7831c082011-06-08 21:44:37 -0700324{
325 uint32_t etmcr;
326 int count;
327
Pratik Patel3b0ca882012-06-01 16:54:14 -0700328 etmcr = etm_readl(drvdata, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700329 etmcr &= ~BIT(10);
Pratik Patel3b0ca882012-06-01 16:54:14 -0700330 etm_writel(drvdata, etmcr, ETMCR);
Pratik Patele6e41da2012-09-12 12:50:29 -0700331 /* recommended by spec for cp14 accesses to ensure etmcr write is
332 * complete before polling etmsr
333 */
334 isb();
Pratik Patel3b0ca882012-06-01 16:54:14 -0700335 for (count = TIMEOUT_US; BVAL(etm_readl(drvdata, ETMSR), 1) != 0
Pratik Patel7831c082011-06-08 21:44:37 -0700336 && count > 0; count--)
337 udelay(1);
Pratik Patel61de7302012-03-07 12:06:10 -0800338 WARN(count == 0, "timeout while clearing prog bit, ETMSR: %#x\n",
Pratik Patel3b0ca882012-06-01 16:54:14 -0700339 etm_readl(drvdata, ETMSR));
Pratik Patel7831c082011-06-08 21:44:37 -0700340}
341
Pratik Patel938e1ff2012-09-28 23:21:46 -0700342static void etm_enable_pcsave(void *info)
343{
344 struct etm_drvdata *drvdata = info;
345
346 ETM_UNLOCK(drvdata);
347
Pratik Patel938e1ff2012-09-28 23:21:46 -0700348 /*
349 * ETMPDCR is only accessible via memory mapped interface and so use
350 * it first to enable power/clock to allow subsequent cp14 accesses.
351 */
352 etm_set_pwrup(drvdata);
353 etm_clr_pwrdwn(drvdata);
Pratik Patel938e1ff2012-09-28 23:21:46 -0700354
355 ETM_LOCK(drvdata);
356}
357
358static void etm_disable_pcsave(void *info)
359{
360 struct etm_drvdata *drvdata = info;
361
362 ETM_UNLOCK(drvdata);
363
Pratik Patelf3238df2012-10-19 16:19:12 -0700364 if (!drvdata->enable) {
365 etm_set_pwrdwn(drvdata);
366 etm_clr_pwrup(drvdata);
367 }
Pratik Patel938e1ff2012-09-28 23:21:46 -0700368
369 ETM_LOCK(drvdata);
370}
371
Pratik Patel66e1a412012-09-06 11:07:06 -0700372static void __etm_enable(void *info)
Pratik Patel7831c082011-06-08 21:44:37 -0700373{
Pratik Patel17f3b822011-11-21 12:41:47 -0800374 int i;
Pratik Pateld1d65c92012-09-25 23:37:43 -0700375 uint32_t etmcr;
Pratik Patel66e1a412012-09-06 11:07:06 -0700376 struct etm_drvdata *drvdata = info;
Pratik Patel7831c082011-06-08 21:44:37 -0700377
Pratik Patel3b0ca882012-06-01 16:54:14 -0700378 ETM_UNLOCK(drvdata);
Pratik Patel938e1ff2012-09-28 23:21:46 -0700379 /*
380 * Vote for ETM power/clock enable. ETMPDCR is only accessible via
381 * memory mapped interface and so use it first to enable power/clock
382 * to allow subsequent cp14 accesses.
383 */
Pratik Patelef6da292012-09-17 17:37:19 -0700384 etm_set_pwrup(drvdata);
Pratik Pateld1d65c92012-09-25 23:37:43 -0700385 /*
386 * Clear power down bit since when this bit is set writes to
Pratik Patelf3238df2012-10-19 16:19:12 -0700387 * certain registers might be ignored. This is also a pre-requisite
388 * for trace enable.
Pratik Pateld1d65c92012-09-25 23:37:43 -0700389 */
390 etm_clr_pwrdwn(drvdata);
Pratik Patel3b0ca882012-06-01 16:54:14 -0700391 etm_set_prog(drvdata);
Pratik Patel7831c082011-06-08 21:44:37 -0700392
Pratik Pateld1d65c92012-09-25 23:37:43 -0700393 etmcr = etm_readl(drvdata, ETMCR);
394 etmcr &= (BIT(10) | BIT(0));
395 etm_writel(drvdata, drvdata->ctrl | etmcr, ETMCR);
Pratik Patel3b0ca882012-06-01 16:54:14 -0700396 etm_writel(drvdata, drvdata->trigger_event, ETMTRIGGER);
397 etm_writel(drvdata, drvdata->startstop_ctrl, ETMTSSCR);
398 etm_writel(drvdata, drvdata->enable_event, ETMTEEVR);
399 etm_writel(drvdata, drvdata->enable_ctrl1, ETMTECR1);
400 etm_writel(drvdata, drvdata->fifofull_level, ETMFFLR);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700401 for (i = 0; i < drvdata->nr_addr_cmp; i++) {
Pratik Patel3b0ca882012-06-01 16:54:14 -0700402 etm_writel(drvdata, drvdata->addr_val[i], ETMACVRn(i));
403 etm_writel(drvdata, drvdata->addr_acctype[i], ETMACTRn(i));
Pratik Patel7831c082011-06-08 21:44:37 -0700404 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700405 for (i = 0; i < drvdata->nr_cntr; i++) {
Pratik Patel3b0ca882012-06-01 16:54:14 -0700406 etm_writel(drvdata, drvdata->cntr_rld_val[i], ETMCNTRLDVRn(i));
407 etm_writel(drvdata, drvdata->cntr_event[i], ETMCNTENRn(i));
408 etm_writel(drvdata, drvdata->cntr_rld_event[i],
Pratik Patel16aefdb2012-05-30 10:41:23 -0700409 ETMCNTRLDEVRn(i));
Pratik Patel3b0ca882012-06-01 16:54:14 -0700410 etm_writel(drvdata, drvdata->cntr_val[i], ETMCNTVRn(i));
Pratik Patel17f3b822011-11-21 12:41:47 -0800411 }
Pratik Patel3b0ca882012-06-01 16:54:14 -0700412 etm_writel(drvdata, drvdata->seq_12_event, ETMSQ12EVR);
413 etm_writel(drvdata, drvdata->seq_21_event, ETMSQ21EVR);
414 etm_writel(drvdata, drvdata->seq_23_event, ETMSQ23EVR);
415 etm_writel(drvdata, drvdata->seq_31_event, ETMSQ31EVR);
416 etm_writel(drvdata, drvdata->seq_32_event, ETMSQ32EVR);
417 etm_writel(drvdata, drvdata->seq_13_event, ETMSQ13EVR);
418 etm_writel(drvdata, drvdata->seq_curr_state, ETMSQR);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700419 for (i = 0; i < drvdata->nr_ext_out; i++)
Pratik Patel3b0ca882012-06-01 16:54:14 -0700420 etm_writel(drvdata, 0x0000406F, ETMEXTOUTEVRn(i));
Pratik Patel16aefdb2012-05-30 10:41:23 -0700421 for (i = 0; i < drvdata->nr_ctxid_cmp; i++)
Pratik Patel3b0ca882012-06-01 16:54:14 -0700422 etm_writel(drvdata, drvdata->ctxid_val[i], ETMCIDCVRn(i));
423 etm_writel(drvdata, drvdata->ctxid_mask, ETMCIDCMR);
424 etm_writel(drvdata, drvdata->sync_freq, ETMSYNCFR);
425 etm_writel(drvdata, 0x00000000, ETMEXTINSELR);
426 etm_writel(drvdata, drvdata->timestamp_event, ETMTSEVR);
427 etm_writel(drvdata, 0x00000000, ETMAUXCR);
428 etm_writel(drvdata, drvdata->cpu + 1, ETMTRACEIDR);
429 etm_writel(drvdata, 0x00000000, ETMVMIDCVR);
Pratik Patel17f3b822011-11-21 12:41:47 -0800430
Pratik Patel3b0ca882012-06-01 16:54:14 -0700431 etm_clr_prog(drvdata);
432 ETM_LOCK(drvdata);
Pratik Patel66e1a412012-09-06 11:07:06 -0700433
434 dev_dbg(drvdata->dev, "cpu: %d enable smp call done\n", drvdata->cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700435}
436
Pratik Patel3b0ca882012-06-01 16:54:14 -0700437static int etm_enable(struct coresight_device *csdev)
Pratik Patel7831c082011-06-08 21:44:37 -0700438{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700439 struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
440 int ret;
Pratik Patel61de7302012-03-07 12:06:10 -0800441
Pratik Patel16aefdb2012-05-30 10:41:23 -0700442 wake_lock(&drvdata->wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700443
Pratik Patel16aefdb2012-05-30 10:41:23 -0700444 ret = clk_prepare_enable(drvdata->clk);
Pratik Patelf17b1472012-05-25 22:23:52 -0700445 if (ret)
446 goto err_clk;
447
Pratik Patel3b0ca882012-06-01 16:54:14 -0700448 mutex_lock(&drvdata->mutex);
Pratik Patelf3238df2012-10-19 16:19:12 -0700449 /*
450 * Executing __etm_enable on the cpu whose ETM is being enabled
Pratik Patel66e1a412012-09-06 11:07:06 -0700451 * ensures that register writes occur when cpu is powered.
452 */
453 smp_call_function_single(drvdata->cpu, __etm_enable, drvdata, 1);
Pratik Patelf3238df2012-10-19 16:19:12 -0700454 drvdata->enable = true;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700455 mutex_unlock(&drvdata->mutex);
Pratik Patel7831c082011-06-08 21:44:37 -0700456
Pratik Patel16aefdb2012-05-30 10:41:23 -0700457 wake_unlock(&drvdata->wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700458
Pratik Patel16aefdb2012-05-30 10:41:23 -0700459 dev_info(drvdata->dev, "ETM tracing enabled\n");
Pratik Patel7831c082011-06-08 21:44:37 -0700460 return 0;
Pratik Patelf17b1472012-05-25 22:23:52 -0700461err_clk:
Pratik Patel16aefdb2012-05-30 10:41:23 -0700462 wake_unlock(&drvdata->wake_lock);
Pratik Patel61de7302012-03-07 12:06:10 -0800463 return ret;
Pratik Patel7831c082011-06-08 21:44:37 -0700464}
465
Pratik Patel66e1a412012-09-06 11:07:06 -0700466static void __etm_disable(void *info)
Pratik Patel7831c082011-06-08 21:44:37 -0700467{
Pratik Patel66e1a412012-09-06 11:07:06 -0700468 struct etm_drvdata *drvdata = info;
469
Pratik Patel3b0ca882012-06-01 16:54:14 -0700470 ETM_UNLOCK(drvdata);
471 etm_set_prog(drvdata);
Pratik Patel7831c082011-06-08 21:44:37 -0700472
Pratik Patel17f3b822011-11-21 12:41:47 -0800473 /* program trace enable to low by using always false event */
Pratik Patel3b0ca882012-06-01 16:54:14 -0700474 etm_writel(drvdata, 0x6F | BIT(14), ETMTEEVR);
Pratik Patel7831c082011-06-08 21:44:37 -0700475
Pratik Patelf3238df2012-10-19 16:19:12 -0700476 if (!drvdata->pcsave_enable) {
477 etm_set_pwrdwn(drvdata);
478 etm_clr_pwrup(drvdata);
479 }
Pratik Patel3b0ca882012-06-01 16:54:14 -0700480 ETM_LOCK(drvdata);
Pratik Patel66e1a412012-09-06 11:07:06 -0700481
482 dev_dbg(drvdata->dev, "cpu: %d disable smp call done\n", drvdata->cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700483}
484
Pratik Patel3b0ca882012-06-01 16:54:14 -0700485static void etm_disable(struct coresight_device *csdev)
Pratik Patel7831c082011-06-08 21:44:37 -0700486{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700487 struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
Pratik Patel17f3b822011-11-21 12:41:47 -0800488
Pratik Patel16aefdb2012-05-30 10:41:23 -0700489 wake_lock(&drvdata->wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700490
Pratik Patel3b0ca882012-06-01 16:54:14 -0700491 mutex_lock(&drvdata->mutex);
Pratik Patelf3238df2012-10-19 16:19:12 -0700492 /*
493 * Executing __etm_disable on the cpu whose ETM is being disabled
Pratik Patel66e1a412012-09-06 11:07:06 -0700494 * ensures that register writes occur when cpu is powered.
495 */
496 smp_call_function_single(drvdata->cpu, __etm_disable, drvdata, 1);
Pratik Patelf3238df2012-10-19 16:19:12 -0700497 drvdata->enable = false;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700498 mutex_unlock(&drvdata->mutex);
Pratik Patel7831c082011-06-08 21:44:37 -0700499
Pratik Patel16aefdb2012-05-30 10:41:23 -0700500 clk_disable_unprepare(drvdata->clk);
Pratik Patel7831c082011-06-08 21:44:37 -0700501
Pratik Patel16aefdb2012-05-30 10:41:23 -0700502 wake_unlock(&drvdata->wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700503
Pratik Patel16aefdb2012-05-30 10:41:23 -0700504 dev_info(drvdata->dev, "ETM tracing disabled\n");
Pratik Patel7831c082011-06-08 21:44:37 -0700505}
506
Pratik Patel3b0ca882012-06-01 16:54:14 -0700507static const struct coresight_ops_source etm_source_ops = {
508 .enable = etm_enable,
509 .disable = etm_disable,
510};
Pratik Patel17f3b822011-11-21 12:41:47 -0800511
Pratik Patel3b0ca882012-06-01 16:54:14 -0700512static const struct coresight_ops etm_cs_ops = {
513 .source_ops = &etm_source_ops,
514};
Pratik Patel6630ebe2012-03-06 16:44:22 -0800515
Pratik Patela9c0e062012-05-28 13:45:35 -0700516static ssize_t etm_show_nr_addr_cmp(struct device *dev,
517 struct device_attribute *attr, char *buf)
518{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700519 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700520 unsigned long val = drvdata->nr_addr_cmp;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700521
Pratik Patela9c0e062012-05-28 13:45:35 -0700522 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
523}
524static DEVICE_ATTR(nr_addr_cmp, S_IRUGO, etm_show_nr_addr_cmp, NULL);
525
526static ssize_t etm_show_nr_cntr(struct device *dev,
527 struct device_attribute *attr, char *buf)
528{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700529 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700530 unsigned long val = drvdata->nr_cntr;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700531
Pratik Patela9c0e062012-05-28 13:45:35 -0700532 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
533}
534static DEVICE_ATTR(nr_cntr, S_IRUGO, etm_show_nr_cntr, NULL);
535
536static ssize_t etm_show_nr_ctxid_cmp(struct device *dev,
537 struct device_attribute *attr, char *buf)
538{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700539 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700540 unsigned long val = drvdata->nr_ctxid_cmp;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700541
Pratik Patela9c0e062012-05-28 13:45:35 -0700542 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
543}
544static DEVICE_ATTR(nr_ctxid_cmp, S_IRUGO, etm_show_nr_ctxid_cmp, NULL);
545
546static ssize_t etm_show_reset(struct device *dev, struct device_attribute *attr,
547 char *buf)
548{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700549 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700550 unsigned long val = drvdata->reset;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700551
Pratik Patela9c0e062012-05-28 13:45:35 -0700552 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
553}
Pratik Patel6630ebe2012-03-06 16:44:22 -0800554
Pratik Pateld30deda2012-02-01 14:40:55 -0800555/* Reset to trace everything i.e. exclude nothing. */
Pratik Patela9c0e062012-05-28 13:45:35 -0700556static ssize_t etm_store_reset(struct device *dev,
557 struct device_attribute *attr, const char *buf,
558 size_t size)
Pratik Pateld30deda2012-02-01 14:40:55 -0800559{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700560 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Pateld30deda2012-02-01 14:40:55 -0800561 int i;
562 unsigned long val;
563
564 if (sscanf(buf, "%lx", &val) != 1)
565 return -EINVAL;
566
Pratik Patel16aefdb2012-05-30 10:41:23 -0700567 mutex_lock(&drvdata->mutex);
Pratik Pateld30deda2012-02-01 14:40:55 -0800568 if (val) {
Pratik Patel16aefdb2012-05-30 10:41:23 -0700569 drvdata->mode = ETM_MODE_EXCLUDE;
570 drvdata->ctrl = 0x0;
Pratik Patel2d0c7b62012-02-24 19:04:37 -0800571 if (cpu_is_krait_v1()) {
Pratik Patel16aefdb2012-05-30 10:41:23 -0700572 drvdata->mode |= ETM_MODE_CYCACC;
573 drvdata->ctrl |= BIT(12);
Pratik Patel2d0c7b62012-02-24 19:04:37 -0800574 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700575 drvdata->trigger_event = 0x406F;
576 drvdata->startstop_ctrl = 0x0;
577 drvdata->enable_event = 0x6F;
578 drvdata->enable_ctrl1 = 0x1000000;
579 drvdata->fifofull_level = 0x28;
580 drvdata->addr_idx = 0x0;
581 for (i = 0; i < drvdata->nr_addr_cmp; i++) {
582 drvdata->addr_val[i] = 0x0;
583 drvdata->addr_acctype[i] = 0x0;
584 drvdata->addr_type[i] = ETM_ADDR_TYPE_NONE;
Pratik Pateld30deda2012-02-01 14:40:55 -0800585 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700586 drvdata->cntr_idx = 0x0;
587 for (i = 0; i < drvdata->nr_cntr; i++) {
588 drvdata->cntr_rld_val[i] = 0x0;
589 drvdata->cntr_event[i] = 0x406F;
590 drvdata->cntr_rld_event[i] = 0x406F;
591 drvdata->cntr_val[i] = 0x0;
Pratik Pateld30deda2012-02-01 14:40:55 -0800592 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700593 drvdata->seq_12_event = 0x406F;
594 drvdata->seq_21_event = 0x406F;
595 drvdata->seq_23_event = 0x406F;
596 drvdata->seq_31_event = 0x406F;
597 drvdata->seq_32_event = 0x406F;
598 drvdata->seq_13_event = 0x406F;
599 drvdata->seq_curr_state = 0x0;
600 drvdata->ctxid_idx = 0x0;
601 for (i = 0; i < drvdata->nr_ctxid_cmp; i++)
602 drvdata->ctxid_val[i] = 0x0;
603 drvdata->ctxid_mask = 0x0;
Pratik Patel77b90632012-07-17 17:54:51 -0700604 /* Bits[7:0] of ETMSYNCFR are reserved on Krait pass3 onwards */
605 if (cpu_is_krait() && !cpu_is_krait_v1() && !cpu_is_krait_v2())
606 drvdata->sync_freq = 0x100;
607 else
608 drvdata->sync_freq = 0x80;
Pratik Patel16aefdb2012-05-30 10:41:23 -0700609 drvdata->timestamp_event = 0x406F;
Pratik Pateld30deda2012-02-01 14:40:55 -0800610 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700611 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700612 return size;
Pratik Pateld30deda2012-02-01 14:40:55 -0800613}
Pratik Patela9c0e062012-05-28 13:45:35 -0700614static DEVICE_ATTR(reset, S_IRUGO | S_IWUSR, etm_show_reset, etm_store_reset);
Pratik Pateld30deda2012-02-01 14:40:55 -0800615
Pratik Patela9c0e062012-05-28 13:45:35 -0700616static ssize_t etm_show_mode(struct device *dev, struct device_attribute *attr,
617 char *buf)
618{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700619 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700620 unsigned long val = drvdata->mode;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700621
Pratik Patela9c0e062012-05-28 13:45:35 -0700622 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
623}
624
625static ssize_t etm_store_mode(struct device *dev, struct device_attribute *attr,
626 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800627{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700628 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800629 unsigned long val;
630
631 if (sscanf(buf, "%lx", &val) != 1)
632 return -EINVAL;
633
Pratik Patel16aefdb2012-05-30 10:41:23 -0700634 mutex_lock(&drvdata->mutex);
635 drvdata->mode = val & ETM_MODE_ALL;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800636
Pratik Patel16aefdb2012-05-30 10:41:23 -0700637 if (drvdata->mode & ETM_MODE_EXCLUDE)
638 drvdata->enable_ctrl1 |= BIT(24);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800639 else
Pratik Patel16aefdb2012-05-30 10:41:23 -0700640 drvdata->enable_ctrl1 &= ~BIT(24);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800641
Pratik Patel16aefdb2012-05-30 10:41:23 -0700642 if (drvdata->mode & ETM_MODE_CYCACC)
643 drvdata->ctrl |= BIT(12);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800644 else
Pratik Patel16aefdb2012-05-30 10:41:23 -0700645 drvdata->ctrl &= ~BIT(12);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800646
Pratik Patel16aefdb2012-05-30 10:41:23 -0700647 if (drvdata->mode & ETM_MODE_STALL)
648 drvdata->ctrl |= BIT(7);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800649 else
Pratik Patel16aefdb2012-05-30 10:41:23 -0700650 drvdata->ctrl &= ~BIT(7);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800651
Pratik Patel16aefdb2012-05-30 10:41:23 -0700652 if (drvdata->mode & ETM_MODE_TIMESTAMP)
653 drvdata->ctrl |= BIT(28);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800654 else
Pratik Patel16aefdb2012-05-30 10:41:23 -0700655 drvdata->ctrl &= ~BIT(28);
Pratik Patel3b0ca882012-06-01 16:54:14 -0700656
Pratik Patel16aefdb2012-05-30 10:41:23 -0700657 if (drvdata->mode & ETM_MODE_CTXID)
658 drvdata->ctrl |= (BIT(14) | BIT(15));
Pratik Patel6630ebe2012-03-06 16:44:22 -0800659 else
Pratik Patel16aefdb2012-05-30 10:41:23 -0700660 drvdata->ctrl &= ~(BIT(14) | BIT(15));
661 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800662
Pratik Patela9c0e062012-05-28 13:45:35 -0700663 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800664}
Pratik Patela9c0e062012-05-28 13:45:35 -0700665static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, etm_show_mode, etm_store_mode);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800666
Pratik Patela9c0e062012-05-28 13:45:35 -0700667static ssize_t etm_show_trigger_event(struct device *dev,
668 struct device_attribute *attr, char *buf)
669{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700670 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700671 unsigned long val = drvdata->trigger_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700672
Pratik Patela9c0e062012-05-28 13:45:35 -0700673 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
674}
Pratik Patel6630ebe2012-03-06 16:44:22 -0800675
Pratik Patela9c0e062012-05-28 13:45:35 -0700676static ssize_t etm_store_trigger_event(struct device *dev,
677 struct device_attribute *attr,
678 const char *buf, size_t size)
679{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700680 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -0700681 unsigned long val;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800682
Pratik Patela9c0e062012-05-28 13:45:35 -0700683 if (sscanf(buf, "%lx", &val) != 1)
684 return -EINVAL;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800685
Pratik Patel16aefdb2012-05-30 10:41:23 -0700686 drvdata->trigger_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -0700687 return size;
688}
689static DEVICE_ATTR(trigger_event, S_IRUGO | S_IWUSR, etm_show_trigger_event,
690 etm_store_trigger_event);
691
692static ssize_t etm_show_enable_event(struct device *dev,
693 struct device_attribute *attr, char *buf)
694{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700695 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700696 unsigned long val = drvdata->enable_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700697
Pratik Patela9c0e062012-05-28 13:45:35 -0700698 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
699}
700
701static ssize_t etm_store_enable_event(struct device *dev,
702 struct device_attribute *attr,
703 const char *buf, size_t size)
704{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700705 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -0700706 unsigned long val;
707
708 if (sscanf(buf, "%lx", &val) != 1)
709 return -EINVAL;
710
Pratik Patel16aefdb2012-05-30 10:41:23 -0700711 drvdata->enable_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -0700712 return size;
713}
714static DEVICE_ATTR(enable_event, S_IRUGO | S_IWUSR, etm_show_enable_event,
715 etm_store_enable_event);
716
717static ssize_t etm_show_fifofull_level(struct device *dev,
718 struct device_attribute *attr, char *buf)
719{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700720 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700721 unsigned long val = drvdata->fifofull_level;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700722
Pratik Patela9c0e062012-05-28 13:45:35 -0700723 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
724}
725
726static ssize_t etm_store_fifofull_level(struct device *dev,
727 struct device_attribute *attr,
728 const char *buf, size_t size)
729{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700730 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -0700731 unsigned long val;
732
733 if (sscanf(buf, "%lx", &val) != 1)
734 return -EINVAL;
735
Pratik Patel16aefdb2012-05-30 10:41:23 -0700736 drvdata->fifofull_level = val;
Pratik Patela9c0e062012-05-28 13:45:35 -0700737 return size;
738}
739static DEVICE_ATTR(fifofull_level, S_IRUGO | S_IWUSR, etm_show_fifofull_level,
740 etm_store_fifofull_level);
741
742static ssize_t etm_show_addr_idx(struct device *dev,
743 struct device_attribute *attr, char *buf)
744{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700745 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -0700746 unsigned long val = drvdata->addr_idx;
Pratik Patel3b0ca882012-06-01 16:54:14 -0700747
Pratik Patela9c0e062012-05-28 13:45:35 -0700748 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
749}
750
751static ssize_t etm_store_addr_idx(struct device *dev,
752 struct device_attribute *attr,
753 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800754{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700755 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800756 unsigned long val;
757
758 if (sscanf(buf, "%lx", &val) != 1)
759 return -EINVAL;
Pratik Patel16aefdb2012-05-30 10:41:23 -0700760 if (val >= drvdata->nr_addr_cmp)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800761 return -EINVAL;
762
763 /* Use mutex to ensure index doesn't change while it gets dereferenced
764 * multiple times within a mutex block elsewhere.
765 */
Pratik Patel16aefdb2012-05-30 10:41:23 -0700766 mutex_lock(&drvdata->mutex);
767 drvdata->addr_idx = val;
768 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700769 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800770}
Pratik Patela9c0e062012-05-28 13:45:35 -0700771static DEVICE_ATTR(addr_idx, S_IRUGO | S_IWUSR, etm_show_addr_idx,
772 etm_store_addr_idx);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800773
Pratik Patela9c0e062012-05-28 13:45:35 -0700774static ssize_t etm_show_addr_single(struct device *dev,
775 struct device_attribute *attr, char *buf)
776{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700777 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -0700778 unsigned long val;
779 uint8_t idx;
780
Pratik Patel16aefdb2012-05-30 10:41:23 -0700781 mutex_lock(&drvdata->mutex);
782 idx = drvdata->addr_idx;
783 if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
784 drvdata->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
785 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700786 return -EPERM;
787 }
788
Pratik Patel16aefdb2012-05-30 10:41:23 -0700789 val = drvdata->addr_val[idx];
790 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700791 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
792}
793
794static ssize_t etm_store_addr_single(struct device *dev,
795 struct device_attribute *attr,
796 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800797{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700798 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800799 unsigned long val;
800 uint8_t idx;
801
802 if (sscanf(buf, "%lx", &val) != 1)
803 return -EINVAL;
804
Pratik Patel16aefdb2012-05-30 10:41:23 -0700805 mutex_lock(&drvdata->mutex);
806 idx = drvdata->addr_idx;
807 if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
808 drvdata->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
809 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800810 return -EPERM;
811 }
812
Pratik Patel16aefdb2012-05-30 10:41:23 -0700813 drvdata->addr_val[idx] = val;
814 drvdata->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
815 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700816 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800817}
Pratik Patela9c0e062012-05-28 13:45:35 -0700818static DEVICE_ATTR(addr_single, S_IRUGO | S_IWUSR, etm_show_addr_single,
819 etm_store_addr_single);
820
821static ssize_t etm_show_addr_range(struct device *dev,
822 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800823{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700824 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -0700825 unsigned long val1, val2;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800826 uint8_t idx;
827
Pratik Patel16aefdb2012-05-30 10:41:23 -0700828 mutex_lock(&drvdata->mutex);
829 idx = drvdata->addr_idx;
Pratik Patela9c0e062012-05-28 13:45:35 -0700830 if (idx % 2 != 0) {
Pratik Patel16aefdb2012-05-30 10:41:23 -0700831 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700832 return -EPERM;
833 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700834 if (!((drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
835 drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
836 (drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
837 drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
838 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800839 return -EPERM;
840 }
841
Pratik Patel16aefdb2012-05-30 10:41:23 -0700842 val1 = drvdata->addr_val[idx];
843 val2 = drvdata->addr_val[idx + 1];
844 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700845 return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800846}
Pratik Patel6630ebe2012-03-06 16:44:22 -0800847
Pratik Patela9c0e062012-05-28 13:45:35 -0700848static ssize_t etm_store_addr_range(struct device *dev,
849 struct device_attribute *attr,
850 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800851{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700852 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800853 unsigned long val1, val2;
854 uint8_t idx;
855
856 if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
857 return -EINVAL;
858 /* lower address comparator cannot have a higher address value */
859 if (val1 > val2)
860 return -EINVAL;
861
Pratik Patel16aefdb2012-05-30 10:41:23 -0700862 mutex_lock(&drvdata->mutex);
863 idx = drvdata->addr_idx;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800864 if (idx % 2 != 0) {
Pratik Patel16aefdb2012-05-30 10:41:23 -0700865 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800866 return -EPERM;
867 }
Pratik Patel16aefdb2012-05-30 10:41:23 -0700868 if (!((drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
869 drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
870 (drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
871 drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
872 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800873 return -EPERM;
874 }
875
Pratik Patel16aefdb2012-05-30 10:41:23 -0700876 drvdata->addr_val[idx] = val1;
877 drvdata->addr_type[idx] = ETM_ADDR_TYPE_RANGE;
878 drvdata->addr_val[idx + 1] = val2;
879 drvdata->addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
880 drvdata->enable_ctrl1 |= (1 << (idx/2));
881 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700882 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800883}
Pratik Patela9c0e062012-05-28 13:45:35 -0700884static DEVICE_ATTR(addr_range, S_IRUGO | S_IWUSR, etm_show_addr_range,
885 etm_store_addr_range);
886
887static ssize_t etm_show_addr_start(struct device *dev,
888 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800889{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700890 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -0700891 unsigned long val;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800892 uint8_t idx;
893
Pratik Patel16aefdb2012-05-30 10:41:23 -0700894 mutex_lock(&drvdata->mutex);
895 idx = drvdata->addr_idx;
896 if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
897 drvdata->addr_type[idx] == ETM_ADDR_TYPE_START)) {
898 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800899 return -EPERM;
900 }
901
Pratik Patel16aefdb2012-05-30 10:41:23 -0700902 val = drvdata->addr_val[idx];
903 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700904 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800905}
Pratik Patel6630ebe2012-03-06 16:44:22 -0800906
Pratik Patela9c0e062012-05-28 13:45:35 -0700907static ssize_t etm_store_addr_start(struct device *dev,
908 struct device_attribute *attr,
909 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800910{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700911 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800912 unsigned long val;
913 uint8_t idx;
914
915 if (sscanf(buf, "%lx", &val) != 1)
916 return -EINVAL;
917
Pratik Patel16aefdb2012-05-30 10:41:23 -0700918 mutex_lock(&drvdata->mutex);
919 idx = drvdata->addr_idx;
920 if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
921 drvdata->addr_type[idx] == ETM_ADDR_TYPE_START)) {
922 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800923 return -EPERM;
924 }
925
Pratik Patel16aefdb2012-05-30 10:41:23 -0700926 drvdata->addr_val[idx] = val;
927 drvdata->addr_type[idx] = ETM_ADDR_TYPE_START;
928 drvdata->startstop_ctrl |= (1 << idx);
929 drvdata->enable_ctrl1 |= BIT(25);
930 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700931 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800932}
Pratik Patela9c0e062012-05-28 13:45:35 -0700933static DEVICE_ATTR(addr_start, S_IRUGO | S_IWUSR, etm_show_addr_start,
934 etm_store_addr_start);
935
936static ssize_t etm_show_addr_stop(struct device *dev,
937 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800938{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700939 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800940 unsigned long val;
941 uint8_t idx;
942
Pratik Patel16aefdb2012-05-30 10:41:23 -0700943 mutex_lock(&drvdata->mutex);
944 idx = drvdata->addr_idx;
945 if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
946 drvdata->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
947 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800948 return -EPERM;
949 }
950
Pratik Patel16aefdb2012-05-30 10:41:23 -0700951 val = drvdata->addr_val[idx];
952 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800953 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
954}
Pratik Patel6630ebe2012-03-06 16:44:22 -0800955
Pratik Patela9c0e062012-05-28 13:45:35 -0700956static ssize_t etm_store_addr_stop(struct device *dev,
957 struct device_attribute *attr,
958 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800959{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700960 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800961 unsigned long val;
962 uint8_t idx;
963
964 if (sscanf(buf, "%lx", &val) != 1)
965 return -EINVAL;
966
Pratik Patel16aefdb2012-05-30 10:41:23 -0700967 mutex_lock(&drvdata->mutex);
968 idx = drvdata->addr_idx;
969 if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
970 drvdata->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
971 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800972 return -EPERM;
973 }
974
Pratik Patel16aefdb2012-05-30 10:41:23 -0700975 drvdata->addr_val[idx] = val;
976 drvdata->addr_type[idx] = ETM_ADDR_TYPE_STOP;
977 drvdata->startstop_ctrl |= (1 << (idx + 16));
978 drvdata->enable_ctrl1 |= BIT(25);
979 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -0700980 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800981}
Pratik Patela9c0e062012-05-28 13:45:35 -0700982static DEVICE_ATTR(addr_stop, S_IRUGO | S_IWUSR, etm_show_addr_stop,
983 etm_store_addr_stop);
984
985static ssize_t etm_show_addr_acctype(struct device *dev,
986 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -0800987{
Pratik Patel3b0ca882012-06-01 16:54:14 -0700988 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800989 unsigned long val;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800990
Pratik Patel16aefdb2012-05-30 10:41:23 -0700991 mutex_lock(&drvdata->mutex);
992 val = drvdata->addr_acctype[drvdata->addr_idx];
993 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800994 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
995}
Pratik Patel6630ebe2012-03-06 16:44:22 -0800996
Pratik Patela9c0e062012-05-28 13:45:35 -0700997static ssize_t etm_store_addr_acctype(struct device *dev,
998 struct device_attribute *attr,
999 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001000{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001001 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001002 unsigned long val;
1003
1004 if (sscanf(buf, "%lx", &val) != 1)
1005 return -EINVAL;
1006
Pratik Patel16aefdb2012-05-30 10:41:23 -07001007 mutex_lock(&drvdata->mutex);
1008 drvdata->addr_acctype[drvdata->addr_idx] = val;
1009 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001010 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001011}
Pratik Patela9c0e062012-05-28 13:45:35 -07001012static DEVICE_ATTR(addr_acctype, S_IRUGO | S_IWUSR, etm_show_addr_acctype,
1013 etm_store_addr_acctype);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001014
Pratik Patela9c0e062012-05-28 13:45:35 -07001015static ssize_t etm_show_cntr_idx(struct device *dev,
1016 struct device_attribute *attr, char *buf)
1017{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001018 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001019 unsigned long val = drvdata->addr_idx;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001020
Pratik Patel6630ebe2012-03-06 16:44:22 -08001021 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1022}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001023
Pratik Patela9c0e062012-05-28 13:45:35 -07001024static ssize_t etm_store_cntr_idx(struct device *dev,
1025 struct device_attribute *attr,
1026 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001027{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001028 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001029 unsigned long val;
1030
1031 if (sscanf(buf, "%lx", &val) != 1)
1032 return -EINVAL;
Pratik Patel16aefdb2012-05-30 10:41:23 -07001033 if (val >= drvdata->nr_cntr)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001034 return -EINVAL;
1035
1036 /* Use mutex to ensure index doesn't change while it gets dereferenced
1037 * multiple times within a mutex block elsewhere.
1038 */
Pratik Patel16aefdb2012-05-30 10:41:23 -07001039 mutex_lock(&drvdata->mutex);
1040 drvdata->cntr_idx = val;
1041 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001042 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001043}
Pratik Patela9c0e062012-05-28 13:45:35 -07001044static DEVICE_ATTR(cntr_idx, S_IRUGO | S_IWUSR, etm_show_cntr_idx,
1045 etm_store_cntr_idx);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001046
Pratik Patela9c0e062012-05-28 13:45:35 -07001047static ssize_t etm_show_cntr_rld_val(struct device *dev,
1048 struct device_attribute *attr, char *buf)
1049{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001050 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001051 unsigned long val;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001052
Pratik Patel16aefdb2012-05-30 10:41:23 -07001053 mutex_lock(&drvdata->mutex);
1054 val = drvdata->cntr_rld_val[drvdata->cntr_idx];
1055 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001056 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1057}
1058
1059static ssize_t etm_store_cntr_rld_val(struct device *dev,
1060 struct device_attribute *attr,
1061 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001062{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001063 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001064 unsigned long val;
1065
1066 if (sscanf(buf, "%lx", &val) != 1)
1067 return -EINVAL;
1068
Pratik Patel16aefdb2012-05-30 10:41:23 -07001069 mutex_lock(&drvdata->mutex);
1070 drvdata->cntr_rld_val[drvdata->cntr_idx] = val;
1071 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001072 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001073}
Pratik Patela9c0e062012-05-28 13:45:35 -07001074static DEVICE_ATTR(cntr_rld_val, S_IRUGO | S_IWUSR, etm_show_cntr_rld_val,
1075 etm_store_cntr_rld_val);
1076
1077static ssize_t etm_show_cntr_event(struct device *dev,
1078 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001079{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001080 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001081 unsigned long val;
Pratik Patela9c0e062012-05-28 13:45:35 -07001082
Pratik Patel16aefdb2012-05-30 10:41:23 -07001083 mutex_lock(&drvdata->mutex);
1084 val = drvdata->cntr_event[drvdata->cntr_idx];
1085 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001086 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1087}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001088
Pratik Patela9c0e062012-05-28 13:45:35 -07001089static ssize_t etm_store_cntr_event(struct device *dev,
1090 struct device_attribute *attr,
1091 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001092{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001093 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001094 unsigned long val;
1095
1096 if (sscanf(buf, "%lx", &val) != 1)
1097 return -EINVAL;
1098
Pratik Patel16aefdb2012-05-30 10:41:23 -07001099 mutex_lock(&drvdata->mutex);
1100 drvdata->cntr_event[drvdata->cntr_idx] = val & ETM_EVENT_MASK;
1101 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001102 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001103}
Pratik Patela9c0e062012-05-28 13:45:35 -07001104static DEVICE_ATTR(cntr_event, S_IRUGO | S_IWUSR, etm_show_cntr_event,
1105 etm_store_cntr_event);
1106
1107static ssize_t etm_show_cntr_rld_event(struct device *dev,
1108 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001109{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001110 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001111 unsigned long val;
1112
Pratik Patel16aefdb2012-05-30 10:41:23 -07001113 mutex_lock(&drvdata->mutex);
1114 val = drvdata->cntr_rld_event[drvdata->cntr_idx];
1115 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001116 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1117}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001118
Pratik Patela9c0e062012-05-28 13:45:35 -07001119static ssize_t etm_store_cntr_rld_event(struct device *dev,
1120 struct device_attribute *attr,
1121 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001122{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001123 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001124 unsigned long val;
1125
1126 if (sscanf(buf, "%lx", &val) != 1)
1127 return -EINVAL;
1128
Pratik Patel16aefdb2012-05-30 10:41:23 -07001129 mutex_lock(&drvdata->mutex);
1130 drvdata->cntr_rld_event[drvdata->cntr_idx] = val & ETM_EVENT_MASK;
1131 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001132 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001133}
Pratik Patela9c0e062012-05-28 13:45:35 -07001134static DEVICE_ATTR(cntr_rld_event, S_IRUGO | S_IWUSR, etm_show_cntr_rld_event,
1135 etm_store_cntr_rld_event);
1136
1137static ssize_t etm_show_cntr_val(struct device *dev,
1138 struct device_attribute *attr, char *buf)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001139{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001140 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001141 unsigned long val;
1142
Pratik Patel16aefdb2012-05-30 10:41:23 -07001143 mutex_lock(&drvdata->mutex);
1144 val = drvdata->cntr_val[drvdata->cntr_idx];
1145 mutex_unlock(&drvdata->mutex);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001146 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1147}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001148
Pratik Patela9c0e062012-05-28 13:45:35 -07001149static ssize_t etm_store_cntr_val(struct device *dev,
1150 struct device_attribute *attr,
1151 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001152{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001153 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001154 unsigned long val;
1155
1156 if (sscanf(buf, "%lx", &val) != 1)
1157 return -EINVAL;
1158
Pratik Patel16aefdb2012-05-30 10:41:23 -07001159 mutex_lock(&drvdata->mutex);
1160 drvdata->cntr_val[drvdata->cntr_idx] = val;
1161 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001162 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001163}
Pratik Patela9c0e062012-05-28 13:45:35 -07001164static DEVICE_ATTR(cntr_val, S_IRUGO | S_IWUSR, etm_show_cntr_val,
1165 etm_store_cntr_val);
1166
1167static ssize_t etm_show_seq_12_event(struct device *dev,
1168 struct device_attribute *attr, char *buf)
1169{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001170 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001171 unsigned long val = drvdata->seq_12_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001172
Pratik Patela9c0e062012-05-28 13:45:35 -07001173 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1174}
1175
1176static ssize_t etm_store_seq_12_event(struct device *dev,
1177 struct device_attribute *attr,
1178 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001179{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001180 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001181 unsigned long val;
1182
Pratik Patela9c0e062012-05-28 13:45:35 -07001183 if (sscanf(buf, "%lx", &val) != 1)
1184 return -EINVAL;
1185
Pratik Patel16aefdb2012-05-30 10:41:23 -07001186 drvdata->seq_12_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001187 return size;
1188}
1189static DEVICE_ATTR(seq_12_event, S_IRUGO | S_IWUSR, etm_show_seq_12_event,
1190 etm_store_seq_12_event);
1191
1192static ssize_t etm_show_seq_21_event(struct device *dev,
1193 struct device_attribute *attr, char *buf)
1194{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001195 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001196 unsigned long val = drvdata->seq_21_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001197
Pratik Patel6630ebe2012-03-06 16:44:22 -08001198 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1199}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001200
Pratik Patela9c0e062012-05-28 13:45:35 -07001201static ssize_t etm_store_seq_21_event(struct device *dev,
1202 struct device_attribute *attr,
1203 const char *buf, size_t size)
1204{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001205 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001206 unsigned long val;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001207
Pratik Patela9c0e062012-05-28 13:45:35 -07001208 if (sscanf(buf, "%lx", &val) != 1)
1209 return -EINVAL;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001210
Pratik Patel16aefdb2012-05-30 10:41:23 -07001211 drvdata->seq_21_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001212 return size;
1213}
1214static DEVICE_ATTR(seq_21_event, S_IRUGO | S_IWUSR, etm_show_seq_21_event,
1215 etm_store_seq_21_event);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001216
Pratik Patela9c0e062012-05-28 13:45:35 -07001217static ssize_t etm_show_seq_23_event(struct device *dev,
1218 struct device_attribute *attr, char *buf)
1219{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001220 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001221 unsigned long val = drvdata->seq_23_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001222
Pratik Patela9c0e062012-05-28 13:45:35 -07001223 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1224}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001225
Pratik Patela9c0e062012-05-28 13:45:35 -07001226static ssize_t etm_store_seq_23_event(struct device *dev,
1227 struct device_attribute *attr,
1228 const char *buf, size_t size)
1229{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001230 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001231 unsigned long val;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001232
Pratik Patela9c0e062012-05-28 13:45:35 -07001233 if (sscanf(buf, "%lx", &val) != 1)
1234 return -EINVAL;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001235
Pratik Patel16aefdb2012-05-30 10:41:23 -07001236 drvdata->seq_23_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001237 return size;
1238}
1239static DEVICE_ATTR(seq_23_event, S_IRUGO | S_IWUSR, etm_show_seq_23_event,
1240 etm_store_seq_23_event);
1241
1242static ssize_t etm_show_seq_31_event(struct device *dev,
1243 struct device_attribute *attr, char *buf)
1244{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001245 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001246 unsigned long val = drvdata->seq_31_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001247
Pratik Patela9c0e062012-05-28 13:45:35 -07001248 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1249}
1250
1251static ssize_t etm_store_seq_31_event(struct device *dev,
1252 struct device_attribute *attr,
1253 const char *buf, size_t size)
1254{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001255 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001256 unsigned long val;
1257
1258 if (sscanf(buf, "%lx", &val) != 1)
1259 return -EINVAL;
1260
Pratik Patel16aefdb2012-05-30 10:41:23 -07001261 drvdata->seq_31_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001262 return size;
1263}
1264static DEVICE_ATTR(seq_31_event, S_IRUGO | S_IWUSR, etm_show_seq_31_event,
1265 etm_store_seq_31_event);
1266
1267static ssize_t etm_show_seq_32_event(struct device *dev,
1268 struct device_attribute *attr, char *buf)
1269{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001270 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001271 unsigned long val = drvdata->seq_32_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001272
Pratik Patela9c0e062012-05-28 13:45:35 -07001273 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1274}
1275
1276static ssize_t etm_store_seq_32_event(struct device *dev,
1277 struct device_attribute *attr,
1278 const char *buf, size_t size)
1279{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001280 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001281 unsigned long val;
1282
1283 if (sscanf(buf, "%lx", &val) != 1)
1284 return -EINVAL;
1285
Pratik Patel16aefdb2012-05-30 10:41:23 -07001286 drvdata->seq_32_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001287 return size;
1288}
1289static DEVICE_ATTR(seq_32_event, S_IRUGO | S_IWUSR, etm_show_seq_32_event,
1290 etm_store_seq_32_event);
1291
1292static ssize_t etm_show_seq_13_event(struct device *dev,
1293 struct device_attribute *attr, char *buf)
1294{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001295 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001296 unsigned long val = drvdata->seq_13_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001297
Pratik Patela9c0e062012-05-28 13:45:35 -07001298 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1299}
1300
1301static ssize_t etm_store_seq_13_event(struct device *dev,
1302 struct device_attribute *attr,
1303 const char *buf, size_t size)
1304{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001305 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001306 unsigned long val;
1307
1308 if (sscanf(buf, "%lx", &val) != 1)
1309 return -EINVAL;
1310
Pratik Patel16aefdb2012-05-30 10:41:23 -07001311 drvdata->seq_13_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001312 return size;
1313}
1314static DEVICE_ATTR(seq_13_event, S_IRUGO | S_IWUSR, etm_show_seq_13_event,
1315 etm_store_seq_13_event);
1316
1317static ssize_t etm_show_seq_curr_state(struct device *dev,
1318 struct device_attribute *attr, char *buf)
1319{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001320 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001321 unsigned long val = drvdata->seq_curr_state;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001322
Pratik Patela9c0e062012-05-28 13:45:35 -07001323 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1324}
1325
1326static ssize_t etm_store_seq_curr_state(struct device *dev,
1327 struct device_attribute *attr,
1328 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001329{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001330 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001331 unsigned long val;
1332
1333 if (sscanf(buf, "%lx", &val) != 1)
1334 return -EINVAL;
1335 if (val > ETM_SEQ_STATE_MAX_VAL)
1336 return -EINVAL;
1337
Pratik Patel16aefdb2012-05-30 10:41:23 -07001338 drvdata->seq_curr_state = val;
Pratik Patela9c0e062012-05-28 13:45:35 -07001339 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001340}
Pratik Patela9c0e062012-05-28 13:45:35 -07001341static DEVICE_ATTR(seq_curr_state, S_IRUGO | S_IWUSR, etm_show_seq_curr_state,
1342 etm_store_seq_curr_state);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001343
Pratik Patela9c0e062012-05-28 13:45:35 -07001344static ssize_t etm_show_ctxid_idx(struct device *dev,
1345 struct device_attribute *attr, char *buf)
1346{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001347 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001348 unsigned long val = drvdata->ctxid_idx;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001349
Pratik Patela9c0e062012-05-28 13:45:35 -07001350 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1351}
1352
1353static ssize_t etm_store_ctxid_idx(struct device *dev,
1354 struct device_attribute *attr,
1355 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001356{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001357 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001358 unsigned long val;
1359
1360 if (sscanf(buf, "%lx", &val) != 1)
1361 return -EINVAL;
Pratik Patel16aefdb2012-05-30 10:41:23 -07001362 if (val >= drvdata->nr_ctxid_cmp)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001363 return -EINVAL;
1364
1365 /* Use mutex to ensure index doesn't change while it gets dereferenced
1366 * multiple times within a mutex block elsewhere.
1367 */
Pratik Patel16aefdb2012-05-30 10:41:23 -07001368 mutex_lock(&drvdata->mutex);
1369 drvdata->ctxid_idx = val;
1370 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001371 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001372}
Pratik Patela9c0e062012-05-28 13:45:35 -07001373static DEVICE_ATTR(ctxid_idx, S_IRUGO | S_IWUSR, etm_show_ctxid_idx,
1374 etm_store_ctxid_idx);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001375
Pratik Patela9c0e062012-05-28 13:45:35 -07001376static ssize_t etm_show_ctxid_val(struct device *dev,
1377 struct device_attribute *attr, char *buf)
1378{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001379 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001380 unsigned long val;
1381
Pratik Patel16aefdb2012-05-30 10:41:23 -07001382 mutex_lock(&drvdata->mutex);
1383 val = drvdata->ctxid_val[drvdata->ctxid_idx];
1384 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001385 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1386}
1387
1388static ssize_t etm_store_ctxid_val(struct device *dev,
1389 struct device_attribute *attr,
1390 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001391{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001392 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001393 unsigned long val;
1394
1395 if (sscanf(buf, "%lx", &val) != 1)
1396 return -EINVAL;
1397
Pratik Patel16aefdb2012-05-30 10:41:23 -07001398 mutex_lock(&drvdata->mutex);
1399 drvdata->ctxid_val[drvdata->ctxid_idx] = val;
1400 mutex_unlock(&drvdata->mutex);
Pratik Patela9c0e062012-05-28 13:45:35 -07001401 return size;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001402}
Pratik Patela9c0e062012-05-28 13:45:35 -07001403static DEVICE_ATTR(ctxid_val, S_IRUGO | S_IWUSR, etm_show_ctxid_val,
1404 etm_store_ctxid_val);
1405
1406static ssize_t etm_show_ctxid_mask(struct device *dev,
1407 struct device_attribute *attr, char *buf)
1408{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001409 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001410 unsigned long val = drvdata->ctxid_mask;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001411
Pratik Patela9c0e062012-05-28 13:45:35 -07001412 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1413}
1414
1415static ssize_t etm_store_ctxid_mask(struct device *dev,
1416 struct device_attribute *attr,
1417 const char *buf, size_t size)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001418{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001419 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001420 unsigned long val;
1421
Pratik Patela9c0e062012-05-28 13:45:35 -07001422 if (sscanf(buf, "%lx", &val) != 1)
1423 return -EINVAL;
1424
Pratik Patel16aefdb2012-05-30 10:41:23 -07001425 drvdata->ctxid_mask = val;
Pratik Patela9c0e062012-05-28 13:45:35 -07001426 return size;
1427}
1428static DEVICE_ATTR(ctxid_mask, S_IRUGO | S_IWUSR, etm_show_ctxid_mask,
1429 etm_store_ctxid_mask);
1430
1431static ssize_t etm_show_sync_freq(struct device *dev,
1432 struct device_attribute *attr, char *buf)
1433{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001434 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001435 unsigned long val = drvdata->sync_freq;
Pratik Patel938e1ff2012-09-28 23:21:46 -07001436
Pratik Patel6630ebe2012-03-06 16:44:22 -08001437 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1438}
Pratik Patel6630ebe2012-03-06 16:44:22 -08001439
Pratik Patela9c0e062012-05-28 13:45:35 -07001440static ssize_t etm_store_sync_freq(struct device *dev,
1441 struct device_attribute *attr,
1442 const char *buf, size_t size)
1443{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001444 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001445 unsigned long val;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001446
Pratik Patela9c0e062012-05-28 13:45:35 -07001447 if (sscanf(buf, "%lx", &val) != 1)
1448 return -EINVAL;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001449
Pratik Patel16aefdb2012-05-30 10:41:23 -07001450 drvdata->sync_freq = val & ETM_SYNC_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001451 return size;
1452}
1453static DEVICE_ATTR(sync_freq, S_IRUGO | S_IWUSR, etm_show_sync_freq,
1454 etm_store_sync_freq);
1455
1456static ssize_t etm_show_timestamp_event(struct device *dev,
1457 struct device_attribute *attr,
1458 char *buf)
1459{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001460 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001461 unsigned long val = drvdata->timestamp_event;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001462
Pratik Patela9c0e062012-05-28 13:45:35 -07001463 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1464}
1465
1466static ssize_t etm_store_timestamp_event(struct device *dev,
1467 struct device_attribute *attr,
1468 const char *buf, size_t size)
1469{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001470 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Pratik Patela9c0e062012-05-28 13:45:35 -07001471 unsigned long val;
1472
1473 if (sscanf(buf, "%lx", &val) != 1)
1474 return -EINVAL;
1475
Pratik Patel16aefdb2012-05-30 10:41:23 -07001476 drvdata->timestamp_event = val & ETM_EVENT_MASK;
Pratik Patela9c0e062012-05-28 13:45:35 -07001477 return size;
1478}
1479static DEVICE_ATTR(timestamp_event, S_IRUGO | S_IWUSR, etm_show_timestamp_event,
1480 etm_store_timestamp_event);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001481
Pratik Patel938e1ff2012-09-28 23:21:46 -07001482static ssize_t etm_show_pcsave(struct device *dev,
1483 struct device_attribute *attr, char *buf)
1484{
1485 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1486 unsigned long val;
1487
1488 val = drvdata->pcsave_enable;
1489 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1490}
1491
1492static int __etm_store_pcsave(struct etm_drvdata *drvdata, unsigned long val)
1493{
Pratik Patel9dbfa372012-10-23 22:36:40 -07001494 int ret = 0;
Pratik Patel938e1ff2012-09-28 23:21:46 -07001495
1496 ret = clk_prepare_enable(drvdata->clk);
1497 if (ret)
1498 return ret;
1499
1500 mutex_lock(&drvdata->mutex);
Pratik Patel9dbfa372012-10-23 22:36:40 -07001501 get_online_cpus();
Pratik Patel938e1ff2012-09-28 23:21:46 -07001502 if (val) {
Pratik Patel9dbfa372012-10-23 22:36:40 -07001503 if (drvdata->pcsave_enable)
1504 goto out;
1505
1506 ret = smp_call_function_single(drvdata->cpu, etm_enable_pcsave,
1507 drvdata, 1);
1508 if (ret)
1509 goto out;
Pratik Patel938e1ff2012-09-28 23:21:46 -07001510 drvdata->pcsave_enable = true;
Pratik Patel9dbfa372012-10-23 22:36:40 -07001511
1512 dev_info(drvdata->dev, "PC save enabled\n");
Pratik Patel938e1ff2012-09-28 23:21:46 -07001513 } else {
Pratik Patel9dbfa372012-10-23 22:36:40 -07001514 if (!drvdata->pcsave_enable)
1515 goto out;
1516
1517 ret = smp_call_function_single(drvdata->cpu, etm_disable_pcsave,
1518 drvdata, 1);
1519 if (ret)
1520 goto out;
Pratik Patel938e1ff2012-09-28 23:21:46 -07001521 drvdata->pcsave_enable = false;
Pratik Patel9dbfa372012-10-23 22:36:40 -07001522
1523 dev_info(drvdata->dev, "PC save disabled\n");
Pratik Patel938e1ff2012-09-28 23:21:46 -07001524 }
Pratik Patel9dbfa372012-10-23 22:36:40 -07001525out:
1526 put_online_cpus();
Pratik Patel938e1ff2012-09-28 23:21:46 -07001527 mutex_unlock(&drvdata->mutex);
1528
1529 clk_disable_unprepare(drvdata->clk);
Pratik Patel9dbfa372012-10-23 22:36:40 -07001530 return ret;
Pratik Patel938e1ff2012-09-28 23:21:46 -07001531}
1532
1533static ssize_t etm_store_pcsave(struct device *dev,
1534 struct device_attribute *attr,
1535 const char *buf, size_t size)
1536{
1537 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1538 unsigned long val;
1539 int ret;
1540
1541 if (sscanf(buf, "%lx", &val) != 1)
1542 return -EINVAL;
1543
1544 ret = __etm_store_pcsave(drvdata, val);
1545 if (ret)
1546 return ret;
1547
1548 return size;
1549}
1550static DEVICE_ATTR(pcsave, S_IRUGO | S_IWUSR, etm_show_pcsave,
1551 etm_store_pcsave);
1552
Pratik Patel6630ebe2012-03-06 16:44:22 -08001553static struct attribute *etm_attrs[] = {
Pratik Patela9c0e062012-05-28 13:45:35 -07001554 &dev_attr_nr_addr_cmp.attr,
1555 &dev_attr_nr_cntr.attr,
1556 &dev_attr_nr_ctxid_cmp.attr,
1557 &dev_attr_reset.attr,
1558 &dev_attr_mode.attr,
1559 &dev_attr_trigger_event.attr,
1560 &dev_attr_enable_event.attr,
1561 &dev_attr_fifofull_level.attr,
1562 &dev_attr_addr_idx.attr,
1563 &dev_attr_addr_single.attr,
1564 &dev_attr_addr_range.attr,
1565 &dev_attr_addr_start.attr,
1566 &dev_attr_addr_stop.attr,
1567 &dev_attr_addr_acctype.attr,
1568 &dev_attr_cntr_idx.attr,
1569 &dev_attr_cntr_rld_val.attr,
1570 &dev_attr_cntr_event.attr,
1571 &dev_attr_cntr_rld_event.attr,
1572 &dev_attr_cntr_val.attr,
1573 &dev_attr_seq_12_event.attr,
1574 &dev_attr_seq_21_event.attr,
1575 &dev_attr_seq_23_event.attr,
1576 &dev_attr_seq_31_event.attr,
1577 &dev_attr_seq_32_event.attr,
1578 &dev_attr_seq_13_event.attr,
1579 &dev_attr_seq_curr_state.attr,
1580 &dev_attr_ctxid_idx.attr,
1581 &dev_attr_ctxid_val.attr,
1582 &dev_attr_ctxid_mask.attr,
1583 &dev_attr_sync_freq.attr,
1584 &dev_attr_timestamp_event.attr,
Pratik Patel6630ebe2012-03-06 16:44:22 -08001585 NULL,
1586};
1587
1588static struct attribute_group etm_attr_grp = {
1589 .attrs = etm_attrs,
1590};
1591
Pratik Patel3b0ca882012-06-01 16:54:14 -07001592static const struct attribute_group *etm_attr_grps[] = {
1593 &etm_attr_grp,
1594 NULL,
1595};
1596
1597/* Memory mapped writes to clear os lock not supported */
1598static void etm_os_unlock(void *unused)
Pratik Patel6630ebe2012-03-06 16:44:22 -08001599{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001600 unsigned long value = 0x0;
Pratik Patel6630ebe2012-03-06 16:44:22 -08001601
Pratik Patel3b0ca882012-06-01 16:54:14 -07001602 asm("mcr p14, 1, %0, c1, c0, 4\n\t" : : "r" (value));
1603 asm("isb\n\t");
Pratik Patel6630ebe2012-03-06 16:44:22 -08001604}
1605
Stephen Boyda9510502012-04-24 16:23:34 -07001606static bool __devinit etm_arch_supported(uint8_t arch)
Pratik Patel7831c082011-06-08 21:44:37 -07001607{
Pratik Patel61de7302012-03-07 12:06:10 -08001608 switch (arch) {
1609 case PFT_ARCH_V1_1:
1610 break;
1611 default:
1612 return false;
1613 }
1614 return true;
1615}
1616
Pratik Patele6e41da2012-09-12 12:50:29 -07001617static void __devinit etm_prepare_arch(struct etm_drvdata *drvdata)
1618{
1619 /* Unlock OS lock first to allow memory mapped reads and writes. This
1620 * is required for Krait pass1
1621 * */
1622 etm_os_unlock(NULL);
1623 smp_call_function(etm_os_unlock, NULL, 1);
1624}
1625
1626static void __devinit etm_init_arch_data(void *info)
Pratik Patel61de7302012-03-07 12:06:10 -08001627{
Pratik Patel61de7302012-03-07 12:06:10 -08001628 uint32_t etmidr;
1629 uint32_t etmccr;
Pratik Patele6e41da2012-09-12 12:50:29 -07001630 struct etm_drvdata *drvdata = info;
Pratik Patel7831c082011-06-08 21:44:37 -07001631
Pratik Patel3b0ca882012-06-01 16:54:14 -07001632 ETM_UNLOCK(drvdata);
Pratik Patel938e1ff2012-09-28 23:21:46 -07001633 /*
1634 * Vote for ETM power/clock enable. ETMPDCR is only accessible via
1635 * memory mapped interface and so use it first to enable power/clock
1636 * to allow subsequent cp14 accesses.
1637 */
Pratik Patelef6da292012-09-17 17:37:19 -07001638 etm_set_pwrup(drvdata);
Pratik Pateld1d65c92012-09-25 23:37:43 -07001639 /*
1640 * Clear power down bit since when this bit is set writes to
1641 * certain registers might be ignored.
1642 */
1643 etm_clr_pwrdwn(drvdata);
Pratik Patel61de7302012-03-07 12:06:10 -08001644 /* Set prog bit. It will be set from reset but this is included to
1645 * ensure it is set
1646 */
Pratik Patel3b0ca882012-06-01 16:54:14 -07001647 etm_set_prog(drvdata);
Pratik Patel7831c082011-06-08 21:44:37 -07001648
1649 /* find all capabilities */
Pratik Patel3b0ca882012-06-01 16:54:14 -07001650 etmidr = etm_readl(drvdata, ETMIDR);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001651 drvdata->arch = BMVAL(etmidr, 4, 11);
Pratik Patel7831c082011-06-08 21:44:37 -07001652
Pratik Patel3b0ca882012-06-01 16:54:14 -07001653 etmccr = etm_readl(drvdata, ETMCCR);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001654 drvdata->nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
1655 drvdata->nr_cntr = BMVAL(etmccr, 13, 15);
1656 drvdata->nr_ext_inp = BMVAL(etmccr, 17, 19);
1657 drvdata->nr_ext_out = BMVAL(etmccr, 20, 22);
1658 drvdata->nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
Pratik Patel2d0c7b62012-02-24 19:04:37 -08001659
Pratik Pateld1d65c92012-09-25 23:37:43 -07001660 etm_set_pwrdwn(drvdata);
Pratik Patelef6da292012-09-17 17:37:19 -07001661 etm_clr_pwrup(drvdata);
Pratik Patel3b0ca882012-06-01 16:54:14 -07001662 ETM_LOCK(drvdata);
Pratik Patel7831c082011-06-08 21:44:37 -07001663}
1664
Pratik Patelc14b4df2012-09-05 18:07:59 -07001665static void __devinit etm_copy_arch_data(struct etm_drvdata *drvdata)
1666{
1667 drvdata->arch = etm0drvdata->arch;
1668 drvdata->nr_addr_cmp = etm0drvdata->nr_addr_cmp;
1669 drvdata->nr_cntr = etm0drvdata->nr_cntr;
1670 drvdata->nr_ext_inp = etm0drvdata->nr_ext_inp;
1671 drvdata->nr_ext_out = etm0drvdata->nr_ext_out;
1672 drvdata->nr_ctxid_cmp = etm0drvdata->nr_ctxid_cmp;
1673}
1674
Pratik Patel3b0ca882012-06-01 16:54:14 -07001675static void __devinit etm_init_default_data(struct etm_drvdata *drvdata)
Pratik Patel16aefdb2012-05-30 10:41:23 -07001676{
1677 int i;
1678
1679 drvdata->trigger_event = 0x406F;
1680 drvdata->enable_event = 0x6F;
1681 drvdata->enable_ctrl1 = 0x1;
1682 drvdata->fifofull_level = 0x28;
1683 if (drvdata->nr_addr_cmp >= 2) {
1684 drvdata->addr_val[0] = (uint32_t) _stext;
1685 drvdata->addr_val[1] = (uint32_t) _etext;
1686 drvdata->addr_type[0] = ETM_ADDR_TYPE_RANGE;
1687 drvdata->addr_type[1] = ETM_ADDR_TYPE_RANGE;
1688 }
1689 for (i = 0; i < drvdata->nr_cntr; i++) {
1690 drvdata->cntr_event[i] = 0x406F;
1691 drvdata->cntr_rld_event[i] = 0x406F;
1692 }
1693 drvdata->seq_12_event = 0x406F;
1694 drvdata->seq_21_event = 0x406F;
1695 drvdata->seq_23_event = 0x406F;
1696 drvdata->seq_31_event = 0x406F;
1697 drvdata->seq_32_event = 0x406F;
1698 drvdata->seq_13_event = 0x406F;
Pratik Patel77b90632012-07-17 17:54:51 -07001699 /* Bits[7:0] of ETMSYNCFR are reserved on Krait pass3 onwards */
1700 if (cpu_is_krait() && !cpu_is_krait_v1() && !cpu_is_krait_v2())
1701 drvdata->sync_freq = 0x100;
1702 else
1703 drvdata->sync_freq = 0x80;
Pratik Patel16aefdb2012-05-30 10:41:23 -07001704 drvdata->timestamp_event = 0x406F;
1705
1706 /* Overrides for Krait pass1 */
1707 if (cpu_is_krait_v1()) {
1708 /* Krait pass1 doesn't support include filtering and non-cycle
1709 * accurate tracing
1710 */
1711 drvdata->mode = (ETM_MODE_EXCLUDE | ETM_MODE_CYCACC);
1712 drvdata->ctrl = 0x1000;
1713 drvdata->enable_ctrl1 = 0x1000000;
1714 for (i = 0; i < drvdata->nr_addr_cmp; i++) {
1715 drvdata->addr_val[i] = 0x0;
1716 drvdata->addr_acctype[i] = 0x0;
1717 drvdata->addr_type[i] = ETM_ADDR_TYPE_NONE;
1718 }
1719 }
1720}
1721
Pratik Patel492b3012012-03-06 14:22:30 -08001722static int __devinit etm_probe(struct platform_device *pdev)
Pratik Patel7831c082011-06-08 21:44:37 -07001723{
Pratik Patele5771792011-09-17 18:33:54 -07001724 int ret;
Pratik Patel4a1b2522012-06-17 15:31:15 -07001725 struct device *dev = &pdev->dev;
Pratik Patel5f6d1af2012-06-13 15:48:13 -07001726 struct coresight_platform_data *pdata;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001727 struct etm_drvdata *drvdata;
Pratik Patel7831c082011-06-08 21:44:37 -07001728 struct resource *res;
Pratik Patel26477792012-09-07 01:35:36 -07001729 uint32_t reg_size;
1730 static int count;
1731 void *baddr;
1732 struct msm_client_dump dump;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001733 struct coresight_desc *desc;
Pratik Patel7831c082011-06-08 21:44:37 -07001734
Pratik Patel5f6d1af2012-06-13 15:48:13 -07001735 if (pdev->dev.of_node) {
1736 pdata = of_get_coresight_platform_data(dev, pdev->dev.of_node);
1737 if (IS_ERR(pdata))
1738 return PTR_ERR(pdata);
1739 pdev->dev.platform_data = pdata;
1740 }
1741
Pratik Patel4a1b2522012-06-17 15:31:15 -07001742 drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
1743 if (!drvdata)
1744 return -ENOMEM;
Pratik Patel16aefdb2012-05-30 10:41:23 -07001745 drvdata->dev = &pdev->dev;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001746 platform_set_drvdata(pdev, drvdata);
Pratik Patel7831c082011-06-08 21:44:37 -07001747
Pratik Patel4a1b2522012-06-17 15:31:15 -07001748 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1749 if (!res)
1750 return -ENODEV;
Pratik Patel26477792012-09-07 01:35:36 -07001751 reg_size = resource_size(res);
Pratik Patel2c09b762012-07-21 15:54:54 -07001752
Pratik Patel4a1b2522012-06-17 15:31:15 -07001753 drvdata->base = devm_ioremap(dev, res->start, resource_size(res));
1754 if (!drvdata->base)
1755 return -ENOMEM;
1756
Pratik Patel16aefdb2012-05-30 10:41:23 -07001757 mutex_init(&drvdata->mutex);
Pratik Patel3b0ca882012-06-01 16:54:14 -07001758 wake_lock_init(&drvdata->wake_lock, WAKE_LOCK_SUSPEND, "coresight-etm");
Pratik Patele10a77c2012-03-20 10:35:16 -07001759
Pratik Patel4a1b2522012-06-17 15:31:15 -07001760 drvdata->clk = devm_clk_get(dev, "core_clk");
Pratik Patel16aefdb2012-05-30 10:41:23 -07001761 if (IS_ERR(drvdata->clk)) {
1762 ret = PTR_ERR(drvdata->clk);
Pratik Patel4a1b2522012-06-17 15:31:15 -07001763 goto err0;
Pratik Patelf17b1472012-05-25 22:23:52 -07001764 }
Pratik Patel2c09b762012-07-21 15:54:54 -07001765
Pratik Patel6fb38342012-06-03 14:51:38 -07001766 ret = clk_set_rate(drvdata->clk, CORESIGHT_CLK_RATE_TRACE);
Pratik Patel7831c082011-06-08 21:44:37 -07001767 if (ret)
Pratik Patel4a1b2522012-06-17 15:31:15 -07001768 goto err0;
1769
Pratik Patel26477792012-09-07 01:35:36 -07001770 drvdata->cpu = count++;
Pratik Patel4a1b2522012-06-17 15:31:15 -07001771
Pratik Patel16aefdb2012-05-30 10:41:23 -07001772 ret = clk_prepare_enable(drvdata->clk);
Pratik Patelf17b1472012-05-25 22:23:52 -07001773 if (ret)
Pratik Patel4a1b2522012-06-17 15:31:15 -07001774 goto err0;
Pratik Patel2c09b762012-07-21 15:54:54 -07001775
Pratik Patelc14b4df2012-09-05 18:07:59 -07001776 /* Use CPU0 to populate read-only configuration data for ETM0. For other
1777 * ETMs copy it over from ETM0.
1778 */
1779 if (drvdata->cpu == 0) {
Pratik Patele6e41da2012-09-12 12:50:29 -07001780 etm_prepare_arch(drvdata);
1781 smp_call_function_single(drvdata->cpu, etm_init_arch_data,
1782 drvdata, 1);
Pratik Patelc14b4df2012-09-05 18:07:59 -07001783 etm0drvdata = drvdata;
1784 } else {
Pratik Pateldc3a0a42012-09-11 17:48:23 -07001785 etm_copy_arch_data(drvdata);
1786 }
1787 if (etm_arch_supported(drvdata->arch) == false) {
1788 ret = -EINVAL;
1789 goto err1;
Pratik Patelc14b4df2012-09-05 18:07:59 -07001790 }
Pratik Patel3b0ca882012-06-01 16:54:14 -07001791 etm_init_default_data(drvdata);
Pratik Patel2c09b762012-07-21 15:54:54 -07001792
Pratik Patel16aefdb2012-05-30 10:41:23 -07001793 clk_disable_unprepare(drvdata->clk);
Pratik Patel7831c082011-06-08 21:44:37 -07001794
Pratik Patel26477792012-09-07 01:35:36 -07001795 baddr = devm_kzalloc(dev, PAGE_SIZE + reg_size, GFP_KERNEL);
1796 if (baddr) {
1797 *(uint32_t *)(baddr + ETM_REG_DUMP_VER_OFF) = ETM_REG_DUMP_VER;
1798 dump.id = MSM_ETM0_REG + drvdata->cpu;
1799 dump.start_addr = virt_to_phys(baddr);
1800 dump.end_addr = dump.start_addr + PAGE_SIZE + reg_size;
1801 ret = msm_dump_table_register(&dump);
1802 if (ret) {
1803 devm_kfree(dev, baddr);
1804 dev_err(dev, "ETM REG dump setup failed\n");
1805 }
1806 } else {
1807 dev_err(dev, "ETM REG dump space allocation failed\n");
1808 }
1809
Pratik Patel4a1b2522012-06-17 15:31:15 -07001810 desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
Pratik Patel3b0ca882012-06-01 16:54:14 -07001811 if (!desc) {
1812 ret = -ENOMEM;
Pratik Patel4a1b2522012-06-17 15:31:15 -07001813 goto err0;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001814 }
1815 desc->type = CORESIGHT_DEV_TYPE_SOURCE;
1816 desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC;
1817 desc->ops = &etm_cs_ops;
1818 desc->pdata = pdev->dev.platform_data;
1819 desc->dev = &pdev->dev;
1820 desc->groups = etm_attr_grps;
1821 desc->owner = THIS_MODULE;
1822 drvdata->csdev = coresight_register(desc);
1823 if (IS_ERR(drvdata->csdev)) {
1824 ret = PTR_ERR(drvdata->csdev);
Pratik Patel4a1b2522012-06-17 15:31:15 -07001825 goto err0;
Pratik Patel3b0ca882012-06-01 16:54:14 -07001826 }
Pratik Patel3b0ca882012-06-01 16:54:14 -07001827
Pratik Patel938e1ff2012-09-28 23:21:46 -07001828 if (pdev->dev.of_node)
1829 drvdata->pcsave_impl = of_property_read_bool(pdev->dev.of_node,
1830 "qcom,pc-save");
1831 if (drvdata->pcsave_impl) {
1832 ret = device_create_file(&drvdata->csdev->dev,
1833 &dev_attr_pcsave);
1834 if (ret)
1835 dev_err(dev, "ETM pcsave dev node creation failed\n");
1836 }
1837
Pratik Patel4a1b2522012-06-17 15:31:15 -07001838 dev_info(dev, "ETM initialized\n");
Pratik Patel7831c082011-06-08 21:44:37 -07001839
Pratik Patel3b0ca882012-06-01 16:54:14 -07001840 if (boot_enable)
1841 coresight_enable(drvdata->csdev);
Pratik Patel7831c082011-06-08 21:44:37 -07001842
Pratik Patel938e1ff2012-09-28 23:21:46 -07001843 if (drvdata->pcsave_impl && boot_pcsave_enable)
1844 __etm_store_pcsave(drvdata, true);
1845
Pratik Patel7831c082011-06-08 21:44:37 -07001846 return 0;
Pratik Patel4a1b2522012-06-17 15:31:15 -07001847err1:
Pratik Patel16aefdb2012-05-30 10:41:23 -07001848 clk_disable_unprepare(drvdata->clk);
Pratik Patel4a1b2522012-06-17 15:31:15 -07001849err0:
Pratik Patel16aefdb2012-05-30 10:41:23 -07001850 wake_lock_destroy(&drvdata->wake_lock);
1851 mutex_destroy(&drvdata->mutex);
Pratik Patel7831c082011-06-08 21:44:37 -07001852 return ret;
1853}
1854
Pratik Patelf6fe9182012-03-20 14:04:18 -07001855static int __devexit etm_remove(struct platform_device *pdev)
Pratik Patel7831c082011-06-08 21:44:37 -07001856{
Pratik Patel3b0ca882012-06-01 16:54:14 -07001857 struct etm_drvdata *drvdata = platform_get_drvdata(pdev);
1858
Pratik Patel938e1ff2012-09-28 23:21:46 -07001859 device_remove_file(&drvdata->csdev->dev, &dev_attr_pcsave);
Pratik Patel3b0ca882012-06-01 16:54:14 -07001860 coresight_unregister(drvdata->csdev);
Pratik Patel16aefdb2012-05-30 10:41:23 -07001861 wake_lock_destroy(&drvdata->wake_lock);
1862 mutex_destroy(&drvdata->mutex);
Pratik Patel7831c082011-06-08 21:44:37 -07001863 return 0;
1864}
1865
Pratik Patel9eae4822012-05-14 17:34:53 -07001866static struct of_device_id etm_match[] = {
Pratik Patel5f6d1af2012-06-13 15:48:13 -07001867 {.compatible = "arm,coresight-etm"},
Pratik Patel9eae4822012-05-14 17:34:53 -07001868 {}
1869};
1870
Pratik Patel492b3012012-03-06 14:22:30 -08001871static struct platform_driver etm_driver = {
1872 .probe = etm_probe,
Pratik Patelf6fe9182012-03-20 14:04:18 -07001873 .remove = __devexit_p(etm_remove),
Pratik Patel7831c082011-06-08 21:44:37 -07001874 .driver = {
Pratik Patel3b0ca882012-06-01 16:54:14 -07001875 .name = "coresight-etm",
Pratik Patel9eae4822012-05-14 17:34:53 -07001876 .owner = THIS_MODULE,
1877 .of_match_table = etm_match,
Pratik Patel7831c082011-06-08 21:44:37 -07001878 },
1879};
1880
Pratik Patel492b3012012-03-06 14:22:30 -08001881int __init etm_init(void)
Pratik Patel7831c082011-06-08 21:44:37 -07001882{
Pratik Patel492b3012012-03-06 14:22:30 -08001883 return platform_driver_register(&etm_driver);
Pratik Patel7831c082011-06-08 21:44:37 -07001884}
Pratik Patelf6fe9182012-03-20 14:04:18 -07001885module_init(etm_init);
Pratik Patel7831c082011-06-08 21:44:37 -07001886
Pratik Patelf6fe9182012-03-20 14:04:18 -07001887void __exit etm_exit(void)
Pratik Patel7831c082011-06-08 21:44:37 -07001888{
Pratik Patel492b3012012-03-06 14:22:30 -08001889 platform_driver_unregister(&etm_driver);
Pratik Patel7831c082011-06-08 21:44:37 -07001890}
Pratik Patelf6fe9182012-03-20 14:04:18 -07001891module_exit(etm_exit);
1892
1893MODULE_LICENSE("GPL v2");
1894MODULE_DESCRIPTION("CoreSight Program Flow Trace driver");