linux/drivers/platform/x86/intel/telemetry/pltdrv.c
<<
>>
Prefs
   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");
1190