cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pltdrv.c (30508B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Intel SOC Telemetry Platform Driver: Currently supports APL
      4 * Copyright (c) 2015, Intel Corporation.
      5 * All Rights Reserved.
      6 *
      7 * This file provides the platform specific telemetry implementation for APL.
      8 * It used the PUNIT and PMC IPC interfaces for configuring the counters.
      9 * The accumulated results are fetched from SRAM.
     10 */
     11
     12#include <linux/io.h>
     13#include <linux/module.h>
     14#include <linux/platform_device.h>
     15
     16#include <asm/cpu_device_id.h>
     17#include <asm/intel-family.h>
     18#include <asm/intel_punit_ipc.h>
     19#include <asm/intel_telemetry.h>
     20
     21#define DRIVER_NAME	"intel_telemetry"
     22#define DRIVER_VERSION	"1.0.0"
     23
     24#define TELEM_TRC_VERBOSITY_MASK	0x3
     25
     26#define TELEM_MIN_PERIOD(x)		((x) & 0x7F0000)
     27#define TELEM_MAX_PERIOD(x)		((x) & 0x7F000000)
     28#define TELEM_SAMPLE_PERIOD_INVALID(x)	((x) & (BIT(7)))
     29#define TELEM_CLEAR_SAMPLE_PERIOD(x)	((x) &= ~0x7F)
     30
     31#define TELEM_SAMPLING_DEFAULT_PERIOD	0xD
     32
     33#define TELEM_MAX_EVENTS_SRAM		28
     34#define TELEM_SSRAM_STARTTIME_OFFSET	8
     35#define TELEM_SSRAM_EVTLOG_OFFSET	16
     36
     37#define IOSS_TELEM			0xeb
     38#define IOSS_TELEM_EVENT_READ		0x0
     39#define IOSS_TELEM_EVENT_WRITE		0x1
     40#define IOSS_TELEM_INFO_READ		0x2
     41#define IOSS_TELEM_TRACE_CTL_READ	0x5
     42#define IOSS_TELEM_TRACE_CTL_WRITE	0x6
     43#define IOSS_TELEM_EVENT_CTL_READ	0x7
     44#define IOSS_TELEM_EVENT_CTL_WRITE	0x8
     45#define IOSS_TELEM_EVT_WRITE_SIZE	0x3
     46
     47#define TELEM_INFO_SRAMEVTS_MASK	0xFF00
     48#define TELEM_INFO_SRAMEVTS_SHIFT	0x8
     49#define TELEM_SSRAM_READ_TIMEOUT	10
     50
     51#define TELEM_INFO_NENABLES_MASK	0xFF
     52#define TELEM_EVENT_ENABLE		0x8000
     53
     54#define TELEM_MASK_BIT			1
     55#define TELEM_MASK_BYTE			0xFF
     56#define BYTES_PER_LONG			8
     57#define TELEM_MASK_PCS_STATE		0xF
     58
     59#define TELEM_DISABLE(x)		((x) &= ~(BIT(31)))
     60#define TELEM_CLEAR_EVENTS(x)		((x) |= (BIT(30)))
     61#define TELEM_ENABLE_SRAM_EVT_TRACE(x)	((x) &= ~(BIT(30) | BIT(24)))
     62#define TELEM_ENABLE_PERIODIC(x)	((x) |= (BIT(23) | BIT(31) | BIT(7)))
     63#define TELEM_EXTRACT_VERBOSITY(x, y)	((y) = (((x) >> 27) & 0x3))
     64#define TELEM_CLEAR_VERBOSITY_BITS(x)	((x) &= ~(BIT(27) | BIT(28)))
     65#define TELEM_SET_VERBOSITY_BITS(x, y)	((x) |= ((y) << 27))
     66
     67enum telemetry_action {
     68	TELEM_UPDATE = 0,
     69	TELEM_ADD,
     70	TELEM_RESET,
     71	TELEM_ACTION_NONE
     72};
     73
     74struct telem_ssram_region {
     75	u64 timestamp;
     76	u64 start_time;
     77	u64 events[TELEM_MAX_EVENTS_SRAM];
     78};
     79
     80static struct telemetry_plt_config *telm_conf;
     81
     82/*
     83 * The following counters are programmed by default during setup.
     84 * Only 20 allocated to kernel driver
     85 */
     86static struct telemetry_evtmap
     87	telemetry_apl_ioss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
     88	{"SOC_S0IX_TOTAL_RES",			0x4800},
     89	{"SOC_S0IX_TOTAL_OCC",			0x4000},
     90	{"SOC_S0IX_SHALLOW_RES",		0x4801},
     91	{"SOC_S0IX_SHALLOW_OCC",		0x4001},
     92	{"SOC_S0IX_DEEP_RES",			0x4802},
     93	{"SOC_S0IX_DEEP_OCC",			0x4002},
     94	{"PMC_POWER_GATE",			0x5818},
     95	{"PMC_D3_STATES",			0x5819},
     96	{"PMC_D0I3_STATES",			0x581A},
     97	{"PMC_S0IX_WAKE_REASON_GPIO",		0x6000},
     98	{"PMC_S0IX_WAKE_REASON_TIMER",		0x6001},
     99	{"PMC_S0IX_WAKE_REASON_VNNREQ",         0x6002},
    100	{"PMC_S0IX_WAKE_REASON_LOWPOWER",       0x6003},
    101	{"PMC_S0IX_WAKE_REASON_EXTERNAL",       0x6004},
    102	{"PMC_S0IX_WAKE_REASON_MISC",           0x6005},
    103	{"PMC_S0IX_BLOCKING_IPS_D3_D0I3",       0x6006},
    104	{"PMC_S0IX_BLOCKING_IPS_PG",            0x6007},
    105	{"PMC_S0IX_BLOCKING_MISC_IPS_PG",       0x6008},
    106	{"PMC_S0IX_BLOCK_IPS_VNN_REQ",          0x6009},
    107	{"PMC_S0IX_BLOCK_IPS_CLOCKS",           0x600B},
    108};
    109
    110
    111static struct telemetry_evtmap
    112	telemetry_apl_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
    113	{"IA_CORE0_C6_RES",			0x0400},
    114	{"IA_CORE0_C6_CTR",			0x0000},
    115	{"IA_MODULE0_C7_RES",			0x0410},
    116	{"IA_MODULE0_C7_CTR",			0x000E},
    117	{"IA_C0_RES",				0x0805},
    118	{"PCS_LTR",				0x2801},
    119	{"PSTATES",				0x2802},
    120	{"SOC_S0I3_RES",			0x0409},
    121	{"SOC_S0I3_CTR",			0x000A},
    122	{"PCS_S0I3_CTR",			0x0009},
    123	{"PCS_C1E_RES",				0x041A},
    124	{"PCS_IDLE_STATUS",			0x2806},
    125	{"IA_PERF_LIMITS",			0x280B},
    126	{"GT_PERF_LIMITS",			0x280C},
    127	{"PCS_WAKEUP_S0IX_CTR",			0x0030},
    128	{"PCS_IDLE_BLOCKED",			0x2C00},
    129	{"PCS_S0IX_BLOCKED",			0x2C01},
    130	{"PCS_S0IX_WAKE_REASONS",		0x2C02},
    131	{"PCS_LTR_BLOCKING",			0x2C03},
    132	{"PC2_AND_MEM_SHALLOW_IDLE_RES",	0x1D40},
    133};
    134
    135static struct telemetry_evtmap
    136	telemetry_glk_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
    137	{"IA_CORE0_C6_RES",			0x0400},
    138	{"IA_CORE0_C6_CTR",			0x0000},
    139	{"IA_MODULE0_C7_RES",			0x0410},
    140	{"IA_MODULE0_C7_CTR",			0x000C},
    141	{"IA_C0_RES",				0x0805},
    142	{"PCS_LTR",				0x2801},
    143	{"PSTATES",				0x2802},
    144	{"SOC_S0I3_RES",			0x0407},
    145	{"SOC_S0I3_CTR",			0x0008},
    146	{"PCS_S0I3_CTR",			0x0007},
    147	{"PCS_C1E_RES",				0x0414},
    148	{"PCS_IDLE_STATUS",			0x2806},
    149	{"IA_PERF_LIMITS",			0x280B},
    150	{"GT_PERF_LIMITS",			0x280C},
    151	{"PCS_WAKEUP_S0IX_CTR",			0x0025},
    152	{"PCS_IDLE_BLOCKED",			0x2C00},
    153	{"PCS_S0IX_BLOCKED",			0x2C01},
    154	{"PCS_S0IX_WAKE_REASONS",		0x2C02},
    155	{"PCS_LTR_BLOCKING",			0x2C03},
    156	{"PC2_AND_MEM_SHALLOW_IDLE_RES",	0x1D40},
    157};
    158
    159/* APL specific Data */
    160static struct telemetry_plt_config telem_apl_config = {
    161	.pss_config = {
    162		.telem_evts = telemetry_apl_pss_default_events,
    163	},
    164	.ioss_config = {
    165		.telem_evts = telemetry_apl_ioss_default_events,
    166	},
    167};
    168
    169/* GLK specific Data */
    170static struct telemetry_plt_config telem_glk_config = {
    171	.pss_config = {
    172		.telem_evts = telemetry_glk_pss_default_events,
    173	},
    174	.ioss_config = {
    175		.telem_evts = telemetry_apl_ioss_default_events,
    176	},
    177};
    178
    179static const struct x86_cpu_id telemetry_cpu_ids[] = {
    180	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT,	&telem_apl_config),
    181	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS,	&telem_glk_config),
    182	{}
    183};
    184
    185MODULE_DEVICE_TABLE(x86cpu, telemetry_cpu_ids);
    186
    187static inline int telem_get_unitconfig(enum telemetry_unit telem_unit,
    188				     struct telemetry_unit_config **unit_config)
    189{
    190	if (telem_unit == TELEM_PSS)
    191		*unit_config = &(telm_conf->pss_config);
    192	else if (telem_unit == TELEM_IOSS)
    193		*unit_config = &(telm_conf->ioss_config);
    194	else
    195		return -EINVAL;
    196
    197	return 0;
    198
    199}
    200
    201static int telemetry_check_evtid(enum telemetry_unit telem_unit,
    202				 u32 *evtmap, u8 len,
    203				 enum telemetry_action action)
    204{
    205	struct telemetry_unit_config *unit_config;
    206	int ret;
    207
    208	ret = telem_get_unitconfig(telem_unit, &unit_config);
    209	if (ret < 0)
    210		return ret;
    211
    212	switch (action) {
    213	case TELEM_RESET:
    214		if (len > TELEM_MAX_EVENTS_SRAM)
    215			return -EINVAL;
    216
    217		break;
    218
    219	case TELEM_UPDATE:
    220		if (len > TELEM_MAX_EVENTS_SRAM)
    221			return -EINVAL;
    222
    223		if ((len > 0) && (evtmap == NULL))
    224			return -EINVAL;
    225
    226		break;
    227
    228	case TELEM_ADD:
    229		if ((len + unit_config->ssram_evts_used) >
    230		    TELEM_MAX_EVENTS_SRAM)
    231			return -EINVAL;
    232
    233		if ((len > 0) && (evtmap == NULL))
    234			return -EINVAL;
    235
    236		break;
    237
    238	default:
    239		pr_err("Unknown Telemetry action specified %d\n", action);
    240		return -EINVAL;
    241	}
    242
    243	return 0;
    244}
    245
    246
    247static inline int telemetry_plt_config_ioss_event(u32 evt_id, int index)
    248{
    249	u32 write_buf;
    250
    251	write_buf = evt_id | TELEM_EVENT_ENABLE;
    252	write_buf <<= BITS_PER_BYTE;
    253	write_buf |= index;
    254
    255	return intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
    256					 IOSS_TELEM_EVENT_WRITE, &write_buf,
    257					 IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0);
    258}
    259
    260static inline int telemetry_plt_config_pss_event(u32 evt_id, int index)
    261{
    262	u32 write_buf;
    263	int ret;
    264
    265	write_buf = evt_id | TELEM_EVENT_ENABLE;
    266	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT,
    267				      index, 0, &write_buf, NULL);
    268
    269	return ret;
    270}
    271
    272static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
    273					 enum telemetry_action action)
    274{
    275	struct intel_scu_ipc_dev *scu = telm_conf->scu;
    276	u8 num_ioss_evts, ioss_period;
    277	int ret, index, idx;
    278	u32 *ioss_evtmap;
    279	u32 telem_ctrl;
    280
    281	num_ioss_evts = evtconfig.num_evts;
    282	ioss_period = evtconfig.period;
    283	ioss_evtmap = evtconfig.evtmap;
    284
    285	/* Get telemetry EVENT CTL */
    286	ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
    287				    IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
    288				    &telem_ctrl, sizeof(telem_ctrl));
    289	if (ret) {
    290		pr_err("IOSS TELEM_CTRL Read Failed\n");
    291		return ret;
    292	}
    293
    294	/* Disable Telemetry */
    295	TELEM_DISABLE(telem_ctrl);
    296
    297	ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
    298				    IOSS_TELEM_EVENT_CTL_WRITE, &telem_ctrl,
    299				    sizeof(telem_ctrl), NULL, 0);
    300	if (ret) {
    301		pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
    302		return ret;
    303	}
    304
    305
    306	/* Reset Everything */
    307	if (action == TELEM_RESET) {
    308		/* Clear All Events */
    309		TELEM_CLEAR_EVENTS(telem_ctrl);
    310
    311		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
    312					    IOSS_TELEM_EVENT_CTL_WRITE,
    313					    &telem_ctrl, sizeof(telem_ctrl),
    314					    NULL, 0);
    315		if (ret) {
    316			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
    317			return ret;
    318		}
    319		telm_conf->ioss_config.ssram_evts_used = 0;
    320
    321		/* Configure Events */
    322		for (idx = 0; idx < num_ioss_evts; idx++) {
    323			if (telemetry_plt_config_ioss_event(
    324			    telm_conf->ioss_config.telem_evts[idx].evt_id,
    325			    idx)) {
    326				pr_err("IOSS TELEM_RESET Fail for data: %x\n",
    327				telm_conf->ioss_config.telem_evts[idx].evt_id);
    328				continue;
    329			}
    330			telm_conf->ioss_config.ssram_evts_used++;
    331		}
    332	}
    333
    334	/* Re-Configure Everything */
    335	if (action == TELEM_UPDATE) {
    336		/* Clear All Events */
    337		TELEM_CLEAR_EVENTS(telem_ctrl);
    338
    339		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
    340					    IOSS_TELEM_EVENT_CTL_WRITE,
    341					    &telem_ctrl, sizeof(telem_ctrl),
    342					    NULL, 0);
    343		if (ret) {
    344			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
    345			return ret;
    346		}
    347		telm_conf->ioss_config.ssram_evts_used = 0;
    348
    349		/* Configure Events */
    350		for (index = 0; index < num_ioss_evts; index++) {
    351			telm_conf->ioss_config.telem_evts[index].evt_id =
    352			ioss_evtmap[index];
    353
    354			if (telemetry_plt_config_ioss_event(
    355			    telm_conf->ioss_config.telem_evts[index].evt_id,
    356			    index)) {
    357				pr_err("IOSS TELEM_UPDATE Fail for Evt%x\n",
    358					ioss_evtmap[index]);
    359				continue;
    360			}
    361			telm_conf->ioss_config.ssram_evts_used++;
    362		}
    363	}
    364
    365	/* Add some Events */
    366	if (action == TELEM_ADD) {
    367		/* Configure Events */
    368		for (index = telm_conf->ioss_config.ssram_evts_used, idx = 0;
    369		     idx < num_ioss_evts; index++, idx++) {
    370			telm_conf->ioss_config.telem_evts[index].evt_id =
    371			ioss_evtmap[idx];
    372
    373			if (telemetry_plt_config_ioss_event(
    374			    telm_conf->ioss_config.telem_evts[index].evt_id,
    375			    index)) {
    376				pr_err("IOSS TELEM_ADD Fail for Event %x\n",
    377					ioss_evtmap[idx]);
    378				continue;
    379			}
    380			telm_conf->ioss_config.ssram_evts_used++;
    381		}
    382	}
    383
    384	/* Enable Periodic Telemetry Events and enable SRAM trace */
    385	TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
    386	TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
    387	TELEM_ENABLE_PERIODIC(telem_ctrl);
    388	telem_ctrl |= ioss_period;
    389
    390	ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
    391				    IOSS_TELEM_EVENT_CTL_WRITE,
    392				    &telem_ctrl, sizeof(telem_ctrl), NULL, 0);
    393	if (ret) {
    394		pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
    395		return ret;
    396	}
    397
    398	telm_conf->ioss_config.curr_period = ioss_period;
    399
    400	return 0;
    401}
    402
    403
    404static int telemetry_setup_pssevtconfig(struct telemetry_evtconfig evtconfig,
    405					enum telemetry_action action)
    406{
    407	u8 num_pss_evts, pss_period;
    408	int ret, index, idx;
    409	u32 *pss_evtmap;
    410	u32 telem_ctrl;
    411
    412	num_pss_evts = evtconfig.num_evts;
    413	pss_period = evtconfig.period;
    414	pss_evtmap = evtconfig.evtmap;
    415
    416	/* PSS Config */
    417	/* Get telemetry EVENT CTL */
    418	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
    419				      0, 0, NULL, &telem_ctrl);
    420	if (ret) {
    421		pr_err("PSS TELEM_CTRL Read Failed\n");
    422		return ret;
    423	}
    424
    425	/* Disable Telemetry */
    426	TELEM_DISABLE(telem_ctrl);
    427	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
    428				      0, 0, &telem_ctrl, NULL);
    429	if (ret) {
    430		pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
    431		return ret;
    432	}
    433
    434	/* Reset Everything */
    435	if (action == TELEM_RESET) {
    436		/* Clear All Events */
    437		TELEM_CLEAR_EVENTS(telem_ctrl);
    438
    439		ret = intel_punit_ipc_command(
    440				IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
    441				0, 0, &telem_ctrl, NULL);
    442		if (ret) {
    443			pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
    444			return ret;
    445		}
    446		telm_conf->pss_config.ssram_evts_used = 0;
    447		/* Configure Events */
    448		for (idx = 0; idx < num_pss_evts; idx++) {
    449			if (telemetry_plt_config_pss_event(
    450			    telm_conf->pss_config.telem_evts[idx].evt_id,
    451			    idx)) {
    452				pr_err("PSS TELEM_RESET Fail for Event %x\n",
    453				telm_conf->pss_config.telem_evts[idx].evt_id);
    454				continue;
    455			}
    456			telm_conf->pss_config.ssram_evts_used++;
    457		}
    458	}
    459
    460	/* Re-Configure Everything */
    461	if (action == TELEM_UPDATE) {
    462		/* Clear All Events */
    463		TELEM_CLEAR_EVENTS(telem_ctrl);
    464
    465		ret = intel_punit_ipc_command(
    466				IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
    467				0, 0, &telem_ctrl, NULL);
    468		if (ret) {
    469			pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
    470			return ret;
    471		}
    472		telm_conf->pss_config.ssram_evts_used = 0;
    473
    474		/* Configure Events */
    475		for (index = 0; index < num_pss_evts; index++) {
    476			telm_conf->pss_config.telem_evts[index].evt_id =
    477			pss_evtmap[index];
    478
    479			if (telemetry_plt_config_pss_event(
    480			    telm_conf->pss_config.telem_evts[index].evt_id,
    481			    index)) {
    482				pr_err("PSS TELEM_UPDATE Fail for Event %x\n",
    483					pss_evtmap[index]);
    484				continue;
    485			}
    486			telm_conf->pss_config.ssram_evts_used++;
    487		}
    488	}
    489
    490	/* Add some Events */
    491	if (action == TELEM_ADD) {
    492		/* Configure Events */
    493		for (index = telm_conf->pss_config.ssram_evts_used, idx = 0;
    494		     idx < num_pss_evts; index++, idx++) {
    495
    496			telm_conf->pss_config.telem_evts[index].evt_id =
    497			pss_evtmap[idx];
    498
    499			if (telemetry_plt_config_pss_event(
    500			    telm_conf->pss_config.telem_evts[index].evt_id,
    501			    index)) {
    502				pr_err("PSS TELEM_ADD Fail for Event %x\n",
    503					pss_evtmap[idx]);
    504				continue;
    505			}
    506			telm_conf->pss_config.ssram_evts_used++;
    507		}
    508	}
    509
    510	/* Enable Periodic Telemetry Events and enable SRAM trace */
    511	TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
    512	TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
    513	TELEM_ENABLE_PERIODIC(telem_ctrl);
    514	telem_ctrl |= pss_period;
    515
    516	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
    517				      0, 0, &telem_ctrl, NULL);
    518	if (ret) {
    519		pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
    520		return ret;
    521	}
    522
    523	telm_conf->pss_config.curr_period = pss_period;
    524
    525	return 0;
    526}
    527
    528static int telemetry_setup_evtconfig(struct telemetry_evtconfig pss_evtconfig,
    529				     struct telemetry_evtconfig ioss_evtconfig,
    530				     enum telemetry_action action)
    531{
    532	int ret;
    533
    534	mutex_lock(&(telm_conf->telem_lock));
    535
    536	if ((action == TELEM_UPDATE) && (telm_conf->telem_in_use)) {
    537		ret = -EBUSY;
    538		goto out;
    539	}
    540
    541	ret = telemetry_check_evtid(TELEM_PSS, pss_evtconfig.evtmap,
    542				    pss_evtconfig.num_evts, action);
    543	if (ret)
    544		goto out;
    545
    546	ret = telemetry_check_evtid(TELEM_IOSS, ioss_evtconfig.evtmap,
    547				    ioss_evtconfig.num_evts, action);
    548	if (ret)
    549		goto out;
    550
    551	if (ioss_evtconfig.num_evts) {
    552		ret = telemetry_setup_iossevtconfig(ioss_evtconfig, action);
    553		if (ret)
    554			goto out;
    555	}
    556
    557	if (pss_evtconfig.num_evts) {
    558		ret = telemetry_setup_pssevtconfig(pss_evtconfig, action);
    559		if (ret)
    560			goto out;
    561	}
    562
    563	if ((action == TELEM_UPDATE) || (action == TELEM_ADD))
    564		telm_conf->telem_in_use = true;
    565	else
    566		telm_conf->telem_in_use = false;
    567
    568out:
    569	mutex_unlock(&(telm_conf->telem_lock));
    570	return ret;
    571}
    572
    573static int telemetry_setup(struct platform_device *pdev)
    574{
    575	struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
    576	u32 read_buf, events, event_regs;
    577	int ret;
    578
    579	ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
    580					IOSS_TELEM_INFO_READ, NULL, 0,
    581					&read_buf, sizeof(read_buf));
    582	if (ret) {
    583		dev_err(&pdev->dev, "IOSS TELEM_INFO Read Failed\n");
    584		return ret;
    585	}
    586
    587	/* Get telemetry Info */
    588	events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
    589		  TELEM_INFO_SRAMEVTS_SHIFT;
    590	event_regs = read_buf & TELEM_INFO_NENABLES_MASK;
    591	if ((events < TELEM_MAX_EVENTS_SRAM) ||
    592	    (event_regs < TELEM_MAX_EVENTS_SRAM)) {
    593		dev_err(&pdev->dev, "IOSS:Insufficient Space for SRAM Trace\n");
    594		dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
    595			events, event_regs);
    596		return -ENOMEM;
    597	}
    598
    599	telm_conf->ioss_config.min_period = TELEM_MIN_PERIOD(read_buf);
    600	telm_conf->ioss_config.max_period = TELEM_MAX_PERIOD(read_buf);
    601
    602	/* PUNIT Mailbox Setup */
    603	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_INFO, 0, 0,
    604				      NULL, &read_buf);
    605	if (ret) {
    606		dev_err(&pdev->dev, "PSS TELEM_INFO Read Failed\n");
    607		return ret;
    608	}
    609
    610	/* Get telemetry Info */
    611	events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
    612		  TELEM_INFO_SRAMEVTS_SHIFT;
    613	event_regs = read_buf & TELEM_INFO_SRAMEVTS_MASK;
    614	if ((events < TELEM_MAX_EVENTS_SRAM) ||
    615	    (event_regs < TELEM_MAX_EVENTS_SRAM)) {
    616		dev_err(&pdev->dev, "PSS:Insufficient Space for SRAM Trace\n");
    617		dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
    618			events, event_regs);
    619		return -ENOMEM;
    620	}
    621
    622	telm_conf->pss_config.min_period = TELEM_MIN_PERIOD(read_buf);
    623	telm_conf->pss_config.max_period = TELEM_MAX_PERIOD(read_buf);
    624
    625	pss_evtconfig.evtmap = NULL;
    626	pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
    627	pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
    628
    629	ioss_evtconfig.evtmap = NULL;
    630	ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
    631	ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
    632
    633	ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
    634					TELEM_RESET);
    635	if (ret) {
    636		dev_err(&pdev->dev, "TELEMETRY Setup Failed\n");
    637		return ret;
    638	}
    639	return 0;
    640}
    641
    642static int telemetry_plt_update_events(struct telemetry_evtconfig pss_evtconfig,
    643				struct telemetry_evtconfig ioss_evtconfig)
    644{
    645	int ret;
    646
    647	if ((pss_evtconfig.num_evts > 0) &&
    648	    (TELEM_SAMPLE_PERIOD_INVALID(pss_evtconfig.period))) {
    649		pr_err("PSS Sampling Period Out of Range\n");
    650		return -EINVAL;
    651	}
    652
    653	if ((ioss_evtconfig.num_evts > 0) &&
    654	    (TELEM_SAMPLE_PERIOD_INVALID(ioss_evtconfig.period))) {
    655		pr_err("IOSS Sampling Period Out of Range\n");
    656		return -EINVAL;
    657	}
    658
    659	ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
    660					TELEM_UPDATE);
    661	if (ret)
    662		pr_err("TELEMETRY Config Failed\n");
    663
    664	return ret;
    665}
    666
    667
    668static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
    669{
    670	u32 telem_ctrl = 0;
    671	int ret = 0;
    672
    673	mutex_lock(&(telm_conf->telem_lock));
    674	if (ioss_period) {
    675		struct intel_scu_ipc_dev *scu = telm_conf->scu;
    676
    677		if (TELEM_SAMPLE_PERIOD_INVALID(ioss_period)) {
    678			pr_err("IOSS Sampling Period Out of Range\n");
    679			ret = -EINVAL;
    680			goto out;
    681		}
    682
    683		/* Get telemetry EVENT CTL */
    684		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
    685					    IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
    686					    &telem_ctrl, sizeof(telem_ctrl));
    687		if (ret) {
    688			pr_err("IOSS TELEM_CTRL Read Failed\n");
    689			goto out;
    690		}
    691
    692		/* Disable Telemetry */
    693		TELEM_DISABLE(telem_ctrl);
    694
    695		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
    696						IOSS_TELEM_EVENT_CTL_WRITE,
    697						&telem_ctrl, sizeof(telem_ctrl),
    698						NULL, 0);
    699		if (ret) {
    700			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
    701			goto out;
    702		}
    703
    704		/* Enable Periodic Telemetry Events and enable SRAM trace */
    705		TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
    706		TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
    707		TELEM_ENABLE_PERIODIC(telem_ctrl);
    708		telem_ctrl |= ioss_period;
    709
    710		ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
    711						IOSS_TELEM_EVENT_CTL_WRITE,
    712						&telem_ctrl, sizeof(telem_ctrl),
    713						NULL, 0);
    714		if (ret) {
    715			pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
    716			goto out;
    717		}
    718		telm_conf->ioss_config.curr_period = ioss_period;
    719	}
    720
    721	if (pss_period) {
    722		if (TELEM_SAMPLE_PERIOD_INVALID(pss_period)) {
    723			pr_err("PSS Sampling Period Out of Range\n");
    724			ret = -EINVAL;
    725			goto out;
    726		}
    727
    728		/* Get telemetry EVENT CTL */
    729		ret = intel_punit_ipc_command(
    730				IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
    731				0, 0, NULL, &telem_ctrl);
    732		if (ret) {
    733			pr_err("PSS TELEM_CTRL Read Failed\n");
    734			goto out;
    735		}
    736
    737		/* Disable Telemetry */
    738		TELEM_DISABLE(telem_ctrl);
    739		ret = intel_punit_ipc_command(
    740				IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
    741				0, 0, &telem_ctrl, NULL);
    742		if (ret) {
    743			pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
    744			goto out;
    745		}
    746
    747		/* Enable Periodic Telemetry Events and enable SRAM trace */
    748		TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
    749		TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
    750		TELEM_ENABLE_PERIODIC(telem_ctrl);
    751		telem_ctrl |= pss_period;
    752
    753		ret = intel_punit_ipc_command(
    754				IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
    755				0, 0, &telem_ctrl, NULL);
    756		if (ret) {
    757			pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
    758			goto out;
    759		}
    760		telm_conf->pss_config.curr_period = pss_period;
    761	}
    762
    763out:
    764	mutex_unlock(&(telm_conf->telem_lock));
    765	return ret;
    766}
    767
    768
    769static int telemetry_plt_get_sampling_period(u8 *pss_min_period,
    770					     u8 *pss_max_period,
    771					     u8 *ioss_min_period,
    772					     u8 *ioss_max_period)
    773{
    774	*pss_min_period = telm_conf->pss_config.min_period;
    775	*pss_max_period = telm_conf->pss_config.max_period;
    776	*ioss_min_period = telm_conf->ioss_config.min_period;
    777	*ioss_max_period = telm_conf->ioss_config.max_period;
    778
    779	return 0;
    780}
    781
    782
    783static int telemetry_plt_reset_events(void)
    784{
    785	struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
    786	int ret;
    787
    788	pss_evtconfig.evtmap = NULL;
    789	pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
    790	pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
    791
    792	ioss_evtconfig.evtmap = NULL;
    793	ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
    794	ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
    795
    796	ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
    797					TELEM_RESET);
    798	if (ret)
    799		pr_err("TELEMETRY Reset Failed\n");
    800
    801	return ret;
    802}
    803
    804
    805static int telemetry_plt_get_eventconfig(struct telemetry_evtconfig *pss_config,
    806					struct telemetry_evtconfig *ioss_config,
    807					int pss_len, int ioss_len)
    808{
    809	u32 *pss_evtmap, *ioss_evtmap;
    810	u32 index;
    811
    812	pss_evtmap = pss_config->evtmap;
    813	ioss_evtmap = ioss_config->evtmap;
    814
    815	mutex_lock(&(telm_conf->telem_lock));
    816	pss_config->num_evts = telm_conf->pss_config.ssram_evts_used;
    817	ioss_config->num_evts = telm_conf->ioss_config.ssram_evts_used;
    818
    819	pss_config->period = telm_conf->pss_config.curr_period;
    820	ioss_config->period = telm_conf->ioss_config.curr_period;
    821
    822	if ((pss_len < telm_conf->pss_config.ssram_evts_used) ||
    823	    (ioss_len < telm_conf->ioss_config.ssram_evts_used)) {
    824		mutex_unlock(&(telm_conf->telem_lock));
    825		return -EINVAL;
    826	}
    827
    828	for (index = 0; index < telm_conf->pss_config.ssram_evts_used;
    829	     index++) {
    830		pss_evtmap[index] =
    831		telm_conf->pss_config.telem_evts[index].evt_id;
    832	}
    833
    834	for (index = 0; index < telm_conf->ioss_config.ssram_evts_used;
    835	     index++) {
    836		ioss_evtmap[index] =
    837		telm_conf->ioss_config.telem_evts[index].evt_id;
    838	}
    839
    840	mutex_unlock(&(telm_conf->telem_lock));
    841	return 0;
    842}
    843
    844
    845static int telemetry_plt_add_events(u8 num_pss_evts, u8 num_ioss_evts,
    846				    u32 *pss_evtmap, u32 *ioss_evtmap)
    847{
    848	struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
    849	int ret;
    850
    851	pss_evtconfig.evtmap = pss_evtmap;
    852	pss_evtconfig.num_evts = num_pss_evts;
    853	pss_evtconfig.period = telm_conf->pss_config.curr_period;
    854
    855	ioss_evtconfig.evtmap = ioss_evtmap;
    856	ioss_evtconfig.num_evts = num_ioss_evts;
    857	ioss_evtconfig.period = telm_conf->ioss_config.curr_period;
    858
    859	ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
    860					TELEM_ADD);
    861	if (ret)
    862		pr_err("TELEMETRY ADD Failed\n");
    863
    864	return ret;
    865}
    866
    867static int telem_evtlog_read(enum telemetry_unit telem_unit,
    868			     struct telem_ssram_region *ssram_region, u8 len)
    869{
    870	struct telemetry_unit_config *unit_config;
    871	u64 timestamp_prev, timestamp_next;
    872	int ret, index, timeout = 0;
    873
    874	ret = telem_get_unitconfig(telem_unit, &unit_config);
    875	if (ret < 0)
    876		return ret;
    877
    878	if (len > unit_config->ssram_evts_used)
    879		len = unit_config->ssram_evts_used;
    880
    881	do {
    882		timestamp_prev = readq(unit_config->regmap);
    883		if (!timestamp_prev) {
    884			pr_err("Ssram under update. Please Try Later\n");
    885			return -EBUSY;
    886		}
    887
    888		ssram_region->start_time = readq(unit_config->regmap +
    889						 TELEM_SSRAM_STARTTIME_OFFSET);
    890
    891		for (index = 0; index < len; index++) {
    892			ssram_region->events[index] =
    893			readq(unit_config->regmap + TELEM_SSRAM_EVTLOG_OFFSET +
    894			      BYTES_PER_LONG*index);
    895		}
    896
    897		timestamp_next = readq(unit_config->regmap);
    898		if (!timestamp_next) {
    899			pr_err("Ssram under update. Please Try Later\n");
    900			return -EBUSY;
    901		}
    902
    903		if (timeout++ > TELEM_SSRAM_READ_TIMEOUT) {
    904			pr_err("Timeout while reading Events\n");
    905			return -EBUSY;
    906		}
    907
    908	} while (timestamp_prev != timestamp_next);
    909
    910	ssram_region->timestamp = timestamp_next;
    911
    912	return len;
    913}
    914
    915static int telemetry_plt_raw_read_eventlog(enum telemetry_unit telem_unit,
    916					   struct telemetry_evtlog *evtlog,
    917					   int len, int log_all_evts)
    918{
    919	int index, idx1, ret, readlen = len;
    920	struct telem_ssram_region ssram_region;
    921	struct telemetry_evtmap *evtmap;
    922
    923	switch (telem_unit)	{
    924	case TELEM_PSS:
    925		evtmap = telm_conf->pss_config.telem_evts;
    926		break;
    927
    928	case TELEM_IOSS:
    929		evtmap = telm_conf->ioss_config.telem_evts;
    930		break;
    931
    932	default:
    933		pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
    934		return -EINVAL;
    935	}
    936
    937	if (!log_all_evts)
    938		readlen = TELEM_MAX_EVENTS_SRAM;
    939
    940	ret = telem_evtlog_read(telem_unit, &ssram_region, readlen);
    941	if (ret < 0)
    942		return ret;
    943
    944	/* Invalid evt-id array specified via length mismatch */
    945	if ((!log_all_evts) && (len > ret))
    946		return -EINVAL;
    947
    948	if (log_all_evts)
    949		for (index = 0; index < ret; index++) {
    950			evtlog[index].telem_evtlog = ssram_region.events[index];
    951			evtlog[index].telem_evtid = evtmap[index].evt_id;
    952		}
    953	else
    954		for (index = 0, readlen = 0; (index < ret) && (readlen < len);
    955		     index++) {
    956			for (idx1 = 0; idx1 < len; idx1++) {
    957				/* Elements matched */
    958				if (evtmap[index].evt_id ==
    959				    evtlog[idx1].telem_evtid) {
    960					evtlog[idx1].telem_evtlog =
    961					ssram_region.events[index];
    962					readlen++;
    963
    964					break;
    965				}
    966			}
    967		}
    968
    969	return readlen;
    970}
    971
    972static int telemetry_plt_read_eventlog(enum telemetry_unit telem_unit,
    973		struct telemetry_evtlog *evtlog, int len, int log_all_evts)
    974{
    975	int ret;
    976
    977	mutex_lock(&(telm_conf->telem_lock));
    978	ret = telemetry_plt_raw_read_eventlog(telem_unit, evtlog,
    979					      len, log_all_evts);
    980	mutex_unlock(&(telm_conf->telem_lock));
    981
    982	return ret;
    983}
    984
    985static int telemetry_plt_get_trace_verbosity(enum telemetry_unit telem_unit,
    986					     u32 *verbosity)
    987{
    988	u32 temp = 0;
    989	int ret;
    990
    991	if (verbosity == NULL)
    992		return -EINVAL;
    993
    994	mutex_lock(&(telm_conf->telem_trace_lock));
    995	switch (telem_unit) {
    996	case TELEM_PSS:
    997		ret = intel_punit_ipc_command(
    998				IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
    999				0, 0, NULL, &temp);
   1000		if (ret) {
   1001			pr_err("PSS TRACE_CTRL Read Failed\n");
   1002			goto out;
   1003		}
   1004
   1005		break;
   1006
   1007	case TELEM_IOSS:
   1008		ret = intel_scu_ipc_dev_command(telm_conf->scu,
   1009				IOSS_TELEM, IOSS_TELEM_TRACE_CTL_READ,
   1010				NULL, 0, &temp, sizeof(temp));
   1011		if (ret) {
   1012			pr_err("IOSS TRACE_CTL Read Failed\n");
   1013			goto out;
   1014		}
   1015
   1016		break;
   1017
   1018	default:
   1019		pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
   1020		ret = -EINVAL;
   1021		break;
   1022	}
   1023	TELEM_EXTRACT_VERBOSITY(temp, *verbosity);
   1024
   1025out:
   1026	mutex_unlock(&(telm_conf->telem_trace_lock));
   1027	return ret;
   1028}
   1029
   1030static int telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit,
   1031					     u32 verbosity)
   1032{
   1033	u32 temp = 0;
   1034	int ret;
   1035
   1036	verbosity &= TELEM_TRC_VERBOSITY_MASK;
   1037
   1038	mutex_lock(&(telm_conf->telem_trace_lock));
   1039	switch (telem_unit) {
   1040	case TELEM_PSS:
   1041		ret = intel_punit_ipc_command(
   1042				IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
   1043				0, 0, NULL, &temp);
   1044		if (ret) {
   1045			pr_err("PSS TRACE_CTRL Read Failed\n");
   1046			goto out;
   1047		}
   1048
   1049		TELEM_CLEAR_VERBOSITY_BITS(temp);
   1050		TELEM_SET_VERBOSITY_BITS(temp, verbosity);
   1051
   1052		ret = intel_punit_ipc_command(
   1053				IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL,
   1054				0, 0, &temp, NULL);
   1055		if (ret) {
   1056			pr_err("PSS TRACE_CTRL Verbosity Set Failed\n");
   1057			goto out;
   1058		}
   1059		break;
   1060
   1061	case TELEM_IOSS:
   1062		ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
   1063						IOSS_TELEM_TRACE_CTL_READ,
   1064						NULL, 0, &temp, sizeof(temp));
   1065		if (ret) {
   1066			pr_err("IOSS TRACE_CTL Read Failed\n");
   1067			goto out;
   1068		}
   1069
   1070		TELEM_CLEAR_VERBOSITY_BITS(temp);
   1071		TELEM_SET_VERBOSITY_BITS(temp, verbosity);
   1072
   1073		ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
   1074						IOSS_TELEM_TRACE_CTL_WRITE,
   1075						&temp, sizeof(temp), NULL, 0);
   1076		if (ret) {
   1077			pr_err("IOSS TRACE_CTL Verbosity Set Failed\n");
   1078			goto out;
   1079		}
   1080		break;
   1081
   1082	default:
   1083		pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
   1084		ret = -EINVAL;
   1085		break;
   1086	}
   1087
   1088out:
   1089	mutex_unlock(&(telm_conf->telem_trace_lock));
   1090	return ret;
   1091}
   1092
   1093static const struct telemetry_core_ops telm_pltops = {
   1094	.get_trace_verbosity = telemetry_plt_get_trace_verbosity,
   1095	.set_trace_verbosity = telemetry_plt_set_trace_verbosity,
   1096	.set_sampling_period = telemetry_plt_set_sampling_period,
   1097	.get_sampling_period = telemetry_plt_get_sampling_period,
   1098	.raw_read_eventlog = telemetry_plt_raw_read_eventlog,
   1099	.get_eventconfig = telemetry_plt_get_eventconfig,
   1100	.update_events = telemetry_plt_update_events,
   1101	.read_eventlog = telemetry_plt_read_eventlog,
   1102	.reset_events = telemetry_plt_reset_events,
   1103	.add_events = telemetry_plt_add_events,
   1104};
   1105
   1106static int telemetry_pltdrv_probe(struct platform_device *pdev)
   1107{
   1108	const struct x86_cpu_id *id;
   1109	void __iomem *mem;
   1110	int ret;
   1111
   1112	id = x86_match_cpu(telemetry_cpu_ids);
   1113	if (!id)
   1114		return -ENODEV;
   1115
   1116	telm_conf = (struct telemetry_plt_config *)id->driver_data;
   1117
   1118	telm_conf->pmc = dev_get_drvdata(pdev->dev.parent);
   1119
   1120	mem = devm_platform_ioremap_resource(pdev, 0);
   1121	if (IS_ERR(mem))
   1122		return PTR_ERR(mem);
   1123
   1124	telm_conf->pss_config.regmap = mem;
   1125
   1126	mem = devm_platform_ioremap_resource(pdev, 1);
   1127	if (IS_ERR(mem))
   1128		return PTR_ERR(mem);
   1129
   1130	telm_conf->ioss_config.regmap = mem;
   1131
   1132	telm_conf->scu = devm_intel_scu_ipc_dev_get(&pdev->dev);
   1133	if (!telm_conf->scu) {
   1134		ret = -EPROBE_DEFER;
   1135		goto out;
   1136	}
   1137
   1138	mutex_init(&telm_conf->telem_lock);
   1139	mutex_init(&telm_conf->telem_trace_lock);
   1140
   1141	ret = telemetry_setup(pdev);
   1142	if (ret)
   1143		goto out;
   1144
   1145	ret = telemetry_set_pltdata(&telm_pltops, telm_conf);
   1146	if (ret) {
   1147		dev_err(&pdev->dev, "TELEMETRY Set Pltops Failed.\n");
   1148		goto out;
   1149	}
   1150
   1151	return 0;
   1152
   1153out:
   1154	dev_err(&pdev->dev, "TELEMETRY Setup Failed.\n");
   1155
   1156	return ret;
   1157}
   1158
   1159static int telemetry_pltdrv_remove(struct platform_device *pdev)
   1160{
   1161	telemetry_clear_pltdata();
   1162	return 0;
   1163}
   1164
   1165static struct platform_driver telemetry_soc_driver = {
   1166	.probe		= telemetry_pltdrv_probe,
   1167	.remove		= telemetry_pltdrv_remove,
   1168	.driver		= {
   1169		.name	= DRIVER_NAME,
   1170	},
   1171};
   1172
   1173static int __init telemetry_module_init(void)
   1174{
   1175	return platform_driver_register(&telemetry_soc_driver);
   1176}
   1177
   1178static void __exit telemetry_module_exit(void)
   1179{
   1180	platform_driver_unregister(&telemetry_soc_driver);
   1181}
   1182
   1183device_initcall(telemetry_module_init);
   1184module_exit(telemetry_module_exit);
   1185
   1186MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
   1187MODULE_DESCRIPTION("Intel SoC Telemetry Platform Driver");
   1188MODULE_VERSION(DRIVER_VERSION);
   1189MODULE_LICENSE("GPL v2");