0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/device.h>
0011 #include <linux/module.h>
0012
0013 #include <asm/intel_telemetry.h>
0014
0015 #define DRIVER_NAME "intel_telemetry_core"
0016
0017 struct telemetry_core_config {
0018 struct telemetry_plt_config *plt_config;
0019 const struct telemetry_core_ops *telem_ops;
0020 };
0021
0022 static struct telemetry_core_config telm_core_conf;
0023
0024 static int telemetry_def_update_events(struct telemetry_evtconfig pss_evtconfig,
0025 struct telemetry_evtconfig ioss_evtconfig)
0026 {
0027 return 0;
0028 }
0029
0030 static int telemetry_def_set_sampling_period(u8 pss_period, u8 ioss_period)
0031 {
0032 return 0;
0033 }
0034
0035 static int telemetry_def_get_sampling_period(u8 *pss_min_period,
0036 u8 *pss_max_period,
0037 u8 *ioss_min_period,
0038 u8 *ioss_max_period)
0039 {
0040 return 0;
0041 }
0042
0043 static int telemetry_def_get_eventconfig(
0044 struct telemetry_evtconfig *pss_evtconfig,
0045 struct telemetry_evtconfig *ioss_evtconfig,
0046 int pss_len, int ioss_len)
0047 {
0048 return 0;
0049 }
0050
0051 static int telemetry_def_get_trace_verbosity(enum telemetry_unit telem_unit,
0052 u32 *verbosity)
0053 {
0054 return 0;
0055 }
0056
0057
0058 static int telemetry_def_set_trace_verbosity(enum telemetry_unit telem_unit,
0059 u32 verbosity)
0060 {
0061 return 0;
0062 }
0063
0064 static int telemetry_def_raw_read_eventlog(enum telemetry_unit telem_unit,
0065 struct telemetry_evtlog *evtlog,
0066 int len, int log_all_evts)
0067 {
0068 return 0;
0069 }
0070
0071 static int telemetry_def_read_eventlog(enum telemetry_unit telem_unit,
0072 struct telemetry_evtlog *evtlog,
0073 int len, int log_all_evts)
0074 {
0075 return 0;
0076 }
0077
0078 static int telemetry_def_add_events(u8 num_pss_evts, u8 num_ioss_evts,
0079 u32 *pss_evtmap, u32 *ioss_evtmap)
0080 {
0081 return 0;
0082 }
0083
0084 static int telemetry_def_reset_events(void)
0085 {
0086 return 0;
0087 }
0088
0089 static const struct telemetry_core_ops telm_defpltops = {
0090 .set_sampling_period = telemetry_def_set_sampling_period,
0091 .get_sampling_period = telemetry_def_get_sampling_period,
0092 .get_trace_verbosity = telemetry_def_get_trace_verbosity,
0093 .set_trace_verbosity = telemetry_def_set_trace_verbosity,
0094 .raw_read_eventlog = telemetry_def_raw_read_eventlog,
0095 .get_eventconfig = telemetry_def_get_eventconfig,
0096 .read_eventlog = telemetry_def_read_eventlog,
0097 .update_events = telemetry_def_update_events,
0098 .reset_events = telemetry_def_reset_events,
0099 .add_events = telemetry_def_add_events,
0100 };
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 int telemetry_update_events(struct telemetry_evtconfig pss_evtconfig,
0115 struct telemetry_evtconfig ioss_evtconfig)
0116 {
0117 return telm_core_conf.telem_ops->update_events(pss_evtconfig,
0118 ioss_evtconfig);
0119 }
0120 EXPORT_SYMBOL_GPL(telemetry_update_events);
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 int telemetry_set_sampling_period(u8 pss_period, u8 ioss_period)
0136 {
0137 return telm_core_conf.telem_ops->set_sampling_period(pss_period,
0138 ioss_period);
0139 }
0140 EXPORT_SYMBOL_GPL(telemetry_set_sampling_period);
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 int telemetry_get_sampling_period(u8 *pss_min_period, u8 *pss_max_period,
0155 u8 *ioss_min_period, u8 *ioss_max_period)
0156 {
0157 return telm_core_conf.telem_ops->get_sampling_period(pss_min_period,
0158 pss_max_period,
0159 ioss_min_period,
0160 ioss_max_period);
0161 }
0162 EXPORT_SYMBOL_GPL(telemetry_get_sampling_period);
0163
0164
0165
0166
0167
0168
0169
0170 int telemetry_reset_events(void)
0171 {
0172 return telm_core_conf.telem_ops->reset_events();
0173 }
0174 EXPORT_SYMBOL_GPL(telemetry_reset_events);
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185 int telemetry_get_eventconfig(struct telemetry_evtconfig *pss_evtconfig,
0186 struct telemetry_evtconfig *ioss_evtconfig,
0187 int pss_len, int ioss_len)
0188 {
0189 return telm_core_conf.telem_ops->get_eventconfig(pss_evtconfig,
0190 ioss_evtconfig,
0191 pss_len, ioss_len);
0192 }
0193 EXPORT_SYMBOL_GPL(telemetry_get_eventconfig);
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207 int telemetry_add_events(u8 num_pss_evts, u8 num_ioss_evts,
0208 u32 *pss_evtmap, u32 *ioss_evtmap)
0209 {
0210 return telm_core_conf.telem_ops->add_events(num_pss_evts,
0211 num_ioss_evts, pss_evtmap,
0212 ioss_evtmap);
0213 }
0214 EXPORT_SYMBOL_GPL(telemetry_add_events);
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225 int telemetry_read_events(enum telemetry_unit telem_unit,
0226 struct telemetry_evtlog *evtlog, int len)
0227 {
0228 return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,
0229 len, 0);
0230 }
0231 EXPORT_SYMBOL_GPL(telemetry_read_events);
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244 int telemetry_raw_read_events(enum telemetry_unit telem_unit,
0245 struct telemetry_evtlog *evtlog, int len)
0246 {
0247 return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,
0248 len, 0);
0249 }
0250 EXPORT_SYMBOL_GPL(telemetry_raw_read_events);
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260 int telemetry_read_eventlog(enum telemetry_unit telem_unit,
0261 struct telemetry_evtlog *evtlog, int len)
0262 {
0263 return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,
0264 len, 1);
0265 }
0266 EXPORT_SYMBOL_GPL(telemetry_read_eventlog);
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278 int telemetry_raw_read_eventlog(enum telemetry_unit telem_unit,
0279 struct telemetry_evtlog *evtlog, int len)
0280 {
0281 return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,
0282 len, 1);
0283 }
0284 EXPORT_SYMBOL_GPL(telemetry_raw_read_eventlog);
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294 int telemetry_get_trace_verbosity(enum telemetry_unit telem_unit,
0295 u32 *verbosity)
0296 {
0297 return telm_core_conf.telem_ops->get_trace_verbosity(telem_unit,
0298 verbosity);
0299 }
0300 EXPORT_SYMBOL_GPL(telemetry_get_trace_verbosity);
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310 int telemetry_set_trace_verbosity(enum telemetry_unit telem_unit, u32 verbosity)
0311 {
0312 return telm_core_conf.telem_ops->set_trace_verbosity(telem_unit,
0313 verbosity);
0314 }
0315 EXPORT_SYMBOL_GPL(telemetry_set_trace_verbosity);
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326 int telemetry_set_pltdata(const struct telemetry_core_ops *ops,
0327 struct telemetry_plt_config *pltconfig)
0328 {
0329 if (ops)
0330 telm_core_conf.telem_ops = ops;
0331
0332 if (pltconfig)
0333 telm_core_conf.plt_config = pltconfig;
0334
0335 return 0;
0336 }
0337 EXPORT_SYMBOL_GPL(telemetry_set_pltdata);
0338
0339
0340
0341
0342
0343
0344
0345
0346 int telemetry_clear_pltdata(void)
0347 {
0348 telm_core_conf.telem_ops = &telm_defpltops;
0349 telm_core_conf.plt_config = NULL;
0350
0351 return 0;
0352 }
0353 EXPORT_SYMBOL_GPL(telemetry_clear_pltdata);
0354
0355
0356
0357
0358
0359
0360
0361 struct telemetry_plt_config *telemetry_get_pltdata(void)
0362 {
0363 return telm_core_conf.plt_config;
0364 }
0365 EXPORT_SYMBOL_GPL(telemetry_get_pltdata);
0366
0367 static inline int telemetry_get_pssevtname(enum telemetry_unit telem_unit,
0368 const char **name, int len)
0369 {
0370 struct telemetry_unit_config psscfg;
0371 int i;
0372
0373 if (!telm_core_conf.plt_config)
0374 return -EINVAL;
0375
0376 psscfg = telm_core_conf.plt_config->pss_config;
0377
0378 if (len > psscfg.ssram_evts_used)
0379 len = psscfg.ssram_evts_used;
0380
0381 for (i = 0; i < len; i++)
0382 name[i] = psscfg.telem_evts[i].name;
0383
0384 return 0;
0385 }
0386
0387 static inline int telemetry_get_iossevtname(enum telemetry_unit telem_unit,
0388 const char **name, int len)
0389 {
0390 struct telemetry_unit_config iosscfg;
0391 int i;
0392
0393 if (!(telm_core_conf.plt_config))
0394 return -EINVAL;
0395
0396 iosscfg = telm_core_conf.plt_config->ioss_config;
0397
0398 if (len > iosscfg.ssram_evts_used)
0399 len = iosscfg.ssram_evts_used;
0400
0401 for (i = 0; i < len; i++)
0402 name[i] = iosscfg.telem_evts[i].name;
0403
0404 return 0;
0405
0406 }
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418 int telemetry_get_evtname(enum telemetry_unit telem_unit,
0419 const char **name, int len)
0420 {
0421 int ret = -EINVAL;
0422
0423 if (telem_unit == TELEM_PSS)
0424 ret = telemetry_get_pssevtname(telem_unit, name, len);
0425
0426 else if (telem_unit == TELEM_IOSS)
0427 ret = telemetry_get_iossevtname(telem_unit, name, len);
0428
0429 return ret;
0430 }
0431 EXPORT_SYMBOL_GPL(telemetry_get_evtname);
0432
0433 static int __init telemetry_module_init(void)
0434 {
0435 pr_info(pr_fmt(DRIVER_NAME) " Init\n");
0436
0437 telm_core_conf.telem_ops = &telm_defpltops;
0438 return 0;
0439 }
0440
0441 static void __exit telemetry_module_exit(void)
0442 {
0443 }
0444
0445 module_init(telemetry_module_init);
0446 module_exit(telemetry_module_exit);
0447
0448 MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
0449 MODULE_DESCRIPTION("Intel SoC Telemetry Interface");
0450 MODULE_LICENSE("GPL v2");