[ERD][NEUS7920-76] [COMMON] lib: dss: support to output notifier call functions
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / drivers / soc / samsung / debug / exynos9610-itmon.c
1 /*
2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * IPs Traffic Monitor(ITMON) Driver for Samsung Exynos9610 SOC
6 * By Hosung Kim (hosung0.kim@samsung.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/slab.h>
16 #include <linux/io.h>
17 #include <linux/interrupt.h>
18 #include <linux/of_irq.h>
19 #include <linux/bitops.h>
20 #include <soc/samsung/exynos-pmu.h>
21 #include <soc/samsung/exynos-itmon.h>
22 #if defined(CONFIG_SEC_MODEM_IF)
23 #include <soc/samsung/exynos-modem-ctrl.h>
24 #endif
25
26
27 #define OFFSET_TMOUT_REG (0x2000)
28 #define OFFSET_REQ_R (0x0)
29 #define OFFSET_REQ_W (0x20)
30 #define OFFSET_RESP_R (0x40)
31 #define OFFSET_RESP_W (0x60)
32 #define OFFSET_ERR_REPT (0x20)
33 #define OFFSET_HW_ASSERT (0x100)
34 #define OFFSET_NUM (0x4)
35
36 #define REG_INT_MASK (0x0)
37 #define REG_INT_CLR (0x4)
38 #define REG_INT_INFO (0x8)
39 #define REG_EXT_INFO_0 (0x10)
40 #define REG_EXT_INFO_1 (0x14)
41 #define REG_EXT_INFO_2 (0x18)
42
43 #define REG_DBG_CTL (0x10)
44 #define REG_TMOUT_INIT_VAL (0x14)
45 #define REG_TMOUT_FRZ_EN (0x18)
46 #define REG_TMOUT_BUF_WR_OFFSET (0x20)
47
48 #define REG_TMOUT_BUF_STATUS (0x1C)
49 #define REG_TMOUT_BUF_POINT_ADDR (0x20)
50 #define REG_TMOUT_BUF_ID (0x24)
51 #define REG_TMOUT_BUF_PAYLOAD (0x28)
52 #define REG_TMOUT_BUF_PAYLOAD_SRAM1 (0x30)
53 #define REG_TMOUT_BUF_PAYLOAD_SRAM2 (0x34)
54 #define REG_TMOUT_BUF_PAYLOAD_SRAM3 (0x38)
55
56 #define REG_HWA_CTL (0x4)
57 #define REG_HWA_INT (0x8)
58 #define REG_HWA_INT_ID (0xC)
59 #define REG_HWA_START_ADDR_LOW (0x10)
60 #define REG_HWA_END_ADDR_LOW (0x14)
61 #define REG_HWA_START_END_ADDR_UPPER (0x18)
62
63 #define RD_RESP_INT_ENABLE (1 << 0)
64 #define WR_RESP_INT_ENABLE (1 << 1)
65 #define ARLEN_RLAST_INT_ENABLE (1 << 2)
66 #define AWLEN_WLAST_INT_ENABLE (1 << 3)
67 #define INTEND_ACCESS_INT_ENABLE (1 << 4)
68
69 #define BIT_HWA_ERR_OCCURRED(x) (((x) & (0x1 << 0)) >> 0)
70 #define BIT_HWA_ERR_CODE(x) (((x) & (0xF << 1)) >> 28)
71
72 #define BIT_ERR_CODE(x) (((x) & (0xF << 28)) >> 28)
73 #define BIT_ERR_OCCURRED(x) (((x) & (0x1 << 27)) >> 27)
74 #define BIT_ERR_VALID(x) (((x) & (0x1 << 26)) >> 26)
75 #define BIT_AXID(x) (((x) & (0xFFFF)))
76 #define BIT_AXUSER(x) (((x) & (0xFFFF << 16)) >> 16)
77 #define BIT_AXBURST(x) (((x) & (0x3)))
78 #define BIT_AXPROT(x) (((x) & (0x3 << 2)) >> 2)
79 #define BIT_AXLEN(x) (((x) & (0xF << 16)) >> 16)
80 #define BIT_AXSIZE(x) (((x) & (0x7 << 28)) >> 28)
81
82 #define M_NODE (0)
83 #define T_S_NODE (1)
84 #define T_M_NODE (2)
85 #define S_NODE (3)
86 #define NODE_TYPE (4)
87
88 #define ERRCODE_SLVERR (0)
89 #define ERRCODE_DECERR (1)
90 #define ERRCODE_UNSUPORTED (2)
91 #define ERRCODE_POWER_DOWN (3)
92 #define ERRCODE_UNKNOWN_4 (4)
93 #define ERRCODE_UNKNOWN_5 (5)
94 #define ERRCODE_TMOUT (6)
95
96 #define BUS_DATA (0)
97 #define BUS_PERI (1)
98 #define BUS_PATH_TYPE (2)
99
100 #define TRANS_TYPE_WRITE (0)
101 #define TRANS_TYPE_READ (1)
102 #define TRANS_TYPE_NUM (2)
103
104 #define FROM_PERI (0)
105 #define FROM_CPU (1)
106 #define FROM_CP (2)
107
108 #define CP_COMMON_STR "CP_"
109
110 #define TMOUT (0xFFFFF)
111 #define TMOUT_TEST (0x1)
112
113 #define PANIC_ALLOWED_THRESHOLD (0x2)
114 #define INVALID_REMAPPING (0x08000000)
115 #define BAAW_RETURN (0x08000000)
116
117 static bool initial_multi_irq_enable = false;
118 static struct itmon_dev *g_itmon = NULL;
119
120 struct itmon_rpathinfo {
121 unsigned int id;
122 char *port_name;
123 char *dest_name;
124 unsigned int bits;
125 unsigned int shift_bits;
126 };
127
128 struct itmon_masterinfo {
129 char *port_name;
130 unsigned int user;
131 char *master_name;
132 unsigned int bits;
133 };
134
135 struct itmon_nodegroup;
136
137 struct itmon_traceinfo {
138 char *port;
139 char *master;
140 char *dest;
141 unsigned long target_addr;
142 unsigned int errcode;
143 bool read;
144 bool path_dirty;
145 bool snode_dirty;
146 bool dirty;
147 unsigned long from;
148 char buf[SZ_32];
149 };
150
151 struct itmon_tracedata {
152 unsigned int int_info;
153 unsigned int ext_info_0;
154 unsigned int ext_info_1;
155 unsigned int ext_info_2;
156 unsigned int hwa_ctl;
157 unsigned int hwa_info;
158 unsigned int hwa_int_id;
159 unsigned int offset;
160 bool logging;
161 bool read;
162 };
163
164 struct itmon_nodeinfo {
165 unsigned int type;
166 char *name;
167 unsigned int phy_regs;
168 void __iomem *regs;
169 unsigned int time_val;
170 bool tmout_enabled;
171 bool tmout_frz_enabled;
172 bool err_enabled;
173 bool hw_assert_enabled;
174 bool retention;
175 struct itmon_tracedata tracedata;
176 struct itmon_nodegroup *group;
177 struct list_head list;
178 };
179
180 static const char *itmon_pathtype[] = {
181 "DATA Path transaction (0x2000_0000 ~ 0xf_ffff_ffff)",
182 "PERI(SFR) Path transaction (0x0 ~ 0x1fff_ffff)",
183 };
184
185 /* Error Code Description */
186 static const char *itmon_errcode[] = {
187 "Error Detect by the Slave(SLVERR)",
188 "Decode error(DECERR)",
189 "Unsupported transaction error",
190 "Power Down access error",
191 "Unsupported transaction",
192 "Unsupported transaction",
193 "Timeout error - response timeout in timeout value",
194 "Invalid errorcode",
195 };
196
197 static const char *itmon_nodestring[] = {
198 "M_NODE",
199 "TAXI_S_NODE",
200 "TAXI_M_NODE",
201 "S_NODE",
202 };
203
204 struct itmon_nodegroup {
205 int irq;
206 char *name;
207 unsigned int phy_regs;
208 void __iomem *regs;
209 struct itmon_nodeinfo *nodeinfo;
210 unsigned int nodesize;
211 unsigned int bus_type;
212 };
213
214 struct itmon_platdata {
215 const struct itmon_rpathinfo *rpathinfo;
216 const struct itmon_masterinfo *masterinfo;
217 struct itmon_nodegroup *nodegroup;
218 struct itmon_traceinfo traceinfo[BUS_PATH_TYPE];
219 struct list_head tracelist[BUS_PATH_TYPE];
220 unsigned int err_cnt;
221 bool panic_allowed;
222 bool crash_in_progress;
223 unsigned int sysfs_tmout_val;
224 bool sysfs_scandump;
225 bool probed;
226 };
227
228 static struct itmon_rpathinfo rpathinfo[] = {
229 /* Data BUS */
230 {0, "MFC0", "S_CCI", GENMASK(3, 0), 0},
231 {1, "MFC1", "S_CCI", GENMASK(3, 0), 0},
232 {2, "VIPX2", "S_CCI", GENMASK(3, 0), 0},
233 {3, "DIT", "S_CCI", GENMASK(3, 0), 0},
234 {4, "G2D", "S_CCI", GENMASK(3, 0), 0},
235 {5, "FSYS", "S_CCI", GENMASK(3, 0), 0},
236 {6, "USB", "S_CCI", GENMASK(3, 0), 0},
237 {7, "ISP0", "S_CCI", GENMASK(3, 0), 0},
238 {8, "ISP1", "S_CCI", GENMASK(3, 0), 0},
239 {9, "CAM", "S_CCI", GENMASK(3, 0), 0},
240 {10, "DPU", "S_CCI", GENMASK(3, 0), 0},
241 {11, "VIPX1", "S_CCI", GENMASK(3, 0), 0},
242
243 {0, "CP_1", "S_NRT", GENMASK(3, 0), 0},
244 {1, "ISP0", "S_NRT", GENMASK(3, 0), 0},
245 {2, "ISP1", "S_NRT", GENMASK(3, 0), 0},
246 {3, "VIPX1", "S_NRT", GENMASK(3, 0), 0},
247 {4, "VIPX2", "S_NRT", GENMASK(3, 0), 0},
248 {5, "MFC0", "S_NRT", GENMASK(3, 0), 0},
249 {6, "MFC1", "S_NRT", GENMASK(3, 0), 0},
250 {7, "G2D", "S_NRT", GENMASK(3, 0), 0},
251 {8, "FSYS", "S_NRT", GENMASK(3, 0), 0},
252 {9, "USB", "S_NRT", GENMASK(3, 0), 0},
253 {10, "COREX", "S_NRT", GENMASK(3, 0), 0},
254 {11, "GNSS", "S_NRT", GENMASK(3, 0), 0},
255 {12, "WLBT", "S_NRT", GENMASK(3, 0), 0},
256 {13, "DIT", "S_NRT", GENMASK(3, 0), 0},
257 {14, "CSSYS", "S_NRT", GENMASK(3, 0), 0},
258
259 {0, "CAM", "RT_MEM", GENMASK(3, 0), 0},
260 {1, "DPU", "RT_MEM", GENMASK(3, 0), 0},
261 {2, "ABOX", "RT_MEM", GENMASK(3, 0), 0},
262 {3, "CP_1", "RT_MEM", GENMASK(3, 0), 0},
263 {4, "WLBT", "RT_MEM", GENMASK(3, 0), 0},
264 {5, "GNSS", "RT_MEM", GENMASK(3, 0), 0},
265 {6, "VIPX1", "RT_MEM", GENMASK(3, 0), 0},
266 {7, "VIPX2", "RT_MEM", GENMASK(3, 0), 0},
267 {8, "ISP0", "RT_MEM", GENMASK(3, 0), 0},
268 {9, "ISP1", "RT_MEM", GENMASK(3, 0), 0},
269
270 {0, "CP_0", "CP_MEM", GENMASK(3, 0), 0},
271 {1, "ABOX", "CP_MEM", GENMASK(3, 0), 0},
272 {2, "CP_1", "CP_MEM", GENMASK(3, 0), 0},
273 {3, "WLBT", "CP_MEM", GENMASK(3, 0), 0},
274 {4, "DIT", "CP_MEM", GENMASK(3, 0), 0},
275
276 /* Peri BUS */
277 {0, "G3D", "PERI", GENMASK(4, 0), 0},
278 {1, "MFC0", "PERI", GENMASK(4, 0), 0},
279 {2, "ISP1", "PERI", GENMASK(4, 0), 0},
280 {3, "CAM", "PERI", GENMASK(4, 0), 0},
281 {4, "DPU", "PERI", GENMASK(4, 0), 0},
282 {5, "ABOX", "PERI", GENMASK(4, 0), 0},
283 {6, "WLBT", "PERI", GENMASK(4, 0), 0},
284 {7, "CP_0", "PERI", GENMASK(4, 0), 0},
285 {8, "CP_1", "PERI", GENMASK(4, 0), 0},
286 {9, "VIPX1", "PERI", GENMASK(4, 0), 0},
287 {10, "VIPX2", "PERI", GENMASK(4, 0), 0},
288 {11, "DIT", "PERI", GENMASK(4, 0), 0},
289 {12, "MFC1", "PERI", GENMASK(4, 0), 0},
290 {13, "G2D", "PERI", GENMASK(4, 0), 0},
291 {14, "FSYS", "PERI", GENMASK(4, 0), 0},
292 {15, "USB", "PERI", GENMASK(4, 0), 0},
293 {16, "COREX", "PERI", GENMASK(4, 0), 0},
294 {17, "GNSS", "PERI", GENMASK(4, 0), 0},
295 {18, "CSSYS", "PERI", GENMASK(4, 0), 0},
296 {19, "ISP0", "PERI", GENMASK(4, 0), 0},
297 };
298
299 /* XIU ID Information */
300 static struct itmon_masterinfo masterinfo[] = {
301 /* BLK_CAM */
302 {"CAM", 0, "PAF-STAT", GENMASK(2, 1)},
303 {"CAM", BIT(1), "3AA", GENMASK(2, 1)},
304
305 /* BLK_DISPAUD */
306 {"DPU", 0, "IDMA0", 0},
307 {"ABOX", 0, "SPUS_SPUM", GENMASK(1, 1)},
308 {"ABOX", BIT(1), "ABOX_CA7", GENMASK(1, 1)},
309
310 /* BLK_VIPX1 */
311 {"VIPX1", 0, "SDMA", GENMASK(1, 1)},
312 {"VIPX1", BIT(1), "CM7", GENMASK(1, 1)},
313
314 /* BLK_VIPX2 */
315 {"VIPX2", 0, "SDMA", 0},
316
317 /* BLK_ISP */
318 {"ISP0", 0, "FIMC-ISP", GENMASK(2, 1)},
319 {"ISP0", BIT(1), "VRA", GENMASK(2, 1)},
320 {"ISP0", BIT(2), "GDC", GENMASK(2, 1)},
321 {"ISP1", 0, "MC_SCALER", 0},
322
323 /* BLK_FSYS */
324 {"FSYS", 0, "UFS", GENMASK(1, 0)},
325 {"FSYS", BIT(0), "MMC_CARD", GENMASK(1, 0)},
326 {"FSYS", BIT(1), "SSS", GENMASK(1, 0)},
327 {"FSYS", BIT(1) | BIT(0), "RTIC", GENMASK(1, 0)},
328
329 /* BLK_USB */
330 {"USB", 0, "USB", 0},
331
332 /* BLK_APM */
333 {"COREX", 0, "APM", GENMASK(1, 0)},
334
335 /* BLK_SHUB */
336 {"COREX", BIT(0), "CM4_SHUB_CD", GENMASK(3, 0)},
337 {"COREX", BIT(0) | BIT(2), "CM4_SHUB_P", GENMASK(3, 0)},
338 {"COREX", BIT(0) | BIT(3), "PDMA_SHUB", GENMASK(3, 0)},
339
340 /* BLK_CORE */
341 {"COREX", BIT(1), "PDMA", GENMASK(1, 0)},
342 {"COREX", BIT(0) | BIT(1), "SPDMA", GENMASK(1, 0)},
343 {"SIREX", 0, "SIREX", 0},
344 {"DIT", 0, "DIT", 0},
345
346 /* BLK_G3D - Unique ID */
347 {"G3D", 0, "", 0},
348
349 /* BLK_MFC */
350 {"MFC0", 0, "MFC0", 0},
351 {"MFC1", 0, "MFC1", GENMASK(1, 1)},
352 {"MFC1", BIT(1), "WFD", GENMASK(1, 1)},
353
354 /* BLK_G2D */
355 {"G2D", 0, "JPEG", GENMASK(2, 1)},
356 {"G2D", BIT(1), "MSCL", GENMASK(2, 1)},
357 {"G2D", BIT(2), "G2D", GENMASK(2, 1)},
358
359 /* BLK_CP */
360 {"CP_0", 0, "UCPUM", GENMASK(5, 0)},
361 {"CP_0", BIT(0), "DMA0", GENMASK(5, 0)},
362 {"CP_0", BIT(0) | BIT(3), "DMA1", GENMASK(5, 0)},
363 {"CP_0", BIT(0) | BIT(4), "DMA2", GENMASK(5, 0)},
364 {"CP_0", BIT(0) | BIT(2), "LCPUMtoL2", GENMASK(5, 0)},
365 {"CP_0", BIT(2), "LMAC", GENMASK(5, 0)},
366 {"CP_0", BIT(1), "CSXAP", GENMASK(5, 0)},
367 {"CP_0", BIT(0) | BIT(1), "DATAMOVER", GENMASK(5, 0)},
368 {"CP_0", BIT(0) | BIT(1) | BIT(4), "BAYES", GENMASK(5, 0)},
369 {"CP_0", BIT(0) | BIT(1) | BIT(3), "LOGGER", GENMASK(5, 0)},
370 {"CP_0", BIT(1) | BIT(2), "HARQMOVER", GENMASK(5, 0)},
371
372 /* BLK_CP */
373 {"CP_1", 0, "UCPUM", GENMASK(5, 0)},
374 {"CP_1", BIT(0), "DMA0", GENMASK(5, 0)},
375 {"CP_1", BIT(0) | BIT(3), "DMA1", GENMASK(5, 0)},
376 {"CP_1", BIT(0) | BIT(4), "DMA2", GENMASK(5, 0)},
377 {"CP_1", BIT(0) | BIT(2), "LCPUMtoL2", GENMASK(5, 0)},
378 {"CP_1", BIT(2), "LMAC", GENMASK(5, 0)},
379 {"CP_1", BIT(1), "CSXAP", GENMASK(5, 0)},
380 {"CP_1", BIT(0) | BIT(1), "DATAMOVER", GENMASK(5, 0)},
381 {"CP_1", BIT(0) | BIT(1) | BIT(4), "BAYES", GENMASK(5, 0)},
382 {"CP_1", BIT(0) | BIT(1) | BIT(3), "LOGGER", GENMASK(5, 0)},
383 {"CP_1", BIT(1) | BIT(2), "HARQMOVER", GENMASK(5, 0)},
384
385 /* BLK_WLBT */
386 {"WLBT", 0, "CR7", GENMASK(2, 0)},
387 {"WLBT", BIT(0), "XDMA", GENMASK(2, 0)},
388 {"WLBT", BIT(1), "ENC_DMA0", GENMASK(2, 0)},
389 {"WLBT", BIT(0) | BIT(1), "ENC_DMA0", GENMASK(2, 0)},
390 {"WLBT", BIT(2), "BTLC", GENMASK(2, 0)},
391
392 /* BLK_GNSS */
393 {"GNSS", 0, "CM7F_S0", GENMASK(2, 0)},
394 {"GNSS", BIT(0), "CM7F_S1_AHB", GENMASK(2, 0)},
395 {"GNSS", BIT(1), "XDMA0", GENMASK(2, 0)},
396 {"GNSS", BIT(0) | BIT(1), "XDMA1", GENMASK(1, 0)},
397 };
398
399 /* data_path is sorted by INT_VEC_DEBUG_INTERRUPT_VECTOR_TABLE bits */
400 static struct itmon_nodeinfo data_path[] = {
401 {M_NODE, "ABOX", 0x12403000, NULL, 0, false, false, true, true, false},
402 {M_NODE, "CAM", 0x12423000, NULL, 0, false, false, true, true, false},
403 {M_NODE, "COREX", 0x12413000, NULL, 0, false, false, true, true, false},
404 {M_NODE, "CSSYS", 0x12433000, NULL, 0, false, false, true, true, false},
405 {M_NODE, "DIT", 0x12453000, NULL, 0, false, false, true, true, false},
406 {M_NODE, "DPU", 0x12443000, NULL, 0, false, false, true, true, false},
407 {M_NODE, "FSYS", 0x12463000, NULL, 0, false, false, true, true, false},
408 {M_NODE, "G2D", 0x12473000, NULL, 0, false, false, true, true, false},
409 {M_NODE, "G3D", 0x12483000, NULL, 0, false, false, true, true, false},
410 {M_NODE, "GNSS", 0x12493000, NULL, 0, false, false, true, true, false},
411 {M_NODE, "ISP0", 0x124A3000, NULL, 0, false, false, true, true, false},
412 {M_NODE, "ISP1", 0x124B3000, NULL, 0, false, false, true, true, false},
413 {M_NODE, "MFC0", 0x124C3000, NULL, 0, false, false, true, true, false},
414 {M_NODE, "MFC1", 0x124D3000, NULL, 0, false, false, true, true, false},
415 {M_NODE, "CP_0", 0x124E3000, NULL, 0, false, false, true, true, false},
416 {M_NODE, "CP_1", 0x124F3000, NULL, 0, false, false, true, true, false},
417 {M_NODE, "USB", 0x12513000, NULL, 0, false, false, true, true, false},
418 {M_NODE, "VIPX1", 0x12523000, NULL, 0, false, false, true, true, false},
419 {M_NODE, "VIPX2", 0x12533000, NULL, 0, false, false, true, true, false},
420 {M_NODE, "WLBT", 0x12503000, NULL, 0, false, false, true, true, false},
421 {S_NODE, "CP_MEM0", 0x12583000, NULL, TMOUT, true, false, true, true, false},
422 {S_NODE, "CP_MEM1", 0x12593000, NULL, TMOUT, true, false, true, true, false},
423 {S_NODE, "PERI", 0x125B3000, NULL, TMOUT, true, false, true, true, false},
424 {S_NODE, "RT_MEM0", 0x12563000, NULL, TMOUT, true, false, true, true, false},
425 {S_NODE, "RT_MEM1", 0x12573000, NULL, TMOUT, true, false, true, true, false},
426 {S_NODE, "S_CCI", 0x125A3000, NULL, TMOUT, true, false, true, true, false},
427 {S_NODE, "S_NRT0", 0x12543000, NULL, TMOUT, true, false, true, true, false},
428 {S_NODE, "S_NRT1", 0x12553000, NULL, TMOUT, true, false, true, true, false},
429 };
430
431 /* peri_path is sorted by INT_VEC_DEBUG_INTERRUPT_VECTOR_TABLE bits */
432 static struct itmon_nodeinfo trex_d_nrt[] = {
433 {M_NODE, "M_NRT0", 0x12A13000, NULL, 0, false, false, true, true, false},
434 {M_NODE, "M_NRT1", 0x12A23000, NULL, 0, false, false, true, true, false},
435 {M_NODE, "SIREX", 0x12A03000, NULL, 0, false, false, true, true, false},
436 {M_NODE, "NRT_MEM0", 0x12A33000, NULL, 0, false, false, true, true, false},
437 {M_NODE, "NRT_MEM1", 0x12A43000, NULL, 0, false, false, true, true, false},
438 };
439
440 /* peri_path is sorted by INT_VEC_DEBUG_INTERRUPT_VECTOR_TABLE bits */
441 static struct itmon_nodeinfo peri_path[] = {
442 {M_NODE, "CPU_TO_SFR", 0x12803000, NULL, 0, false, false, true, true, false},
443 {M_NODE, "PERI_TO_SFR", 0x12813000, NULL, 0, false, false, true, true, false},
444 {S_NODE, "APMP", 0x12833000, NULL, TMOUT, true, false, true, true, false},
445 {S_NODE, "CAMP", 0x12843000, NULL, TMOUT, true, false, true, true, false},
446 {S_NODE, "COREP_SFR", 0x12893000, NULL, TMOUT, true, false, true, true, false},
447 {S_NODE, "COREP_TREX", 0x12883000, NULL, TMOUT, true, false, true, true, false},
448 {S_NODE, "CPU_CL0P", 0x12853000, NULL, TMOUT, true, false, true, true, false},
449 {S_NODE, "CPU_CL1P", 0x12863000, NULL, TMOUT, true, false, true, true, false},
450 {S_NODE, "CSSYS", 0x12873000, NULL, TMOUT, true, false, true, true, false},
451 {S_NODE, "DISPAUDP", 0x128A3000, NULL, TMOUT, true, false, true, true, false},
452 {S_NODE, "FSYSP", 0x128B3000, NULL, TMOUT, true, false, true, true, false},
453 {S_NODE, "G2DP", 0x128C3000, NULL, TMOUT, true, false, true, true, false},
454 {S_NODE, "G3DP", 0x128D3000, NULL, TMOUT, true, false, true, true, false},
455 {S_NODE, "GICP", 0x128E3000, NULL, TMOUT, true, false, true, true, false},
456 {S_NODE, "GNSSP", 0x128F3000, NULL, TMOUT, true, false, true, true, false},
457 {S_NODE, "ISPP", 0x12903000, NULL, TMOUT, true, false, true, true, false},
458 {S_NODE, "MFCP", 0x12913000, NULL, TMOUT, true, false, true, true, false},
459 {S_NODE, "MIF0P", 0x12923000, NULL, TMOUT, true, false, true, true, false},
460 {S_NODE, "MIF1P", 0x12933000, NULL, TMOUT, true, false, true, true, false},
461 {S_NODE, "CP_P", 0x12943000, NULL, TMOUT, true, false, true, true, false},
462 {S_NODE, "PERIP", 0x12953000, NULL, TMOUT, true, false, true, true, false},
463 {S_NODE, "SHUBP", 0x12963000, NULL, TMOUT, true, false, true, true, false},
464 {S_NODE, "SIREXP", 0x12973000, NULL, TMOUT, true, false, true, true, false},
465 {S_NODE, "USBP", 0x12983000, NULL, TMOUT, true, false, true, true, false},
466 {S_NODE, "VIPX1P", 0x129A3000, NULL, TMOUT, true, false, true, true, false},
467 {S_NODE, "VIPX2P", 0x129B3000, NULL, TMOUT, true, false, true, true, false},
468 {S_NODE, "WLBTP", 0x12993000, NULL, TMOUT, true, false, true, true, false},
469 };
470
471 static struct itmon_nodegroup nodegroup[] = {
472 {306, "TREX_D_CORE", 0x127F3000, NULL, data_path, ARRAY_SIZE(data_path), BUS_DATA},
473 {320, "TREX_D_NRT", 0x12BF3000, NULL, trex_d_nrt, ARRAY_SIZE(trex_d_nrt), BUS_DATA},
474 {307, "TREX_P_CORE", 0x129F3000, NULL, peri_path, ARRAY_SIZE(peri_path), BUS_PERI},
475 };
476
477 struct itmon_dev {
478 struct device *dev;
479 struct itmon_platdata *pdata;
480 struct of_device_id *match;
481 int irq;
482 int id;
483 void __iomem *regs;
484 spinlock_t ctrl_lock;
485 struct itmon_notifier notifier_info;
486 };
487
488 struct itmon_panic_block {
489 struct notifier_block nb_panic_block;
490 struct itmon_dev *pdev;
491 };
492
493 /* declare notifier_list */
494 ATOMIC_NOTIFIER_HEAD(itmon_notifier_list);
495
496 static const struct of_device_id itmon_dt_match[] = {
497 {.compatible = "samsung,exynos-itmon",
498 .data = NULL,},
499 {},
500 };
501 MODULE_DEVICE_TABLE(of, itmon_dt_match);
502
503 #define EXYNOS_PMU_BURNIN_CTRL 0x0A08
504 #define BIT_ENABLE_DBGSEL_WDTRESET BIT(25)
505 #ifdef CONFIG_S3C2410_WATCHDOG
506 extern int s3c2410wdt_set_emergency_reset(unsigned int timeout, int index);
507 #else
508 #define s3c2410wdt_set_emergency_reset(a, b) do { } while (0)
509 #endif
510 static void itmon_switch_scandump(void)
511 {
512 unsigned int val;
513 int ret;
514
515 ret = exynos_pmu_read(EXYNOS_PMU_BURNIN_CTRL, &val);
516 ret = exynos_pmu_write(EXYNOS_PMU_BURNIN_CTRL, val | BIT_ENABLE_DBGSEL_WDTRESET);
517 s3c2410wdt_set_emergency_reset(5, 0);
518 }
519
520 static struct itmon_rpathinfo *itmon_get_rpathinfo(struct itmon_dev *itmon,
521 unsigned int id,
522 char *dest_name)
523 {
524 struct itmon_platdata *pdata = itmon->pdata;
525 struct itmon_rpathinfo *rpath = NULL;
526 int i;
527
528 if (!dest_name)
529 return NULL;
530
531 for (i = 0; i < ARRAY_SIZE(rpathinfo); i++) {
532 if (pdata->rpathinfo[i].id == (id & pdata->rpathinfo[i].bits)) {
533 if (dest_name && !strncmp(pdata->rpathinfo[i].dest_name,
534 dest_name,
535 strlen(pdata->rpathinfo[i].dest_name))) {
536 rpath = (struct itmon_rpathinfo *)&pdata->rpathinfo[i];
537 break;
538 }
539 }
540 }
541 return rpath;
542 }
543
544 static struct itmon_masterinfo *itmon_get_masterinfo(struct itmon_dev *itmon,
545 char *port_name,
546 unsigned int user)
547 {
548 struct itmon_platdata *pdata = itmon->pdata;
549 struct itmon_masterinfo *master = NULL;
550 unsigned int val;
551 int i;
552
553 if (!port_name)
554 return NULL;
555
556 for (i = 0; i < ARRAY_SIZE(masterinfo); i++) {
557 if (!strncmp(pdata->masterinfo[i].port_name, port_name, strlen(port_name))) {
558 val = user & pdata->masterinfo[i].bits;
559 if (val == pdata->masterinfo[i].user) {
560 master = (struct itmon_masterinfo *)&pdata->masterinfo[i];
561 break;
562 }
563 }
564 }
565 return master;
566 }
567
568 static void itmon_init(struct itmon_dev *itmon, bool enabled)
569 {
570 struct itmon_platdata *pdata = itmon->pdata;
571 struct itmon_nodeinfo *node;
572 unsigned int offset;
573 int i, j;
574
575 for (i = 0; i < ARRAY_SIZE(nodegroup); i++) {
576 node = pdata->nodegroup[i].nodeinfo;
577 for (j = 0; j < pdata->nodegroup[i].nodesize; j++) {
578 if (node[j].type == S_NODE && node[j].tmout_enabled) {
579 offset = OFFSET_TMOUT_REG;
580 /* Enable Timeout setting */
581 __raw_writel(enabled, node[j].regs + offset + REG_DBG_CTL);
582 /* set tmout interval value */
583 __raw_writel(node[j].time_val,
584 node[j].regs + offset + REG_TMOUT_INIT_VAL);
585 pr_debug("Exynos ITMON - %s timeout enabled\n", node[j].name);
586 if (node[j].tmout_frz_enabled) {
587 /* Enable freezing */
588 __raw_writel(enabled,
589 node[j].regs + offset + REG_TMOUT_FRZ_EN);
590 }
591 }
592 if (node[j].err_enabled) {
593 /* clear previous interrupt of req_read */
594 offset = OFFSET_REQ_R;
595 if (!pdata->probed || !node->retention)
596 __raw_writel(1, node[j].regs + offset + REG_INT_CLR);
597 /* enable interrupt */
598 __raw_writel(enabled, node[j].regs + offset + REG_INT_MASK);
599
600 /* clear previous interrupt of req_write */
601 offset = OFFSET_REQ_W;
602 if (pdata->probed || !node->retention)
603 __raw_writel(1, node[j].regs + offset + REG_INT_CLR);
604 /* enable interrupt */
605 __raw_writel(enabled, node[j].regs + offset + REG_INT_MASK);
606
607 /* clear previous interrupt of response_read */
608 offset = OFFSET_RESP_R;
609 if (!pdata->probed || !node->retention)
610 __raw_writel(1, node[j].regs + offset + REG_INT_CLR);
611 /* enable interrupt */
612 __raw_writel(enabled, node[j].regs + offset + REG_INT_MASK);
613
614 /* clear previous interrupt of response_write */
615 offset = OFFSET_RESP_W;
616 if (!pdata->probed || !node->retention)
617 __raw_writel(1, node[j].regs + offset + REG_INT_CLR);
618 /* enable interrupt */
619 __raw_writel(enabled, node[j].regs + offset + REG_INT_MASK);
620 pr_debug("Exynos ITMON - %s error reporting enabled\n", node[j].name);
621 }
622 if (node[j].hw_assert_enabled) {
623 offset = OFFSET_HW_ASSERT;
624 __raw_writel(RD_RESP_INT_ENABLE | WR_RESP_INT_ENABLE |
625 ARLEN_RLAST_INT_ENABLE | AWLEN_WLAST_INT_ENABLE,
626 node[j].regs + offset + REG_HWA_CTL);
627 }
628 }
629 }
630 }
631
632 void itmon_enable(bool enabled)
633 {
634 if (g_itmon)
635 itmon_init(g_itmon, enabled);
636 }
637
638 void itmon_set_errcnt(int cnt)
639 {
640 struct itmon_platdata *pdata;
641
642 if (g_itmon) {
643 pdata = g_itmon->pdata;
644 pdata->err_cnt = cnt;
645 }
646 }
647
648 static void itmon_post_handler_to_notifier(struct itmon_dev *itmon,
649 unsigned int trans_type)
650 {
651 struct itmon_platdata *pdata = itmon->pdata;
652 struct itmon_traceinfo *traceinfo = &pdata->traceinfo[trans_type];
653
654 /* After treatment by port */
655 if (!traceinfo->port || strlen(traceinfo->port) < 1)
656 return;
657
658 itmon->notifier_info.port = traceinfo->port;
659 itmon->notifier_info.master = traceinfo->master;
660 itmon->notifier_info.dest = traceinfo->dest;
661 itmon->notifier_info.read = traceinfo->read;
662 itmon->notifier_info.target_addr = traceinfo->target_addr;
663 itmon->notifier_info.errcode = traceinfo->errcode;
664
665 /* call notifier_call_chain of itmon */
666 atomic_notifier_call_chain(&itmon_notifier_list, 0, &itmon->notifier_info);
667 }
668
669 static void itmon_post_handler_by_master(struct itmon_dev *itmon,
670 unsigned int trans_type)
671 {
672 struct itmon_platdata *pdata = itmon->pdata;
673 struct itmon_traceinfo *traceinfo = &pdata->traceinfo[trans_type];
674
675 /* After treatment by port */
676 if (!traceinfo->port || strlen(traceinfo->port) < 1)
677 return;
678
679 if (!strncmp(traceinfo->port, "CPU", strlen("CPU"))) {
680 /* if master is CPU, then we expect any exception */
681 if (pdata->err_cnt > PANIC_ALLOWED_THRESHOLD) {
682 pdata->err_cnt = 0;
683 itmon_init(itmon, false);
684 pr_info("ITMON is turn-off when CPU transaction is detected repeatly\n");
685 } else {
686 pr_info("ITMON skips CPU transaction detected\n");
687 }
688 } else if (!strncmp(traceinfo->port, CP_COMMON_STR, strlen(CP_COMMON_STR))) {
689 /* if master is DSP and operation is read, we don't care this */
690 if (traceinfo->master && traceinfo->target_addr == INVALID_REMAPPING &&
691 !strncmp(traceinfo->master, "CR4MtoL2", strlen(traceinfo->master))) {
692 pdata->err_cnt = 0;
693 pr_info("ITMON skips CP's DSP(CR4MtoL2) detected\n");
694 } else {
695 /* Disable busmon all interrupts */
696 itmon_init(itmon, false);
697 #if defined(CONFIG_SEC_MODEM_IF)
698 pdata->crash_in_progress = true;
699 modem_force_crash_exit_ext();
700 #endif
701 }
702 }
703 }
704
705 void itmon_report_timeout(struct itmon_dev *itmon,
706 struct itmon_nodeinfo *node,
707 unsigned int trans_type)
708 {
709 unsigned int info, axid, valid, timeout, payload;
710 unsigned long addr;
711 char *master_name, *port_name;
712 struct itmon_rpathinfo *port;
713 struct itmon_masterinfo *master;
714 int i, num = (trans_type == TRANS_TYPE_READ ? SZ_128 : SZ_64);
715 int fz_offset = (trans_type == TRANS_TYPE_READ ? 0 : REG_TMOUT_BUF_WR_OFFSET);
716
717 pr_info("\n TIMEOUT_BUFFER Information\n\n");
718 pr_info(" > NUM| BLOCK| MASTER| VALID| TIMEOUT| ID| ADDRESS| INFO|\n");
719
720 for (i = 0; i < num; i++) {
721 writel(i, node->regs + OFFSET_TMOUT_REG +
722 REG_TMOUT_BUF_POINT_ADDR + fz_offset);
723 axid = readl(node->regs + OFFSET_TMOUT_REG +
724 REG_TMOUT_BUF_ID + fz_offset);
725 payload = readl(node->regs + OFFSET_TMOUT_REG +
726 REG_TMOUT_BUF_PAYLOAD + fz_offset);
727 addr = (((unsigned long)readl(node->regs + OFFSET_TMOUT_REG +
728 REG_TMOUT_BUF_PAYLOAD_SRAM1 + fz_offset) &
729 GENMASK(15, 0)) << 32ULL);
730 addr |= (readl(node->regs + OFFSET_TMOUT_REG +
731 REG_TMOUT_BUF_PAYLOAD_SRAM2 + fz_offset));
732 info = readl(node->regs + OFFSET_TMOUT_REG +
733 REG_TMOUT_BUF_PAYLOAD_SRAM3 + fz_offset);
734
735 valid = payload & BIT(0);
736 timeout = (payload & GENMASK(19, 16)) >> 16;
737
738 port = (struct itmon_rpathinfo *)
739 itmon_get_rpathinfo(itmon, axid, node->name);
740 if (port) {
741 port_name = port->port_name;
742 master = (struct itmon_masterinfo *)
743 itmon_get_masterinfo(itmon, port_name,
744 axid >> port->shift_bits);
745 if (master)
746 master_name = master->master_name;
747 else
748 master_name = "Unknown";
749 } else {
750 port_name = "Unknown";
751 master_name = "Unknown";
752 }
753 pr_info(" > %03d|%8s|%8s|%8u|%8x|%08x|%010zx|%08x|\n",
754 i, port_name, master_name, valid, timeout, axid, addr, info);
755 }
756 pr_info("--------------------------------------------------------------------------\n");
757 }
758
759 static unsigned int power(unsigned int param, unsigned int num)
760 {
761 if (num == 0)
762 return 1;
763 return param * (power(param, num - 1));
764 }
765
766 static void itmon_report_traceinfo(struct itmon_dev *itmon,
767 struct itmon_nodeinfo *node,
768 unsigned int trans_type)
769 {
770 struct itmon_platdata *pdata = itmon->pdata;
771 struct itmon_traceinfo *traceinfo = &pdata->traceinfo[trans_type];
772 struct itmon_nodegroup *group = NULL;
773
774 if (!traceinfo->dirty)
775 return;
776
777 pr_info("--------------------------------------------------------------------------\n"
778 " Transaction Information\n\n"
779 " > Master : %s %s\n"
780 " > Target : %s\n"
781 " > Target Address : 0x%lX %s\n"
782 " > Type : %s\n"
783 " > Error code : %s\n",
784 traceinfo->port, traceinfo->master ? traceinfo->master : "",
785 traceinfo->dest ? traceinfo->dest : "Unknown",
786 traceinfo->target_addr,
787 (unsigned int)traceinfo->target_addr == INVALID_REMAPPING ?
788 "(BAAW Remapped address)" : "",
789 trans_type == TRANS_TYPE_READ ? "READ" : "WRITE",
790 itmon_errcode[traceinfo->errcode]);
791
792 if (node) {
793 struct itmon_tracedata *tracedata = &node->tracedata;
794
795 pr_info(" > Size : %u bytes x %u burst => %u bytes\n"
796 " > Burst Type : %u (0:FIXED, 1:INCR, 2:WRAP)\n"
797 " > Level : %s\n"
798 " > Protection : %s\n",
799 power(BIT_AXSIZE(tracedata->ext_info_1), 2), BIT_AXLEN(tracedata->ext_info_1) + 1,
800 power(BIT_AXSIZE(tracedata->ext_info_1), 2) * (BIT_AXLEN(tracedata->ext_info_1) + 1),
801 BIT_AXBURST(tracedata->ext_info_2),
802 (BIT_AXPROT(tracedata->ext_info_2) & 0x1) ? "Privileged access" : "Unprivileged access",
803 (BIT_AXPROT(tracedata->ext_info_2) & 0x2) ? "Non-secure access" : "Secure access");
804
805 group = node->group;
806 pr_info(" > Path Type : %s\n"
807 "--------------------------------------------------------------------------\n",
808 itmon_pathtype[group->bus_type]);
809
810 } else {
811 pr_info("--------------------------------------------------------------------------\n");
812 }
813 }
814
815 static void itmon_report_pathinfo(struct itmon_dev *itmon,
816 struct itmon_nodeinfo *node,
817 unsigned int trans_type)
818 {
819 struct itmon_platdata *pdata = itmon->pdata;
820 struct itmon_tracedata *tracedata = &node->tracedata;
821 struct itmon_traceinfo *traceinfo = &pdata->traceinfo[trans_type];
822
823 if (!traceinfo->path_dirty) {
824 pr_info("--------------------------------------------------------------------------\n"
825 " ITMON Report (%s)\n"
826 "--------------------------------------------------------------------------\n"
827 " PATH Information\n",
828 trans_type == TRANS_TYPE_READ ? "READ" : "WRITE");
829 traceinfo->path_dirty = true;
830 }
831 switch (node->type) {
832 case M_NODE:
833 pr_info(" > %14s, %8s(0x%08X)\n",
834 node->name, "M_NODE", node->phy_regs + tracedata->offset);
835 break;
836 case T_S_NODE:
837 pr_info(" > %14s, %8s(0x%08X)\n",
838 node->name, "T_S_NODE", node->phy_regs + tracedata->offset);
839 break;
840 case T_M_NODE:
841 pr_info(" > %14s, %8s(0x%08X)\n",
842 node->name, "T_M_NODE", node->phy_regs + tracedata->offset);
843 break;
844 case S_NODE:
845 pr_info(" > %14s, %8s(0x%08X)\n",
846 node->name, "S_NODE", node->phy_regs + tracedata->offset);
847 break;
848 }
849 }
850
851 static void itmon_report_tracedata(struct itmon_dev *itmon,
852 struct itmon_nodeinfo *node,
853 unsigned int trans_type)
854 {
855 struct itmon_platdata *pdata = itmon->pdata;
856 struct itmon_tracedata *tracedata = &node->tracedata;
857 struct itmon_traceinfo *traceinfo = &pdata->traceinfo[trans_type];
858 struct itmon_masterinfo *master;
859 struct itmon_rpathinfo *port;
860 unsigned int errcode, axid;
861
862 errcode = BIT_ERR_CODE(tracedata->int_info);
863 axid = BIT_AXID(tracedata->int_info);
864
865 switch (node->type) {
866 case M_NODE:
867 /* In this case, we can get information from M_NODE
868 * Fill traceinfo->port / target_addr / read / master */
869 if (BIT_ERR_VALID(tracedata->int_info) && tracedata->ext_info_2) {
870 /* If only detecting M_NODE only(DECERR) */
871 traceinfo->port = node->name;
872 master = (struct itmon_masterinfo *)
873 itmon_get_masterinfo(itmon, node->name, axid);
874 if (master)
875 traceinfo->master = master->master_name;
876 else
877 traceinfo->master = NULL;
878
879 traceinfo->target_addr =
880 (((unsigned long)node->tracedata.ext_info_1
881 & GENMASK(3, 0)) << 32ULL);
882 traceinfo->target_addr |= node->tracedata.ext_info_0;
883 traceinfo->read = tracedata->read;
884 traceinfo->errcode = errcode;
885 traceinfo->dirty = true;
886 } else {
887 traceinfo->master = NULL;
888 traceinfo->target_addr = 0;
889 traceinfo->read = tracedata->read;
890 traceinfo->port = node->name;
891 traceinfo->errcode = errcode;
892 traceinfo->dirty = true;
893 }
894 itmon_report_pathinfo(itmon, node, trans_type);
895 break;
896 case S_NODE:
897 /*
898 * In DECERR case, the follow information was already filled in M_NODE.
899 */
900 port = (struct itmon_rpathinfo *) itmon_get_rpathinfo(itmon, axid, node->name);
901
902 if (port) {
903 struct itmon_nodeinfo *m_node, *next_m_node;
904 struct itmon_tracedata *m_tracedata;
905 unsigned int m_axid;
906
907 traceinfo->port = port->port_name;
908 list_for_each_entry_safe(m_node, next_m_node,
909 &pdata->tracelist[trans_type], list) {
910 if (m_node && m_node->name && port->port_name && m_node->type == M_NODE &&
911 strncmp(m_node->name, port->port_name,
912 strlen(port->port_name)) == 0) {
913 m_tracedata = &m_node->tracedata;
914 m_axid = BIT_AXID(m_tracedata->int_info);
915 master = (struct itmon_masterinfo *)
916 itmon_get_masterinfo(itmon, traceinfo->port, m_axid);
917 if (master) {
918 traceinfo->master = master->master_name;
919 break;
920 }
921 }
922 }
923 }
924 if (!traceinfo->port)
925 traceinfo->port = "Unknown";
926 if (!traceinfo->master)
927 traceinfo->master = "Unknown";
928
929 traceinfo->target_addr =
930 (((unsigned long)node->tracedata.ext_info_1
931 & GENMASK(3, 0)) << 32ULL);
932 traceinfo->target_addr |= node->tracedata.ext_info_0;
933 traceinfo->errcode = errcode;
934 traceinfo->dest = node->name;
935 traceinfo->dirty = true;
936 traceinfo->snode_dirty = true;
937 itmon_report_pathinfo(itmon, node, trans_type);
938 itmon_report_traceinfo(itmon, node, trans_type);
939 break;
940 default:
941 pr_info("Unknown Error - offset:%u\n", tracedata->offset);
942 break;
943 }
944 }
945
946 static void itmon_report_hwa_rawdata(struct itmon_dev *itmon,
947 struct itmon_nodeinfo *node)
948 {
949 unsigned int hwa_ctl, hwa_info, hwa_int_id;
950
951 hwa_ctl = __raw_readl(node->regs + OFFSET_HW_ASSERT + REG_HWA_CTL);
952 hwa_info = __raw_readl(node->regs + OFFSET_HW_ASSERT + REG_HWA_INT);
953 hwa_int_id = __raw_readl(node->regs + OFFSET_HW_ASSERT + REG_HWA_INT_ID);
954
955 /* Output Raw register information */
956 pr_info("--------------------------------------------------------------------------\n"
957 " HWA Raw Register Information(ITMON information)\n\n");
958 pr_info(" > %s(%s, 0x%08X)\n"
959 " > REG(0x104~0x10C) : 0x%08X, 0x%08X, 0x%08X\n",
960 node->name, itmon_nodestring[node->type],
961 node->phy_regs,
962 hwa_ctl,
963 hwa_info,
964 hwa_int_id);
965 }
966
967 static void itmon_report_rawdata(struct itmon_dev *itmon,
968 struct itmon_nodeinfo *node,
969 unsigned int trans_type)
970 {
971 struct itmon_platdata *pdata = itmon->pdata;
972 struct itmon_traceinfo *traceinfo = &pdata->traceinfo[trans_type];
973 struct itmon_tracedata *tracedata = &node->tracedata;
974
975 /* Output Raw register information */
976 pr_info(" > %s(%s, 0x%08X)\n"
977 " > REG(0x08~0x18) : 0x%08X, 0x%08X, 0x%08X, 0x%08X\n"
978 " > REG(0x104~0x10C) : 0x%08X, 0x%08X, 0x%08X\n",
979 node->name, itmon_nodestring[node->type],
980 node->phy_regs + tracedata->offset,
981 tracedata->int_info,
982 tracedata->ext_info_0,
983 tracedata->ext_info_1,
984 tracedata->ext_info_2,
985 tracedata->hwa_ctl,
986 tracedata->hwa_info,
987 tracedata->hwa_int_id);
988
989 /* If node is to DREX S_NODE, Outputing timeout freezing result */
990 if (node->type == S_NODE && traceinfo->errcode == ERRCODE_TMOUT)
991 itmon_report_timeout(itmon, node, trans_type);
992 }
993
994 static void itmon_route_tracedata(struct itmon_dev *itmon)
995 {
996 struct itmon_platdata *pdata = itmon->pdata;
997 struct itmon_traceinfo *traceinfo;
998 struct itmon_nodeinfo *node, *next_node;
999 unsigned int trans_type;
1000 int i;
1001
1002 /* To call function is sorted by declaration */
1003 for (trans_type = 0; trans_type < TRANS_TYPE_NUM; trans_type++) {
1004 for (i = M_NODE; i < NODE_TYPE; i++) {
1005 list_for_each_entry(node, &pdata->tracelist[trans_type], list) {
1006 if (i == node->type)
1007 itmon_report_tracedata(itmon, node, trans_type);
1008 }
1009 }
1010 /* If there is no S_NODE information, check one more */
1011 traceinfo = &pdata->traceinfo[trans_type];
1012 if (!traceinfo->snode_dirty)
1013 itmon_report_traceinfo(itmon, NULL, trans_type);
1014 }
1015
1016 if (pdata->traceinfo[TRANS_TYPE_READ].dirty ||
1017 pdata->traceinfo[TRANS_TYPE_WRITE].dirty)
1018 pr_info(" Raw Register Information(ITMON Internal Information)\n\n");
1019
1020 for (trans_type = 0; trans_type < TRANS_TYPE_NUM; trans_type++) {
1021 for (i = M_NODE; i < NODE_TYPE; i++) {
1022 list_for_each_entry_safe(node, next_node, &pdata->tracelist[trans_type], list) {
1023 if (i == node->type) {
1024 itmon_report_rawdata(itmon, node, trans_type);
1025 /* clean up */
1026 list_del(&node->list);
1027 kfree(node);
1028 }
1029 }
1030 }
1031 }
1032
1033 if (pdata->traceinfo[TRANS_TYPE_READ].dirty ||
1034 pdata->traceinfo[TRANS_TYPE_WRITE].dirty)
1035 pr_info("--------------------------------------------------------------------------\n");
1036
1037 for (trans_type = 0; trans_type < TRANS_TYPE_NUM; trans_type++) {
1038 itmon_post_handler_to_notifier(itmon, trans_type);
1039 itmon_post_handler_by_master(itmon, trans_type);
1040 }
1041 }
1042
1043 static void itmon_trace_data(struct itmon_dev *itmon,
1044 struct itmon_nodegroup *group,
1045 struct itmon_nodeinfo *node,
1046 unsigned int offset)
1047 {
1048 struct itmon_platdata *pdata = itmon->pdata;
1049 struct itmon_nodeinfo *new_node = NULL;
1050 unsigned int int_info, info0, info1, info2;
1051 unsigned int hwa_ctl, hwa_info, hwa_int_id;
1052 bool read = TRANS_TYPE_WRITE;
1053 bool req = false;
1054
1055 int_info = __raw_readl(node->regs + offset + REG_INT_INFO);
1056 info0 = __raw_readl(node->regs + offset + REG_EXT_INFO_0);
1057 info1 = __raw_readl(node->regs + offset + REG_EXT_INFO_1);
1058 info2 = __raw_readl(node->regs + offset + REG_EXT_INFO_2);
1059
1060 hwa_ctl = __raw_readl(node->regs + OFFSET_HW_ASSERT + REG_HWA_CTL);
1061 hwa_info = __raw_readl(node->regs + OFFSET_HW_ASSERT + REG_HWA_INT);
1062 hwa_int_id = __raw_readl(node->regs + OFFSET_HW_ASSERT + REG_HWA_INT_ID);
1063
1064 switch (offset) {
1065 case OFFSET_REQ_R:
1066 read = TRANS_TYPE_READ;
1067 /* fall down */
1068 case OFFSET_REQ_W:
1069 req = true;
1070 /* Only S-Node is able to make log to registers */
1071 break;
1072 case OFFSET_RESP_R:
1073 read = TRANS_TYPE_READ;
1074 /* fall down */
1075 case OFFSET_RESP_W:
1076 req = false;
1077 /* Only NOT S-Node is able to make log to registers */
1078 break;
1079 default:
1080 pr_info("Unknown Error - node:%s offset:%u\n", node->name, offset);
1081 break;
1082 }
1083
1084 new_node = kmalloc(sizeof(struct itmon_nodeinfo), GFP_ATOMIC);
1085 if (new_node) {
1086 /* Fill detected node information to tracedata's list */
1087 memcpy(new_node, node, sizeof(struct itmon_nodeinfo));
1088 new_node->tracedata.int_info = int_info;
1089 new_node->tracedata.ext_info_0 = info0;
1090 new_node->tracedata.ext_info_1 = info1;
1091 new_node->tracedata.ext_info_2 = info2;
1092 new_node->tracedata.hwa_ctl = hwa_ctl;
1093 new_node->tracedata.hwa_info = hwa_info;
1094 new_node->tracedata.hwa_int_id = hwa_int_id;
1095
1096 new_node->tracedata.offset = offset;
1097 new_node->tracedata.read = read;
1098 new_node->group = group;
1099 if (BIT_ERR_VALID(int_info))
1100 node->tracedata.logging = true;
1101 else
1102 node->tracedata.logging = false;
1103
1104 list_add(&new_node->list, &pdata->tracelist[read]);
1105 } else {
1106 pr_info("failed to kmalloc for %s node %x offset\n",
1107 node->name, offset);
1108 }
1109 }
1110
1111 static int itmon_search_node(struct itmon_dev *itmon, struct itmon_nodegroup *group, bool clear)
1112 {
1113 struct itmon_platdata *pdata = itmon->pdata;
1114 struct itmon_nodeinfo *node = NULL;
1115 unsigned int val, offset;
1116 unsigned long vec, flags, bit = 0;
1117 int i, j, ret = 0;
1118
1119 spin_lock_irqsave(&itmon->ctrl_lock, flags);
1120 memset(pdata->traceinfo, 0, sizeof(struct itmon_traceinfo) * 2);
1121 if (group) {
1122 /* Processing only this group and select detected node */
1123 vec = (unsigned long)__raw_readl(group->regs);
1124 node = group->nodeinfo;
1125 if (!vec)
1126 goto exit;
1127
1128 for_each_set_bit(bit, &vec, group->nodesize) {
1129 /* exist array */
1130 for (i = 0; i < OFFSET_NUM; i++) {
1131 offset = i * OFFSET_ERR_REPT;
1132 /* Check Request information */
1133 val = __raw_readl(node[bit].regs + offset + REG_INT_INFO);
1134 if (BIT_ERR_OCCURRED(val)) {
1135 /* This node occurs the error */
1136 itmon_trace_data(itmon, group, &node[bit], offset);
1137 if (clear)
1138 __raw_writel(1, node[bit].regs
1139 + offset + REG_INT_CLR);
1140 ret = true;
1141 }
1142 }
1143 /* Check H/W assertion */
1144 if (node[bit].hw_assert_enabled) {
1145 val = __raw_readl(node[bit].regs + OFFSET_HW_ASSERT +
1146 REG_HWA_INT);
1147 if (BIT_HWA_ERR_OCCURRED(val)) {
1148 itmon_report_hwa_rawdata(itmon, &node[bit]);
1149 /* Go panic now */
1150 pdata->err_cnt = PANIC_ALLOWED_THRESHOLD + 1;
1151 ret = true;
1152 }
1153 }
1154 }
1155 } else {
1156 /* Processing all group & nodes */
1157 for (i = 0; i < ARRAY_SIZE(nodegroup); i++) {
1158 group = &nodegroup[i];
1159 if (group->phy_regs)
1160 vec = (unsigned long)__raw_readl(group->regs);
1161 else
1162 vec = GENMASK(group->nodesize, 0);
1163
1164 node = group->nodeinfo;
1165 bit = 0;
1166
1167 for_each_set_bit(bit, &vec, group->nodesize) {
1168 for (j = 0; j < OFFSET_NUM; j++) {
1169 offset = j * OFFSET_ERR_REPT;
1170 /* Check Request information */
1171 val = __raw_readl(node[bit].regs + offset + REG_INT_INFO);
1172 if (BIT_ERR_OCCURRED(val)) {
1173 /* This node occurs the error */
1174 itmon_trace_data(itmon, group, &node[bit], offset);
1175 if (clear)
1176 __raw_writel(1, node[bit].regs
1177 + offset + REG_INT_CLR);
1178 ret = true;
1179 }
1180 }
1181 /* Check H/W assertion */
1182 if (node[bit].hw_assert_enabled) {
1183 val = __raw_readl(node[bit].regs + OFFSET_HW_ASSERT +
1184 REG_HWA_INT);
1185 if (BIT_HWA_ERR_OCCURRED(val)) {
1186 itmon_report_hwa_rawdata(itmon, &node[bit]);
1187 /* Go panic now */
1188 pdata->err_cnt = PANIC_ALLOWED_THRESHOLD + 1;
1189 ret = true;
1190 }
1191 }
1192 }
1193 }
1194 }
1195 itmon_route_tracedata(itmon);
1196 exit:
1197 spin_unlock_irqrestore(&itmon->ctrl_lock, flags);
1198 return ret;
1199 }
1200
1201 static irqreturn_t itmon_irq_handler(int irq, void *data)
1202 {
1203 struct itmon_dev *itmon = (struct itmon_dev *)data;
1204 struct itmon_platdata *pdata = itmon->pdata;
1205 struct itmon_nodegroup *group = NULL;
1206 bool ret;
1207 int i;
1208
1209 /* Search itmon group */
1210 for (i = 0; i < ARRAY_SIZE(nodegroup); i++) {
1211 if (irq == nodegroup[i].irq) {
1212 group = &pdata->nodegroup[i];
1213 if (group->phy_regs != 0) {
1214 pr_info("\nITMON Detected: %d irq, %s group, 0x%x vec, err_cnt:%u\n",
1215 irq, group->name, __raw_readl(group->regs), pdata->err_cnt);
1216 } else {
1217 pr_info("\nITMON Detected: %d irq, %s group, err_cnt:%u\n",
1218 irq, group->name, pdata->err_cnt);
1219 }
1220 break;
1221 }
1222 }
1223
1224 ret = itmon_search_node(itmon, NULL, true);
1225 if (!ret) {
1226 pr_info("ITMON could not detect any error\n");
1227 } else {
1228 if (pdata->sysfs_scandump) {
1229 itmon_switch_scandump();
1230 wfi();
1231 }
1232 if (pdata->err_cnt++ > PANIC_ALLOWED_THRESHOLD)
1233 pdata->panic_allowed = true;
1234 }
1235
1236 if (pdata->panic_allowed)
1237 panic("ITMON occurs panic, Transaction is invalid from IPs");
1238
1239 return IRQ_HANDLED;
1240 }
1241
1242 void itmon_notifier_chain_register(struct notifier_block *block)
1243 {
1244 atomic_notifier_chain_register(&itmon_notifier_list, block);
1245 }
1246
1247 static struct bus_type itmon_subsys = {
1248 .name = "itmon",
1249 .dev_name = "itmon",
1250 };
1251
1252 static ssize_t itmon_timeout_fix_val_show(struct device *dev,
1253 struct device_attribute *attr, char *buf)
1254 {
1255 ssize_t n = 0;
1256 struct itmon_platdata *pdata = g_itmon->pdata;
1257
1258 n = scnprintf(buf + n, 24, "set timeout val: 0x%x\n", pdata->sysfs_tmout_val);
1259
1260 return n;
1261 }
1262
1263 static ssize_t itmon_timeout_fix_val_store(struct device *dev,
1264 struct device_attribute *attr, const char *buf, size_t count)
1265 {
1266 unsigned long val = simple_strtoul(buf, NULL, 0);
1267 struct itmon_platdata *pdata = g_itmon->pdata;
1268
1269 if (val > 0 && val <= 0xFFFFF)
1270 pdata->sysfs_tmout_val = val;
1271
1272 return count;
1273 }
1274
1275 static ssize_t itmon_scandump_show(struct device *dev,
1276 struct device_attribute *attr, char *buf)
1277 {
1278 ssize_t n = 0;
1279 struct itmon_platdata *pdata = g_itmon->pdata;
1280
1281 n = scnprintf(buf + n, 30, "scandump mode is %sable : %d\n",
1282 pdata->sysfs_scandump == 1 ? "en" : "dis",
1283 pdata->sysfs_scandump);
1284
1285 return n;
1286 }
1287
1288 static ssize_t itmon_scandump_store(struct device *dev,
1289 struct device_attribute *attr, const char *buf, size_t count)
1290 {
1291 unsigned long val = simple_strtoul(buf, NULL, 0);
1292 struct itmon_platdata *pdata = g_itmon->pdata;
1293
1294 if (val > 0 && val <= 0xFFFFF) {
1295 pdata = g_itmon->pdata;
1296 pdata->sysfs_scandump = val;
1297 }
1298
1299 return count;
1300 }
1301
1302 static ssize_t itmon_timeout_show(struct device *dev,
1303 struct device_attribute *attr, char *buf)
1304 {
1305 unsigned long i, offset;
1306 ssize_t n = 0;
1307 unsigned long vec, bit = 0;
1308 struct itmon_nodegroup *group = NULL;
1309 struct itmon_nodeinfo *node;
1310
1311 /* Processing all group & nodes */
1312 offset = OFFSET_TMOUT_REG;
1313 for (i = 0; i < ARRAY_SIZE(nodegroup); i++) {
1314 group = &nodegroup[i];
1315 node = group->nodeinfo;
1316 vec = GENMASK(group->nodesize, 0);
1317 bit = 0;
1318 for_each_set_bit(bit, &vec, group->nodesize) {
1319 if (node[bit].type == S_NODE) {
1320 n += scnprintf(buf + n, 60, "%-12s : 0x%08X, timeout : %x\n",
1321 node[bit].name, node[bit].phy_regs,
1322 __raw_readl(node[bit].regs + offset + REG_DBG_CTL));
1323 }
1324 }
1325 }
1326 return n;
1327 }
1328
1329 static ssize_t itmon_timeout_val_show(struct device *dev,
1330 struct device_attribute *attr, char *buf)
1331 {
1332 unsigned long i, offset;
1333 ssize_t n = 0;
1334 unsigned long vec, bit = 0;
1335 struct itmon_nodegroup *group = NULL;
1336 struct itmon_nodeinfo *node;
1337
1338 /* Processing all group & nodes */
1339 offset = OFFSET_TMOUT_REG;
1340 for (i = 0; i < ARRAY_SIZE(nodegroup); i++) {
1341 group = &nodegroup[i];
1342 node = group->nodeinfo;
1343 vec = GENMASK(group->nodesize, 0);
1344 bit = 0;
1345 for_each_set_bit(bit, &vec, group->nodesize) {
1346 if (node[bit].type == S_NODE) {
1347 n += scnprintf(buf + n, 60, "%-12s : 0x%08X, timeout : 0x%x\n",
1348 node[bit].name, node[bit].phy_regs,
1349 __raw_readl(node[bit].regs + offset + REG_TMOUT_INIT_VAL));
1350 }
1351 }
1352 }
1353 return n;
1354 }
1355
1356 static ssize_t itmon_timeout_freeze_show(struct device *dev,
1357 struct device_attribute *attr, char *buf)
1358 {
1359 unsigned long i, offset;
1360 ssize_t n = 0;
1361 unsigned long vec, bit = 0;
1362 struct itmon_nodegroup *group = NULL;
1363 struct itmon_nodeinfo *node;
1364
1365 /* Processing all group & nodes */
1366 offset = OFFSET_TMOUT_REG;
1367 for (i = 0; i < ARRAY_SIZE(nodegroup); i++) {
1368 group = &nodegroup[i];
1369 node = group->nodeinfo;
1370 vec = GENMASK(group->nodesize, 0);
1371 bit = 0;
1372 for_each_set_bit(bit, &vec, group->nodesize) {
1373 if (node[bit].type == S_NODE) {
1374 n += scnprintf(buf + n, 60, "%-12s : 0x%08X, timeout_freeze : %x\n",
1375 node[bit].name, node[bit].phy_regs,
1376 __raw_readl(node[bit].regs + offset + REG_TMOUT_FRZ_EN));
1377 }
1378 }
1379 }
1380 return n;
1381 }
1382
1383 static ssize_t itmon_timeout_store(struct device *dev,
1384 struct device_attribute *attr,
1385 const char *buf, size_t count)
1386 {
1387 char *name;
1388 unsigned int val, offset, i;
1389 unsigned long vec, bit = 0;
1390 struct itmon_nodegroup *group = NULL;
1391 struct itmon_nodeinfo *node;
1392
1393 name = (char *)kstrndup(buf, count, GFP_KERNEL);
1394 if (!name)
1395 return count;
1396
1397 name[count - 1] = '\0';
1398 offset = OFFSET_TMOUT_REG;
1399 for (i = 0; i < ARRAY_SIZE(nodegroup); i++) {
1400 group = &nodegroup[i];
1401 node = group->nodeinfo;
1402 vec = GENMASK(group->nodesize, 0);
1403 bit = 0;
1404 for_each_set_bit(bit, &vec, group->nodesize) {
1405 if (node[bit].type == S_NODE &&
1406 !strncmp(name, node[bit].name, strlen(name))) {
1407 val = __raw_readl(node[bit].regs + offset + REG_DBG_CTL);
1408 if (!val)
1409 val = 1;
1410 else
1411 val = 0;
1412 __raw_writel(val, node[bit].regs + offset + REG_DBG_CTL);
1413 node[bit].tmout_enabled = val;
1414 }
1415 }
1416 }
1417 kfree(name);
1418 return count;
1419 }
1420
1421 static ssize_t itmon_timeout_val_store(struct device *dev,
1422 struct device_attribute *attr,
1423 const char *buf, size_t count)
1424 {
1425 char *name;
1426 unsigned int offset, i;
1427 unsigned long vec, bit = 0;
1428 struct itmon_nodegroup *group = NULL;
1429 struct itmon_nodeinfo *node;
1430 struct itmon_platdata *pdata = g_itmon->pdata;
1431
1432 name = (char *)kstrndup(buf, count, GFP_KERNEL);
1433 if (!name)
1434 return count;
1435
1436 name[count - 1] = '\0';
1437 offset = OFFSET_TMOUT_REG;
1438 for (i = 0; i < ARRAY_SIZE(nodegroup); i++) {
1439 group = &nodegroup[i];
1440 node = group->nodeinfo;
1441 vec = GENMASK(group->nodesize, 0);
1442 bit = 0;
1443 for_each_set_bit(bit, &vec, group->nodesize) {
1444 if (node[bit].type == S_NODE &&
1445 !strncmp(name, node[bit].name, strlen(name))) {
1446 __raw_writel(pdata->sysfs_tmout_val,
1447 node[bit].regs + offset + REG_TMOUT_INIT_VAL);
1448 node[bit].time_val = pdata->sysfs_tmout_val;
1449 }
1450 }
1451 }
1452 kfree(name);
1453 return count;
1454 }
1455
1456 static ssize_t itmon_timeout_freeze_store(struct device *dev,
1457 struct device_attribute *attr,
1458 const char *buf, size_t count)
1459 {
1460 char *name;
1461 unsigned int val, offset, i;
1462 unsigned long vec, bit = 0;
1463 struct itmon_nodegroup *group = NULL;
1464 struct itmon_nodeinfo *node;
1465
1466 name = (char *)kstrndup(buf, count, GFP_KERNEL);
1467 if (!name)
1468 return count;
1469
1470 name[count - 1] = '\0';
1471 offset = OFFSET_TMOUT_REG;
1472 for (i = 0; i < ARRAY_SIZE(nodegroup); i++) {
1473 group = &nodegroup[i];
1474 node = group->nodeinfo;
1475 vec = GENMASK(group->nodesize, 0);
1476 bit = 0;
1477 for_each_set_bit(bit, &vec, group->nodesize) {
1478 if (node[bit].type == S_NODE &&
1479 !strncmp(name, node[bit].name, strlen(name))) {
1480 val = __raw_readl(node[bit].regs + offset + REG_TMOUT_FRZ_EN);
1481 if (!val)
1482 val = 1;
1483 else
1484 val = 0;
1485 __raw_writel(val, node[bit].regs + offset + REG_TMOUT_FRZ_EN);
1486 node[bit].tmout_frz_enabled = val;
1487 }
1488 }
1489 }
1490 kfree(name);
1491 return count;
1492 }
1493
1494 static struct device_attribute itmon_timeout_attr =
1495 __ATTR(timeout_en, 0644, itmon_timeout_show, itmon_timeout_store);
1496 static struct device_attribute itmon_timeout_fix_attr =
1497 __ATTR(set_val, 0644, itmon_timeout_fix_val_show, itmon_timeout_fix_val_store);
1498 static struct device_attribute itmon_scandump_attr =
1499 __ATTR(scandump_en, 0644, itmon_scandump_show, itmon_scandump_store);
1500 static struct device_attribute itmon_timeout_val_attr =
1501 __ATTR(timeout_val, 0644, itmon_timeout_val_show, itmon_timeout_val_store);
1502 static struct device_attribute itmon_timeout_freeze_attr =
1503 __ATTR(timeout_freeze, 0644, itmon_timeout_freeze_show, itmon_timeout_freeze_store);
1504
1505 static struct attribute *itmon_sysfs_attrs[] = {
1506 &itmon_timeout_attr.attr,
1507 &itmon_timeout_fix_attr.attr,
1508 &itmon_timeout_val_attr.attr,
1509 &itmon_timeout_freeze_attr.attr,
1510 &itmon_scandump_attr.attr,
1511 NULL,
1512 };
1513
1514 static struct attribute_group itmon_sysfs_group = {
1515 .attrs = itmon_sysfs_attrs,
1516 };
1517
1518 static const struct attribute_group *itmon_sysfs_groups[] = {
1519 &itmon_sysfs_group,
1520 NULL,
1521 };
1522
1523 static int __init itmon_sysfs_init(void)
1524 {
1525 int ret = 0;
1526
1527 ret = subsys_system_register(&itmon_subsys, itmon_sysfs_groups);
1528 if (ret)
1529 pr_err("fail to register exynos-snapshop subsys\n");
1530
1531 return ret;
1532 }
1533 late_initcall(itmon_sysfs_init);
1534
1535 static int itmon_logging_panic_handler(struct notifier_block *nb,
1536 unsigned long l, void *buf)
1537 {
1538 struct itmon_panic_block *itmon_panic = (struct itmon_panic_block *)nb;
1539 struct itmon_dev *itmon = itmon_panic->pdev;
1540 struct itmon_platdata *pdata = itmon->pdata;
1541 int ret;
1542
1543 if (!IS_ERR_OR_NULL(itmon)) {
1544 /* Check error has been logged */
1545 ret = itmon_search_node(itmon, NULL, false);
1546 if (!ret) {
1547 pr_info("No found error in %s\n", __func__);
1548 } else {
1549 pr_info("Found errors in %s\n", __func__);
1550 if (pdata->sysfs_scandump) {
1551 itmon_switch_scandump();
1552 wfi();
1553 }
1554 }
1555 }
1556 return 0;
1557 }
1558
1559 static int itmon_probe(struct platform_device *pdev)
1560 {
1561 struct itmon_dev *itmon;
1562 struct itmon_panic_block *itmon_panic = NULL;
1563 struct itmon_platdata *pdata;
1564 struct itmon_nodeinfo *node;
1565 unsigned int irq_option = 0, irq;
1566 char *dev_name;
1567 int ret, i, j;
1568
1569 itmon = devm_kzalloc(&pdev->dev, sizeof(struct itmon_dev), GFP_KERNEL);
1570 if (!itmon) {
1571 dev_err(&pdev->dev, "failed to allocate memory for driver's "
1572 "private data\n");
1573 return -ENOMEM;
1574 }
1575 itmon->dev = &pdev->dev;
1576
1577 spin_lock_init(&itmon->ctrl_lock);
1578
1579 pdata = devm_kzalloc(&pdev->dev, sizeof(struct itmon_platdata), GFP_KERNEL);
1580 if (!pdata) {
1581 dev_err(&pdev->dev, "failed to allocate memory for driver's "
1582 "platform data\n");
1583 return -ENOMEM;
1584 }
1585 itmon->pdata = pdata;
1586 itmon->pdata->masterinfo = masterinfo;
1587 itmon->pdata->rpathinfo = rpathinfo;
1588 itmon->pdata->nodegroup = nodegroup;
1589
1590 for (i = 0; i < ARRAY_SIZE(nodegroup); i++) {
1591 dev_name = nodegroup[i].name;
1592 node = nodegroup[i].nodeinfo;
1593
1594 if (nodegroup[i].phy_regs) {
1595 nodegroup[i].regs = devm_ioremap_nocache(&pdev->dev,
1596 nodegroup[i].phy_regs, SZ_16K);
1597 if (nodegroup[i].regs == NULL) {
1598 dev_err(&pdev->dev, "failed to claim register region - %s\n",
1599 dev_name);
1600 return -ENOENT;
1601 }
1602 }
1603
1604 if (initial_multi_irq_enable)
1605 irq_option = IRQF_GIC_MULTI_TARGET;
1606
1607 irq = irq_of_parse_and_map(pdev->dev.of_node, i);
1608 nodegroup[i].irq = irq;
1609
1610 ret = devm_request_irq(&pdev->dev, irq,
1611 itmon_irq_handler, irq_option, dev_name, itmon);
1612 if (ret < 0) {
1613 dev_err(&pdev->dev, "failed to request irq - %s\n", dev_name);
1614 return -ENOENT;
1615 } else {
1616 dev_err(&pdev->dev, "success to register request irq%u - %s\n", irq, dev_name);
1617 }
1618
1619 for (j = 0; j < nodegroup[i].nodesize; j++) {
1620 node[j].regs = devm_ioremap_nocache(&pdev->dev, node[j].phy_regs, SZ_16K);
1621 if (node[j].regs == NULL) {
1622 dev_err(&pdev->dev, "failed to claim register region - %s\n",
1623 dev_name);
1624 return -ENOENT;
1625 }
1626 }
1627 }
1628
1629 itmon_panic = devm_kzalloc(&pdev->dev, sizeof(struct itmon_panic_block),
1630 GFP_KERNEL);
1631
1632 if (!itmon_panic) {
1633 dev_err(&pdev->dev, "failed to allocate memory for driver's "
1634 "panic handler data\n");
1635 } else {
1636 itmon_panic->nb_panic_block.notifier_call = itmon_logging_panic_handler;
1637 itmon_panic->pdev = itmon;
1638 atomic_notifier_chain_register(&panic_notifier_list,
1639 &itmon_panic->nb_panic_block);
1640 }
1641
1642 platform_set_drvdata(pdev, itmon);
1643
1644 INIT_LIST_HEAD(&pdata->tracelist[BUS_DATA]);
1645 INIT_LIST_HEAD(&pdata->tracelist[BUS_PERI]);
1646
1647 pdata->crash_in_progress = false;
1648 itmon_init(itmon, true);
1649
1650 g_itmon = itmon;
1651 pdata->probed = true;
1652
1653 dev_info(&pdev->dev, "success to probe Exynos ITMON driver\n");
1654
1655 return 0;
1656 }
1657
1658 static int itmon_remove(struct platform_device *pdev)
1659 {
1660 platform_set_drvdata(pdev, NULL);
1661 return 0;
1662 }
1663
1664 #ifdef CONFIG_PM_SLEEP
1665 static int itmon_suspend(struct device *dev)
1666 {
1667 return 0;
1668 }
1669
1670 static int itmon_resume(struct device *dev)
1671 {
1672 struct platform_device *pdev = to_platform_device(dev);
1673 struct itmon_dev *itmon = platform_get_drvdata(pdev);
1674 struct itmon_platdata *pdata = itmon->pdata;
1675
1676 /* re-enable ITMON if cp-crash progress is not starting */
1677 if (!pdata->crash_in_progress)
1678 itmon_init(itmon, true);
1679
1680 return 0;
1681 }
1682
1683 static SIMPLE_DEV_PM_OPS(itmon_pm_ops, itmon_suspend, itmon_resume);
1684 #define ITMON_PM (itmon_pm_ops)
1685 #else
1686 #define ITM_ONPM NULL
1687 #endif
1688
1689 static struct platform_driver exynos_itmon_driver = {
1690 .probe = itmon_probe,
1691 .remove = itmon_remove,
1692 .driver = {
1693 .name = "exynos-itmon",
1694 .of_match_table = itmon_dt_match,
1695 .pm = &itmon_pm_ops,
1696 },
1697 };
1698
1699 module_platform_driver(exynos_itmon_driver);
1700
1701 MODULE_DESCRIPTION("Samsung Exynos ITMON DRIVER");
1702 MODULE_AUTHOR("Hosung Kim <hosung0.kim@samsung.com");
1703 MODULE_LICENSE("GPL v2");
1704 MODULE_ALIAS("platform:exynos-itmon");