blob: 5bc4f208cc8bf039b950afcbf6cfd018ca41ad9d [file] [log] [blame]
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +05301/*
2 * Intel SOC Telemetry debugfs Driver: Currently supports APL
3 * Copyright (c) 2015, Intel Corporation.
4 * All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * This file provides the debugfs interfaces for telemetry.
16 * /sys/kernel/debug/telemetry/pss_info: Shows Primary Control Sub-Sys Counters
17 * /sys/kernel/debug/telemetry/ioss_info: Shows IO Sub-System Counters
18 * /sys/kernel/debug/telemetry/soc_states: Shows SoC State
19 * /sys/kernel/debug/telemetry/pss_trace_verbosity: Read and Change Tracing
20 * Verbosity via firmware
21 * /sys/kernel/debug/telemetry/ioss_race_verbosity: Write and Change Tracing
22 * Verbosity via firmware
23 */
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +053024#include <linux/debugfs.h>
Rajneesh Bhardwaja5e50222017-10-10 15:35:19 +053025#include <linux/device.h>
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +053026#include <linux/io.h>
Rajneesh Bhardwaja5e50222017-10-10 15:35:19 +053027#include <linux/module.h>
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +053028#include <linux/pci.h>
Rajneesh Bhardwaja5e50222017-10-10 15:35:19 +053029#include <linux/seq_file.h>
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +053030#include <linux/suspend.h>
31
32#include <asm/cpu_device_id.h>
Dave Hansen678dec02016-06-02 17:19:47 -070033#include <asm/intel-family.h>
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +053034#include <asm/intel_pmc_ipc.h>
35#include <asm/intel_punit_ipc.h>
36#include <asm/intel_telemetry.h>
37
38#define DRIVER_NAME "telemetry_soc_debugfs"
39#define DRIVER_VERSION "1.0.0"
40
41/* ApolloLake SoC Event-IDs */
42#define TELEM_APL_PSS_PSTATES_ID 0x2802
43#define TELEM_APL_PSS_IDLE_ID 0x2806
44#define TELEM_APL_PCS_IDLE_BLOCKED_ID 0x2C00
45#define TELEM_APL_PCS_S0IX_BLOCKED_ID 0x2C01
46#define TELEM_APL_PSS_WAKEUP_ID 0x2C02
47#define TELEM_APL_PSS_LTR_BLOCKING_ID 0x2C03
48
49#define TELEM_APL_S0IX_TOTAL_OCC_ID 0x4000
50#define TELEM_APL_S0IX_SHLW_OCC_ID 0x4001
51#define TELEM_APL_S0IX_DEEP_OCC_ID 0x4002
52#define TELEM_APL_S0IX_TOTAL_RES_ID 0x4800
53#define TELEM_APL_S0IX_SHLW_RES_ID 0x4801
54#define TELEM_APL_S0IX_DEEP_RES_ID 0x4802
55#define TELEM_APL_D0IX_ID 0x581A
56#define TELEM_APL_D3_ID 0x5819
57#define TELEM_APL_PG_ID 0x5818
58
59#define TELEM_INFO_SRAMEVTS_MASK 0xFF00
60#define TELEM_INFO_SRAMEVTS_SHIFT 0x8
61#define TELEM_SSRAM_READ_TIMEOUT 10
62
63#define TELEM_MASK_BIT 1
64#define TELEM_MASK_BYTE 0xFF
65#define BYTES_PER_LONG 8
66#define TELEM_APL_MASK_PCS_STATE 0xF
67
68/* Max events in bitmap to check for */
69#define TELEM_PSS_IDLE_EVTS 25
70#define TELEM_PSS_IDLE_BLOCKED_EVTS 20
71#define TELEM_PSS_S0IX_BLOCKED_EVTS 20
72#define TELEM_PSS_S0IX_WAKEUP_EVTS 20
73#define TELEM_PSS_LTR_BLOCKING_EVTS 20
74#define TELEM_IOSS_DX_D0IX_EVTS 25
75#define TELEM_IOSS_PG_EVTS 30
76
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +053077#define TELEM_DEBUGFS_CPU(model, data) \
Yu, Ong Hock08a24512016-06-23 14:59:58 +080078 { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&data}
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +053079
80#define TELEM_CHECK_AND_PARSE_EVTS(EVTID, EVTNUM, BUF, EVTLOG, EVTDAT, MASK) { \
81 if (evtlog[index].telem_evtid == (EVTID)) { \
82 for (idx = 0; idx < (EVTNUM); idx++) \
83 (BUF)[idx] = ((EVTLOG) >> (EVTDAT)[idx].bit_pos) & \
84 (MASK); \
85 continue; \
86 } \
87}
88
89#define TELEM_CHECK_AND_PARSE_CTRS(EVTID, CTR) { \
90 if (evtlog[index].telem_evtid == (EVTID)) { \
91 (CTR) = evtlog[index].telem_evtlog; \
92 continue; \
93 } \
94}
95
96static u8 suspend_prep_ok;
97static u32 suspend_shlw_ctr_temp, suspend_deep_ctr_temp;
98static u64 suspend_shlw_res_temp, suspend_deep_res_temp;
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +053099
100struct telemetry_susp_stats {
101 u32 shlw_swake_ctr;
102 u32 deep_swake_ctr;
103 u64 shlw_swake_res;
104 u64 deep_swake_res;
105 u32 shlw_ctr;
106 u32 deep_ctr;
107 u64 shlw_res;
108 u64 deep_res;
109};
110
111/* Bitmap definitions for default counters in APL */
112struct telem_pss_idle_stateinfo {
113 const char *name;
114 u32 bit_pos;
115};
116
117static struct telem_pss_idle_stateinfo telem_apl_pss_idle_data[] = {
118 {"IA_CORE0_C1E", 0},
119 {"IA_CORE1_C1E", 1},
120 {"IA_CORE2_C1E", 2},
121 {"IA_CORE3_C1E", 3},
122 {"IA_CORE0_C6", 16},
123 {"IA_CORE1_C6", 17},
124 {"IA_CORE2_C6", 18},
125 {"IA_CORE3_C6", 19},
126 {"IA_MODULE0_C7", 32},
127 {"IA_MODULE1_C7", 33},
128 {"GT_RC6", 40},
129 {"IUNIT_PROCESSING_IDLE", 41},
130 {"FAR_MEM_IDLE", 43},
131 {"DISPLAY_IDLE", 44},
132 {"IUNIT_INPUT_SYSTEM_IDLE", 45},
133 {"PCS_STATUS", 60},
134};
135
136struct telem_pcs_blkd_info {
137 const char *name;
138 u32 bit_pos;
139};
140
141static struct telem_pcs_blkd_info telem_apl_pcs_idle_blkd_data[] = {
142 {"COMPUTE", 0},
143 {"MISC", 8},
144 {"MODULE_ACTIONS_PENDING", 16},
145 {"LTR", 24},
146 {"DISPLAY_WAKE", 32},
147 {"ISP_WAKE", 40},
148 {"PSF0_ACTIVE", 48},
149};
150
151static struct telem_pcs_blkd_info telem_apl_pcs_s0ix_blkd_data[] = {
152 {"LTR", 0},
153 {"IRTL", 8},
154 {"WAKE_DEADLINE_PENDING", 16},
155 {"DISPLAY", 24},
156 {"ISP", 32},
157 {"CORE", 40},
158 {"PMC", 48},
159 {"MISC", 56},
160};
161
162struct telem_pss_ltr_info {
163 const char *name;
164 u32 bit_pos;
165};
166
167static struct telem_pss_ltr_info telem_apl_pss_ltr_data[] = {
168 {"CORE_ACTIVE", 0},
169 {"MEM_UP", 8},
170 {"DFX", 16},
171 {"DFX_FORCE_LTR", 24},
172 {"DISPLAY", 32},
173 {"ISP", 40},
174 {"SOUTH", 48},
175};
176
177struct telem_pss_wakeup_info {
178 const char *name;
179 u32 bit_pos;
180};
181
182static struct telem_pss_wakeup_info telem_apl_pss_wakeup[] = {
183 {"IP_IDLE", 0},
184 {"DISPLAY_WAKE", 8},
185 {"VOLTAGE_REG_INT", 16},
186 {"DROWSY_TIMER (HOTPLUG)", 24},
187 {"CORE_WAKE", 32},
188 {"MISC_S0IX", 40},
189 {"MISC_ABORT", 56},
190};
191
192struct telem_ioss_d0ix_stateinfo {
193 const char *name;
194 u32 bit_pos;
195};
196
197static struct telem_ioss_d0ix_stateinfo telem_apl_ioss_d0ix_data[] = {
198 {"CSE", 0},
199 {"SCC2", 1},
200 {"GMM", 2},
201 {"XDCI", 3},
202 {"XHCI", 4},
203 {"ISH", 5},
204 {"AVS", 6},
205 {"PCIE0P1", 7},
206 {"PECI0P0", 8},
207 {"LPSS", 9},
208 {"SCC", 10},
209 {"PWM", 11},
210 {"PCIE1_P3", 12},
211 {"PCIE1_P2", 13},
212 {"PCIE1_P1", 14},
213 {"PCIE1_P0", 15},
214 {"CNV", 16},
215 {"SATA", 17},
216 {"PRTC", 18},
217};
218
219struct telem_ioss_pg_info {
220 const char *name;
221 u32 bit_pos;
222};
223
224static struct telem_ioss_pg_info telem_apl_ioss_pg_data[] = {
225 {"LPSS", 0},
226 {"SCC", 1},
227 {"P2SB", 2},
228 {"SCC2", 3},
229 {"GMM", 4},
230 {"PCIE0", 5},
231 {"XDCI", 6},
232 {"xHCI", 7},
233 {"CSE", 8},
234 {"SPI", 9},
235 {"AVSPGD4", 10},
236 {"AVSPGD3", 11},
237 {"AVSPGD2", 12},
238 {"AVSPGD1", 13},
239 {"ISH", 14},
240 {"EXI", 15},
241 {"NPKVRC", 16},
242 {"NPKVNN", 17},
243 {"CUNIT", 18},
244 {"FUSE_CTRL", 19},
245 {"PCIE1", 20},
246 {"CNV", 21},
247 {"LPC", 22},
248 {"SATA", 23},
249 {"SMB", 24},
250 {"PRTC", 25},
251};
252
253
254struct telemetry_debugfs_conf {
255 struct telemetry_susp_stats suspend_stats;
256 struct dentry *telemetry_dbg_dir;
257
258 /* Bitmap Data */
259 struct telem_ioss_d0ix_stateinfo *ioss_d0ix_data;
260 struct telem_pss_idle_stateinfo *pss_idle_data;
261 struct telem_pcs_blkd_info *pcs_idle_blkd_data;
262 struct telem_pcs_blkd_info *pcs_s0ix_blkd_data;
263 struct telem_pss_wakeup_info *pss_wakeup;
264 struct telem_pss_ltr_info *pss_ltr_data;
265 struct telem_ioss_pg_info *ioss_pg_data;
266 u8 pcs_idle_blkd_evts;
267 u8 pcs_s0ix_blkd_evts;
268 u8 pss_wakeup_evts;
269 u8 pss_idle_evts;
270 u8 pss_ltr_evts;
271 u8 ioss_d0ix_evts;
272 u8 ioss_pg_evts;
273
274 /* IDs */
275 u16 pss_ltr_blocking_id;
276 u16 pcs_idle_blkd_id;
277 u16 pcs_s0ix_blkd_id;
278 u16 s0ix_total_occ_id;
279 u16 s0ix_shlw_occ_id;
280 u16 s0ix_deep_occ_id;
281 u16 s0ix_total_res_id;
282 u16 s0ix_shlw_res_id;
283 u16 s0ix_deep_res_id;
284 u16 pss_wakeup_id;
285 u16 ioss_d0ix_id;
286 u16 pstates_id;
287 u16 pss_idle_id;
288 u16 ioss_d3_id;
289 u16 ioss_pg_id;
290};
291
292static struct telemetry_debugfs_conf *debugfs_conf;
293
294static struct telemetry_debugfs_conf telem_apl_debugfs_conf = {
295 .pss_idle_data = telem_apl_pss_idle_data,
296 .pcs_idle_blkd_data = telem_apl_pcs_idle_blkd_data,
297 .pcs_s0ix_blkd_data = telem_apl_pcs_s0ix_blkd_data,
298 .pss_ltr_data = telem_apl_pss_ltr_data,
299 .pss_wakeup = telem_apl_pss_wakeup,
300 .ioss_d0ix_data = telem_apl_ioss_d0ix_data,
301 .ioss_pg_data = telem_apl_ioss_pg_data,
302
Allen Paisae11c5b2017-09-13 16:29:31 +0530303 .pss_idle_evts = ARRAY_SIZE(telem_apl_pss_idle_data),
304 .pcs_idle_blkd_evts = ARRAY_SIZE(telem_apl_pcs_idle_blkd_data),
305 .pcs_s0ix_blkd_evts = ARRAY_SIZE(telem_apl_pcs_s0ix_blkd_data),
306 .pss_ltr_evts = ARRAY_SIZE(telem_apl_pss_ltr_data),
307 .pss_wakeup_evts = ARRAY_SIZE(telem_apl_pss_wakeup),
308 .ioss_d0ix_evts = ARRAY_SIZE(telem_apl_ioss_d0ix_data),
309 .ioss_pg_evts = ARRAY_SIZE(telem_apl_ioss_pg_data),
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +0530310
311 .pstates_id = TELEM_APL_PSS_PSTATES_ID,
312 .pss_idle_id = TELEM_APL_PSS_IDLE_ID,
313 .pcs_idle_blkd_id = TELEM_APL_PCS_IDLE_BLOCKED_ID,
314 .pcs_s0ix_blkd_id = TELEM_APL_PCS_S0IX_BLOCKED_ID,
315 .pss_wakeup_id = TELEM_APL_PSS_WAKEUP_ID,
316 .pss_ltr_blocking_id = TELEM_APL_PSS_LTR_BLOCKING_ID,
317 .s0ix_total_occ_id = TELEM_APL_S0IX_TOTAL_OCC_ID,
318 .s0ix_shlw_occ_id = TELEM_APL_S0IX_SHLW_OCC_ID,
319 .s0ix_deep_occ_id = TELEM_APL_S0IX_DEEP_OCC_ID,
320 .s0ix_total_res_id = TELEM_APL_S0IX_TOTAL_RES_ID,
321 .s0ix_shlw_res_id = TELEM_APL_S0IX_SHLW_RES_ID,
322 .s0ix_deep_res_id = TELEM_APL_S0IX_DEEP_RES_ID,
323 .ioss_d0ix_id = TELEM_APL_D0IX_ID,
324 .ioss_d3_id = TELEM_APL_D3_ID,
325 .ioss_pg_id = TELEM_APL_PG_ID,
326};
327
328static const struct x86_cpu_id telemetry_debugfs_cpu_ids[] = {
Dave Hansen678dec02016-06-02 17:19:47 -0700329 TELEM_DEBUGFS_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_debugfs_conf),
Rajneesh Bhardwaj54949a62017-07-20 19:51:13 +0530330 TELEM_DEBUGFS_CPU(INTEL_FAM6_ATOM_GEMINI_LAKE, telem_apl_debugfs_conf),
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +0530331 {}
332};
333
334MODULE_DEVICE_TABLE(x86cpu, telemetry_debugfs_cpu_ids);
335
336static int telemetry_debugfs_check_evts(void)
337{
338 if ((debugfs_conf->pss_idle_evts > TELEM_PSS_IDLE_EVTS) ||
339 (debugfs_conf->pcs_idle_blkd_evts > TELEM_PSS_IDLE_BLOCKED_EVTS) ||
340 (debugfs_conf->pcs_s0ix_blkd_evts > TELEM_PSS_S0IX_BLOCKED_EVTS) ||
341 (debugfs_conf->pss_ltr_evts > TELEM_PSS_LTR_BLOCKING_EVTS) ||
342 (debugfs_conf->pss_wakeup_evts > TELEM_PSS_S0IX_WAKEUP_EVTS) ||
343 (debugfs_conf->ioss_d0ix_evts > TELEM_IOSS_DX_D0IX_EVTS) ||
344 (debugfs_conf->ioss_pg_evts > TELEM_IOSS_PG_EVTS))
345 return -EINVAL;
346
347 return 0;
348}
349
350static int telem_pss_states_show(struct seq_file *s, void *unused)
351{
352 struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
353 struct telemetry_debugfs_conf *conf = debugfs_conf;
354 const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
355 u32 pcs_idle_blkd[TELEM_PSS_IDLE_BLOCKED_EVTS],
356 pcs_s0ix_blkd[TELEM_PSS_S0IX_BLOCKED_EVTS],
357 pss_s0ix_wakeup[TELEM_PSS_S0IX_WAKEUP_EVTS],
358 pss_ltr_blkd[TELEM_PSS_LTR_BLOCKING_EVTS],
359 pss_idle[TELEM_PSS_IDLE_EVTS];
360 int index, idx, ret, err = 0;
361 u64 pstates = 0;
362
363 ret = telemetry_read_eventlog(TELEM_PSS, evtlog,
364 TELEM_MAX_OS_ALLOCATED_EVENTS);
365 if (ret < 0)
366 return ret;
367
368 err = telemetry_get_evtname(TELEM_PSS, name,
369 TELEM_MAX_OS_ALLOCATED_EVENTS);
370 if (err < 0)
371 return err;
372
373 seq_puts(s, "\n----------------------------------------------------\n");
374 seq_puts(s, "\tPSS TELEM EVENTLOG (Residency = field/19.2 us\n");
375 seq_puts(s, "----------------------------------------------------\n");
376 for (index = 0; index < ret; index++) {
377 seq_printf(s, "%-32s %llu\n",
378 name[index], evtlog[index].telem_evtlog);
379
380 /* Fetch PSS IDLE State */
381 if (evtlog[index].telem_evtid == conf->pss_idle_id) {
382 pss_idle[conf->pss_idle_evts - 1] =
383 (evtlog[index].telem_evtlog >>
384 conf->pss_idle_data[conf->pss_idle_evts - 1].bit_pos) &
385 TELEM_APL_MASK_PCS_STATE;
386 }
387
388
389 TELEM_CHECK_AND_PARSE_EVTS(conf->pss_idle_id,
390 conf->pss_idle_evts - 1,
391 pss_idle, evtlog[index].telem_evtlog,
392 conf->pss_idle_data, TELEM_MASK_BIT);
393
394 TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_idle_blkd_id,
395 conf->pcs_idle_blkd_evts,
396 pcs_idle_blkd,
397 evtlog[index].telem_evtlog,
398 conf->pcs_idle_blkd_data,
399 TELEM_MASK_BYTE);
400
401 TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_s0ix_blkd_id,
402 conf->pcs_s0ix_blkd_evts,
403 pcs_s0ix_blkd,
404 evtlog[index].telem_evtlog,
405 conf->pcs_s0ix_blkd_data,
406 TELEM_MASK_BYTE);
407
408
409 TELEM_CHECK_AND_PARSE_EVTS(conf->pss_wakeup_id,
410 conf->pss_wakeup_evts,
411 pss_s0ix_wakeup,
412 evtlog[index].telem_evtlog,
413 conf->pss_wakeup, TELEM_MASK_BYTE);
414
415 TELEM_CHECK_AND_PARSE_EVTS(conf->pss_ltr_blocking_id,
416 conf->pss_ltr_evts, pss_ltr_blkd,
417 evtlog[index].telem_evtlog,
418 conf->pss_ltr_data, TELEM_MASK_BYTE);
419
420 if (evtlog[index].telem_evtid == debugfs_conf->pstates_id)
421 pstates = evtlog[index].telem_evtlog;
422 }
423
424 seq_puts(s, "\n--------------------------------------\n");
425 seq_puts(s, "PStates\n");
426 seq_puts(s, "--------------------------------------\n");
427 seq_puts(s, "Domain\t\t\t\tFreq(Mhz)\n");
428 seq_printf(s, " IA\t\t\t\t %llu\n GT\t\t\t\t %llu\n",
429 (pstates & TELEM_MASK_BYTE)*100,
430 ((pstates >> 8) & TELEM_MASK_BYTE)*50/3);
431
432 seq_printf(s, " IUNIT\t\t\t\t %llu\n SA\t\t\t\t %llu\n",
433 ((pstates >> 16) & TELEM_MASK_BYTE)*25,
434 ((pstates >> 24) & TELEM_MASK_BYTE)*50/3);
435
436 seq_puts(s, "\n--------------------------------------\n");
437 seq_puts(s, "PSS IDLE Status\n");
438 seq_puts(s, "--------------------------------------\n");
439 seq_puts(s, "Device\t\t\t\t\tIDLE\n");
440 for (index = 0; index < debugfs_conf->pss_idle_evts; index++) {
441 seq_printf(s, "%-32s\t%u\n",
442 debugfs_conf->pss_idle_data[index].name,
443 pss_idle[index]);
444 }
445
446 seq_puts(s, "\n--------------------------------------\n");
447 seq_puts(s, "PSS Idle blkd Status (~1ms saturating bucket)\n");
448 seq_puts(s, "--------------------------------------\n");
449 seq_puts(s, "Blocker\t\t\t\t\tCount\n");
450 for (index = 0; index < debugfs_conf->pcs_idle_blkd_evts; index++) {
451 seq_printf(s, "%-32s\t%u\n",
452 debugfs_conf->pcs_idle_blkd_data[index].name,
453 pcs_idle_blkd[index]);
454 }
455
456 seq_puts(s, "\n--------------------------------------\n");
457 seq_puts(s, "PSS S0ix blkd Status (~1ms saturating bucket)\n");
458 seq_puts(s, "--------------------------------------\n");
459 seq_puts(s, "Blocker\t\t\t\t\tCount\n");
460 for (index = 0; index < debugfs_conf->pcs_s0ix_blkd_evts; index++) {
461 seq_printf(s, "%-32s\t%u\n",
462 debugfs_conf->pcs_s0ix_blkd_data[index].name,
463 pcs_s0ix_blkd[index]);
464 }
465
466 seq_puts(s, "\n--------------------------------------\n");
467 seq_puts(s, "LTR Blocking Status (~1ms saturating bucket)\n");
468 seq_puts(s, "--------------------------------------\n");
469 seq_puts(s, "Blocker\t\t\t\t\tCount\n");
470 for (index = 0; index < debugfs_conf->pss_ltr_evts; index++) {
471 seq_printf(s, "%-32s\t%u\n",
472 debugfs_conf->pss_ltr_data[index].name,
473 pss_s0ix_wakeup[index]);
474 }
475
476 seq_puts(s, "\n--------------------------------------\n");
477 seq_puts(s, "Wakes Status (~1ms saturating bucket)\n");
478 seq_puts(s, "--------------------------------------\n");
479 seq_puts(s, "Wakes\t\t\t\t\tCount\n");
480 for (index = 0; index < debugfs_conf->pss_wakeup_evts; index++) {
481 seq_printf(s, "%-32s\t%u\n",
482 debugfs_conf->pss_wakeup[index].name,
483 pss_ltr_blkd[index]);
484 }
485
486 return 0;
487}
488
489static int telem_pss_state_open(struct inode *inode, struct file *file)
490{
491 return single_open(file, telem_pss_states_show, inode->i_private);
492}
493
494static const struct file_operations telem_pss_ops = {
495 .open = telem_pss_state_open,
496 .read = seq_read,
497 .llseek = seq_lseek,
498 .release = single_release,
499};
500
501
502static int telem_ioss_states_show(struct seq_file *s, void *unused)
503{
504 struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
505 const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
506 int index, ret, err;
507
508 ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
509 TELEM_MAX_OS_ALLOCATED_EVENTS);
510 if (ret < 0)
511 return ret;
512
513 err = telemetry_get_evtname(TELEM_IOSS, name,
514 TELEM_MAX_OS_ALLOCATED_EVENTS);
515 if (err < 0)
516 return err;
517
518 seq_puts(s, "--------------------------------------\n");
519 seq_puts(s, "\tI0SS TELEMETRY EVENTLOG\n");
520 seq_puts(s, "--------------------------------------\n");
521 for (index = 0; index < ret; index++) {
522 seq_printf(s, "%-32s 0x%llx\n",
523 name[index], evtlog[index].telem_evtlog);
524 }
525
526 return 0;
527}
528
529static int telem_ioss_state_open(struct inode *inode, struct file *file)
530{
531 return single_open(file, telem_ioss_states_show, inode->i_private);
532}
533
534static const struct file_operations telem_ioss_ops = {
535 .open = telem_ioss_state_open,
536 .read = seq_read,
537 .llseek = seq_lseek,
538 .release = single_release,
539};
540
541static int telem_soc_states_show(struct seq_file *s, void *unused)
542{
543 u32 d3_sts[TELEM_IOSS_DX_D0IX_EVTS], d0ix_sts[TELEM_IOSS_DX_D0IX_EVTS];
544 u32 pg_sts[TELEM_IOSS_PG_EVTS], pss_idle[TELEM_PSS_IDLE_EVTS];
545 struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
546 u32 s0ix_total_ctr = 0, s0ix_shlw_ctr = 0, s0ix_deep_ctr = 0;
547 u64 s0ix_total_res = 0, s0ix_shlw_res = 0, s0ix_deep_res = 0;
548 struct telemetry_debugfs_conf *conf = debugfs_conf;
549 struct pci_dev *dev = NULL;
550 int index, idx, ret;
551 u32 d3_state;
552 u16 pmcsr;
553
554 ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
555 TELEM_MAX_OS_ALLOCATED_EVENTS);
556 if (ret < 0)
557 return ret;
558
559 for (index = 0; index < ret; index++) {
560 TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d3_id,
561 conf->ioss_d0ix_evts,
562 d3_sts, evtlog[index].telem_evtlog,
563 conf->ioss_d0ix_data,
564 TELEM_MASK_BIT);
565
566 TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_pg_id, conf->ioss_pg_evts,
567 pg_sts, evtlog[index].telem_evtlog,
568 conf->ioss_pg_data, TELEM_MASK_BIT);
569
570 TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d0ix_id,
571 conf->ioss_d0ix_evts,
572 d0ix_sts, evtlog[index].telem_evtlog,
573 conf->ioss_d0ix_data,
574 TELEM_MASK_BIT);
575
576 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_occ_id,
577 s0ix_total_ctr);
578
579 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
580 s0ix_shlw_ctr);
581
582 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
583 s0ix_deep_ctr);
584
585 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_res_id,
586 s0ix_total_res);
587
588 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
589 s0ix_shlw_res);
590
591 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
592 s0ix_deep_res);
593 }
594
595 seq_puts(s, "\n---------------------------------------------------\n");
596 seq_puts(s, "S0IX Type\t\t\t Occurrence\t\t Residency(us)\n");
597 seq_puts(s, "---------------------------------------------------\n");
598
599 seq_printf(s, "S0IX Shallow\t\t\t %10u\t %10llu\n",
600 s0ix_shlw_ctr -
601 conf->suspend_stats.shlw_ctr -
602 conf->suspend_stats.shlw_swake_ctr,
603 (u64)((s0ix_shlw_res -
604 conf->suspend_stats.shlw_res -
605 conf->suspend_stats.shlw_swake_res)*10/192));
606
607 seq_printf(s, "S0IX Deep\t\t\t %10u\t %10llu\n",
608 s0ix_deep_ctr -
609 conf->suspend_stats.deep_ctr -
610 conf->suspend_stats.deep_swake_ctr,
611 (u64)((s0ix_deep_res -
612 conf->suspend_stats.deep_res -
613 conf->suspend_stats.deep_swake_res)*10/192));
614
615 seq_printf(s, "Suspend(With S0ixShallow)\t %10u\t %10llu\n",
616 conf->suspend_stats.shlw_ctr,
617 (u64)(conf->suspend_stats.shlw_res*10)/192);
618
619 seq_printf(s, "Suspend(With S0ixDeep)\t\t %10u\t %10llu\n",
620 conf->suspend_stats.deep_ctr,
621 (u64)(conf->suspend_stats.deep_res*10)/192);
622
623 seq_printf(s, "Suspend(With Shallow-Wakes)\t %10u\t %10llu\n",
624 conf->suspend_stats.shlw_swake_ctr +
625 conf->suspend_stats.deep_swake_ctr,
626 (u64)((conf->suspend_stats.shlw_swake_res +
627 conf->suspend_stats.deep_swake_res)*10/192));
628
629 seq_printf(s, "S0IX+Suspend Total\t\t %10u\t %10llu\n", s0ix_total_ctr,
630 (u64)(s0ix_total_res*10/192));
631 seq_puts(s, "\n-------------------------------------------------\n");
632 seq_puts(s, "\t\tDEVICE STATES\n");
633 seq_puts(s, "-------------------------------------------------\n");
634
635 for_each_pci_dev(dev) {
636 pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
637 d3_state = ((pmcsr & PCI_PM_CTRL_STATE_MASK) ==
638 (__force int)PCI_D3hot) ? 1 : 0;
639
640 seq_printf(s, "pci %04x %04X %s %20.20s: ",
641 dev->vendor, dev->device, dev_name(&dev->dev),
642 dev_driver_string(&dev->dev));
643 seq_printf(s, " d3:%x\n", d3_state);
644 }
645
646 seq_puts(s, "\n--------------------------------------\n");
647 seq_puts(s, "D3/D0i3 Status\n");
648 seq_puts(s, "--------------------------------------\n");
649 seq_puts(s, "Block\t\t D3\t D0i3\n");
650 for (index = 0; index < conf->ioss_d0ix_evts; index++) {
651 seq_printf(s, "%-10s\t %u\t %u\n",
652 conf->ioss_d0ix_data[index].name,
653 d3_sts[index], d0ix_sts[index]);
654 }
655
656 seq_puts(s, "\n--------------------------------------\n");
657 seq_puts(s, "South Complex PowerGate Status\n");
658 seq_puts(s, "--------------------------------------\n");
659 seq_puts(s, "Device\t\t PG\n");
660 for (index = 0; index < conf->ioss_pg_evts; index++) {
661 seq_printf(s, "%-10s\t %u\n",
662 conf->ioss_pg_data[index].name,
663 pg_sts[index]);
664 }
665
666 evtlog->telem_evtid = conf->pss_idle_id;
667 ret = telemetry_read_events(TELEM_PSS, evtlog, 1);
668 if (ret < 0)
669 return ret;
670
671 seq_puts(s, "\n-----------------------------------------\n");
672 seq_puts(s, "North Idle Status\n");
673 seq_puts(s, "-----------------------------------------\n");
674 for (idx = 0; idx < conf->pss_idle_evts - 1; idx++) {
675 pss_idle[idx] = (evtlog->telem_evtlog >>
676 conf->pss_idle_data[idx].bit_pos) &
677 TELEM_MASK_BIT;
678 }
679
680 pss_idle[idx] = (evtlog->telem_evtlog >>
681 conf->pss_idle_data[idx].bit_pos) &
682 TELEM_APL_MASK_PCS_STATE;
683
684 for (index = 0; index < conf->pss_idle_evts; index++) {
685 seq_printf(s, "%-30s %u\n",
686 conf->pss_idle_data[index].name,
687 pss_idle[index]);
688 }
689
690 seq_puts(s, "\nPCS_STATUS Code\n");
691 seq_puts(s, "0:C0 1:C1 2:C1_DN_WT_DEV 3:C2 4:C2_WT_DE_MEM_UP\n");
692 seq_puts(s, "5:C2_WT_DE_MEM_DOWN 6:C2_UP_WT_DEV 7:C2_DN 8:C2_VOA\n");
693 seq_puts(s, "9:C2_VOA_UP 10:S0IX_PRE 11:S0IX\n");
694
695 return 0;
696}
697
698static int telem_soc_state_open(struct inode *inode, struct file *file)
699{
700 return single_open(file, telem_soc_states_show, inode->i_private);
701}
702
703static const struct file_operations telem_socstate_ops = {
704 .open = telem_soc_state_open,
705 .read = seq_read,
706 .llseek = seq_lseek,
707 .release = single_release,
708};
709
Rajneesh Bhardwajbc8c47a2017-06-23 22:22:35 +0530710static int telem_s0ix_res_get(void *data, u64 *val)
711{
712 u64 s0ix_total_res;
713 int ret;
714
715 ret = intel_pmc_s0ix_counter_read(&s0ix_total_res);
716 if (ret) {
717 pr_err("Failed to read S0ix residency");
718 return ret;
719 }
720
721 *val = s0ix_total_res;
722
723 return 0;
724}
725
726DEFINE_DEBUGFS_ATTRIBUTE(telem_s0ix_fops, telem_s0ix_res_get, NULL, "%llu\n");
727
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +0530728static int telem_pss_trc_verb_show(struct seq_file *s, void *unused)
729{
730 u32 verbosity;
731 int err;
732
733 err = telemetry_get_trace_verbosity(TELEM_PSS, &verbosity);
734 if (err) {
735 pr_err("Get PSS Trace Verbosity Failed with Error %d\n", err);
736 return -EFAULT;
737 }
738
739 seq_printf(s, "PSS Trace Verbosity %u\n", verbosity);
740 return 0;
741}
742
743static ssize_t telem_pss_trc_verb_write(struct file *file,
744 const char __user *userbuf,
745 size_t count, loff_t *ppos)
746{
747 u32 verbosity;
748 int err;
749
750 if (kstrtou32_from_user(userbuf, count, 0, &verbosity))
751 return -EFAULT;
752
753 err = telemetry_set_trace_verbosity(TELEM_PSS, verbosity);
754 if (err) {
755 pr_err("Changing PSS Trace Verbosity Failed. Error %d\n", err);
756 count = err;
757 }
758
759 return count;
760}
761
762static int telem_pss_trc_verb_open(struct inode *inode, struct file *file)
763{
764 return single_open(file, telem_pss_trc_verb_show, inode->i_private);
765}
766
767static const struct file_operations telem_pss_trc_verb_ops = {
768 .open = telem_pss_trc_verb_open,
769 .read = seq_read,
770 .write = telem_pss_trc_verb_write,
771 .llseek = seq_lseek,
772 .release = single_release,
773};
774
775
776static int telem_ioss_trc_verb_show(struct seq_file *s, void *unused)
777{
778 u32 verbosity;
779 int err;
780
781 err = telemetry_get_trace_verbosity(TELEM_IOSS, &verbosity);
782 if (err) {
783 pr_err("Get IOSS Trace Verbosity Failed with Error %d\n", err);
784 return -EFAULT;
785 }
786
787 seq_printf(s, "IOSS Trace Verbosity %u\n", verbosity);
788 return 0;
789}
790
791static ssize_t telem_ioss_trc_verb_write(struct file *file,
792 const char __user *userbuf,
793 size_t count, loff_t *ppos)
794{
795 u32 verbosity;
796 int err;
797
798 if (kstrtou32_from_user(userbuf, count, 0, &verbosity))
799 return -EFAULT;
800
801 err = telemetry_set_trace_verbosity(TELEM_IOSS, verbosity);
802 if (err) {
803 pr_err("Changing IOSS Trace Verbosity Failed. Error %d\n", err);
804 count = err;
805 }
806
807 return count;
808}
809
810static int telem_ioss_trc_verb_open(struct inode *inode, struct file *file)
811{
812 return single_open(file, telem_ioss_trc_verb_show, inode->i_private);
813}
814
815static const struct file_operations telem_ioss_trc_verb_ops = {
816 .open = telem_ioss_trc_verb_open,
817 .read = seq_read,
818 .write = telem_ioss_trc_verb_write,
819 .llseek = seq_lseek,
820 .release = single_release,
821};
822
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +0530823static int pm_suspend_prep_cb(void)
824{
825 struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
826 struct telemetry_debugfs_conf *conf = debugfs_conf;
827 int ret, index;
828
829 ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
830 TELEM_MAX_OS_ALLOCATED_EVENTS);
831 if (ret < 0) {
832 suspend_prep_ok = 0;
833 goto out;
834 }
835
836 for (index = 0; index < ret; index++) {
837
838 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
839 suspend_shlw_ctr_temp);
840
841 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
842 suspend_deep_ctr_temp);
843
844 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
845 suspend_shlw_res_temp);
846
847 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
848 suspend_deep_res_temp);
849 }
850 suspend_prep_ok = 1;
851out:
852 return NOTIFY_OK;
853}
854
855static int pm_suspend_exit_cb(void)
856{
857 struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
858 static u32 suspend_shlw_ctr_exit, suspend_deep_ctr_exit;
859 static u64 suspend_shlw_res_exit, suspend_deep_res_exit;
860 struct telemetry_debugfs_conf *conf = debugfs_conf;
861 int ret, index;
862
863 if (!suspend_prep_ok)
864 goto out;
865
866 ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
867 TELEM_MAX_OS_ALLOCATED_EVENTS);
868 if (ret < 0)
869 goto out;
870
871 for (index = 0; index < ret; index++) {
872 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
873 suspend_shlw_ctr_exit);
874
875 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
876 suspend_deep_ctr_exit);
877
878 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
879 suspend_shlw_res_exit);
880
881 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
882 suspend_deep_res_exit);
883 }
884
885 if ((suspend_shlw_ctr_exit < suspend_shlw_ctr_temp) ||
886 (suspend_deep_ctr_exit < suspend_deep_ctr_temp) ||
887 (suspend_shlw_res_exit < suspend_shlw_res_temp) ||
888 (suspend_deep_res_exit < suspend_deep_res_temp)) {
889 pr_err("Wrong s0ix counters detected\n");
890 goto out;
891 }
892
Chakravarty, Souvik K0946a052017-11-24 19:04:42 +0530893 /*
894 * Due to some design limitations in the firmware, sometimes the
895 * counters do not get updated by the time we reach here. As a
896 * workaround, we try to see if this was a genuine case of sleep
897 * failure or not by cross-checking from PMC GCR registers directly.
898 */
899 if (suspend_shlw_ctr_exit == suspend_shlw_ctr_temp &&
900 suspend_deep_ctr_exit == suspend_deep_ctr_temp) {
901 ret = intel_pmc_gcr_read64(PMC_GCR_TELEM_SHLW_S0IX_REG,
902 &suspend_shlw_res_exit);
903 if (ret < 0)
904 goto out;
905
906 ret = intel_pmc_gcr_read64(PMC_GCR_TELEM_DEEP_S0IX_REG,
907 &suspend_deep_res_exit);
908 if (ret < 0)
909 goto out;
910
911 if (suspend_shlw_res_exit > suspend_shlw_res_temp)
912 suspend_shlw_ctr_exit++;
913
914 if (suspend_deep_res_exit > suspend_deep_res_temp)
915 suspend_deep_ctr_exit++;
916 }
917
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +0530918 suspend_shlw_ctr_exit -= suspend_shlw_ctr_temp;
919 suspend_deep_ctr_exit -= suspend_deep_ctr_temp;
920 suspend_shlw_res_exit -= suspend_shlw_res_temp;
921 suspend_deep_res_exit -= suspend_deep_res_temp;
922
923 if (suspend_shlw_ctr_exit == 1) {
924 conf->suspend_stats.shlw_ctr +=
925 suspend_shlw_ctr_exit;
926
927 conf->suspend_stats.shlw_res +=
928 suspend_shlw_res_exit;
929 }
930 /* Shallow Wakes Case */
931 else if (suspend_shlw_ctr_exit > 1) {
932 conf->suspend_stats.shlw_swake_ctr +=
933 suspend_shlw_ctr_exit;
934
935 conf->suspend_stats.shlw_swake_res +=
936 suspend_shlw_res_exit;
937 }
938
939 if (suspend_deep_ctr_exit == 1) {
940 conf->suspend_stats.deep_ctr +=
941 suspend_deep_ctr_exit;
942
943 conf->suspend_stats.deep_res +=
944 suspend_deep_res_exit;
945 }
946
947 /* Shallow Wakes Case */
948 else if (suspend_deep_ctr_exit > 1) {
949 conf->suspend_stats.deep_swake_ctr +=
950 suspend_deep_ctr_exit;
951
952 conf->suspend_stats.deep_swake_res +=
953 suspend_deep_res_exit;
954 }
955
956out:
957 suspend_prep_ok = 0;
958 return NOTIFY_OK;
959}
960
961static int pm_notification(struct notifier_block *this,
962 unsigned long event, void *ptr)
963{
964 switch (event) {
965 case PM_SUSPEND_PREPARE:
966 return pm_suspend_prep_cb();
967 case PM_POST_SUSPEND:
968 return pm_suspend_exit_cb();
969 }
970
971 return NOTIFY_DONE;
972}
973
974static struct notifier_block pm_notifier = {
975 .notifier_call = pm_notification,
976};
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +0530977
978static int __init telemetry_debugfs_init(void)
979{
980 const struct x86_cpu_id *id;
Dan Carpenter7a3a51a2017-06-30 10:52:18 +0300981 int err;
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +0530982 struct dentry *f;
983
984 /* Only APL supported for now */
985 id = x86_match_cpu(telemetry_debugfs_cpu_ids);
986 if (!id)
987 return -ENODEV;
988
989 debugfs_conf = (struct telemetry_debugfs_conf *)id->driver_data;
990
991 err = telemetry_pltconfig_valid();
992 if (err < 0)
993 return -ENODEV;
994
995 err = telemetry_debugfs_check_evts();
996 if (err < 0)
997 return -EINVAL;
998
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +0530999 register_pm_notifier(&pm_notifier);
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +05301000
Dan Carpenter7a3a51a2017-06-30 10:52:18 +03001001 err = -ENOMEM;
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +05301002 debugfs_conf->telemetry_dbg_dir = debugfs_create_dir("telemetry", NULL);
Dan Carpenter7a3a51a2017-06-30 10:52:18 +03001003 if (!debugfs_conf->telemetry_dbg_dir)
Priyalee Kushwaha74a1eb52017-06-03 10:21:24 -07001004 goto out_pm;
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +05301005
1006 f = debugfs_create_file("pss_info", S_IFREG | S_IRUGO,
1007 debugfs_conf->telemetry_dbg_dir, NULL,
1008 &telem_pss_ops);
1009 if (!f) {
1010 pr_err("pss_sample_info debugfs register failed\n");
1011 goto out;
1012 }
1013
1014 f = debugfs_create_file("ioss_info", S_IFREG | S_IRUGO,
1015 debugfs_conf->telemetry_dbg_dir, NULL,
1016 &telem_ioss_ops);
1017 if (!f) {
1018 pr_err("ioss_sample_info debugfs register failed\n");
1019 goto out;
1020 }
1021
1022 f = debugfs_create_file("soc_states", S_IFREG | S_IRUGO,
1023 debugfs_conf->telemetry_dbg_dir,
1024 NULL, &telem_socstate_ops);
1025 if (!f) {
1026 pr_err("ioss_sample_info debugfs register failed\n");
1027 goto out;
1028 }
1029
Rajneesh Bhardwajbc8c47a2017-06-23 22:22:35 +05301030 f = debugfs_create_file("s0ix_residency_usec", S_IFREG | S_IRUGO,
1031 debugfs_conf->telemetry_dbg_dir,
1032 NULL, &telem_s0ix_fops);
1033 if (!f) {
1034 pr_err("s0ix_residency_usec debugfs register failed\n");
1035 goto out;
1036 }
1037
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +05301038 f = debugfs_create_file("pss_trace_verbosity", S_IFREG | S_IRUGO,
1039 debugfs_conf->telemetry_dbg_dir, NULL,
1040 &telem_pss_trc_verb_ops);
1041 if (!f) {
1042 pr_err("pss_trace_verbosity debugfs register failed\n");
1043 goto out;
1044 }
1045
1046 f = debugfs_create_file("ioss_trace_verbosity", S_IFREG | S_IRUGO,
1047 debugfs_conf->telemetry_dbg_dir, NULL,
1048 &telem_ioss_trc_verb_ops);
1049 if (!f) {
1050 pr_err("ioss_trace_verbosity debugfs register failed\n");
1051 goto out;
1052 }
1053
1054 return 0;
1055
1056out:
1057 debugfs_remove_recursive(debugfs_conf->telemetry_dbg_dir);
1058 debugfs_conf->telemetry_dbg_dir = NULL;
Priyalee Kushwaha74a1eb52017-06-03 10:21:24 -07001059out_pm:
1060 unregister_pm_notifier(&pm_notifier);
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +05301061
1062 return err;
1063}
1064
1065static void __exit telemetry_debugfs_exit(void)
1066{
1067 debugfs_remove_recursive(debugfs_conf->telemetry_dbg_dir);
1068 debugfs_conf->telemetry_dbg_dir = NULL;
Priyalee Kushwaha74a1eb52017-06-03 10:21:24 -07001069 unregister_pm_notifier(&pm_notifier);
Souvik Kumar Chakravarty87bee292016-01-12 16:05:14 +05301070}
1071
1072late_initcall(telemetry_debugfs_init);
1073module_exit(telemetry_debugfs_exit);
1074
1075MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
1076MODULE_DESCRIPTION("Intel SoC Telemetry debugfs Interface");
1077MODULE_VERSION(DRIVER_VERSION);
1078MODULE_LICENSE("GPL");