platform/x86: intel_telemetry: Move to intel sub-directory
authorKate Hsuan <hpa@redhat.com>
Fri, 20 Aug 2021 11:04:46 +0000 (14:04 +0300)
committerHans de Goede <hdegoede@redhat.com>
Fri, 20 Aug 2021 18:08:09 +0000 (20:08 +0200)
Move Intel telemetry driver to intel sub-directory to improve readability.

While at it, spell APL fully in the Kconfig.

Signed-off-by: Kate Hsuan <hpa@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Rajneesh Bhardwaj <irenic.rajneesh@gmail.com>
Link: https://lore.kernel.org/r/20210820110458.73018-9-andriy.shevchenko@linux.intel.com
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
13 files changed:
MAINTAINERS
drivers/platform/x86/Kconfig
drivers/platform/x86/Makefile
drivers/platform/x86/intel/Kconfig
drivers/platform/x86/intel/Makefile
drivers/platform/x86/intel/telemetry/Kconfig [new file with mode: 0644]
drivers/platform/x86/intel/telemetry/Makefile [new file with mode: 0644]
drivers/platform/x86/intel/telemetry/core.c [new file with mode: 0644]
drivers/platform/x86/intel/telemetry/debugfs.c [new file with mode: 0644]
drivers/platform/x86/intel/telemetry/pltdrv.c [new file with mode: 0644]
drivers/platform/x86/intel_telemetry_core.c [deleted file]
drivers/platform/x86/intel_telemetry_debugfs.c [deleted file]
drivers/platform/x86/intel_telemetry_pltdrv.c [deleted file]

index eefe4edb1b3dcea57e91524be082da764031042e..bb0fcf309cc8cd2f341bdb8b74a65e6a6fcedcbb 100644 (file)
@@ -9559,7 +9559,7 @@ M:        "David E. Box" <david.e.box@linux.intel.com>
 L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
 F:     arch/x86/include/asm/intel_telemetry.h
-F:     drivers/platform/x86/intel_telemetry*
+F:     drivers/platform/x86/intel/telemetry/
 
 INTEL UNCORE FREQUENCY CONTROL
 M:     Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
index aed7570388ef1c650e23babd20e070ede7775bc8..4e42ebac88921d0ddb85a2fdfe72faf845a4b5eb 100644 (file)
@@ -1206,18 +1206,6 @@ config INTEL_SCU_IPC_UTIL
          low level access for debug work and updating the firmware. Say
          N unless you will be doing this on an Intel MID platform.
 
-config INTEL_TELEMETRY
-       tristate "Intel SoC Telemetry Driver"
-       depends on X86_64
-       depends on MFD_INTEL_PMC_BXT
-       depends on INTEL_PUNIT_IPC
-       help
-         This driver provides interfaces to configure and use
-         telemetry for INTEL SoC from APL onwards. It is also
-         used to get various SoC events and parameters
-         directly via debugfs files. Various tools may use
-         this interface for SoC state monitoring.
-
 endif # X86_PLATFORM_DEVICES
 
 config PMC_ATOM
index 1668f736083399ef3ae756c191b0ee5b081fbdb5..bde20c13ceac11062e3b8503b00242b7ce61829d 100644 (file)
@@ -132,7 +132,4 @@ obj-$(CONFIG_INTEL_SCU_PCI)         += intel_scu_pcidrv.o
 obj-$(CONFIG_INTEL_SCU_PLATFORM)       += intel_scu_pltdrv.o
 obj-$(CONFIG_INTEL_SCU_WDT)            += intel_scu_wdt.o
 obj-$(CONFIG_INTEL_SCU_IPC_UTIL)       += intel_scu_ipcutil.o
-obj-$(CONFIG_INTEL_TELEMETRY)          += intel_telemetry_core.o \
-                                          intel_telemetry_pltdrv.o \
-                                          intel_telemetry_debugfs.o
 obj-$(CONFIG_PMC_ATOM)                 += pmc_atom.o
index 7de11636904d9b009390c85ab75ecc8013dee809..379d9e425cc7a65313723b08e37a498ef9bf1d6c 100644 (file)
@@ -21,6 +21,7 @@ source "drivers/platform/x86/intel/int33fe/Kconfig"
 source "drivers/platform/x86/intel/int3472/Kconfig"
 source "drivers/platform/x86/intel/pmc/Kconfig"
 source "drivers/platform/x86/intel/pmt/Kconfig"
+source "drivers/platform/x86/intel/telemetry/Kconfig"
 
 config INTEL_BXTWC_PMIC_TMU
        tristate "Intel Broxton Whiskey Cove TMU Driver"
index a1555a1e421d8174de19bdd95b57ef60c1069a3f..e8c2b1249f87e32397ab52be8d38ca834078499a 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_INTEL_CHT_INT33FE)         += int33fe/
 obj-$(CONFIG_INTEL_SKL_INT3472)                += int3472/
 obj-$(CONFIG_INTEL_PMC_CORE)           += pmc/
 obj-$(CONFIG_INTEL_PMT_CLASS)          += pmt/
+obj-$(CONFIG_INTEL_TELEMETRY)          += telemetry/
 
 # Intel PMIC / PMC / P-Unit drivers
 intel_bxtwc_tmu-y                      := bxtwc_tmu.o
diff --git a/drivers/platform/x86/intel/telemetry/Kconfig b/drivers/platform/x86/intel/telemetry/Kconfig
new file mode 100644 (file)
index 0000000..da887bd
--- /dev/null
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Intel x86 Platform Specific Drivers
+#
+
+config INTEL_TELEMETRY
+       tristate "Intel SoC Telemetry driver"
+       depends on X86_64
+       depends on MFD_INTEL_PMC_BXT
+       depends on INTEL_PUNIT_IPC
+       help
+         This driver provides interfaces to configure and use
+         telemetry for Intel SoC from Apollo Lake onwards.
+         It is also used to get various SoC events and parameters
+         directly via debugfs files. Various tools may use
+         this interface for SoC state monitoring.
diff --git a/drivers/platform/x86/intel/telemetry/Makefile b/drivers/platform/x86/intel/telemetry/Makefile
new file mode 100644 (file)
index 0000000..bfdba5b
--- /dev/null
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Intel x86 Platform Specific Drivers
+#
+
+intel_telemetry_core-y                 := core.o
+obj-$(CONFIG_INTEL_TELEMETRY)          += intel_telemetry_core.o
+intel_telemetry_pltdrv-y               := pltdrv.o
+obj-$(CONFIG_INTEL_TELEMETRY)          += intel_telemetry_pltdrv.o
+intel_telemetry_debugfs-y              := debugfs.o
+obj-$(CONFIG_INTEL_TELEMETRY)          += intel_telemetry_debugfs.o
diff --git a/drivers/platform/x86/intel/telemetry/core.c b/drivers/platform/x86/intel/telemetry/core.c
new file mode 100644 (file)
index 0000000..fdf55b5
--- /dev/null
@@ -0,0 +1,450 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel SoC Core Telemetry Driver
+ * Copyright (C) 2015, Intel Corporation.
+ * All Rights Reserved.
+ *
+ * Telemetry Framework provides platform related PM and performance statistics.
+ * This file provides the core telemetry API implementation.
+ */
+#include <linux/device.h>
+#include <linux/module.h>
+
+#include <asm/intel_telemetry.h>
+
+#define DRIVER_NAME "intel_telemetry_core"
+
+struct telemetry_core_config {
+       struct telemetry_plt_config *plt_config;
+       const struct telemetry_core_ops *telem_ops;
+};
+
+static struct telemetry_core_config telm_core_conf;
+
+static int telemetry_def_update_events(struct telemetry_evtconfig pss_evtconfig,
+                                     struct telemetry_evtconfig ioss_evtconfig)
+{
+       return 0;
+}
+
+static int telemetry_def_set_sampling_period(u8 pss_period, u8 ioss_period)
+{
+       return 0;
+}
+
+static int telemetry_def_get_sampling_period(u8 *pss_min_period,
+                                            u8 *pss_max_period,
+                                            u8 *ioss_min_period,
+                                            u8 *ioss_max_period)
+{
+       return 0;
+}
+
+static int telemetry_def_get_eventconfig(
+                       struct telemetry_evtconfig *pss_evtconfig,
+                       struct telemetry_evtconfig *ioss_evtconfig,
+                       int pss_len, int ioss_len)
+{
+       return 0;
+}
+
+static int telemetry_def_get_trace_verbosity(enum telemetry_unit telem_unit,
+                                            u32 *verbosity)
+{
+       return 0;
+}
+
+
+static int telemetry_def_set_trace_verbosity(enum telemetry_unit telem_unit,
+                                            u32 verbosity)
+{
+       return 0;
+}
+
+static int telemetry_def_raw_read_eventlog(enum telemetry_unit telem_unit,
+                                          struct telemetry_evtlog *evtlog,
+                                          int len, int log_all_evts)
+{
+       return 0;
+}
+
+static int telemetry_def_read_eventlog(enum telemetry_unit telem_unit,
+                                      struct telemetry_evtlog *evtlog,
+                                      int len, int log_all_evts)
+{
+       return 0;
+}
+
+static int telemetry_def_add_events(u8 num_pss_evts, u8 num_ioss_evts,
+                                   u32 *pss_evtmap, u32 *ioss_evtmap)
+{
+       return 0;
+}
+
+static int telemetry_def_reset_events(void)
+{
+       return 0;
+}
+
+static const struct telemetry_core_ops telm_defpltops = {
+       .set_sampling_period = telemetry_def_set_sampling_period,
+       .get_sampling_period = telemetry_def_get_sampling_period,
+       .get_trace_verbosity = telemetry_def_get_trace_verbosity,
+       .set_trace_verbosity = telemetry_def_set_trace_verbosity,
+       .raw_read_eventlog = telemetry_def_raw_read_eventlog,
+       .get_eventconfig = telemetry_def_get_eventconfig,
+       .read_eventlog = telemetry_def_read_eventlog,
+       .update_events = telemetry_def_update_events,
+       .reset_events = telemetry_def_reset_events,
+       .add_events = telemetry_def_add_events,
+};
+
+/**
+ * telemetry_update_events() - Update telemetry Configuration
+ * @pss_evtconfig: PSS related config. No change if num_evts = 0.
+ * @pss_evtconfig: IOSS related config. No change if num_evts = 0.
+ *
+ * This API updates the IOSS & PSS Telemetry configuration. Old config
+ * is overwritten. Call telemetry_reset_events when logging is over
+ * All sample period values should be in the form of:
+ * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_update_events(struct telemetry_evtconfig pss_evtconfig,
+                           struct telemetry_evtconfig ioss_evtconfig)
+{
+       return telm_core_conf.telem_ops->update_events(pss_evtconfig,
+                                                      ioss_evtconfig);
+}
+EXPORT_SYMBOL_GPL(telemetry_update_events);
+
+
+/**
+ * telemetry_set_sampling_period() - Sets the IOSS & PSS sampling period
+ * @pss_period:  placeholder for PSS Period to be set.
+ *              Set to 0 if not required to be updated
+ * @ioss_period: placeholder for IOSS Period to be set
+ *              Set to 0 if not required to be updated
+ *
+ * All values should be in the form of:
+ * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_set_sampling_period(u8 pss_period, u8 ioss_period)
+{
+       return telm_core_conf.telem_ops->set_sampling_period(pss_period,
+                                                            ioss_period);
+}
+EXPORT_SYMBOL_GPL(telemetry_set_sampling_period);
+
+/**
+ * telemetry_get_sampling_period() - Get IOSS & PSS min & max sampling period
+ * @pss_min_period:  placeholder for PSS Min Period supported
+ * @pss_max_period:  placeholder for PSS Max Period supported
+ * @ioss_min_period: placeholder for IOSS Min Period supported
+ * @ioss_max_period: placeholder for IOSS Max Period supported
+ *
+ * All values should be in the form of:
+ * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_get_sampling_period(u8 *pss_min_period, u8 *pss_max_period,
+                                 u8 *ioss_min_period, u8 *ioss_max_period)
+{
+       return telm_core_conf.telem_ops->get_sampling_period(pss_min_period,
+                                                            pss_max_period,
+                                                            ioss_min_period,
+                                                            ioss_max_period);
+}
+EXPORT_SYMBOL_GPL(telemetry_get_sampling_period);
+
+
+/**
+ * telemetry_reset_events() - Restore the IOSS & PSS configuration to default
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_reset_events(void)
+{
+       return telm_core_conf.telem_ops->reset_events();
+}
+EXPORT_SYMBOL_GPL(telemetry_reset_events);
+
+/**
+ * telemetry_get_eventconfig() - Returns the pss and ioss events enabled
+ * @pss_evtconfig: Pointer to PSS related configuration.
+ * @pss_evtconfig: Pointer to IOSS related configuration.
+ * @pss_len:      Number of u32 elements allocated for pss_evtconfig array
+ * @ioss_len:     Number of u32 elements allocated for ioss_evtconfig array
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_get_eventconfig(struct telemetry_evtconfig *pss_evtconfig,
+                             struct telemetry_evtconfig *ioss_evtconfig,
+                             int pss_len, int ioss_len)
+{
+       return telm_core_conf.telem_ops->get_eventconfig(pss_evtconfig,
+                                                        ioss_evtconfig,
+                                                        pss_len, ioss_len);
+}
+EXPORT_SYMBOL_GPL(telemetry_get_eventconfig);
+
+/**
+ * telemetry_add_events() - Add IOSS & PSS configuration to existing settings.
+ * @num_pss_evts:  Number of PSS Events (<29) in pss_evtmap. Can be 0.
+ * @num_ioss_evts: Number of IOSS Events (<29) in ioss_evtmap. Can be 0.
+ * @pss_evtmap:    Array of PSS Event-IDs to Enable
+ * @ioss_evtmap:   Array of PSS Event-IDs to Enable
+ *
+ * Events are appended to Old Configuration. In case of total events > 28, it
+ * returns error. Call telemetry_reset_events to reset after eventlog done
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_add_events(u8 num_pss_evts, u8 num_ioss_evts,
+                        u32 *pss_evtmap, u32 *ioss_evtmap)
+{
+       return telm_core_conf.telem_ops->add_events(num_pss_evts,
+                                                   num_ioss_evts, pss_evtmap,
+                                                   ioss_evtmap);
+}
+EXPORT_SYMBOL_GPL(telemetry_add_events);
+
+/**
+ * telemetry_read_events() - Fetches samples as specified by evtlog.telem_evt_id
+ * @telem_unit: Specify whether IOSS or PSS Read
+ * @evtlog:     Array of telemetry_evtlog structs to fill data
+ *             evtlog.telem_evt_id specifies the ids to read
+ * @len:       Length of array of evtlog
+ *
+ * Return: number of eventlogs read for success, < 0 for failure
+ */
+int telemetry_read_events(enum telemetry_unit telem_unit,
+                         struct telemetry_evtlog *evtlog, int len)
+{
+       return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,
+                                                      len, 0);
+}
+EXPORT_SYMBOL_GPL(telemetry_read_events);
+
+/**
+ * telemetry_raw_read_events() - Fetch samples specified by evtlog.telem_evt_id
+ * @telem_unit: Specify whether IOSS or PSS Read
+ * @evtlog:    Array of telemetry_evtlog structs to fill data
+ *             evtlog.telem_evt_id specifies the ids to read
+ * @len:       Length of array of evtlog
+ *
+ * The caller must take care of locking in this case.
+ *
+ * Return: number of eventlogs read for success, < 0 for failure
+ */
+int telemetry_raw_read_events(enum telemetry_unit telem_unit,
+                             struct telemetry_evtlog *evtlog, int len)
+{
+       return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,
+                                                          len, 0);
+}
+EXPORT_SYMBOL_GPL(telemetry_raw_read_events);
+
+/**
+ * telemetry_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
+ * @telem_unit: Specify whether IOSS or PSS Read
+ * @evtlog:    Array of telemetry_evtlog structs to fill data
+ * @len:       Length of array of evtlog
+ *
+ * Return: number of eventlogs read for success, < 0 for failure
+ */
+int telemetry_read_eventlog(enum telemetry_unit telem_unit,
+                           struct telemetry_evtlog *evtlog, int len)
+{
+       return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,
+                                                      len, 1);
+}
+EXPORT_SYMBOL_GPL(telemetry_read_eventlog);
+
+/**
+ * telemetry_raw_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
+ * @telem_unit: Specify whether IOSS or PSS Read
+ * @evtlog:    Array of telemetry_evtlog structs to fill data
+ * @len:       Length of array of evtlog
+ *
+ * The caller must take care of locking in this case.
+ *
+ * Return: number of eventlogs read for success, < 0 for failure
+ */
+int telemetry_raw_read_eventlog(enum telemetry_unit telem_unit,
+                               struct telemetry_evtlog *evtlog, int len)
+{
+       return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,
+                                                          len, 1);
+}
+EXPORT_SYMBOL_GPL(telemetry_raw_read_eventlog);
+
+
+/**
+ * telemetry_get_trace_verbosity() - Get the IOSS & PSS Trace verbosity
+ * @telem_unit: Specify whether IOSS or PSS Read
+ * @verbosity: Pointer to return Verbosity
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_get_trace_verbosity(enum telemetry_unit telem_unit,
+                                 u32 *verbosity)
+{
+       return telm_core_conf.telem_ops->get_trace_verbosity(telem_unit,
+                                                            verbosity);
+}
+EXPORT_SYMBOL_GPL(telemetry_get_trace_verbosity);
+
+
+/**
+ * telemetry_set_trace_verbosity() - Update the IOSS & PSS Trace verbosity
+ * @telem_unit: Specify whether IOSS or PSS Read
+ * @verbosity: Verbosity to set
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_set_trace_verbosity(enum telemetry_unit telem_unit, u32 verbosity)
+{
+       return telm_core_conf.telem_ops->set_trace_verbosity(telem_unit,
+                                                            verbosity);
+}
+EXPORT_SYMBOL_GPL(telemetry_set_trace_verbosity);
+
+/**
+ * telemetry_set_pltdata() - Set the platform specific Data
+ * @ops:       Pointer to ops structure
+ * @pltconfig: Platform config data
+ *
+ * Usage by other than telemetry pltdrv module is invalid
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_set_pltdata(const struct telemetry_core_ops *ops,
+                         struct telemetry_plt_config *pltconfig)
+{
+       if (ops)
+               telm_core_conf.telem_ops = ops;
+
+       if (pltconfig)
+               telm_core_conf.plt_config = pltconfig;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(telemetry_set_pltdata);
+
+/**
+ * telemetry_clear_pltdata() - Clear the platform specific Data
+ *
+ * Usage by other than telemetry pltdrv module is invalid
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_clear_pltdata(void)
+{
+       telm_core_conf.telem_ops = &telm_defpltops;
+       telm_core_conf.plt_config = NULL;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(telemetry_clear_pltdata);
+
+/**
+ * telemetry_get_pltdata() - Return telemetry platform config
+ *
+ * May be used by other telemetry modules to get platform specific
+ * configuration.
+ */
+struct telemetry_plt_config *telemetry_get_pltdata(void)
+{
+       return telm_core_conf.plt_config;
+}
+EXPORT_SYMBOL_GPL(telemetry_get_pltdata);
+
+static inline int telemetry_get_pssevtname(enum telemetry_unit telem_unit,
+                                          const char **name, int len)
+{
+       struct telemetry_unit_config psscfg;
+       int i;
+
+       if (!telm_core_conf.plt_config)
+               return -EINVAL;
+
+       psscfg = telm_core_conf.plt_config->pss_config;
+
+       if (len > psscfg.ssram_evts_used)
+               len = psscfg.ssram_evts_used;
+
+       for (i = 0; i < len; i++)
+               name[i] = psscfg.telem_evts[i].name;
+
+       return 0;
+}
+
+static inline int telemetry_get_iossevtname(enum telemetry_unit telem_unit,
+                                           const char **name, int len)
+{
+       struct telemetry_unit_config iosscfg;
+       int i;
+
+       if (!(telm_core_conf.plt_config))
+               return -EINVAL;
+
+       iosscfg = telm_core_conf.plt_config->ioss_config;
+
+       if (len > iosscfg.ssram_evts_used)
+               len = iosscfg.ssram_evts_used;
+
+       for (i = 0; i < len; i++)
+               name[i] = iosscfg.telem_evts[i].name;
+
+       return 0;
+
+}
+
+/**
+ * telemetry_get_evtname() - Checkif platform config is valid
+ * @telem_unit:        Telemetry Unit to check
+ * @name:      Array of character pointers to contain name
+ * @len:       length of array name provided by user
+ *
+ * Usage by other than telemetry debugfs module is invalid
+ *
+ * Return: 0 success, < 0 for failure
+ */
+int telemetry_get_evtname(enum telemetry_unit telem_unit,
+                         const char **name, int len)
+{
+       int ret = -EINVAL;
+
+       if (telem_unit == TELEM_PSS)
+               ret = telemetry_get_pssevtname(telem_unit, name, len);
+
+       else if (telem_unit == TELEM_IOSS)
+               ret = telemetry_get_iossevtname(telem_unit, name, len);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(telemetry_get_evtname);
+
+static int __init telemetry_module_init(void)
+{
+       pr_info(pr_fmt(DRIVER_NAME) " Init\n");
+
+       telm_core_conf.telem_ops = &telm_defpltops;
+       return 0;
+}
+
+static void __exit telemetry_module_exit(void)
+{
+}
+
+module_init(telemetry_module_init);
+module_exit(telemetry_module_exit);
+
+MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
+MODULE_DESCRIPTION("Intel SoC Telemetry Interface");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/intel/telemetry/debugfs.c b/drivers/platform/x86/intel/telemetry/debugfs.c
new file mode 100644 (file)
index 0000000..1d4d0fb
--- /dev/null
@@ -0,0 +1,961 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel SOC Telemetry debugfs Driver: Currently supports APL
+ * Copyright (c) 2015, Intel Corporation.
+ * All Rights Reserved.
+ *
+ * This file provides the debugfs interfaces for telemetry.
+ * /sys/kernel/debug/telemetry/pss_info: Shows Primary Control Sub-Sys Counters
+ * /sys/kernel/debug/telemetry/ioss_info: Shows IO Sub-System Counters
+ * /sys/kernel/debug/telemetry/soc_states: Shows SoC State
+ * /sys/kernel/debug/telemetry/pss_trace_verbosity: Read and Change Tracing
+ *                             Verbosity via firmware
+ * /sys/kernel/debug/telemetry/ioss_race_verbosity: Write and Change Tracing
+ *                             Verbosity via firmware
+ */
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/mfd/intel_pmc_bxt.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/seq_file.h>
+#include <linux/suspend.h>
+
+#include <asm/cpu_device_id.h>
+#include <asm/intel-family.h>
+#include <asm/intel_telemetry.h>
+
+#define DRIVER_NAME                    "telemetry_soc_debugfs"
+#define DRIVER_VERSION                 "1.0.0"
+
+/* ApolloLake SoC Event-IDs */
+#define TELEM_APL_PSS_PSTATES_ID       0x2802
+#define TELEM_APL_PSS_IDLE_ID          0x2806
+#define TELEM_APL_PCS_IDLE_BLOCKED_ID  0x2C00
+#define TELEM_APL_PCS_S0IX_BLOCKED_ID  0x2C01
+#define TELEM_APL_PSS_WAKEUP_ID                0x2C02
+#define TELEM_APL_PSS_LTR_BLOCKING_ID  0x2C03
+
+#define TELEM_APL_S0IX_TOTAL_OCC_ID    0x4000
+#define TELEM_APL_S0IX_SHLW_OCC_ID     0x4001
+#define TELEM_APL_S0IX_DEEP_OCC_ID     0x4002
+#define TELEM_APL_S0IX_TOTAL_RES_ID    0x4800
+#define TELEM_APL_S0IX_SHLW_RES_ID     0x4801
+#define TELEM_APL_S0IX_DEEP_RES_ID     0x4802
+#define TELEM_APL_D0IX_ID              0x581A
+#define TELEM_APL_D3_ID                        0x5819
+#define TELEM_APL_PG_ID                        0x5818
+
+#define TELEM_INFO_SRAMEVTS_MASK       0xFF00
+#define TELEM_INFO_SRAMEVTS_SHIFT      0x8
+#define TELEM_SSRAM_READ_TIMEOUT       10
+
+#define TELEM_MASK_BIT                 1
+#define TELEM_MASK_BYTE                        0xFF
+#define BYTES_PER_LONG                 8
+#define TELEM_APL_MASK_PCS_STATE       0xF
+
+/* Max events in bitmap to check for */
+#define TELEM_PSS_IDLE_EVTS            25
+#define TELEM_PSS_IDLE_BLOCKED_EVTS    20
+#define TELEM_PSS_S0IX_BLOCKED_EVTS    20
+#define TELEM_PSS_S0IX_WAKEUP_EVTS     20
+#define TELEM_PSS_LTR_BLOCKING_EVTS    20
+#define TELEM_IOSS_DX_D0IX_EVTS                25
+#define TELEM_IOSS_PG_EVTS             30
+
+#define TELEM_CHECK_AND_PARSE_EVTS(EVTID, EVTNUM, BUF, EVTLOG, EVTDAT, MASK) { \
+       if (evtlog[index].telem_evtid == (EVTID)) { \
+               for (idx = 0; idx < (EVTNUM); idx++) \
+                       (BUF)[idx] = ((EVTLOG) >> (EVTDAT)[idx].bit_pos) & \
+                                    (MASK); \
+       continue; \
+       } \
+}
+
+#define TELEM_CHECK_AND_PARSE_CTRS(EVTID, CTR) { \
+       if (evtlog[index].telem_evtid == (EVTID)) { \
+               (CTR) = evtlog[index].telem_evtlog; \
+               continue; \
+       } \
+}
+
+static u8 suspend_prep_ok;
+static u32 suspend_shlw_ctr_temp, suspend_deep_ctr_temp;
+static u64 suspend_shlw_res_temp, suspend_deep_res_temp;
+
+struct telemetry_susp_stats {
+       u32 shlw_ctr;
+       u32 deep_ctr;
+       u64 shlw_res;
+       u64 deep_res;
+};
+
+/* Bitmap definitions for default counters in APL */
+struct telem_pss_idle_stateinfo {
+       const char *name;
+       u32 bit_pos;
+};
+
+static struct telem_pss_idle_stateinfo telem_apl_pss_idle_data[] = {
+       {"IA_CORE0_C1E",                0},
+       {"IA_CORE1_C1E",                1},
+       {"IA_CORE2_C1E",                2},
+       {"IA_CORE3_C1E",                3},
+       {"IA_CORE0_C6",                 16},
+       {"IA_CORE1_C6",                 17},
+       {"IA_CORE2_C6",                 18},
+       {"IA_CORE3_C6",                 19},
+       {"IA_MODULE0_C7",               32},
+       {"IA_MODULE1_C7",               33},
+       {"GT_RC6",                      40},
+       {"IUNIT_PROCESSING_IDLE",       41},
+       {"FAR_MEM_IDLE",                43},
+       {"DISPLAY_IDLE",                44},
+       {"IUNIT_INPUT_SYSTEM_IDLE",     45},
+       {"PCS_STATUS",                  60},
+};
+
+struct telem_pcs_blkd_info {
+       const char *name;
+       u32 bit_pos;
+};
+
+static struct telem_pcs_blkd_info telem_apl_pcs_idle_blkd_data[] = {
+       {"COMPUTE",                     0},
+       {"MISC",                        8},
+       {"MODULE_ACTIONS_PENDING",      16},
+       {"LTR",                         24},
+       {"DISPLAY_WAKE",                32},
+       {"ISP_WAKE",                    40},
+       {"PSF0_ACTIVE",                 48},
+};
+
+static struct telem_pcs_blkd_info telem_apl_pcs_s0ix_blkd_data[] = {
+       {"LTR",                         0},
+       {"IRTL",                        8},
+       {"WAKE_DEADLINE_PENDING",       16},
+       {"DISPLAY",                     24},
+       {"ISP",                         32},
+       {"CORE",                        40},
+       {"PMC",                         48},
+       {"MISC",                        56},
+};
+
+struct telem_pss_ltr_info {
+       const char *name;
+       u32 bit_pos;
+};
+
+static struct telem_pss_ltr_info telem_apl_pss_ltr_data[] = {
+       {"CORE_ACTIVE",         0},
+       {"MEM_UP",              8},
+       {"DFX",                 16},
+       {"DFX_FORCE_LTR",       24},
+       {"DISPLAY",             32},
+       {"ISP",                 40},
+       {"SOUTH",               48},
+};
+
+struct telem_pss_wakeup_info {
+       const char *name;
+       u32 bit_pos;
+};
+
+static struct telem_pss_wakeup_info telem_apl_pss_wakeup[] = {
+       {"IP_IDLE",                     0},
+       {"DISPLAY_WAKE",                8},
+       {"VOLTAGE_REG_INT",             16},
+       {"DROWSY_TIMER (HOTPLUG)",      24},
+       {"CORE_WAKE",                   32},
+       {"MISC_S0IX",                   40},
+       {"MISC_ABORT",                  56},
+};
+
+struct telem_ioss_d0ix_stateinfo {
+       const char *name;
+       u32 bit_pos;
+};
+
+static struct telem_ioss_d0ix_stateinfo telem_apl_ioss_d0ix_data[] = {
+       {"CSE",         0},
+       {"SCC2",        1},
+       {"GMM",         2},
+       {"XDCI",        3},
+       {"XHCI",        4},
+       {"ISH",         5},
+       {"AVS",         6},
+       {"PCIE0P1",     7},
+       {"PECI0P0",     8},
+       {"LPSS",        9},
+       {"SCC",         10},
+       {"PWM",         11},
+       {"PCIE1_P3",    12},
+       {"PCIE1_P2",    13},
+       {"PCIE1_P1",    14},
+       {"PCIE1_P0",    15},
+       {"CNV",         16},
+       {"SATA",        17},
+       {"PRTC",        18},
+};
+
+struct telem_ioss_pg_info {
+       const char *name;
+       u32 bit_pos;
+};
+
+static struct telem_ioss_pg_info telem_apl_ioss_pg_data[] = {
+       {"LPSS",        0},
+       {"SCC",         1},
+       {"P2SB",        2},
+       {"SCC2",        3},
+       {"GMM",         4},
+       {"PCIE0",       5},
+       {"XDCI",        6},
+       {"xHCI",        7},
+       {"CSE",         8},
+       {"SPI",         9},
+       {"AVSPGD4",     10},
+       {"AVSPGD3",     11},
+       {"AVSPGD2",     12},
+       {"AVSPGD1",     13},
+       {"ISH",         14},
+       {"EXI",         15},
+       {"NPKVRC",      16},
+       {"NPKVNN",      17},
+       {"CUNIT",       18},
+       {"FUSE_CTRL",   19},
+       {"PCIE1",       20},
+       {"CNV",         21},
+       {"LPC",         22},
+       {"SATA",        23},
+       {"SMB",         24},
+       {"PRTC",        25},
+};
+
+struct telemetry_debugfs_conf {
+       struct telemetry_susp_stats suspend_stats;
+       struct dentry *telemetry_dbg_dir;
+
+       /* Bitmap Data */
+       struct telem_ioss_d0ix_stateinfo *ioss_d0ix_data;
+       struct telem_pss_idle_stateinfo *pss_idle_data;
+       struct telem_pcs_blkd_info *pcs_idle_blkd_data;
+       struct telem_pcs_blkd_info *pcs_s0ix_blkd_data;
+       struct telem_pss_wakeup_info *pss_wakeup;
+       struct telem_pss_ltr_info *pss_ltr_data;
+       struct telem_ioss_pg_info *ioss_pg_data;
+       u8 pcs_idle_blkd_evts;
+       u8 pcs_s0ix_blkd_evts;
+       u8 pss_wakeup_evts;
+       u8 pss_idle_evts;
+       u8 pss_ltr_evts;
+       u8 ioss_d0ix_evts;
+       u8 ioss_pg_evts;
+
+       /* IDs */
+       u16  pss_ltr_blocking_id;
+       u16  pcs_idle_blkd_id;
+       u16  pcs_s0ix_blkd_id;
+       u16  s0ix_total_occ_id;
+       u16  s0ix_shlw_occ_id;
+       u16  s0ix_deep_occ_id;
+       u16  s0ix_total_res_id;
+       u16  s0ix_shlw_res_id;
+       u16  s0ix_deep_res_id;
+       u16  pss_wakeup_id;
+       u16  ioss_d0ix_id;
+       u16  pstates_id;
+       u16  pss_idle_id;
+       u16  ioss_d3_id;
+       u16  ioss_pg_id;
+};
+
+static struct telemetry_debugfs_conf *debugfs_conf;
+
+static struct telemetry_debugfs_conf telem_apl_debugfs_conf = {
+       .pss_idle_data = telem_apl_pss_idle_data,
+       .pcs_idle_blkd_data = telem_apl_pcs_idle_blkd_data,
+       .pcs_s0ix_blkd_data = telem_apl_pcs_s0ix_blkd_data,
+       .pss_ltr_data = telem_apl_pss_ltr_data,
+       .pss_wakeup = telem_apl_pss_wakeup,
+       .ioss_d0ix_data = telem_apl_ioss_d0ix_data,
+       .ioss_pg_data = telem_apl_ioss_pg_data,
+
+       .pss_idle_evts = ARRAY_SIZE(telem_apl_pss_idle_data),
+       .pcs_idle_blkd_evts = ARRAY_SIZE(telem_apl_pcs_idle_blkd_data),
+       .pcs_s0ix_blkd_evts = ARRAY_SIZE(telem_apl_pcs_s0ix_blkd_data),
+       .pss_ltr_evts = ARRAY_SIZE(telem_apl_pss_ltr_data),
+       .pss_wakeup_evts = ARRAY_SIZE(telem_apl_pss_wakeup),
+       .ioss_d0ix_evts = ARRAY_SIZE(telem_apl_ioss_d0ix_data),
+       .ioss_pg_evts = ARRAY_SIZE(telem_apl_ioss_pg_data),
+
+       .pstates_id = TELEM_APL_PSS_PSTATES_ID,
+       .pss_idle_id = TELEM_APL_PSS_IDLE_ID,
+       .pcs_idle_blkd_id = TELEM_APL_PCS_IDLE_BLOCKED_ID,
+       .pcs_s0ix_blkd_id = TELEM_APL_PCS_S0IX_BLOCKED_ID,
+       .pss_wakeup_id = TELEM_APL_PSS_WAKEUP_ID,
+       .pss_ltr_blocking_id = TELEM_APL_PSS_LTR_BLOCKING_ID,
+       .s0ix_total_occ_id = TELEM_APL_S0IX_TOTAL_OCC_ID,
+       .s0ix_shlw_occ_id = TELEM_APL_S0IX_SHLW_OCC_ID,
+       .s0ix_deep_occ_id = TELEM_APL_S0IX_DEEP_OCC_ID,
+       .s0ix_total_res_id = TELEM_APL_S0IX_TOTAL_RES_ID,
+       .s0ix_shlw_res_id = TELEM_APL_S0IX_SHLW_RES_ID,
+       .s0ix_deep_res_id = TELEM_APL_S0IX_DEEP_RES_ID,
+       .ioss_d0ix_id = TELEM_APL_D0IX_ID,
+       .ioss_d3_id = TELEM_APL_D3_ID,
+       .ioss_pg_id = TELEM_APL_PG_ID,
+};
+
+static const struct x86_cpu_id telemetry_debugfs_cpu_ids[] = {
+       X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT,       &telem_apl_debugfs_conf),
+       X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS,  &telem_apl_debugfs_conf),
+       {}
+};
+MODULE_DEVICE_TABLE(x86cpu, telemetry_debugfs_cpu_ids);
+
+static int telemetry_debugfs_check_evts(void)
+{
+       if ((debugfs_conf->pss_idle_evts > TELEM_PSS_IDLE_EVTS) ||
+           (debugfs_conf->pcs_idle_blkd_evts > TELEM_PSS_IDLE_BLOCKED_EVTS) ||
+           (debugfs_conf->pcs_s0ix_blkd_evts > TELEM_PSS_S0IX_BLOCKED_EVTS) ||
+           (debugfs_conf->pss_ltr_evts > TELEM_PSS_LTR_BLOCKING_EVTS) ||
+           (debugfs_conf->pss_wakeup_evts > TELEM_PSS_S0IX_WAKEUP_EVTS) ||
+           (debugfs_conf->ioss_d0ix_evts > TELEM_IOSS_DX_D0IX_EVTS) ||
+           (debugfs_conf->ioss_pg_evts > TELEM_IOSS_PG_EVTS))
+               return -EINVAL;
+
+       return 0;
+}
+
+static int telem_pss_states_show(struct seq_file *s, void *unused)
+{
+       struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
+       struct telemetry_debugfs_conf *conf = debugfs_conf;
+       const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
+       u32 pcs_idle_blkd[TELEM_PSS_IDLE_BLOCKED_EVTS],
+           pcs_s0ix_blkd[TELEM_PSS_S0IX_BLOCKED_EVTS],
+           pss_s0ix_wakeup[TELEM_PSS_S0IX_WAKEUP_EVTS],
+           pss_ltr_blkd[TELEM_PSS_LTR_BLOCKING_EVTS],
+           pss_idle[TELEM_PSS_IDLE_EVTS];
+       int index, idx, ret, err = 0;
+       u64 pstates = 0;
+
+       ret = telemetry_read_eventlog(TELEM_PSS, evtlog,
+                                     TELEM_MAX_OS_ALLOCATED_EVENTS);
+       if (ret < 0)
+               return ret;
+
+       err = telemetry_get_evtname(TELEM_PSS, name,
+                                   TELEM_MAX_OS_ALLOCATED_EVENTS);
+       if (err < 0)
+               return err;
+
+       seq_puts(s, "\n----------------------------------------------------\n");
+       seq_puts(s, "\tPSS TELEM EVENTLOG (Residency = field/19.2 us\n");
+       seq_puts(s, "----------------------------------------------------\n");
+       for (index = 0; index < ret; index++) {
+               seq_printf(s, "%-32s %llu\n",
+                          name[index], evtlog[index].telem_evtlog);
+
+               /* Fetch PSS IDLE State */
+               if (evtlog[index].telem_evtid == conf->pss_idle_id) {
+                       pss_idle[conf->pss_idle_evts - 1] =
+                       (evtlog[index].telem_evtlog >>
+                       conf->pss_idle_data[conf->pss_idle_evts - 1].bit_pos) &
+                       TELEM_APL_MASK_PCS_STATE;
+               }
+
+               TELEM_CHECK_AND_PARSE_EVTS(conf->pss_idle_id,
+                                          conf->pss_idle_evts - 1,
+                                          pss_idle, evtlog[index].telem_evtlog,
+                                          conf->pss_idle_data, TELEM_MASK_BIT);
+
+               TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_idle_blkd_id,
+                                          conf->pcs_idle_blkd_evts,
+                                          pcs_idle_blkd,
+                                          evtlog[index].telem_evtlog,
+                                          conf->pcs_idle_blkd_data,
+                                          TELEM_MASK_BYTE);
+
+               TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_s0ix_blkd_id,
+                                          conf->pcs_s0ix_blkd_evts,
+                                          pcs_s0ix_blkd,
+                                          evtlog[index].telem_evtlog,
+                                          conf->pcs_s0ix_blkd_data,
+                                          TELEM_MASK_BYTE);
+
+               TELEM_CHECK_AND_PARSE_EVTS(conf->pss_wakeup_id,
+                                          conf->pss_wakeup_evts,
+                                          pss_s0ix_wakeup,
+                                          evtlog[index].telem_evtlog,
+                                          conf->pss_wakeup, TELEM_MASK_BYTE);
+
+               TELEM_CHECK_AND_PARSE_EVTS(conf->pss_ltr_blocking_id,
+                                          conf->pss_ltr_evts, pss_ltr_blkd,
+                                          evtlog[index].telem_evtlog,
+                                          conf->pss_ltr_data, TELEM_MASK_BYTE);
+
+               if (evtlog[index].telem_evtid == debugfs_conf->pstates_id)
+                       pstates = evtlog[index].telem_evtlog;
+       }
+
+       seq_puts(s, "\n--------------------------------------\n");
+       seq_puts(s, "PStates\n");
+       seq_puts(s, "--------------------------------------\n");
+       seq_puts(s, "Domain\t\t\t\tFreq(Mhz)\n");
+       seq_printf(s, " IA\t\t\t\t %llu\n GT\t\t\t\t %llu\n",
+                  (pstates & TELEM_MASK_BYTE)*100,
+                  ((pstates >> 8) & TELEM_MASK_BYTE)*50/3);
+
+       seq_printf(s, " IUNIT\t\t\t\t %llu\n SA\t\t\t\t %llu\n",
+                  ((pstates >> 16) & TELEM_MASK_BYTE)*25,
+                  ((pstates >> 24) & TELEM_MASK_BYTE)*50/3);
+
+       seq_puts(s, "\n--------------------------------------\n");
+       seq_puts(s, "PSS IDLE Status\n");
+       seq_puts(s, "--------------------------------------\n");
+       seq_puts(s, "Device\t\t\t\t\tIDLE\n");
+       for (index = 0; index < debugfs_conf->pss_idle_evts; index++) {
+               seq_printf(s, "%-32s\t%u\n",
+                          debugfs_conf->pss_idle_data[index].name,
+                          pss_idle[index]);
+       }
+
+       seq_puts(s, "\n--------------------------------------\n");
+       seq_puts(s, "PSS Idle blkd Status (~1ms saturating bucket)\n");
+       seq_puts(s, "--------------------------------------\n");
+       seq_puts(s, "Blocker\t\t\t\t\tCount\n");
+       for (index = 0; index < debugfs_conf->pcs_idle_blkd_evts; index++) {
+               seq_printf(s, "%-32s\t%u\n",
+                          debugfs_conf->pcs_idle_blkd_data[index].name,
+                          pcs_idle_blkd[index]);
+       }
+
+       seq_puts(s, "\n--------------------------------------\n");
+       seq_puts(s, "PSS S0ix blkd Status (~1ms saturating bucket)\n");
+       seq_puts(s, "--------------------------------------\n");
+       seq_puts(s, "Blocker\t\t\t\t\tCount\n");
+       for (index = 0; index < debugfs_conf->pcs_s0ix_blkd_evts; index++) {
+               seq_printf(s, "%-32s\t%u\n",
+                          debugfs_conf->pcs_s0ix_blkd_data[index].name,
+                          pcs_s0ix_blkd[index]);
+       }
+
+       seq_puts(s, "\n--------------------------------------\n");
+       seq_puts(s, "LTR Blocking Status (~1ms saturating bucket)\n");
+       seq_puts(s, "--------------------------------------\n");
+       seq_puts(s, "Blocker\t\t\t\t\tCount\n");
+       for (index = 0; index < debugfs_conf->pss_ltr_evts; index++) {
+               seq_printf(s, "%-32s\t%u\n",
+                          debugfs_conf->pss_ltr_data[index].name,
+                          pss_s0ix_wakeup[index]);
+       }
+
+       seq_puts(s, "\n--------------------------------------\n");
+       seq_puts(s, "Wakes Status (~1ms saturating bucket)\n");
+       seq_puts(s, "--------------------------------------\n");
+       seq_puts(s, "Wakes\t\t\t\t\tCount\n");
+       for (index = 0; index < debugfs_conf->pss_wakeup_evts; index++) {
+               seq_printf(s, "%-32s\t%u\n",
+                          debugfs_conf->pss_wakeup[index].name,
+                          pss_ltr_blkd[index]);
+       }
+
+       return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(telem_pss_states);
+
+static int telem_ioss_states_show(struct seq_file *s, void *unused)
+{
+       struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
+       const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
+       int index, ret, err;
+
+       ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
+                                     TELEM_MAX_OS_ALLOCATED_EVENTS);
+       if (ret < 0)
+               return ret;
+
+       err = telemetry_get_evtname(TELEM_IOSS, name,
+                                   TELEM_MAX_OS_ALLOCATED_EVENTS);
+       if (err < 0)
+               return err;
+
+       seq_puts(s, "--------------------------------------\n");
+       seq_puts(s, "\tI0SS TELEMETRY EVENTLOG\n");
+       seq_puts(s, "--------------------------------------\n");
+       for (index = 0; index < ret; index++) {
+               seq_printf(s, "%-32s 0x%llx\n",
+                          name[index], evtlog[index].telem_evtlog);
+       }
+
+       return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(telem_ioss_states);
+
+static int telem_soc_states_show(struct seq_file *s, void *unused)
+{
+       u32 d3_sts[TELEM_IOSS_DX_D0IX_EVTS], d0ix_sts[TELEM_IOSS_DX_D0IX_EVTS];
+       u32 pg_sts[TELEM_IOSS_PG_EVTS], pss_idle[TELEM_PSS_IDLE_EVTS];
+       struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
+       u32 s0ix_total_ctr = 0, s0ix_shlw_ctr = 0, s0ix_deep_ctr = 0;
+       u64 s0ix_total_res = 0, s0ix_shlw_res = 0, s0ix_deep_res = 0;
+       struct telemetry_debugfs_conf *conf = debugfs_conf;
+       struct pci_dev *dev = NULL;
+       int index, idx, ret;
+       u32 d3_state;
+       u16 pmcsr;
+
+       ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
+                                     TELEM_MAX_OS_ALLOCATED_EVENTS);
+       if (ret < 0)
+               return ret;
+
+       for (index = 0; index < ret; index++) {
+               TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d3_id,
+                                          conf->ioss_d0ix_evts,
+                                          d3_sts, evtlog[index].telem_evtlog,
+                                          conf->ioss_d0ix_data,
+                                          TELEM_MASK_BIT);
+
+               TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_pg_id, conf->ioss_pg_evts,
+                                          pg_sts, evtlog[index].telem_evtlog,
+                                          conf->ioss_pg_data, TELEM_MASK_BIT);
+
+               TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d0ix_id,
+                                          conf->ioss_d0ix_evts,
+                                          d0ix_sts, evtlog[index].telem_evtlog,
+                                          conf->ioss_d0ix_data,
+                                          TELEM_MASK_BIT);
+
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_occ_id,
+                                          s0ix_total_ctr);
+
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
+                                          s0ix_shlw_ctr);
+
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
+                                          s0ix_deep_ctr);
+
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_res_id,
+                                          s0ix_total_res);
+
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
+                                          s0ix_shlw_res);
+
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
+                                          s0ix_deep_res);
+       }
+
+       seq_puts(s, "\n---------------------------------------------------\n");
+       seq_puts(s, "S0IX Type\t\t\t Occurrence\t\t Residency(us)\n");
+       seq_puts(s, "---------------------------------------------------\n");
+
+       seq_printf(s, "S0IX Shallow\t\t\t %10u\t %10llu\n",
+                  s0ix_shlw_ctr -
+                  conf->suspend_stats.shlw_ctr,
+                  (u64)((s0ix_shlw_res -
+                  conf->suspend_stats.shlw_res)*10/192));
+
+       seq_printf(s, "S0IX Deep\t\t\t %10u\t %10llu\n",
+                  s0ix_deep_ctr -
+                  conf->suspend_stats.deep_ctr,
+                  (u64)((s0ix_deep_res -
+                  conf->suspend_stats.deep_res)*10/192));
+
+       seq_printf(s, "Suspend(With S0ixShallow)\t %10u\t %10llu\n",
+                  conf->suspend_stats.shlw_ctr,
+                  (u64)(conf->suspend_stats.shlw_res*10)/192);
+
+       seq_printf(s, "Suspend(With S0ixDeep)\t\t %10u\t %10llu\n",
+                  conf->suspend_stats.deep_ctr,
+                  (u64)(conf->suspend_stats.deep_res*10)/192);
+
+       seq_printf(s, "TOTAL S0IX\t\t\t %10u\t %10llu\n", s0ix_total_ctr,
+                  (u64)(s0ix_total_res*10/192));
+       seq_puts(s, "\n-------------------------------------------------\n");
+       seq_puts(s, "\t\tDEVICE STATES\n");
+       seq_puts(s, "-------------------------------------------------\n");
+
+       for_each_pci_dev(dev) {
+               pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
+               d3_state = ((pmcsr & PCI_PM_CTRL_STATE_MASK) ==
+                           (__force int)PCI_D3hot) ? 1 : 0;
+
+               seq_printf(s, "pci %04x %04X %s %20.20s: ",
+                          dev->vendor, dev->device, dev_name(&dev->dev),
+                          dev_driver_string(&dev->dev));
+               seq_printf(s, " d3:%x\n", d3_state);
+       }
+
+       seq_puts(s, "\n--------------------------------------\n");
+       seq_puts(s, "D3/D0i3 Status\n");
+       seq_puts(s, "--------------------------------------\n");
+       seq_puts(s, "Block\t\t D3\t D0i3\n");
+       for (index = 0; index < conf->ioss_d0ix_evts; index++) {
+               seq_printf(s, "%-10s\t %u\t %u\n",
+                          conf->ioss_d0ix_data[index].name,
+                          d3_sts[index], d0ix_sts[index]);
+       }
+
+       seq_puts(s, "\n--------------------------------------\n");
+       seq_puts(s, "South Complex PowerGate Status\n");
+       seq_puts(s, "--------------------------------------\n");
+       seq_puts(s, "Device\t\t PG\n");
+       for (index = 0; index < conf->ioss_pg_evts; index++) {
+               seq_printf(s, "%-10s\t %u\n",
+                          conf->ioss_pg_data[index].name,
+                          pg_sts[index]);
+       }
+
+       evtlog->telem_evtid = conf->pss_idle_id;
+       ret = telemetry_read_events(TELEM_PSS, evtlog, 1);
+       if (ret < 0)
+               return ret;
+
+       seq_puts(s, "\n-----------------------------------------\n");
+       seq_puts(s, "North Idle Status\n");
+       seq_puts(s, "-----------------------------------------\n");
+       for (idx = 0; idx < conf->pss_idle_evts - 1; idx++) {
+               pss_idle[idx] = (evtlog->telem_evtlog >>
+                               conf->pss_idle_data[idx].bit_pos) &
+                               TELEM_MASK_BIT;
+       }
+
+       pss_idle[idx] = (evtlog->telem_evtlog >>
+                       conf->pss_idle_data[idx].bit_pos) &
+                       TELEM_APL_MASK_PCS_STATE;
+
+       for (index = 0; index < conf->pss_idle_evts; index++) {
+               seq_printf(s, "%-30s %u\n",
+                          conf->pss_idle_data[index].name,
+                          pss_idle[index]);
+       }
+
+       seq_puts(s, "\nPCS_STATUS Code\n");
+       seq_puts(s, "0:C0 1:C1 2:C1_DN_WT_DEV 3:C2 4:C2_WT_DE_MEM_UP\n");
+       seq_puts(s, "5:C2_WT_DE_MEM_DOWN 6:C2_UP_WT_DEV 7:C2_DN 8:C2_VOA\n");
+       seq_puts(s, "9:C2_VOA_UP 10:S0IX_PRE 11:S0IX\n");
+
+       return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(telem_soc_states);
+
+static int telem_s0ix_res_get(void *data, u64 *val)
+{
+       struct telemetry_plt_config *plt_config = telemetry_get_pltdata();
+       u64 s0ix_total_res;
+       int ret;
+
+       ret = intel_pmc_s0ix_counter_read(plt_config->pmc, &s0ix_total_res);
+       if (ret) {
+               pr_err("Failed to read S0ix residency");
+               return ret;
+       }
+
+       *val = s0ix_total_res;
+
+       return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(telem_s0ix_fops, telem_s0ix_res_get, NULL, "%llu\n");
+
+static int telem_pss_trc_verb_show(struct seq_file *s, void *unused)
+{
+       u32 verbosity;
+       int err;
+
+       err = telemetry_get_trace_verbosity(TELEM_PSS, &verbosity);
+       if (err) {
+               pr_err("Get PSS Trace Verbosity Failed with Error %d\n", err);
+               return -EFAULT;
+       }
+
+       seq_printf(s, "PSS Trace Verbosity %u\n", verbosity);
+       return 0;
+}
+
+static ssize_t telem_pss_trc_verb_write(struct file *file,
+                                       const char __user *userbuf,
+                                       size_t count, loff_t *ppos)
+{
+       u32 verbosity;
+       int err;
+
+       err = kstrtou32_from_user(userbuf, count, 0, &verbosity);
+       if (err)
+               return err;
+
+       err = telemetry_set_trace_verbosity(TELEM_PSS, verbosity);
+       if (err) {
+               pr_err("Changing PSS Trace Verbosity Failed. Error %d\n", err);
+               return err;
+       }
+
+       return count;
+}
+
+static int telem_pss_trc_verb_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, telem_pss_trc_verb_show, inode->i_private);
+}
+
+static const struct file_operations telem_pss_trc_verb_ops = {
+       .open           = telem_pss_trc_verb_open,
+       .read           = seq_read,
+       .write          = telem_pss_trc_verb_write,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int telem_ioss_trc_verb_show(struct seq_file *s, void *unused)
+{
+       u32 verbosity;
+       int err;
+
+       err = telemetry_get_trace_verbosity(TELEM_IOSS, &verbosity);
+       if (err) {
+               pr_err("Get IOSS Trace Verbosity Failed with Error %d\n", err);
+               return -EFAULT;
+       }
+
+       seq_printf(s, "IOSS Trace Verbosity %u\n", verbosity);
+       return 0;
+}
+
+static ssize_t telem_ioss_trc_verb_write(struct file *file,
+                                        const char __user *userbuf,
+                                        size_t count, loff_t *ppos)
+{
+       u32 verbosity;
+       int err;
+
+       err = kstrtou32_from_user(userbuf, count, 0, &verbosity);
+       if (err)
+               return err;
+
+       err = telemetry_set_trace_verbosity(TELEM_IOSS, verbosity);
+       if (err) {
+               pr_err("Changing IOSS Trace Verbosity Failed. Error %d\n", err);
+               return err;
+       }
+
+       return count;
+}
+
+static int telem_ioss_trc_verb_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, telem_ioss_trc_verb_show, inode->i_private);
+}
+
+static const struct file_operations telem_ioss_trc_verb_ops = {
+       .open           = telem_ioss_trc_verb_open,
+       .read           = seq_read,
+       .write          = telem_ioss_trc_verb_write,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int pm_suspend_prep_cb(void)
+{
+       struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
+       struct telemetry_debugfs_conf *conf = debugfs_conf;
+       int ret, index;
+
+       ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
+                       TELEM_MAX_OS_ALLOCATED_EVENTS);
+       if (ret < 0) {
+               suspend_prep_ok = 0;
+               goto out;
+       }
+
+       for (index = 0; index < ret; index++) {
+
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
+                                          suspend_shlw_ctr_temp);
+
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
+                                          suspend_deep_ctr_temp);
+
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
+                                          suspend_shlw_res_temp);
+
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
+                                          suspend_deep_res_temp);
+       }
+       suspend_prep_ok = 1;
+out:
+       return NOTIFY_OK;
+}
+
+static int pm_suspend_exit_cb(void)
+{
+       struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
+       static u32 suspend_shlw_ctr_exit, suspend_deep_ctr_exit;
+       static u64 suspend_shlw_res_exit, suspend_deep_res_exit;
+       struct telemetry_debugfs_conf *conf = debugfs_conf;
+       int ret, index;
+
+       if (!suspend_prep_ok)
+               goto out;
+
+       ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
+                                         TELEM_MAX_OS_ALLOCATED_EVENTS);
+       if (ret < 0)
+               goto out;
+
+       for (index = 0; index < ret; index++) {
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
+                                          suspend_shlw_ctr_exit);
+
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
+                                          suspend_deep_ctr_exit);
+
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
+                                          suspend_shlw_res_exit);
+
+               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
+                                          suspend_deep_res_exit);
+       }
+
+       if ((suspend_shlw_ctr_exit < suspend_shlw_ctr_temp) ||
+           (suspend_deep_ctr_exit < suspend_deep_ctr_temp) ||
+           (suspend_shlw_res_exit < suspend_shlw_res_temp) ||
+           (suspend_deep_res_exit < suspend_deep_res_temp)) {
+               pr_err("Wrong s0ix counters detected\n");
+               goto out;
+       }
+
+       /*
+        * Due to some design limitations in the firmware, sometimes the
+        * counters do not get updated by the time we reach here. As a
+        * workaround, we try to see if this was a genuine case of sleep
+        * failure or not by cross-checking from PMC GCR registers directly.
+        */
+       if (suspend_shlw_ctr_exit == suspend_shlw_ctr_temp &&
+           suspend_deep_ctr_exit == suspend_deep_ctr_temp) {
+               struct telemetry_plt_config *plt_config = telemetry_get_pltdata();
+               struct intel_pmc_dev *pmc = plt_config->pmc;
+
+               ret = intel_pmc_gcr_read64(pmc, PMC_GCR_TELEM_SHLW_S0IX_REG,
+                                         &suspend_shlw_res_exit);
+               if (ret < 0)
+                       goto out;
+
+               ret = intel_pmc_gcr_read64(pmc, PMC_GCR_TELEM_DEEP_S0IX_REG,
+                                         &suspend_deep_res_exit);
+               if (ret < 0)
+                       goto out;
+
+               if (suspend_shlw_res_exit > suspend_shlw_res_temp)
+                       suspend_shlw_ctr_exit++;
+
+               if (suspend_deep_res_exit > suspend_deep_res_temp)
+                       suspend_deep_ctr_exit++;
+       }
+
+       suspend_shlw_ctr_exit -= suspend_shlw_ctr_temp;
+       suspend_deep_ctr_exit -= suspend_deep_ctr_temp;
+       suspend_shlw_res_exit -= suspend_shlw_res_temp;
+       suspend_deep_res_exit -= suspend_deep_res_temp;
+
+       if (suspend_shlw_ctr_exit != 0) {
+               conf->suspend_stats.shlw_ctr +=
+               suspend_shlw_ctr_exit;
+
+               conf->suspend_stats.shlw_res +=
+               suspend_shlw_res_exit;
+       }
+
+       if (suspend_deep_ctr_exit != 0) {
+               conf->suspend_stats.deep_ctr +=
+               suspend_deep_ctr_exit;
+
+               conf->suspend_stats.deep_res +=
+               suspend_deep_res_exit;
+       }
+
+out:
+       suspend_prep_ok = 0;
+       return NOTIFY_OK;
+}
+
+static int pm_notification(struct notifier_block *this,
+                          unsigned long event, void *ptr)
+{
+       switch (event) {
+       case PM_SUSPEND_PREPARE:
+               return pm_suspend_prep_cb();
+       case PM_POST_SUSPEND:
+               return pm_suspend_exit_cb();
+       }
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block pm_notifier = {
+       .notifier_call = pm_notification,
+};
+
+static int __init telemetry_debugfs_init(void)
+{
+       const struct x86_cpu_id *id;
+       int err;
+       struct dentry *dir;
+
+       /* Only APL supported for now */
+       id = x86_match_cpu(telemetry_debugfs_cpu_ids);
+       if (!id)
+               return -ENODEV;
+
+       debugfs_conf = (struct telemetry_debugfs_conf *)id->driver_data;
+
+       if (!telemetry_get_pltdata()) {
+               pr_info("Invalid pltconfig, ensure IPC1 device is enabled in BIOS\n");
+               return -ENODEV;
+       }
+
+       err = telemetry_debugfs_check_evts();
+       if (err < 0) {
+               pr_info("telemetry_debugfs_check_evts failed\n");
+               return -EINVAL;
+       }
+
+       register_pm_notifier(&pm_notifier);
+
+       dir = debugfs_create_dir("telemetry", NULL);
+       debugfs_conf->telemetry_dbg_dir = dir;
+
+       debugfs_create_file("pss_info", S_IFREG | S_IRUGO, dir, NULL,
+                           &telem_pss_states_fops);
+       debugfs_create_file("ioss_info", S_IFREG | S_IRUGO, dir, NULL,
+                           &telem_ioss_states_fops);
+       debugfs_create_file("soc_states", S_IFREG | S_IRUGO, dir, NULL,
+                           &telem_soc_states_fops);
+       debugfs_create_file("s0ix_residency_usec", S_IFREG | S_IRUGO, dir, NULL,
+                           &telem_s0ix_fops);
+       debugfs_create_file("pss_trace_verbosity", S_IFREG | S_IRUGO, dir, NULL,
+                           &telem_pss_trc_verb_ops);
+       debugfs_create_file("ioss_trace_verbosity", S_IFREG | S_IRUGO, dir,
+                           NULL, &telem_ioss_trc_verb_ops);
+       return 0;
+}
+
+static void __exit telemetry_debugfs_exit(void)
+{
+       debugfs_remove_recursive(debugfs_conf->telemetry_dbg_dir);
+       debugfs_conf->telemetry_dbg_dir = NULL;
+       unregister_pm_notifier(&pm_notifier);
+}
+
+late_initcall(telemetry_debugfs_init);
+module_exit(telemetry_debugfs_exit);
+
+MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
+MODULE_DESCRIPTION("Intel SoC Telemetry debugfs Interface");
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/intel/telemetry/pltdrv.c b/drivers/platform/x86/intel/telemetry/pltdrv.c
new file mode 100644 (file)
index 0000000..405dea8
--- /dev/null
@@ -0,0 +1,1189 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel SOC Telemetry Platform Driver: Currently supports APL
+ * Copyright (c) 2015, Intel Corporation.
+ * All Rights Reserved.
+ *
+ * This file provides the platform specific telemetry implementation for APL.
+ * It used the PUNIT and PMC IPC interfaces for configuring the counters.
+ * The accumulated results are fetched from SRAM.
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/cpu_device_id.h>
+#include <asm/intel-family.h>
+#include <asm/intel_punit_ipc.h>
+#include <asm/intel_telemetry.h>
+
+#define DRIVER_NAME    "intel_telemetry"
+#define DRIVER_VERSION "1.0.0"
+
+#define TELEM_TRC_VERBOSITY_MASK       0x3
+
+#define TELEM_MIN_PERIOD(x)            ((x) & 0x7F0000)
+#define TELEM_MAX_PERIOD(x)            ((x) & 0x7F000000)
+#define TELEM_SAMPLE_PERIOD_INVALID(x) ((x) & (BIT(7)))
+#define TELEM_CLEAR_SAMPLE_PERIOD(x)   ((x) &= ~0x7F)
+
+#define TELEM_SAMPLING_DEFAULT_PERIOD  0xD
+
+#define TELEM_MAX_EVENTS_SRAM          28
+#define TELEM_SSRAM_STARTTIME_OFFSET   8
+#define TELEM_SSRAM_EVTLOG_OFFSET      16
+
+#define IOSS_TELEM                     0xeb
+#define IOSS_TELEM_EVENT_READ          0x0
+#define IOSS_TELEM_EVENT_WRITE         0x1
+#define IOSS_TELEM_INFO_READ           0x2
+#define IOSS_TELEM_TRACE_CTL_READ      0x5
+#define IOSS_TELEM_TRACE_CTL_WRITE     0x6
+#define IOSS_TELEM_EVENT_CTL_READ      0x7
+#define IOSS_TELEM_EVENT_CTL_WRITE     0x8
+#define IOSS_TELEM_EVT_WRITE_SIZE      0x3
+
+#define TELEM_INFO_SRAMEVTS_MASK       0xFF00
+#define TELEM_INFO_SRAMEVTS_SHIFT      0x8
+#define TELEM_SSRAM_READ_TIMEOUT       10
+
+#define TELEM_INFO_NENABLES_MASK       0xFF
+#define TELEM_EVENT_ENABLE             0x8000
+
+#define TELEM_MASK_BIT                 1
+#define TELEM_MASK_BYTE                        0xFF
+#define BYTES_PER_LONG                 8
+#define TELEM_MASK_PCS_STATE           0xF
+
+#define TELEM_DISABLE(x)               ((x) &= ~(BIT(31)))
+#define TELEM_CLEAR_EVENTS(x)          ((x) |= (BIT(30)))
+#define TELEM_ENABLE_SRAM_EVT_TRACE(x) ((x) &= ~(BIT(30) | BIT(24)))
+#define TELEM_ENABLE_PERIODIC(x)       ((x) |= (BIT(23) | BIT(31) | BIT(7)))
+#define TELEM_EXTRACT_VERBOSITY(x, y)  ((y) = (((x) >> 27) & 0x3))
+#define TELEM_CLEAR_VERBOSITY_BITS(x)  ((x) &= ~(BIT(27) | BIT(28)))
+#define TELEM_SET_VERBOSITY_BITS(x, y) ((x) |= ((y) << 27))
+
+enum telemetry_action {
+       TELEM_UPDATE = 0,
+       TELEM_ADD,
+       TELEM_RESET,
+       TELEM_ACTION_NONE
+};
+
+struct telem_ssram_region {
+       u64 timestamp;
+       u64 start_time;
+       u64 events[TELEM_MAX_EVENTS_SRAM];
+};
+
+static struct telemetry_plt_config *telm_conf;
+
+/*
+ * The following counters are programmed by default during setup.
+ * Only 20 allocated to kernel driver
+ */
+static struct telemetry_evtmap
+       telemetry_apl_ioss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
+       {"SOC_S0IX_TOTAL_RES",                  0x4800},
+       {"SOC_S0IX_TOTAL_OCC",                  0x4000},
+       {"SOC_S0IX_SHALLOW_RES",                0x4801},
+       {"SOC_S0IX_SHALLOW_OCC",                0x4001},
+       {"SOC_S0IX_DEEP_RES",                   0x4802},
+       {"SOC_S0IX_DEEP_OCC",                   0x4002},
+       {"PMC_POWER_GATE",                      0x5818},
+       {"PMC_D3_STATES",                       0x5819},
+       {"PMC_D0I3_STATES",                     0x581A},
+       {"PMC_S0IX_WAKE_REASON_GPIO",           0x6000},
+       {"PMC_S0IX_WAKE_REASON_TIMER",          0x6001},
+       {"PMC_S0IX_WAKE_REASON_VNNREQ",         0x6002},
+       {"PMC_S0IX_WAKE_REASON_LOWPOWER",       0x6003},
+       {"PMC_S0IX_WAKE_REASON_EXTERNAL",       0x6004},
+       {"PMC_S0IX_WAKE_REASON_MISC",           0x6005},
+       {"PMC_S0IX_BLOCKING_IPS_D3_D0I3",       0x6006},
+       {"PMC_S0IX_BLOCKING_IPS_PG",            0x6007},
+       {"PMC_S0IX_BLOCKING_MISC_IPS_PG",       0x6008},
+       {"PMC_S0IX_BLOCK_IPS_VNN_REQ",          0x6009},
+       {"PMC_S0IX_BLOCK_IPS_CLOCKS",           0x600B},
+};
+
+
+static struct telemetry_evtmap
+       telemetry_apl_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
+       {"IA_CORE0_C6_RES",                     0x0400},
+       {"IA_CORE0_C6_CTR",                     0x0000},
+       {"IA_MODULE0_C7_RES",                   0x0410},
+       {"IA_MODULE0_C7_CTR",                   0x000E},
+       {"IA_C0_RES",                           0x0805},
+       {"PCS_LTR",                             0x2801},
+       {"PSTATES",                             0x2802},
+       {"SOC_S0I3_RES",                        0x0409},
+       {"SOC_S0I3_CTR",                        0x000A},
+       {"PCS_S0I3_CTR",                        0x0009},
+       {"PCS_C1E_RES",                         0x041A},
+       {"PCS_IDLE_STATUS",                     0x2806},
+       {"IA_PERF_LIMITS",                      0x280B},
+       {"GT_PERF_LIMITS",                      0x280C},
+       {"PCS_WAKEUP_S0IX_CTR",                 0x0030},
+       {"PCS_IDLE_BLOCKED",                    0x2C00},
+       {"PCS_S0IX_BLOCKED",                    0x2C01},
+       {"PCS_S0IX_WAKE_REASONS",               0x2C02},
+       {"PCS_LTR_BLOCKING",                    0x2C03},
+       {"PC2_AND_MEM_SHALLOW_IDLE_RES",        0x1D40},
+};
+
+static struct telemetry_evtmap
+       telemetry_glk_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
+       {"IA_CORE0_C6_RES",                     0x0400},
+       {"IA_CORE0_C6_CTR",                     0x0000},
+       {"IA_MODULE0_C7_RES",                   0x0410},
+       {"IA_MODULE0_C7_CTR",                   0x000C},
+       {"IA_C0_RES",                           0x0805},
+       {"PCS_LTR",                             0x2801},
+       {"PSTATES",                             0x2802},
+       {"SOC_S0I3_RES",                        0x0407},
+       {"SOC_S0I3_CTR",                        0x0008},
+       {"PCS_S0I3_CTR",                        0x0007},
+       {"PCS_C1E_RES",                         0x0414},
+       {"PCS_IDLE_STATUS",                     0x2806},
+       {"IA_PERF_LIMITS",                      0x280B},
+       {"GT_PERF_LIMITS",                      0x280C},
+       {"PCS_WAKEUP_S0IX_CTR",                 0x0025},
+       {"PCS_IDLE_BLOCKED",                    0x2C00},
+       {"PCS_S0IX_BLOCKED",                    0x2C01},
+       {"PCS_S0IX_WAKE_REASONS",               0x2C02},
+       {"PCS_LTR_BLOCKING",                    0x2C03},
+       {"PC2_AND_MEM_SHALLOW_IDLE_RES",        0x1D40},
+};
+
+/* APL specific Data */
+static struct telemetry_plt_config telem_apl_config = {
+       .pss_config = {
+               .telem_evts = telemetry_apl_pss_default_events,
+       },
+       .ioss_config = {
+               .telem_evts = telemetry_apl_ioss_default_events,
+       },
+};
+
+/* GLK specific Data */
+static struct telemetry_plt_config telem_glk_config = {
+       .pss_config = {
+               .telem_evts = telemetry_glk_pss_default_events,
+       },
+       .ioss_config = {
+               .telem_evts = telemetry_apl_ioss_default_events,
+       },
+};
+
+static const struct x86_cpu_id telemetry_cpu_ids[] = {
+       X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT,       &telem_apl_config),
+       X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS,  &telem_glk_config),
+       {}
+};
+
+MODULE_DEVICE_TABLE(x86cpu, telemetry_cpu_ids);
+
+static inline int telem_get_unitconfig(enum telemetry_unit telem_unit,
+                                    struct telemetry_unit_config **unit_config)
+{
+       if (telem_unit == TELEM_PSS)
+               *unit_config = &(telm_conf->pss_config);
+       else if (telem_unit == TELEM_IOSS)
+               *unit_config = &(telm_conf->ioss_config);
+       else
+               return -EINVAL;
+
+       return 0;
+
+}
+
+static int telemetry_check_evtid(enum telemetry_unit telem_unit,
+                                u32 *evtmap, u8 len,
+                                enum telemetry_action action)
+{
+       struct telemetry_unit_config *unit_config;
+       int ret;
+
+       ret = telem_get_unitconfig(telem_unit, &unit_config);
+       if (ret < 0)
+               return ret;
+
+       switch (action) {
+       case TELEM_RESET:
+               if (len > TELEM_MAX_EVENTS_SRAM)
+                       return -EINVAL;
+
+               break;
+
+       case TELEM_UPDATE:
+               if (len > TELEM_MAX_EVENTS_SRAM)
+                       return -EINVAL;
+
+               if ((len > 0) && (evtmap == NULL))
+                       return -EINVAL;
+
+               break;
+
+       case TELEM_ADD:
+               if ((len + unit_config->ssram_evts_used) >
+                   TELEM_MAX_EVENTS_SRAM)
+                       return -EINVAL;
+
+               if ((len > 0) && (evtmap == NULL))
+                       return -EINVAL;
+
+               break;
+
+       default:
+               pr_err("Unknown Telemetry action specified %d\n", action);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+
+static inline int telemetry_plt_config_ioss_event(u32 evt_id, int index)
+{
+       u32 write_buf;
+
+       write_buf = evt_id | TELEM_EVENT_ENABLE;
+       write_buf <<= BITS_PER_BYTE;
+       write_buf |= index;
+
+       return intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
+                                        IOSS_TELEM_EVENT_WRITE, &write_buf,
+                                        IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0);
+}
+
+static inline int telemetry_plt_config_pss_event(u32 evt_id, int index)
+{
+       u32 write_buf;
+       int ret;
+
+       write_buf = evt_id | TELEM_EVENT_ENABLE;
+       ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT,
+                                     index, 0, &write_buf, NULL);
+
+       return ret;
+}
+
+static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
+                                        enum telemetry_action action)
+{
+       struct intel_scu_ipc_dev *scu = telm_conf->scu;
+       u8 num_ioss_evts, ioss_period;
+       int ret, index, idx;
+       u32 *ioss_evtmap;
+       u32 telem_ctrl;
+
+       num_ioss_evts = evtconfig.num_evts;
+       ioss_period = evtconfig.period;
+       ioss_evtmap = evtconfig.evtmap;
+
+       /* Get telemetry EVENT CTL */
+       ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
+                                   IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
+                                   &telem_ctrl, sizeof(telem_ctrl));
+       if (ret) {
+               pr_err("IOSS TELEM_CTRL Read Failed\n");
+               return ret;
+       }
+
+       /* Disable Telemetry */
+       TELEM_DISABLE(telem_ctrl);
+
+       ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
+                                   IOSS_TELEM_EVENT_CTL_WRITE, &telem_ctrl,
+                                   sizeof(telem_ctrl), NULL, 0);
+       if (ret) {
+               pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
+               return ret;
+       }
+
+
+       /* Reset Everything */
+       if (action == TELEM_RESET) {
+               /* Clear All Events */
+               TELEM_CLEAR_EVENTS(telem_ctrl);
+
+               ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
+                                           IOSS_TELEM_EVENT_CTL_WRITE,
+                                           &telem_ctrl, sizeof(telem_ctrl),
+                                           NULL, 0);
+               if (ret) {
+                       pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
+                       return ret;
+               }
+               telm_conf->ioss_config.ssram_evts_used = 0;
+
+               /* Configure Events */
+               for (idx = 0; idx < num_ioss_evts; idx++) {
+                       if (telemetry_plt_config_ioss_event(
+                           telm_conf->ioss_config.telem_evts[idx].evt_id,
+                           idx)) {
+                               pr_err("IOSS TELEM_RESET Fail for data: %x\n",
+                               telm_conf->ioss_config.telem_evts[idx].evt_id);
+                               continue;
+                       }
+                       telm_conf->ioss_config.ssram_evts_used++;
+               }
+       }
+
+       /* Re-Configure Everything */
+       if (action == TELEM_UPDATE) {
+               /* Clear All Events */
+               TELEM_CLEAR_EVENTS(telem_ctrl);
+
+               ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
+                                           IOSS_TELEM_EVENT_CTL_WRITE,
+                                           &telem_ctrl, sizeof(telem_ctrl),
+                                           NULL, 0);
+               if (ret) {
+                       pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
+                       return ret;
+               }
+               telm_conf->ioss_config.ssram_evts_used = 0;
+
+               /* Configure Events */
+               for (index = 0; index < num_ioss_evts; index++) {
+                       telm_conf->ioss_config.telem_evts[index].evt_id =
+                       ioss_evtmap[index];
+
+                       if (telemetry_plt_config_ioss_event(
+                           telm_conf->ioss_config.telem_evts[index].evt_id,
+                           index)) {
+                               pr_err("IOSS TELEM_UPDATE Fail for Evt%x\n",
+                                       ioss_evtmap[index]);
+                               continue;
+                       }
+                       telm_conf->ioss_config.ssram_evts_used++;
+               }
+       }
+
+       /* Add some Events */
+       if (action == TELEM_ADD) {
+               /* Configure Events */
+               for (index = telm_conf->ioss_config.ssram_evts_used, idx = 0;
+                    idx < num_ioss_evts; index++, idx++) {
+                       telm_conf->ioss_config.telem_evts[index].evt_id =
+                       ioss_evtmap[idx];
+
+                       if (telemetry_plt_config_ioss_event(
+                           telm_conf->ioss_config.telem_evts[index].evt_id,
+                           index)) {
+                               pr_err("IOSS TELEM_ADD Fail for Event %x\n",
+                                       ioss_evtmap[idx]);
+                               continue;
+                       }
+                       telm_conf->ioss_config.ssram_evts_used++;
+               }
+       }
+
+       /* Enable Periodic Telemetry Events and enable SRAM trace */
+       TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
+       TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
+       TELEM_ENABLE_PERIODIC(telem_ctrl);
+       telem_ctrl |= ioss_period;
+
+       ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
+                                   IOSS_TELEM_EVENT_CTL_WRITE,
+                                   &telem_ctrl, sizeof(telem_ctrl), NULL, 0);
+       if (ret) {
+               pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
+               return ret;
+       }
+
+       telm_conf->ioss_config.curr_period = ioss_period;
+
+       return 0;
+}
+
+
+static int telemetry_setup_pssevtconfig(struct telemetry_evtconfig evtconfig,
+                                       enum telemetry_action action)
+{
+       u8 num_pss_evts, pss_period;
+       int ret, index, idx;
+       u32 *pss_evtmap;
+       u32 telem_ctrl;
+
+       num_pss_evts = evtconfig.num_evts;
+       pss_period = evtconfig.period;
+       pss_evtmap = evtconfig.evtmap;
+
+       /* PSS Config */
+       /* Get telemetry EVENT CTL */
+       ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
+                                     0, 0, NULL, &telem_ctrl);
+       if (ret) {
+               pr_err("PSS TELEM_CTRL Read Failed\n");
+               return ret;
+       }
+
+       /* Disable Telemetry */
+       TELEM_DISABLE(telem_ctrl);
+       ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
+                                     0, 0, &telem_ctrl, NULL);
+       if (ret) {
+               pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
+               return ret;
+       }
+
+       /* Reset Everything */
+       if (action == TELEM_RESET) {
+               /* Clear All Events */
+               TELEM_CLEAR_EVENTS(telem_ctrl);
+
+               ret = intel_punit_ipc_command(
+                               IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
+                               0, 0, &telem_ctrl, NULL);
+               if (ret) {
+                       pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
+                       return ret;
+               }
+               telm_conf->pss_config.ssram_evts_used = 0;
+               /* Configure Events */
+               for (idx = 0; idx < num_pss_evts; idx++) {
+                       if (telemetry_plt_config_pss_event(
+                           telm_conf->pss_config.telem_evts[idx].evt_id,
+                           idx)) {
+                               pr_err("PSS TELEM_RESET Fail for Event %x\n",
+                               telm_conf->pss_config.telem_evts[idx].evt_id);
+                               continue;
+                       }
+                       telm_conf->pss_config.ssram_evts_used++;
+               }
+       }
+
+       /* Re-Configure Everything */
+       if (action == TELEM_UPDATE) {
+               /* Clear All Events */
+               TELEM_CLEAR_EVENTS(telem_ctrl);
+
+               ret = intel_punit_ipc_command(
+                               IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
+                               0, 0, &telem_ctrl, NULL);
+               if (ret) {
+                       pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
+                       return ret;
+               }
+               telm_conf->pss_config.ssram_evts_used = 0;
+
+               /* Configure Events */
+               for (index = 0; index < num_pss_evts; index++) {
+                       telm_conf->pss_config.telem_evts[index].evt_id =
+                       pss_evtmap[index];
+
+                       if (telemetry_plt_config_pss_event(
+                           telm_conf->pss_config.telem_evts[index].evt_id,
+                           index)) {
+                               pr_err("PSS TELEM_UPDATE Fail for Event %x\n",
+                                       pss_evtmap[index]);
+                               continue;
+                       }
+                       telm_conf->pss_config.ssram_evts_used++;
+               }
+       }
+
+       /* Add some Events */
+       if (action == TELEM_ADD) {
+               /* Configure Events */
+               for (index = telm_conf->pss_config.ssram_evts_used, idx = 0;
+                    idx < num_pss_evts; index++, idx++) {
+
+                       telm_conf->pss_config.telem_evts[index].evt_id =
+                       pss_evtmap[idx];
+
+                       if (telemetry_plt_config_pss_event(
+                           telm_conf->pss_config.telem_evts[index].evt_id,
+                           index)) {
+                               pr_err("PSS TELEM_ADD Fail for Event %x\n",
+                                       pss_evtmap[idx]);
+                               continue;
+                       }
+                       telm_conf->pss_config.ssram_evts_used++;
+               }
+       }
+
+       /* Enable Periodic Telemetry Events and enable SRAM trace */
+       TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
+       TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
+       TELEM_ENABLE_PERIODIC(telem_ctrl);
+       telem_ctrl |= pss_period;
+
+       ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
+                                     0, 0, &telem_ctrl, NULL);
+       if (ret) {
+               pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
+               return ret;
+       }
+
+       telm_conf->pss_config.curr_period = pss_period;
+
+       return 0;
+}
+
+static int telemetry_setup_evtconfig(struct telemetry_evtconfig pss_evtconfig,
+                                    struct telemetry_evtconfig ioss_evtconfig,
+                                    enum telemetry_action action)
+{
+       int ret;
+
+       mutex_lock(&(telm_conf->telem_lock));
+
+       if ((action == TELEM_UPDATE) && (telm_conf->telem_in_use)) {
+               ret = -EBUSY;
+               goto out;
+       }
+
+       ret = telemetry_check_evtid(TELEM_PSS, pss_evtconfig.evtmap,
+                                   pss_evtconfig.num_evts, action);
+       if (ret)
+               goto out;
+
+       ret = telemetry_check_evtid(TELEM_IOSS, ioss_evtconfig.evtmap,
+                                   ioss_evtconfig.num_evts, action);
+       if (ret)
+               goto out;
+
+       if (ioss_evtconfig.num_evts) {
+               ret = telemetry_setup_iossevtconfig(ioss_evtconfig, action);
+               if (ret)
+                       goto out;
+       }
+
+       if (pss_evtconfig.num_evts) {
+               ret = telemetry_setup_pssevtconfig(pss_evtconfig, action);
+               if (ret)
+                       goto out;
+       }
+
+       if ((action == TELEM_UPDATE) || (action == TELEM_ADD))
+               telm_conf->telem_in_use = true;
+       else
+               telm_conf->telem_in_use = false;
+
+out:
+       mutex_unlock(&(telm_conf->telem_lock));
+       return ret;
+}
+
+static int telemetry_setup(struct platform_device *pdev)
+{
+       struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
+       u32 read_buf, events, event_regs;
+       int ret;
+
+       ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
+                                       IOSS_TELEM_INFO_READ, NULL, 0,
+                                       &read_buf, sizeof(read_buf));
+       if (ret) {
+               dev_err(&pdev->dev, "IOSS TELEM_INFO Read Failed\n");
+               return ret;
+       }
+
+       /* Get telemetry Info */
+       events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
+                 TELEM_INFO_SRAMEVTS_SHIFT;
+       event_regs = read_buf & TELEM_INFO_NENABLES_MASK;
+       if ((events < TELEM_MAX_EVENTS_SRAM) ||
+           (event_regs < TELEM_MAX_EVENTS_SRAM)) {
+               dev_err(&pdev->dev, "IOSS:Insufficient Space for SRAM Trace\n");
+               dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
+                       events, event_regs);
+               return -ENOMEM;
+       }
+
+       telm_conf->ioss_config.min_period = TELEM_MIN_PERIOD(read_buf);
+       telm_conf->ioss_config.max_period = TELEM_MAX_PERIOD(read_buf);
+
+       /* PUNIT Mailbox Setup */
+       ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_INFO, 0, 0,
+                                     NULL, &read_buf);
+       if (ret) {
+               dev_err(&pdev->dev, "PSS TELEM_INFO Read Failed\n");
+               return ret;
+       }
+
+       /* Get telemetry Info */
+       events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
+                 TELEM_INFO_SRAMEVTS_SHIFT;
+       event_regs = read_buf & TELEM_INFO_SRAMEVTS_MASK;
+       if ((events < TELEM_MAX_EVENTS_SRAM) ||
+           (event_regs < TELEM_MAX_EVENTS_SRAM)) {
+               dev_err(&pdev->dev, "PSS:Insufficient Space for SRAM Trace\n");
+               dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
+                       events, event_regs);
+               return -ENOMEM;
+       }
+
+       telm_conf->pss_config.min_period = TELEM_MIN_PERIOD(read_buf);
+       telm_conf->pss_config.max_period = TELEM_MAX_PERIOD(read_buf);
+
+       pss_evtconfig.evtmap = NULL;
+       pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
+       pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
+
+       ioss_evtconfig.evtmap = NULL;
+       ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
+       ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
+
+       ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
+                                       TELEM_RESET);
+       if (ret) {
+               dev_err(&pdev->dev, "TELEMETRY Setup Failed\n");
+               return ret;
+       }
+       return 0;
+}
+
+static int telemetry_plt_update_events(struct telemetry_evtconfig pss_evtconfig,
+                               struct telemetry_evtconfig ioss_evtconfig)
+{
+       int ret;
+
+       if ((pss_evtconfig.num_evts > 0) &&
+           (TELEM_SAMPLE_PERIOD_INVALID(pss_evtconfig.period))) {
+               pr_err("PSS Sampling Period Out of Range\n");
+               return -EINVAL;
+       }
+
+       if ((ioss_evtconfig.num_evts > 0) &&
+           (TELEM_SAMPLE_PERIOD_INVALID(ioss_evtconfig.period))) {
+               pr_err("IOSS Sampling Period Out of Range\n");
+               return -EINVAL;
+       }
+
+       ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
+                                       TELEM_UPDATE);
+       if (ret)
+               pr_err("TELEMETRY Config Failed\n");
+
+       return ret;
+}
+
+
+static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
+{
+       u32 telem_ctrl = 0;
+       int ret = 0;
+
+       mutex_lock(&(telm_conf->telem_lock));
+       if (ioss_period) {
+               struct intel_scu_ipc_dev *scu = telm_conf->scu;
+
+               if (TELEM_SAMPLE_PERIOD_INVALID(ioss_period)) {
+                       pr_err("IOSS Sampling Period Out of Range\n");
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               /* Get telemetry EVENT CTL */
+               ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
+                                           IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
+                                           &telem_ctrl, sizeof(telem_ctrl));
+               if (ret) {
+                       pr_err("IOSS TELEM_CTRL Read Failed\n");
+                       goto out;
+               }
+
+               /* Disable Telemetry */
+               TELEM_DISABLE(telem_ctrl);
+
+               ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
+                                               IOSS_TELEM_EVENT_CTL_WRITE,
+                                               &telem_ctrl, sizeof(telem_ctrl),
+                                               NULL, 0);
+               if (ret) {
+                       pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
+                       goto out;
+               }
+
+               /* Enable Periodic Telemetry Events and enable SRAM trace */
+               TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
+               TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
+               TELEM_ENABLE_PERIODIC(telem_ctrl);
+               telem_ctrl |= ioss_period;
+
+               ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
+                                               IOSS_TELEM_EVENT_CTL_WRITE,
+                                               &telem_ctrl, sizeof(telem_ctrl),
+                                               NULL, 0);
+               if (ret) {
+                       pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
+                       goto out;
+               }
+               telm_conf->ioss_config.curr_period = ioss_period;
+       }
+
+       if (pss_period) {
+               if (TELEM_SAMPLE_PERIOD_INVALID(pss_period)) {
+                       pr_err("PSS Sampling Period Out of Range\n");
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               /* Get telemetry EVENT CTL */
+               ret = intel_punit_ipc_command(
+                               IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
+                               0, 0, NULL, &telem_ctrl);
+               if (ret) {
+                       pr_err("PSS TELEM_CTRL Read Failed\n");
+                       goto out;
+               }
+
+               /* Disable Telemetry */
+               TELEM_DISABLE(telem_ctrl);
+               ret = intel_punit_ipc_command(
+                               IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
+                               0, 0, &telem_ctrl, NULL);
+               if (ret) {
+                       pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
+                       goto out;
+               }
+
+               /* Enable Periodic Telemetry Events and enable SRAM trace */
+               TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
+               TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
+               TELEM_ENABLE_PERIODIC(telem_ctrl);
+               telem_ctrl |= pss_period;
+
+               ret = intel_punit_ipc_command(
+                               IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
+                               0, 0, &telem_ctrl, NULL);
+               if (ret) {
+                       pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
+                       goto out;
+               }
+               telm_conf->pss_config.curr_period = pss_period;
+       }
+
+out:
+       mutex_unlock(&(telm_conf->telem_lock));
+       return ret;
+}
+
+
+static int telemetry_plt_get_sampling_period(u8 *pss_min_period,
+                                            u8 *pss_max_period,
+                                            u8 *ioss_min_period,
+                                            u8 *ioss_max_period)
+{
+       *pss_min_period = telm_conf->pss_config.min_period;
+       *pss_max_period = telm_conf->pss_config.max_period;
+       *ioss_min_period = telm_conf->ioss_config.min_period;
+       *ioss_max_period = telm_conf->ioss_config.max_period;
+
+       return 0;
+}
+
+
+static int telemetry_plt_reset_events(void)
+{
+       struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
+       int ret;
+
+       pss_evtconfig.evtmap = NULL;
+       pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
+       pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
+
+       ioss_evtconfig.evtmap = NULL;
+       ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
+       ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
+
+       ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
+                                       TELEM_RESET);
+       if (ret)
+               pr_err("TELEMETRY Reset Failed\n");
+
+       return ret;
+}
+
+
+static int telemetry_plt_get_eventconfig(struct telemetry_evtconfig *pss_config,
+                                       struct telemetry_evtconfig *ioss_config,
+                                       int pss_len, int ioss_len)
+{
+       u32 *pss_evtmap, *ioss_evtmap;
+       u32 index;
+
+       pss_evtmap = pss_config->evtmap;
+       ioss_evtmap = ioss_config->evtmap;
+
+       mutex_lock(&(telm_conf->telem_lock));
+       pss_config->num_evts = telm_conf->pss_config.ssram_evts_used;
+       ioss_config->num_evts = telm_conf->ioss_config.ssram_evts_used;
+
+       pss_config->period = telm_conf->pss_config.curr_period;
+       ioss_config->period = telm_conf->ioss_config.curr_period;
+
+       if ((pss_len < telm_conf->pss_config.ssram_evts_used) ||
+           (ioss_len < telm_conf->ioss_config.ssram_evts_used)) {
+               mutex_unlock(&(telm_conf->telem_lock));
+               return -EINVAL;
+       }
+
+       for (index = 0; index < telm_conf->pss_config.ssram_evts_used;
+            index++) {
+               pss_evtmap[index] =
+               telm_conf->pss_config.telem_evts[index].evt_id;
+       }
+
+       for (index = 0; index < telm_conf->ioss_config.ssram_evts_used;
+            index++) {
+               ioss_evtmap[index] =
+               telm_conf->ioss_config.telem_evts[index].evt_id;
+       }
+
+       mutex_unlock(&(telm_conf->telem_lock));
+       return 0;
+}
+
+
+static int telemetry_plt_add_events(u8 num_pss_evts, u8 num_ioss_evts,
+                                   u32 *pss_evtmap, u32 *ioss_evtmap)
+{
+       struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
+       int ret;
+
+       pss_evtconfig.evtmap = pss_evtmap;
+       pss_evtconfig.num_evts = num_pss_evts;
+       pss_evtconfig.period = telm_conf->pss_config.curr_period;
+
+       ioss_evtconfig.evtmap = ioss_evtmap;
+       ioss_evtconfig.num_evts = num_ioss_evts;
+       ioss_evtconfig.period = telm_conf->ioss_config.curr_period;
+
+       ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
+                                       TELEM_ADD);
+       if (ret)
+               pr_err("TELEMETRY ADD Failed\n");
+
+       return ret;
+}
+
+static int telem_evtlog_read(enum telemetry_unit telem_unit,
+                            struct telem_ssram_region *ssram_region, u8 len)
+{
+       struct telemetry_unit_config *unit_config;
+       u64 timestamp_prev, timestamp_next;
+       int ret, index, timeout = 0;
+
+       ret = telem_get_unitconfig(telem_unit, &unit_config);
+       if (ret < 0)
+               return ret;
+
+       if (len > unit_config->ssram_evts_used)
+               len = unit_config->ssram_evts_used;
+
+       do {
+               timestamp_prev = readq(unit_config->regmap);
+               if (!timestamp_prev) {
+                       pr_err("Ssram under update. Please Try Later\n");
+                       return -EBUSY;
+               }
+
+               ssram_region->start_time = readq(unit_config->regmap +
+                                                TELEM_SSRAM_STARTTIME_OFFSET);
+
+               for (index = 0; index < len; index++) {
+                       ssram_region->events[index] =
+                       readq(unit_config->regmap + TELEM_SSRAM_EVTLOG_OFFSET +
+                             BYTES_PER_LONG*index);
+               }
+
+               timestamp_next = readq(unit_config->regmap);
+               if (!timestamp_next) {
+                       pr_err("Ssram under update. Please Try Later\n");
+                       return -EBUSY;
+               }
+
+               if (timeout++ > TELEM_SSRAM_READ_TIMEOUT) {
+                       pr_err("Timeout while reading Events\n");
+                       return -EBUSY;
+               }
+
+       } while (timestamp_prev != timestamp_next);
+
+       ssram_region->timestamp = timestamp_next;
+
+       return len;
+}
+
+static int telemetry_plt_raw_read_eventlog(enum telemetry_unit telem_unit,
+                                          struct telemetry_evtlog *evtlog,
+                                          int len, int log_all_evts)
+{
+       int index, idx1, ret, readlen = len;
+       struct telem_ssram_region ssram_region;
+       struct telemetry_evtmap *evtmap;
+
+       switch (telem_unit)     {
+       case TELEM_PSS:
+               evtmap = telm_conf->pss_config.telem_evts;
+               break;
+
+       case TELEM_IOSS:
+               evtmap = telm_conf->ioss_config.telem_evts;
+               break;
+
+       default:
+               pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
+               return -EINVAL;
+       }
+
+       if (!log_all_evts)
+               readlen = TELEM_MAX_EVENTS_SRAM;
+
+       ret = telem_evtlog_read(telem_unit, &ssram_region, readlen);
+       if (ret < 0)
+               return ret;
+
+       /* Invalid evt-id array specified via length mismatch */
+       if ((!log_all_evts) && (len > ret))
+               return -EINVAL;
+
+       if (log_all_evts)
+               for (index = 0; index < ret; index++) {
+                       evtlog[index].telem_evtlog = ssram_region.events[index];
+                       evtlog[index].telem_evtid = evtmap[index].evt_id;
+               }
+       else
+               for (index = 0, readlen = 0; (index < ret) && (readlen < len);
+                    index++) {
+                       for (idx1 = 0; idx1 < len; idx1++) {
+                               /* Elements matched */
+                               if (evtmap[index].evt_id ==
+                                   evtlog[idx1].telem_evtid) {
+                                       evtlog[idx1].telem_evtlog =
+                                       ssram_region.events[index];
+                                       readlen++;
+
+                                       break;
+                               }
+                       }
+               }
+
+       return readlen;
+}
+
+static int telemetry_plt_read_eventlog(enum telemetry_unit telem_unit,
+               struct telemetry_evtlog *evtlog, int len, int log_all_evts)
+{
+       int ret;
+
+       mutex_lock(&(telm_conf->telem_lock));
+       ret = telemetry_plt_raw_read_eventlog(telem_unit, evtlog,
+                                             len, log_all_evts);
+       mutex_unlock(&(telm_conf->telem_lock));
+
+       return ret;
+}
+
+static int telemetry_plt_get_trace_verbosity(enum telemetry_unit telem_unit,
+                                            u32 *verbosity)
+{
+       u32 temp = 0;
+       int ret;
+
+       if (verbosity == NULL)
+               return -EINVAL;
+
+       mutex_lock(&(telm_conf->telem_trace_lock));
+       switch (telem_unit) {
+       case TELEM_PSS:
+               ret = intel_punit_ipc_command(
+                               IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
+                               0, 0, NULL, &temp);
+               if (ret) {
+                       pr_err("PSS TRACE_CTRL Read Failed\n");
+                       goto out;
+               }
+
+               break;
+
+       case TELEM_IOSS:
+               ret = intel_scu_ipc_dev_command(telm_conf->scu,
+                               IOSS_TELEM, IOSS_TELEM_TRACE_CTL_READ,
+                               NULL, 0, &temp, sizeof(temp));
+               if (ret) {
+                       pr_err("IOSS TRACE_CTL Read Failed\n");
+                       goto out;
+               }
+
+               break;
+
+       default:
+               pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
+               ret = -EINVAL;
+               break;
+       }
+       TELEM_EXTRACT_VERBOSITY(temp, *verbosity);
+
+out:
+       mutex_unlock(&(telm_conf->telem_trace_lock));
+       return ret;
+}
+
+static int telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit,
+                                            u32 verbosity)
+{
+       u32 temp = 0;
+       int ret;
+
+       verbosity &= TELEM_TRC_VERBOSITY_MASK;
+
+       mutex_lock(&(telm_conf->telem_trace_lock));
+       switch (telem_unit) {
+       case TELEM_PSS:
+               ret = intel_punit_ipc_command(
+                               IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
+                               0, 0, NULL, &temp);
+               if (ret) {
+                       pr_err("PSS TRACE_CTRL Read Failed\n");
+                       goto out;
+               }
+
+               TELEM_CLEAR_VERBOSITY_BITS(temp);
+               TELEM_SET_VERBOSITY_BITS(temp, verbosity);
+
+               ret = intel_punit_ipc_command(
+                               IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL,
+                               0, 0, &temp, NULL);
+               if (ret) {
+                       pr_err("PSS TRACE_CTRL Verbosity Set Failed\n");
+                       goto out;
+               }
+               break;
+
+       case TELEM_IOSS:
+               ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
+                                               IOSS_TELEM_TRACE_CTL_READ,
+                                               NULL, 0, &temp, sizeof(temp));
+               if (ret) {
+                       pr_err("IOSS TRACE_CTL Read Failed\n");
+                       goto out;
+               }
+
+               TELEM_CLEAR_VERBOSITY_BITS(temp);
+               TELEM_SET_VERBOSITY_BITS(temp, verbosity);
+
+               ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
+                                               IOSS_TELEM_TRACE_CTL_WRITE,
+                                               &temp, sizeof(temp), NULL, 0);
+               if (ret) {
+                       pr_err("IOSS TRACE_CTL Verbosity Set Failed\n");
+                       goto out;
+               }
+               break;
+
+       default:
+               pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
+               ret = -EINVAL;
+               break;
+       }
+
+out:
+       mutex_unlock(&(telm_conf->telem_trace_lock));
+       return ret;
+}
+
+static const struct telemetry_core_ops telm_pltops = {
+       .get_trace_verbosity = telemetry_plt_get_trace_verbosity,
+       .set_trace_verbosity = telemetry_plt_set_trace_verbosity,
+       .set_sampling_period = telemetry_plt_set_sampling_period,
+       .get_sampling_period = telemetry_plt_get_sampling_period,
+       .raw_read_eventlog = telemetry_plt_raw_read_eventlog,
+       .get_eventconfig = telemetry_plt_get_eventconfig,
+       .update_events = telemetry_plt_update_events,
+       .read_eventlog = telemetry_plt_read_eventlog,
+       .reset_events = telemetry_plt_reset_events,
+       .add_events = telemetry_plt_add_events,
+};
+
+static int telemetry_pltdrv_probe(struct platform_device *pdev)
+{
+       const struct x86_cpu_id *id;
+       void __iomem *mem;
+       int ret;
+
+       id = x86_match_cpu(telemetry_cpu_ids);
+       if (!id)
+               return -ENODEV;
+
+       telm_conf = (struct telemetry_plt_config *)id->driver_data;
+
+       telm_conf->pmc = dev_get_drvdata(pdev->dev.parent);
+
+       mem = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(mem))
+               return PTR_ERR(mem);
+
+       telm_conf->pss_config.regmap = mem;
+
+       mem = devm_platform_ioremap_resource(pdev, 1);
+       if (IS_ERR(mem))
+               return PTR_ERR(mem);
+
+       telm_conf->ioss_config.regmap = mem;
+
+       telm_conf->scu = devm_intel_scu_ipc_dev_get(&pdev->dev);
+       if (!telm_conf->scu) {
+               ret = -EPROBE_DEFER;
+               goto out;
+       }
+
+       mutex_init(&telm_conf->telem_lock);
+       mutex_init(&telm_conf->telem_trace_lock);
+
+       ret = telemetry_setup(pdev);
+       if (ret)
+               goto out;
+
+       ret = telemetry_set_pltdata(&telm_pltops, telm_conf);
+       if (ret) {
+               dev_err(&pdev->dev, "TELEMETRY Set Pltops Failed.\n");
+               goto out;
+       }
+
+       return 0;
+
+out:
+       dev_err(&pdev->dev, "TELEMETRY Setup Failed.\n");
+
+       return ret;
+}
+
+static int telemetry_pltdrv_remove(struct platform_device *pdev)
+{
+       telemetry_clear_pltdata();
+       return 0;
+}
+
+static struct platform_driver telemetry_soc_driver = {
+       .probe          = telemetry_pltdrv_probe,
+       .remove         = telemetry_pltdrv_remove,
+       .driver         = {
+               .name   = DRIVER_NAME,
+       },
+};
+
+static int __init telemetry_module_init(void)
+{
+       return platform_driver_register(&telemetry_soc_driver);
+}
+
+static void __exit telemetry_module_exit(void)
+{
+       platform_driver_unregister(&telemetry_soc_driver);
+}
+
+device_initcall(telemetry_module_init);
+module_exit(telemetry_module_exit);
+
+MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
+MODULE_DESCRIPTION("Intel SoC Telemetry Platform Driver");
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/intel_telemetry_core.c b/drivers/platform/x86/intel_telemetry_core.c
deleted file mode 100644 (file)
index fdf55b5..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Intel SoC Core Telemetry Driver
- * Copyright (C) 2015, Intel Corporation.
- * All Rights Reserved.
- *
- * Telemetry Framework provides platform related PM and performance statistics.
- * This file provides the core telemetry API implementation.
- */
-#include <linux/device.h>
-#include <linux/module.h>
-
-#include <asm/intel_telemetry.h>
-
-#define DRIVER_NAME "intel_telemetry_core"
-
-struct telemetry_core_config {
-       struct telemetry_plt_config *plt_config;
-       const struct telemetry_core_ops *telem_ops;
-};
-
-static struct telemetry_core_config telm_core_conf;
-
-static int telemetry_def_update_events(struct telemetry_evtconfig pss_evtconfig,
-                                     struct telemetry_evtconfig ioss_evtconfig)
-{
-       return 0;
-}
-
-static int telemetry_def_set_sampling_period(u8 pss_period, u8 ioss_period)
-{
-       return 0;
-}
-
-static int telemetry_def_get_sampling_period(u8 *pss_min_period,
-                                            u8 *pss_max_period,
-                                            u8 *ioss_min_period,
-                                            u8 *ioss_max_period)
-{
-       return 0;
-}
-
-static int telemetry_def_get_eventconfig(
-                       struct telemetry_evtconfig *pss_evtconfig,
-                       struct telemetry_evtconfig *ioss_evtconfig,
-                       int pss_len, int ioss_len)
-{
-       return 0;
-}
-
-static int telemetry_def_get_trace_verbosity(enum telemetry_unit telem_unit,
-                                            u32 *verbosity)
-{
-       return 0;
-}
-
-
-static int telemetry_def_set_trace_verbosity(enum telemetry_unit telem_unit,
-                                            u32 verbosity)
-{
-       return 0;
-}
-
-static int telemetry_def_raw_read_eventlog(enum telemetry_unit telem_unit,
-                                          struct telemetry_evtlog *evtlog,
-                                          int len, int log_all_evts)
-{
-       return 0;
-}
-
-static int telemetry_def_read_eventlog(enum telemetry_unit telem_unit,
-                                      struct telemetry_evtlog *evtlog,
-                                      int len, int log_all_evts)
-{
-       return 0;
-}
-
-static int telemetry_def_add_events(u8 num_pss_evts, u8 num_ioss_evts,
-                                   u32 *pss_evtmap, u32 *ioss_evtmap)
-{
-       return 0;
-}
-
-static int telemetry_def_reset_events(void)
-{
-       return 0;
-}
-
-static const struct telemetry_core_ops telm_defpltops = {
-       .set_sampling_period = telemetry_def_set_sampling_period,
-       .get_sampling_period = telemetry_def_get_sampling_period,
-       .get_trace_verbosity = telemetry_def_get_trace_verbosity,
-       .set_trace_verbosity = telemetry_def_set_trace_verbosity,
-       .raw_read_eventlog = telemetry_def_raw_read_eventlog,
-       .get_eventconfig = telemetry_def_get_eventconfig,
-       .read_eventlog = telemetry_def_read_eventlog,
-       .update_events = telemetry_def_update_events,
-       .reset_events = telemetry_def_reset_events,
-       .add_events = telemetry_def_add_events,
-};
-
-/**
- * telemetry_update_events() - Update telemetry Configuration
- * @pss_evtconfig: PSS related config. No change if num_evts = 0.
- * @pss_evtconfig: IOSS related config. No change if num_evts = 0.
- *
- * This API updates the IOSS & PSS Telemetry configuration. Old config
- * is overwritten. Call telemetry_reset_events when logging is over
- * All sample period values should be in the form of:
- * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
- *
- * Return: 0 success, < 0 for failure
- */
-int telemetry_update_events(struct telemetry_evtconfig pss_evtconfig,
-                           struct telemetry_evtconfig ioss_evtconfig)
-{
-       return telm_core_conf.telem_ops->update_events(pss_evtconfig,
-                                                      ioss_evtconfig);
-}
-EXPORT_SYMBOL_GPL(telemetry_update_events);
-
-
-/**
- * telemetry_set_sampling_period() - Sets the IOSS & PSS sampling period
- * @pss_period:  placeholder for PSS Period to be set.
- *              Set to 0 if not required to be updated
- * @ioss_period: placeholder for IOSS Period to be set
- *              Set to 0 if not required to be updated
- *
- * All values should be in the form of:
- * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
- *
- * Return: 0 success, < 0 for failure
- */
-int telemetry_set_sampling_period(u8 pss_period, u8 ioss_period)
-{
-       return telm_core_conf.telem_ops->set_sampling_period(pss_period,
-                                                            ioss_period);
-}
-EXPORT_SYMBOL_GPL(telemetry_set_sampling_period);
-
-/**
- * telemetry_get_sampling_period() - Get IOSS & PSS min & max sampling period
- * @pss_min_period:  placeholder for PSS Min Period supported
- * @pss_max_period:  placeholder for PSS Max Period supported
- * @ioss_min_period: placeholder for IOSS Min Period supported
- * @ioss_max_period: placeholder for IOSS Max Period supported
- *
- * All values should be in the form of:
- * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
- *
- * Return: 0 success, < 0 for failure
- */
-int telemetry_get_sampling_period(u8 *pss_min_period, u8 *pss_max_period,
-                                 u8 *ioss_min_period, u8 *ioss_max_period)
-{
-       return telm_core_conf.telem_ops->get_sampling_period(pss_min_period,
-                                                            pss_max_period,
-                                                            ioss_min_period,
-                                                            ioss_max_period);
-}
-EXPORT_SYMBOL_GPL(telemetry_get_sampling_period);
-
-
-/**
- * telemetry_reset_events() - Restore the IOSS & PSS configuration to default
- *
- * Return: 0 success, < 0 for failure
- */
-int telemetry_reset_events(void)
-{
-       return telm_core_conf.telem_ops->reset_events();
-}
-EXPORT_SYMBOL_GPL(telemetry_reset_events);
-
-/**
- * telemetry_get_eventconfig() - Returns the pss and ioss events enabled
- * @pss_evtconfig: Pointer to PSS related configuration.
- * @pss_evtconfig: Pointer to IOSS related configuration.
- * @pss_len:      Number of u32 elements allocated for pss_evtconfig array
- * @ioss_len:     Number of u32 elements allocated for ioss_evtconfig array
- *
- * Return: 0 success, < 0 for failure
- */
-int telemetry_get_eventconfig(struct telemetry_evtconfig *pss_evtconfig,
-                             struct telemetry_evtconfig *ioss_evtconfig,
-                             int pss_len, int ioss_len)
-{
-       return telm_core_conf.telem_ops->get_eventconfig(pss_evtconfig,
-                                                        ioss_evtconfig,
-                                                        pss_len, ioss_len);
-}
-EXPORT_SYMBOL_GPL(telemetry_get_eventconfig);
-
-/**
- * telemetry_add_events() - Add IOSS & PSS configuration to existing settings.
- * @num_pss_evts:  Number of PSS Events (<29) in pss_evtmap. Can be 0.
- * @num_ioss_evts: Number of IOSS Events (<29) in ioss_evtmap. Can be 0.
- * @pss_evtmap:    Array of PSS Event-IDs to Enable
- * @ioss_evtmap:   Array of PSS Event-IDs to Enable
- *
- * Events are appended to Old Configuration. In case of total events > 28, it
- * returns error. Call telemetry_reset_events to reset after eventlog done
- *
- * Return: 0 success, < 0 for failure
- */
-int telemetry_add_events(u8 num_pss_evts, u8 num_ioss_evts,
-                        u32 *pss_evtmap, u32 *ioss_evtmap)
-{
-       return telm_core_conf.telem_ops->add_events(num_pss_evts,
-                                                   num_ioss_evts, pss_evtmap,
-                                                   ioss_evtmap);
-}
-EXPORT_SYMBOL_GPL(telemetry_add_events);
-
-/**
- * telemetry_read_events() - Fetches samples as specified by evtlog.telem_evt_id
- * @telem_unit: Specify whether IOSS or PSS Read
- * @evtlog:     Array of telemetry_evtlog structs to fill data
- *             evtlog.telem_evt_id specifies the ids to read
- * @len:       Length of array of evtlog
- *
- * Return: number of eventlogs read for success, < 0 for failure
- */
-int telemetry_read_events(enum telemetry_unit telem_unit,
-                         struct telemetry_evtlog *evtlog, int len)
-{
-       return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,
-                                                      len, 0);
-}
-EXPORT_SYMBOL_GPL(telemetry_read_events);
-
-/**
- * telemetry_raw_read_events() - Fetch samples specified by evtlog.telem_evt_id
- * @telem_unit: Specify whether IOSS or PSS Read
- * @evtlog:    Array of telemetry_evtlog structs to fill data
- *             evtlog.telem_evt_id specifies the ids to read
- * @len:       Length of array of evtlog
- *
- * The caller must take care of locking in this case.
- *
- * Return: number of eventlogs read for success, < 0 for failure
- */
-int telemetry_raw_read_events(enum telemetry_unit telem_unit,
-                             struct telemetry_evtlog *evtlog, int len)
-{
-       return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,
-                                                          len, 0);
-}
-EXPORT_SYMBOL_GPL(telemetry_raw_read_events);
-
-/**
- * telemetry_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
- * @telem_unit: Specify whether IOSS or PSS Read
- * @evtlog:    Array of telemetry_evtlog structs to fill data
- * @len:       Length of array of evtlog
- *
- * Return: number of eventlogs read for success, < 0 for failure
- */
-int telemetry_read_eventlog(enum telemetry_unit telem_unit,
-                           struct telemetry_evtlog *evtlog, int len)
-{
-       return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,
-                                                      len, 1);
-}
-EXPORT_SYMBOL_GPL(telemetry_read_eventlog);
-
-/**
- * telemetry_raw_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
- * @telem_unit: Specify whether IOSS or PSS Read
- * @evtlog:    Array of telemetry_evtlog structs to fill data
- * @len:       Length of array of evtlog
- *
- * The caller must take care of locking in this case.
- *
- * Return: number of eventlogs read for success, < 0 for failure
- */
-int telemetry_raw_read_eventlog(enum telemetry_unit telem_unit,
-                               struct telemetry_evtlog *evtlog, int len)
-{
-       return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,
-                                                          len, 1);
-}
-EXPORT_SYMBOL_GPL(telemetry_raw_read_eventlog);
-
-
-/**
- * telemetry_get_trace_verbosity() - Get the IOSS & PSS Trace verbosity
- * @telem_unit: Specify whether IOSS or PSS Read
- * @verbosity: Pointer to return Verbosity
- *
- * Return: 0 success, < 0 for failure
- */
-int telemetry_get_trace_verbosity(enum telemetry_unit telem_unit,
-                                 u32 *verbosity)
-{
-       return telm_core_conf.telem_ops->get_trace_verbosity(telem_unit,
-                                                            verbosity);
-}
-EXPORT_SYMBOL_GPL(telemetry_get_trace_verbosity);
-
-
-/**
- * telemetry_set_trace_verbosity() - Update the IOSS & PSS Trace verbosity
- * @telem_unit: Specify whether IOSS or PSS Read
- * @verbosity: Verbosity to set
- *
- * Return: 0 success, < 0 for failure
- */
-int telemetry_set_trace_verbosity(enum telemetry_unit telem_unit, u32 verbosity)
-{
-       return telm_core_conf.telem_ops->set_trace_verbosity(telem_unit,
-                                                            verbosity);
-}
-EXPORT_SYMBOL_GPL(telemetry_set_trace_verbosity);
-
-/**
- * telemetry_set_pltdata() - Set the platform specific Data
- * @ops:       Pointer to ops structure
- * @pltconfig: Platform config data
- *
- * Usage by other than telemetry pltdrv module is invalid
- *
- * Return: 0 success, < 0 for failure
- */
-int telemetry_set_pltdata(const struct telemetry_core_ops *ops,
-                         struct telemetry_plt_config *pltconfig)
-{
-       if (ops)
-               telm_core_conf.telem_ops = ops;
-
-       if (pltconfig)
-               telm_core_conf.plt_config = pltconfig;
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(telemetry_set_pltdata);
-
-/**
- * telemetry_clear_pltdata() - Clear the platform specific Data
- *
- * Usage by other than telemetry pltdrv module is invalid
- *
- * Return: 0 success, < 0 for failure
- */
-int telemetry_clear_pltdata(void)
-{
-       telm_core_conf.telem_ops = &telm_defpltops;
-       telm_core_conf.plt_config = NULL;
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(telemetry_clear_pltdata);
-
-/**
- * telemetry_get_pltdata() - Return telemetry platform config
- *
- * May be used by other telemetry modules to get platform specific
- * configuration.
- */
-struct telemetry_plt_config *telemetry_get_pltdata(void)
-{
-       return telm_core_conf.plt_config;
-}
-EXPORT_SYMBOL_GPL(telemetry_get_pltdata);
-
-static inline int telemetry_get_pssevtname(enum telemetry_unit telem_unit,
-                                          const char **name, int len)
-{
-       struct telemetry_unit_config psscfg;
-       int i;
-
-       if (!telm_core_conf.plt_config)
-               return -EINVAL;
-
-       psscfg = telm_core_conf.plt_config->pss_config;
-
-       if (len > psscfg.ssram_evts_used)
-               len = psscfg.ssram_evts_used;
-
-       for (i = 0; i < len; i++)
-               name[i] = psscfg.telem_evts[i].name;
-
-       return 0;
-}
-
-static inline int telemetry_get_iossevtname(enum telemetry_unit telem_unit,
-                                           const char **name, int len)
-{
-       struct telemetry_unit_config iosscfg;
-       int i;
-
-       if (!(telm_core_conf.plt_config))
-               return -EINVAL;
-
-       iosscfg = telm_core_conf.plt_config->ioss_config;
-
-       if (len > iosscfg.ssram_evts_used)
-               len = iosscfg.ssram_evts_used;
-
-       for (i = 0; i < len; i++)
-               name[i] = iosscfg.telem_evts[i].name;
-
-       return 0;
-
-}
-
-/**
- * telemetry_get_evtname() - Checkif platform config is valid
- * @telem_unit:        Telemetry Unit to check
- * @name:      Array of character pointers to contain name
- * @len:       length of array name provided by user
- *
- * Usage by other than telemetry debugfs module is invalid
- *
- * Return: 0 success, < 0 for failure
- */
-int telemetry_get_evtname(enum telemetry_unit telem_unit,
-                         const char **name, int len)
-{
-       int ret = -EINVAL;
-
-       if (telem_unit == TELEM_PSS)
-               ret = telemetry_get_pssevtname(telem_unit, name, len);
-
-       else if (telem_unit == TELEM_IOSS)
-               ret = telemetry_get_iossevtname(telem_unit, name, len);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(telemetry_get_evtname);
-
-static int __init telemetry_module_init(void)
-{
-       pr_info(pr_fmt(DRIVER_NAME) " Init\n");
-
-       telm_core_conf.telem_ops = &telm_defpltops;
-       return 0;
-}
-
-static void __exit telemetry_module_exit(void)
-{
-}
-
-module_init(telemetry_module_init);
-module_exit(telemetry_module_exit);
-
-MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
-MODULE_DESCRIPTION("Intel SoC Telemetry Interface");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/intel_telemetry_debugfs.c b/drivers/platform/x86/intel_telemetry_debugfs.c
deleted file mode 100644 (file)
index 1d4d0fb..0000000
+++ /dev/null
@@ -1,961 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Intel SOC Telemetry debugfs Driver: Currently supports APL
- * Copyright (c) 2015, Intel Corporation.
- * All Rights Reserved.
- *
- * This file provides the debugfs interfaces for telemetry.
- * /sys/kernel/debug/telemetry/pss_info: Shows Primary Control Sub-Sys Counters
- * /sys/kernel/debug/telemetry/ioss_info: Shows IO Sub-System Counters
- * /sys/kernel/debug/telemetry/soc_states: Shows SoC State
- * /sys/kernel/debug/telemetry/pss_trace_verbosity: Read and Change Tracing
- *                             Verbosity via firmware
- * /sys/kernel/debug/telemetry/ioss_race_verbosity: Write and Change Tracing
- *                             Verbosity via firmware
- */
-#include <linux/debugfs.h>
-#include <linux/device.h>
-#include <linux/mfd/intel_pmc_bxt.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/seq_file.h>
-#include <linux/suspend.h>
-
-#include <asm/cpu_device_id.h>
-#include <asm/intel-family.h>
-#include <asm/intel_telemetry.h>
-
-#define DRIVER_NAME                    "telemetry_soc_debugfs"
-#define DRIVER_VERSION                 "1.0.0"
-
-/* ApolloLake SoC Event-IDs */
-#define TELEM_APL_PSS_PSTATES_ID       0x2802
-#define TELEM_APL_PSS_IDLE_ID          0x2806
-#define TELEM_APL_PCS_IDLE_BLOCKED_ID  0x2C00
-#define TELEM_APL_PCS_S0IX_BLOCKED_ID  0x2C01
-#define TELEM_APL_PSS_WAKEUP_ID                0x2C02
-#define TELEM_APL_PSS_LTR_BLOCKING_ID  0x2C03
-
-#define TELEM_APL_S0IX_TOTAL_OCC_ID    0x4000
-#define TELEM_APL_S0IX_SHLW_OCC_ID     0x4001
-#define TELEM_APL_S0IX_DEEP_OCC_ID     0x4002
-#define TELEM_APL_S0IX_TOTAL_RES_ID    0x4800
-#define TELEM_APL_S0IX_SHLW_RES_ID     0x4801
-#define TELEM_APL_S0IX_DEEP_RES_ID     0x4802
-#define TELEM_APL_D0IX_ID              0x581A
-#define TELEM_APL_D3_ID                        0x5819
-#define TELEM_APL_PG_ID                        0x5818
-
-#define TELEM_INFO_SRAMEVTS_MASK       0xFF00
-#define TELEM_INFO_SRAMEVTS_SHIFT      0x8
-#define TELEM_SSRAM_READ_TIMEOUT       10
-
-#define TELEM_MASK_BIT                 1
-#define TELEM_MASK_BYTE                        0xFF
-#define BYTES_PER_LONG                 8
-#define TELEM_APL_MASK_PCS_STATE       0xF
-
-/* Max events in bitmap to check for */
-#define TELEM_PSS_IDLE_EVTS            25
-#define TELEM_PSS_IDLE_BLOCKED_EVTS    20
-#define TELEM_PSS_S0IX_BLOCKED_EVTS    20
-#define TELEM_PSS_S0IX_WAKEUP_EVTS     20
-#define TELEM_PSS_LTR_BLOCKING_EVTS    20
-#define TELEM_IOSS_DX_D0IX_EVTS                25
-#define TELEM_IOSS_PG_EVTS             30
-
-#define TELEM_CHECK_AND_PARSE_EVTS(EVTID, EVTNUM, BUF, EVTLOG, EVTDAT, MASK) { \
-       if (evtlog[index].telem_evtid == (EVTID)) { \
-               for (idx = 0; idx < (EVTNUM); idx++) \
-                       (BUF)[idx] = ((EVTLOG) >> (EVTDAT)[idx].bit_pos) & \
-                                    (MASK); \
-       continue; \
-       } \
-}
-
-#define TELEM_CHECK_AND_PARSE_CTRS(EVTID, CTR) { \
-       if (evtlog[index].telem_evtid == (EVTID)) { \
-               (CTR) = evtlog[index].telem_evtlog; \
-               continue; \
-       } \
-}
-
-static u8 suspend_prep_ok;
-static u32 suspend_shlw_ctr_temp, suspend_deep_ctr_temp;
-static u64 suspend_shlw_res_temp, suspend_deep_res_temp;
-
-struct telemetry_susp_stats {
-       u32 shlw_ctr;
-       u32 deep_ctr;
-       u64 shlw_res;
-       u64 deep_res;
-};
-
-/* Bitmap definitions for default counters in APL */
-struct telem_pss_idle_stateinfo {
-       const char *name;
-       u32 bit_pos;
-};
-
-static struct telem_pss_idle_stateinfo telem_apl_pss_idle_data[] = {
-       {"IA_CORE0_C1E",                0},
-       {"IA_CORE1_C1E",                1},
-       {"IA_CORE2_C1E",                2},
-       {"IA_CORE3_C1E",                3},
-       {"IA_CORE0_C6",                 16},
-       {"IA_CORE1_C6",                 17},
-       {"IA_CORE2_C6",                 18},
-       {"IA_CORE3_C6",                 19},
-       {"IA_MODULE0_C7",               32},
-       {"IA_MODULE1_C7",               33},
-       {"GT_RC6",                      40},
-       {"IUNIT_PROCESSING_IDLE",       41},
-       {"FAR_MEM_IDLE",                43},
-       {"DISPLAY_IDLE",                44},
-       {"IUNIT_INPUT_SYSTEM_IDLE",     45},
-       {"PCS_STATUS",                  60},
-};
-
-struct telem_pcs_blkd_info {
-       const char *name;
-       u32 bit_pos;
-};
-
-static struct telem_pcs_blkd_info telem_apl_pcs_idle_blkd_data[] = {
-       {"COMPUTE",                     0},
-       {"MISC",                        8},
-       {"MODULE_ACTIONS_PENDING",      16},
-       {"LTR",                         24},
-       {"DISPLAY_WAKE",                32},
-       {"ISP_WAKE",                    40},
-       {"PSF0_ACTIVE",                 48},
-};
-
-static struct telem_pcs_blkd_info telem_apl_pcs_s0ix_blkd_data[] = {
-       {"LTR",                         0},
-       {"IRTL",                        8},
-       {"WAKE_DEADLINE_PENDING",       16},
-       {"DISPLAY",                     24},
-       {"ISP",                         32},
-       {"CORE",                        40},
-       {"PMC",                         48},
-       {"MISC",                        56},
-};
-
-struct telem_pss_ltr_info {
-       const char *name;
-       u32 bit_pos;
-};
-
-static struct telem_pss_ltr_info telem_apl_pss_ltr_data[] = {
-       {"CORE_ACTIVE",         0},
-       {"MEM_UP",              8},
-       {"DFX",                 16},
-       {"DFX_FORCE_LTR",       24},
-       {"DISPLAY",             32},
-       {"ISP",                 40},
-       {"SOUTH",               48},
-};
-
-struct telem_pss_wakeup_info {
-       const char *name;
-       u32 bit_pos;
-};
-
-static struct telem_pss_wakeup_info telem_apl_pss_wakeup[] = {
-       {"IP_IDLE",                     0},
-       {"DISPLAY_WAKE",                8},
-       {"VOLTAGE_REG_INT",             16},
-       {"DROWSY_TIMER (HOTPLUG)",      24},
-       {"CORE_WAKE",                   32},
-       {"MISC_S0IX",                   40},
-       {"MISC_ABORT",                  56},
-};
-
-struct telem_ioss_d0ix_stateinfo {
-       const char *name;
-       u32 bit_pos;
-};
-
-static struct telem_ioss_d0ix_stateinfo telem_apl_ioss_d0ix_data[] = {
-       {"CSE",         0},
-       {"SCC2",        1},
-       {"GMM",         2},
-       {"XDCI",        3},
-       {"XHCI",        4},
-       {"ISH",         5},
-       {"AVS",         6},
-       {"PCIE0P1",     7},
-       {"PECI0P0",     8},
-       {"LPSS",        9},
-       {"SCC",         10},
-       {"PWM",         11},
-       {"PCIE1_P3",    12},
-       {"PCIE1_P2",    13},
-       {"PCIE1_P1",    14},
-       {"PCIE1_P0",    15},
-       {"CNV",         16},
-       {"SATA",        17},
-       {"PRTC",        18},
-};
-
-struct telem_ioss_pg_info {
-       const char *name;
-       u32 bit_pos;
-};
-
-static struct telem_ioss_pg_info telem_apl_ioss_pg_data[] = {
-       {"LPSS",        0},
-       {"SCC",         1},
-       {"P2SB",        2},
-       {"SCC2",        3},
-       {"GMM",         4},
-       {"PCIE0",       5},
-       {"XDCI",        6},
-       {"xHCI",        7},
-       {"CSE",         8},
-       {"SPI",         9},
-       {"AVSPGD4",     10},
-       {"AVSPGD3",     11},
-       {"AVSPGD2",     12},
-       {"AVSPGD1",     13},
-       {"ISH",         14},
-       {"EXI",         15},
-       {"NPKVRC",      16},
-       {"NPKVNN",      17},
-       {"CUNIT",       18},
-       {"FUSE_CTRL",   19},
-       {"PCIE1",       20},
-       {"CNV",         21},
-       {"LPC",         22},
-       {"SATA",        23},
-       {"SMB",         24},
-       {"PRTC",        25},
-};
-
-struct telemetry_debugfs_conf {
-       struct telemetry_susp_stats suspend_stats;
-       struct dentry *telemetry_dbg_dir;
-
-       /* Bitmap Data */
-       struct telem_ioss_d0ix_stateinfo *ioss_d0ix_data;
-       struct telem_pss_idle_stateinfo *pss_idle_data;
-       struct telem_pcs_blkd_info *pcs_idle_blkd_data;
-       struct telem_pcs_blkd_info *pcs_s0ix_blkd_data;
-       struct telem_pss_wakeup_info *pss_wakeup;
-       struct telem_pss_ltr_info *pss_ltr_data;
-       struct telem_ioss_pg_info *ioss_pg_data;
-       u8 pcs_idle_blkd_evts;
-       u8 pcs_s0ix_blkd_evts;
-       u8 pss_wakeup_evts;
-       u8 pss_idle_evts;
-       u8 pss_ltr_evts;
-       u8 ioss_d0ix_evts;
-       u8 ioss_pg_evts;
-
-       /* IDs */
-       u16  pss_ltr_blocking_id;
-       u16  pcs_idle_blkd_id;
-       u16  pcs_s0ix_blkd_id;
-       u16  s0ix_total_occ_id;
-       u16  s0ix_shlw_occ_id;
-       u16  s0ix_deep_occ_id;
-       u16  s0ix_total_res_id;
-       u16  s0ix_shlw_res_id;
-       u16  s0ix_deep_res_id;
-       u16  pss_wakeup_id;
-       u16  ioss_d0ix_id;
-       u16  pstates_id;
-       u16  pss_idle_id;
-       u16  ioss_d3_id;
-       u16  ioss_pg_id;
-};
-
-static struct telemetry_debugfs_conf *debugfs_conf;
-
-static struct telemetry_debugfs_conf telem_apl_debugfs_conf = {
-       .pss_idle_data = telem_apl_pss_idle_data,
-       .pcs_idle_blkd_data = telem_apl_pcs_idle_blkd_data,
-       .pcs_s0ix_blkd_data = telem_apl_pcs_s0ix_blkd_data,
-       .pss_ltr_data = telem_apl_pss_ltr_data,
-       .pss_wakeup = telem_apl_pss_wakeup,
-       .ioss_d0ix_data = telem_apl_ioss_d0ix_data,
-       .ioss_pg_data = telem_apl_ioss_pg_data,
-
-       .pss_idle_evts = ARRAY_SIZE(telem_apl_pss_idle_data),
-       .pcs_idle_blkd_evts = ARRAY_SIZE(telem_apl_pcs_idle_blkd_data),
-       .pcs_s0ix_blkd_evts = ARRAY_SIZE(telem_apl_pcs_s0ix_blkd_data),
-       .pss_ltr_evts = ARRAY_SIZE(telem_apl_pss_ltr_data),
-       .pss_wakeup_evts = ARRAY_SIZE(telem_apl_pss_wakeup),
-       .ioss_d0ix_evts = ARRAY_SIZE(telem_apl_ioss_d0ix_data),
-       .ioss_pg_evts = ARRAY_SIZE(telem_apl_ioss_pg_data),
-
-       .pstates_id = TELEM_APL_PSS_PSTATES_ID,
-       .pss_idle_id = TELEM_APL_PSS_IDLE_ID,
-       .pcs_idle_blkd_id = TELEM_APL_PCS_IDLE_BLOCKED_ID,
-       .pcs_s0ix_blkd_id = TELEM_APL_PCS_S0IX_BLOCKED_ID,
-       .pss_wakeup_id = TELEM_APL_PSS_WAKEUP_ID,
-       .pss_ltr_blocking_id = TELEM_APL_PSS_LTR_BLOCKING_ID,
-       .s0ix_total_occ_id = TELEM_APL_S0IX_TOTAL_OCC_ID,
-       .s0ix_shlw_occ_id = TELEM_APL_S0IX_SHLW_OCC_ID,
-       .s0ix_deep_occ_id = TELEM_APL_S0IX_DEEP_OCC_ID,
-       .s0ix_total_res_id = TELEM_APL_S0IX_TOTAL_RES_ID,
-       .s0ix_shlw_res_id = TELEM_APL_S0IX_SHLW_RES_ID,
-       .s0ix_deep_res_id = TELEM_APL_S0IX_DEEP_RES_ID,
-       .ioss_d0ix_id = TELEM_APL_D0IX_ID,
-       .ioss_d3_id = TELEM_APL_D3_ID,
-       .ioss_pg_id = TELEM_APL_PG_ID,
-};
-
-static const struct x86_cpu_id telemetry_debugfs_cpu_ids[] = {
-       X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT,       &telem_apl_debugfs_conf),
-       X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS,  &telem_apl_debugfs_conf),
-       {}
-};
-MODULE_DEVICE_TABLE(x86cpu, telemetry_debugfs_cpu_ids);
-
-static int telemetry_debugfs_check_evts(void)
-{
-       if ((debugfs_conf->pss_idle_evts > TELEM_PSS_IDLE_EVTS) ||
-           (debugfs_conf->pcs_idle_blkd_evts > TELEM_PSS_IDLE_BLOCKED_EVTS) ||
-           (debugfs_conf->pcs_s0ix_blkd_evts > TELEM_PSS_S0IX_BLOCKED_EVTS) ||
-           (debugfs_conf->pss_ltr_evts > TELEM_PSS_LTR_BLOCKING_EVTS) ||
-           (debugfs_conf->pss_wakeup_evts > TELEM_PSS_S0IX_WAKEUP_EVTS) ||
-           (debugfs_conf->ioss_d0ix_evts > TELEM_IOSS_DX_D0IX_EVTS) ||
-           (debugfs_conf->ioss_pg_evts > TELEM_IOSS_PG_EVTS))
-               return -EINVAL;
-
-       return 0;
-}
-
-static int telem_pss_states_show(struct seq_file *s, void *unused)
-{
-       struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
-       struct telemetry_debugfs_conf *conf = debugfs_conf;
-       const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
-       u32 pcs_idle_blkd[TELEM_PSS_IDLE_BLOCKED_EVTS],
-           pcs_s0ix_blkd[TELEM_PSS_S0IX_BLOCKED_EVTS],
-           pss_s0ix_wakeup[TELEM_PSS_S0IX_WAKEUP_EVTS],
-           pss_ltr_blkd[TELEM_PSS_LTR_BLOCKING_EVTS],
-           pss_idle[TELEM_PSS_IDLE_EVTS];
-       int index, idx, ret, err = 0;
-       u64 pstates = 0;
-
-       ret = telemetry_read_eventlog(TELEM_PSS, evtlog,
-                                     TELEM_MAX_OS_ALLOCATED_EVENTS);
-       if (ret < 0)
-               return ret;
-
-       err = telemetry_get_evtname(TELEM_PSS, name,
-                                   TELEM_MAX_OS_ALLOCATED_EVENTS);
-       if (err < 0)
-               return err;
-
-       seq_puts(s, "\n----------------------------------------------------\n");
-       seq_puts(s, "\tPSS TELEM EVENTLOG (Residency = field/19.2 us\n");
-       seq_puts(s, "----------------------------------------------------\n");
-       for (index = 0; index < ret; index++) {
-               seq_printf(s, "%-32s %llu\n",
-                          name[index], evtlog[index].telem_evtlog);
-
-               /* Fetch PSS IDLE State */
-               if (evtlog[index].telem_evtid == conf->pss_idle_id) {
-                       pss_idle[conf->pss_idle_evts - 1] =
-                       (evtlog[index].telem_evtlog >>
-                       conf->pss_idle_data[conf->pss_idle_evts - 1].bit_pos) &
-                       TELEM_APL_MASK_PCS_STATE;
-               }
-
-               TELEM_CHECK_AND_PARSE_EVTS(conf->pss_idle_id,
-                                          conf->pss_idle_evts - 1,
-                                          pss_idle, evtlog[index].telem_evtlog,
-                                          conf->pss_idle_data, TELEM_MASK_BIT);
-
-               TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_idle_blkd_id,
-                                          conf->pcs_idle_blkd_evts,
-                                          pcs_idle_blkd,
-                                          evtlog[index].telem_evtlog,
-                                          conf->pcs_idle_blkd_data,
-                                          TELEM_MASK_BYTE);
-
-               TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_s0ix_blkd_id,
-                                          conf->pcs_s0ix_blkd_evts,
-                                          pcs_s0ix_blkd,
-                                          evtlog[index].telem_evtlog,
-                                          conf->pcs_s0ix_blkd_data,
-                                          TELEM_MASK_BYTE);
-
-               TELEM_CHECK_AND_PARSE_EVTS(conf->pss_wakeup_id,
-                                          conf->pss_wakeup_evts,
-                                          pss_s0ix_wakeup,
-                                          evtlog[index].telem_evtlog,
-                                          conf->pss_wakeup, TELEM_MASK_BYTE);
-
-               TELEM_CHECK_AND_PARSE_EVTS(conf->pss_ltr_blocking_id,
-                                          conf->pss_ltr_evts, pss_ltr_blkd,
-                                          evtlog[index].telem_evtlog,
-                                          conf->pss_ltr_data, TELEM_MASK_BYTE);
-
-               if (evtlog[index].telem_evtid == debugfs_conf->pstates_id)
-                       pstates = evtlog[index].telem_evtlog;
-       }
-
-       seq_puts(s, "\n--------------------------------------\n");
-       seq_puts(s, "PStates\n");
-       seq_puts(s, "--------------------------------------\n");
-       seq_puts(s, "Domain\t\t\t\tFreq(Mhz)\n");
-       seq_printf(s, " IA\t\t\t\t %llu\n GT\t\t\t\t %llu\n",
-                  (pstates & TELEM_MASK_BYTE)*100,
-                  ((pstates >> 8) & TELEM_MASK_BYTE)*50/3);
-
-       seq_printf(s, " IUNIT\t\t\t\t %llu\n SA\t\t\t\t %llu\n",
-                  ((pstates >> 16) & TELEM_MASK_BYTE)*25,
-                  ((pstates >> 24) & TELEM_MASK_BYTE)*50/3);
-
-       seq_puts(s, "\n--------------------------------------\n");
-       seq_puts(s, "PSS IDLE Status\n");
-       seq_puts(s, "--------------------------------------\n");
-       seq_puts(s, "Device\t\t\t\t\tIDLE\n");
-       for (index = 0; index < debugfs_conf->pss_idle_evts; index++) {
-               seq_printf(s, "%-32s\t%u\n",
-                          debugfs_conf->pss_idle_data[index].name,
-                          pss_idle[index]);
-       }
-
-       seq_puts(s, "\n--------------------------------------\n");
-       seq_puts(s, "PSS Idle blkd Status (~1ms saturating bucket)\n");
-       seq_puts(s, "--------------------------------------\n");
-       seq_puts(s, "Blocker\t\t\t\t\tCount\n");
-       for (index = 0; index < debugfs_conf->pcs_idle_blkd_evts; index++) {
-               seq_printf(s, "%-32s\t%u\n",
-                          debugfs_conf->pcs_idle_blkd_data[index].name,
-                          pcs_idle_blkd[index]);
-       }
-
-       seq_puts(s, "\n--------------------------------------\n");
-       seq_puts(s, "PSS S0ix blkd Status (~1ms saturating bucket)\n");
-       seq_puts(s, "--------------------------------------\n");
-       seq_puts(s, "Blocker\t\t\t\t\tCount\n");
-       for (index = 0; index < debugfs_conf->pcs_s0ix_blkd_evts; index++) {
-               seq_printf(s, "%-32s\t%u\n",
-                          debugfs_conf->pcs_s0ix_blkd_data[index].name,
-                          pcs_s0ix_blkd[index]);
-       }
-
-       seq_puts(s, "\n--------------------------------------\n");
-       seq_puts(s, "LTR Blocking Status (~1ms saturating bucket)\n");
-       seq_puts(s, "--------------------------------------\n");
-       seq_puts(s, "Blocker\t\t\t\t\tCount\n");
-       for (index = 0; index < debugfs_conf->pss_ltr_evts; index++) {
-               seq_printf(s, "%-32s\t%u\n",
-                          debugfs_conf->pss_ltr_data[index].name,
-                          pss_s0ix_wakeup[index]);
-       }
-
-       seq_puts(s, "\n--------------------------------------\n");
-       seq_puts(s, "Wakes Status (~1ms saturating bucket)\n");
-       seq_puts(s, "--------------------------------------\n");
-       seq_puts(s, "Wakes\t\t\t\t\tCount\n");
-       for (index = 0; index < debugfs_conf->pss_wakeup_evts; index++) {
-               seq_printf(s, "%-32s\t%u\n",
-                          debugfs_conf->pss_wakeup[index].name,
-                          pss_ltr_blkd[index]);
-       }
-
-       return 0;
-}
-
-DEFINE_SHOW_ATTRIBUTE(telem_pss_states);
-
-static int telem_ioss_states_show(struct seq_file *s, void *unused)
-{
-       struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
-       const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
-       int index, ret, err;
-
-       ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
-                                     TELEM_MAX_OS_ALLOCATED_EVENTS);
-       if (ret < 0)
-               return ret;
-
-       err = telemetry_get_evtname(TELEM_IOSS, name,
-                                   TELEM_MAX_OS_ALLOCATED_EVENTS);
-       if (err < 0)
-               return err;
-
-       seq_puts(s, "--------------------------------------\n");
-       seq_puts(s, "\tI0SS TELEMETRY EVENTLOG\n");
-       seq_puts(s, "--------------------------------------\n");
-       for (index = 0; index < ret; index++) {
-               seq_printf(s, "%-32s 0x%llx\n",
-                          name[index], evtlog[index].telem_evtlog);
-       }
-
-       return 0;
-}
-
-DEFINE_SHOW_ATTRIBUTE(telem_ioss_states);
-
-static int telem_soc_states_show(struct seq_file *s, void *unused)
-{
-       u32 d3_sts[TELEM_IOSS_DX_D0IX_EVTS], d0ix_sts[TELEM_IOSS_DX_D0IX_EVTS];
-       u32 pg_sts[TELEM_IOSS_PG_EVTS], pss_idle[TELEM_PSS_IDLE_EVTS];
-       struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
-       u32 s0ix_total_ctr = 0, s0ix_shlw_ctr = 0, s0ix_deep_ctr = 0;
-       u64 s0ix_total_res = 0, s0ix_shlw_res = 0, s0ix_deep_res = 0;
-       struct telemetry_debugfs_conf *conf = debugfs_conf;
-       struct pci_dev *dev = NULL;
-       int index, idx, ret;
-       u32 d3_state;
-       u16 pmcsr;
-
-       ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
-                                     TELEM_MAX_OS_ALLOCATED_EVENTS);
-       if (ret < 0)
-               return ret;
-
-       for (index = 0; index < ret; index++) {
-               TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d3_id,
-                                          conf->ioss_d0ix_evts,
-                                          d3_sts, evtlog[index].telem_evtlog,
-                                          conf->ioss_d0ix_data,
-                                          TELEM_MASK_BIT);
-
-               TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_pg_id, conf->ioss_pg_evts,
-                                          pg_sts, evtlog[index].telem_evtlog,
-                                          conf->ioss_pg_data, TELEM_MASK_BIT);
-
-               TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d0ix_id,
-                                          conf->ioss_d0ix_evts,
-                                          d0ix_sts, evtlog[index].telem_evtlog,
-                                          conf->ioss_d0ix_data,
-                                          TELEM_MASK_BIT);
-
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_occ_id,
-                                          s0ix_total_ctr);
-
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
-                                          s0ix_shlw_ctr);
-
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
-                                          s0ix_deep_ctr);
-
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_res_id,
-                                          s0ix_total_res);
-
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
-                                          s0ix_shlw_res);
-
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
-                                          s0ix_deep_res);
-       }
-
-       seq_puts(s, "\n---------------------------------------------------\n");
-       seq_puts(s, "S0IX Type\t\t\t Occurrence\t\t Residency(us)\n");
-       seq_puts(s, "---------------------------------------------------\n");
-
-       seq_printf(s, "S0IX Shallow\t\t\t %10u\t %10llu\n",
-                  s0ix_shlw_ctr -
-                  conf->suspend_stats.shlw_ctr,
-                  (u64)((s0ix_shlw_res -
-                  conf->suspend_stats.shlw_res)*10/192));
-
-       seq_printf(s, "S0IX Deep\t\t\t %10u\t %10llu\n",
-                  s0ix_deep_ctr -
-                  conf->suspend_stats.deep_ctr,
-                  (u64)((s0ix_deep_res -
-                  conf->suspend_stats.deep_res)*10/192));
-
-       seq_printf(s, "Suspend(With S0ixShallow)\t %10u\t %10llu\n",
-                  conf->suspend_stats.shlw_ctr,
-                  (u64)(conf->suspend_stats.shlw_res*10)/192);
-
-       seq_printf(s, "Suspend(With S0ixDeep)\t\t %10u\t %10llu\n",
-                  conf->suspend_stats.deep_ctr,
-                  (u64)(conf->suspend_stats.deep_res*10)/192);
-
-       seq_printf(s, "TOTAL S0IX\t\t\t %10u\t %10llu\n", s0ix_total_ctr,
-                  (u64)(s0ix_total_res*10/192));
-       seq_puts(s, "\n-------------------------------------------------\n");
-       seq_puts(s, "\t\tDEVICE STATES\n");
-       seq_puts(s, "-------------------------------------------------\n");
-
-       for_each_pci_dev(dev) {
-               pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
-               d3_state = ((pmcsr & PCI_PM_CTRL_STATE_MASK) ==
-                           (__force int)PCI_D3hot) ? 1 : 0;
-
-               seq_printf(s, "pci %04x %04X %s %20.20s: ",
-                          dev->vendor, dev->device, dev_name(&dev->dev),
-                          dev_driver_string(&dev->dev));
-               seq_printf(s, " d3:%x\n", d3_state);
-       }
-
-       seq_puts(s, "\n--------------------------------------\n");
-       seq_puts(s, "D3/D0i3 Status\n");
-       seq_puts(s, "--------------------------------------\n");
-       seq_puts(s, "Block\t\t D3\t D0i3\n");
-       for (index = 0; index < conf->ioss_d0ix_evts; index++) {
-               seq_printf(s, "%-10s\t %u\t %u\n",
-                          conf->ioss_d0ix_data[index].name,
-                          d3_sts[index], d0ix_sts[index]);
-       }
-
-       seq_puts(s, "\n--------------------------------------\n");
-       seq_puts(s, "South Complex PowerGate Status\n");
-       seq_puts(s, "--------------------------------------\n");
-       seq_puts(s, "Device\t\t PG\n");
-       for (index = 0; index < conf->ioss_pg_evts; index++) {
-               seq_printf(s, "%-10s\t %u\n",
-                          conf->ioss_pg_data[index].name,
-                          pg_sts[index]);
-       }
-
-       evtlog->telem_evtid = conf->pss_idle_id;
-       ret = telemetry_read_events(TELEM_PSS, evtlog, 1);
-       if (ret < 0)
-               return ret;
-
-       seq_puts(s, "\n-----------------------------------------\n");
-       seq_puts(s, "North Idle Status\n");
-       seq_puts(s, "-----------------------------------------\n");
-       for (idx = 0; idx < conf->pss_idle_evts - 1; idx++) {
-               pss_idle[idx] = (evtlog->telem_evtlog >>
-                               conf->pss_idle_data[idx].bit_pos) &
-                               TELEM_MASK_BIT;
-       }
-
-       pss_idle[idx] = (evtlog->telem_evtlog >>
-                       conf->pss_idle_data[idx].bit_pos) &
-                       TELEM_APL_MASK_PCS_STATE;
-
-       for (index = 0; index < conf->pss_idle_evts; index++) {
-               seq_printf(s, "%-30s %u\n",
-                          conf->pss_idle_data[index].name,
-                          pss_idle[index]);
-       }
-
-       seq_puts(s, "\nPCS_STATUS Code\n");
-       seq_puts(s, "0:C0 1:C1 2:C1_DN_WT_DEV 3:C2 4:C2_WT_DE_MEM_UP\n");
-       seq_puts(s, "5:C2_WT_DE_MEM_DOWN 6:C2_UP_WT_DEV 7:C2_DN 8:C2_VOA\n");
-       seq_puts(s, "9:C2_VOA_UP 10:S0IX_PRE 11:S0IX\n");
-
-       return 0;
-}
-
-DEFINE_SHOW_ATTRIBUTE(telem_soc_states);
-
-static int telem_s0ix_res_get(void *data, u64 *val)
-{
-       struct telemetry_plt_config *plt_config = telemetry_get_pltdata();
-       u64 s0ix_total_res;
-       int ret;
-
-       ret = intel_pmc_s0ix_counter_read(plt_config->pmc, &s0ix_total_res);
-       if (ret) {
-               pr_err("Failed to read S0ix residency");
-               return ret;
-       }
-
-       *val = s0ix_total_res;
-
-       return 0;
-}
-
-DEFINE_DEBUGFS_ATTRIBUTE(telem_s0ix_fops, telem_s0ix_res_get, NULL, "%llu\n");
-
-static int telem_pss_trc_verb_show(struct seq_file *s, void *unused)
-{
-       u32 verbosity;
-       int err;
-
-       err = telemetry_get_trace_verbosity(TELEM_PSS, &verbosity);
-       if (err) {
-               pr_err("Get PSS Trace Verbosity Failed with Error %d\n", err);
-               return -EFAULT;
-       }
-
-       seq_printf(s, "PSS Trace Verbosity %u\n", verbosity);
-       return 0;
-}
-
-static ssize_t telem_pss_trc_verb_write(struct file *file,
-                                       const char __user *userbuf,
-                                       size_t count, loff_t *ppos)
-{
-       u32 verbosity;
-       int err;
-
-       err = kstrtou32_from_user(userbuf, count, 0, &verbosity);
-       if (err)
-               return err;
-
-       err = telemetry_set_trace_verbosity(TELEM_PSS, verbosity);
-       if (err) {
-               pr_err("Changing PSS Trace Verbosity Failed. Error %d\n", err);
-               return err;
-       }
-
-       return count;
-}
-
-static int telem_pss_trc_verb_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, telem_pss_trc_verb_show, inode->i_private);
-}
-
-static const struct file_operations telem_pss_trc_verb_ops = {
-       .open           = telem_pss_trc_verb_open,
-       .read           = seq_read,
-       .write          = telem_pss_trc_verb_write,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-static int telem_ioss_trc_verb_show(struct seq_file *s, void *unused)
-{
-       u32 verbosity;
-       int err;
-
-       err = telemetry_get_trace_verbosity(TELEM_IOSS, &verbosity);
-       if (err) {
-               pr_err("Get IOSS Trace Verbosity Failed with Error %d\n", err);
-               return -EFAULT;
-       }
-
-       seq_printf(s, "IOSS Trace Verbosity %u\n", verbosity);
-       return 0;
-}
-
-static ssize_t telem_ioss_trc_verb_write(struct file *file,
-                                        const char __user *userbuf,
-                                        size_t count, loff_t *ppos)
-{
-       u32 verbosity;
-       int err;
-
-       err = kstrtou32_from_user(userbuf, count, 0, &verbosity);
-       if (err)
-               return err;
-
-       err = telemetry_set_trace_verbosity(TELEM_IOSS, verbosity);
-       if (err) {
-               pr_err("Changing IOSS Trace Verbosity Failed. Error %d\n", err);
-               return err;
-       }
-
-       return count;
-}
-
-static int telem_ioss_trc_verb_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, telem_ioss_trc_verb_show, inode->i_private);
-}
-
-static const struct file_operations telem_ioss_trc_verb_ops = {
-       .open           = telem_ioss_trc_verb_open,
-       .read           = seq_read,
-       .write          = telem_ioss_trc_verb_write,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-static int pm_suspend_prep_cb(void)
-{
-       struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
-       struct telemetry_debugfs_conf *conf = debugfs_conf;
-       int ret, index;
-
-       ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
-                       TELEM_MAX_OS_ALLOCATED_EVENTS);
-       if (ret < 0) {
-               suspend_prep_ok = 0;
-               goto out;
-       }
-
-       for (index = 0; index < ret; index++) {
-
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
-                                          suspend_shlw_ctr_temp);
-
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
-                                          suspend_deep_ctr_temp);
-
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
-                                          suspend_shlw_res_temp);
-
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
-                                          suspend_deep_res_temp);
-       }
-       suspend_prep_ok = 1;
-out:
-       return NOTIFY_OK;
-}
-
-static int pm_suspend_exit_cb(void)
-{
-       struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
-       static u32 suspend_shlw_ctr_exit, suspend_deep_ctr_exit;
-       static u64 suspend_shlw_res_exit, suspend_deep_res_exit;
-       struct telemetry_debugfs_conf *conf = debugfs_conf;
-       int ret, index;
-
-       if (!suspend_prep_ok)
-               goto out;
-
-       ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
-                                         TELEM_MAX_OS_ALLOCATED_EVENTS);
-       if (ret < 0)
-               goto out;
-
-       for (index = 0; index < ret; index++) {
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
-                                          suspend_shlw_ctr_exit);
-
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
-                                          suspend_deep_ctr_exit);
-
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
-                                          suspend_shlw_res_exit);
-
-               TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
-                                          suspend_deep_res_exit);
-       }
-
-       if ((suspend_shlw_ctr_exit < suspend_shlw_ctr_temp) ||
-           (suspend_deep_ctr_exit < suspend_deep_ctr_temp) ||
-           (suspend_shlw_res_exit < suspend_shlw_res_temp) ||
-           (suspend_deep_res_exit < suspend_deep_res_temp)) {
-               pr_err("Wrong s0ix counters detected\n");
-               goto out;
-       }
-
-       /*
-        * Due to some design limitations in the firmware, sometimes the
-        * counters do not get updated by the time we reach here. As a
-        * workaround, we try to see if this was a genuine case of sleep
-        * failure or not by cross-checking from PMC GCR registers directly.
-        */
-       if (suspend_shlw_ctr_exit == suspend_shlw_ctr_temp &&
-           suspend_deep_ctr_exit == suspend_deep_ctr_temp) {
-               struct telemetry_plt_config *plt_config = telemetry_get_pltdata();
-               struct intel_pmc_dev *pmc = plt_config->pmc;
-
-               ret = intel_pmc_gcr_read64(pmc, PMC_GCR_TELEM_SHLW_S0IX_REG,
-                                         &suspend_shlw_res_exit);
-               if (ret < 0)
-                       goto out;
-
-               ret = intel_pmc_gcr_read64(pmc, PMC_GCR_TELEM_DEEP_S0IX_REG,
-                                         &suspend_deep_res_exit);
-               if (ret < 0)
-                       goto out;
-
-               if (suspend_shlw_res_exit > suspend_shlw_res_temp)
-                       suspend_shlw_ctr_exit++;
-
-               if (suspend_deep_res_exit > suspend_deep_res_temp)
-                       suspend_deep_ctr_exit++;
-       }
-
-       suspend_shlw_ctr_exit -= suspend_shlw_ctr_temp;
-       suspend_deep_ctr_exit -= suspend_deep_ctr_temp;
-       suspend_shlw_res_exit -= suspend_shlw_res_temp;
-       suspend_deep_res_exit -= suspend_deep_res_temp;
-
-       if (suspend_shlw_ctr_exit != 0) {
-               conf->suspend_stats.shlw_ctr +=
-               suspend_shlw_ctr_exit;
-
-               conf->suspend_stats.shlw_res +=
-               suspend_shlw_res_exit;
-       }
-
-       if (suspend_deep_ctr_exit != 0) {
-               conf->suspend_stats.deep_ctr +=
-               suspend_deep_ctr_exit;
-
-               conf->suspend_stats.deep_res +=
-               suspend_deep_res_exit;
-       }
-
-out:
-       suspend_prep_ok = 0;
-       return NOTIFY_OK;
-}
-
-static int pm_notification(struct notifier_block *this,
-                          unsigned long event, void *ptr)
-{
-       switch (event) {
-       case PM_SUSPEND_PREPARE:
-               return pm_suspend_prep_cb();
-       case PM_POST_SUSPEND:
-               return pm_suspend_exit_cb();
-       }
-
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block pm_notifier = {
-       .notifier_call = pm_notification,
-};
-
-static int __init telemetry_debugfs_init(void)
-{
-       const struct x86_cpu_id *id;
-       int err;
-       struct dentry *dir;
-
-       /* Only APL supported for now */
-       id = x86_match_cpu(telemetry_debugfs_cpu_ids);
-       if (!id)
-               return -ENODEV;
-
-       debugfs_conf = (struct telemetry_debugfs_conf *)id->driver_data;
-
-       if (!telemetry_get_pltdata()) {
-               pr_info("Invalid pltconfig, ensure IPC1 device is enabled in BIOS\n");
-               return -ENODEV;
-       }
-
-       err = telemetry_debugfs_check_evts();
-       if (err < 0) {
-               pr_info("telemetry_debugfs_check_evts failed\n");
-               return -EINVAL;
-       }
-
-       register_pm_notifier(&pm_notifier);
-
-       dir = debugfs_create_dir("telemetry", NULL);
-       debugfs_conf->telemetry_dbg_dir = dir;
-
-       debugfs_create_file("pss_info", S_IFREG | S_IRUGO, dir, NULL,
-                           &telem_pss_states_fops);
-       debugfs_create_file("ioss_info", S_IFREG | S_IRUGO, dir, NULL,
-                           &telem_ioss_states_fops);
-       debugfs_create_file("soc_states", S_IFREG | S_IRUGO, dir, NULL,
-                           &telem_soc_states_fops);
-       debugfs_create_file("s0ix_residency_usec", S_IFREG | S_IRUGO, dir, NULL,
-                           &telem_s0ix_fops);
-       debugfs_create_file("pss_trace_verbosity", S_IFREG | S_IRUGO, dir, NULL,
-                           &telem_pss_trc_verb_ops);
-       debugfs_create_file("ioss_trace_verbosity", S_IFREG | S_IRUGO, dir,
-                           NULL, &telem_ioss_trc_verb_ops);
-       return 0;
-}
-
-static void __exit telemetry_debugfs_exit(void)
-{
-       debugfs_remove_recursive(debugfs_conf->telemetry_dbg_dir);
-       debugfs_conf->telemetry_dbg_dir = NULL;
-       unregister_pm_notifier(&pm_notifier);
-}
-
-late_initcall(telemetry_debugfs_init);
-module_exit(telemetry_debugfs_exit);
-
-MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
-MODULE_DESCRIPTION("Intel SoC Telemetry debugfs Interface");
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/intel_telemetry_pltdrv.c b/drivers/platform/x86/intel_telemetry_pltdrv.c
deleted file mode 100644 (file)
index 405dea8..0000000
+++ /dev/null
@@ -1,1189 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Intel SOC Telemetry Platform Driver: Currently supports APL
- * Copyright (c) 2015, Intel Corporation.
- * All Rights Reserved.
- *
- * This file provides the platform specific telemetry implementation for APL.
- * It used the PUNIT and PMC IPC interfaces for configuring the counters.
- * The accumulated results are fetched from SRAM.
- */
-
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-
-#include <asm/cpu_device_id.h>
-#include <asm/intel-family.h>
-#include <asm/intel_punit_ipc.h>
-#include <asm/intel_telemetry.h>
-
-#define DRIVER_NAME    "intel_telemetry"
-#define DRIVER_VERSION "1.0.0"
-
-#define TELEM_TRC_VERBOSITY_MASK       0x3
-
-#define TELEM_MIN_PERIOD(x)            ((x) & 0x7F0000)
-#define TELEM_MAX_PERIOD(x)            ((x) & 0x7F000000)
-#define TELEM_SAMPLE_PERIOD_INVALID(x) ((x) & (BIT(7)))
-#define TELEM_CLEAR_SAMPLE_PERIOD(x)   ((x) &= ~0x7F)
-
-#define TELEM_SAMPLING_DEFAULT_PERIOD  0xD
-
-#define TELEM_MAX_EVENTS_SRAM          28
-#define TELEM_SSRAM_STARTTIME_OFFSET   8
-#define TELEM_SSRAM_EVTLOG_OFFSET      16
-
-#define IOSS_TELEM                     0xeb
-#define IOSS_TELEM_EVENT_READ          0x0
-#define IOSS_TELEM_EVENT_WRITE         0x1
-#define IOSS_TELEM_INFO_READ           0x2
-#define IOSS_TELEM_TRACE_CTL_READ      0x5
-#define IOSS_TELEM_TRACE_CTL_WRITE     0x6
-#define IOSS_TELEM_EVENT_CTL_READ      0x7
-#define IOSS_TELEM_EVENT_CTL_WRITE     0x8
-#define IOSS_TELEM_EVT_WRITE_SIZE      0x3
-
-#define TELEM_INFO_SRAMEVTS_MASK       0xFF00
-#define TELEM_INFO_SRAMEVTS_SHIFT      0x8
-#define TELEM_SSRAM_READ_TIMEOUT       10
-
-#define TELEM_INFO_NENABLES_MASK       0xFF
-#define TELEM_EVENT_ENABLE             0x8000
-
-#define TELEM_MASK_BIT                 1
-#define TELEM_MASK_BYTE                        0xFF
-#define BYTES_PER_LONG                 8
-#define TELEM_MASK_PCS_STATE           0xF
-
-#define TELEM_DISABLE(x)               ((x) &= ~(BIT(31)))
-#define TELEM_CLEAR_EVENTS(x)          ((x) |= (BIT(30)))
-#define TELEM_ENABLE_SRAM_EVT_TRACE(x) ((x) &= ~(BIT(30) | BIT(24)))
-#define TELEM_ENABLE_PERIODIC(x)       ((x) |= (BIT(23) | BIT(31) | BIT(7)))
-#define TELEM_EXTRACT_VERBOSITY(x, y)  ((y) = (((x) >> 27) & 0x3))
-#define TELEM_CLEAR_VERBOSITY_BITS(x)  ((x) &= ~(BIT(27) | BIT(28)))
-#define TELEM_SET_VERBOSITY_BITS(x, y) ((x) |= ((y) << 27))
-
-enum telemetry_action {
-       TELEM_UPDATE = 0,
-       TELEM_ADD,
-       TELEM_RESET,
-       TELEM_ACTION_NONE
-};
-
-struct telem_ssram_region {
-       u64 timestamp;
-       u64 start_time;
-       u64 events[TELEM_MAX_EVENTS_SRAM];
-};
-
-static struct telemetry_plt_config *telm_conf;
-
-/*
- * The following counters are programmed by default during setup.
- * Only 20 allocated to kernel driver
- */
-static struct telemetry_evtmap
-       telemetry_apl_ioss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
-       {"SOC_S0IX_TOTAL_RES",                  0x4800},
-       {"SOC_S0IX_TOTAL_OCC",                  0x4000},
-       {"SOC_S0IX_SHALLOW_RES",                0x4801},
-       {"SOC_S0IX_SHALLOW_OCC",                0x4001},
-       {"SOC_S0IX_DEEP_RES",                   0x4802},
-       {"SOC_S0IX_DEEP_OCC",                   0x4002},
-       {"PMC_POWER_GATE",                      0x5818},
-       {"PMC_D3_STATES",                       0x5819},
-       {"PMC_D0I3_STATES",                     0x581A},
-       {"PMC_S0IX_WAKE_REASON_GPIO",           0x6000},
-       {"PMC_S0IX_WAKE_REASON_TIMER",          0x6001},
-       {"PMC_S0IX_WAKE_REASON_VNNREQ",         0x6002},
-       {"PMC_S0IX_WAKE_REASON_LOWPOWER",       0x6003},
-       {"PMC_S0IX_WAKE_REASON_EXTERNAL",       0x6004},
-       {"PMC_S0IX_WAKE_REASON_MISC",           0x6005},
-       {"PMC_S0IX_BLOCKING_IPS_D3_D0I3",       0x6006},
-       {"PMC_S0IX_BLOCKING_IPS_PG",            0x6007},
-       {"PMC_S0IX_BLOCKING_MISC_IPS_PG",       0x6008},
-       {"PMC_S0IX_BLOCK_IPS_VNN_REQ",          0x6009},
-       {"PMC_S0IX_BLOCK_IPS_CLOCKS",           0x600B},
-};
-
-
-static struct telemetry_evtmap
-       telemetry_apl_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
-       {"IA_CORE0_C6_RES",                     0x0400},
-       {"IA_CORE0_C6_CTR",                     0x0000},
-       {"IA_MODULE0_C7_RES",                   0x0410},
-       {"IA_MODULE0_C7_CTR",                   0x000E},
-       {"IA_C0_RES",                           0x0805},
-       {"PCS_LTR",                             0x2801},
-       {"PSTATES",                             0x2802},
-       {"SOC_S0I3_RES",                        0x0409},
-       {"SOC_S0I3_CTR",                        0x000A},
-       {"PCS_S0I3_CTR",                        0x0009},
-       {"PCS_C1E_RES",                         0x041A},
-       {"PCS_IDLE_STATUS",                     0x2806},
-       {"IA_PERF_LIMITS",                      0x280B},
-       {"GT_PERF_LIMITS",                      0x280C},
-       {"PCS_WAKEUP_S0IX_CTR",                 0x0030},
-       {"PCS_IDLE_BLOCKED",                    0x2C00},
-       {"PCS_S0IX_BLOCKED",                    0x2C01},
-       {"PCS_S0IX_WAKE_REASONS",               0x2C02},
-       {"PCS_LTR_BLOCKING",                    0x2C03},
-       {"PC2_AND_MEM_SHALLOW_IDLE_RES",        0x1D40},
-};
-
-static struct telemetry_evtmap
-       telemetry_glk_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
-       {"IA_CORE0_C6_RES",                     0x0400},
-       {"IA_CORE0_C6_CTR",                     0x0000},
-       {"IA_MODULE0_C7_RES",                   0x0410},
-       {"IA_MODULE0_C7_CTR",                   0x000C},
-       {"IA_C0_RES",                           0x0805},
-       {"PCS_LTR",                             0x2801},
-       {"PSTATES",                             0x2802},
-       {"SOC_S0I3_RES",                        0x0407},
-       {"SOC_S0I3_CTR",                        0x0008},
-       {"PCS_S0I3_CTR",                        0x0007},
-       {"PCS_C1E_RES",                         0x0414},
-       {"PCS_IDLE_STATUS",                     0x2806},
-       {"IA_PERF_LIMITS",                      0x280B},
-       {"GT_PERF_LIMITS",                      0x280C},
-       {"PCS_WAKEUP_S0IX_CTR",                 0x0025},
-       {"PCS_IDLE_BLOCKED",                    0x2C00},
-       {"PCS_S0IX_BLOCKED",                    0x2C01},
-       {"PCS_S0IX_WAKE_REASONS",               0x2C02},
-       {"PCS_LTR_BLOCKING",                    0x2C03},
-       {"PC2_AND_MEM_SHALLOW_IDLE_RES",        0x1D40},
-};
-
-/* APL specific Data */
-static struct telemetry_plt_config telem_apl_config = {
-       .pss_config = {
-               .telem_evts = telemetry_apl_pss_default_events,
-       },
-       .ioss_config = {
-               .telem_evts = telemetry_apl_ioss_default_events,
-       },
-};
-
-/* GLK specific Data */
-static struct telemetry_plt_config telem_glk_config = {
-       .pss_config = {
-               .telem_evts = telemetry_glk_pss_default_events,
-       },
-       .ioss_config = {
-               .telem_evts = telemetry_apl_ioss_default_events,
-       },
-};
-
-static const struct x86_cpu_id telemetry_cpu_ids[] = {
-       X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT,       &telem_apl_config),
-       X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS,  &telem_glk_config),
-       {}
-};
-
-MODULE_DEVICE_TABLE(x86cpu, telemetry_cpu_ids);
-
-static inline int telem_get_unitconfig(enum telemetry_unit telem_unit,
-                                    struct telemetry_unit_config **unit_config)
-{
-       if (telem_unit == TELEM_PSS)
-               *unit_config = &(telm_conf->pss_config);
-       else if (telem_unit == TELEM_IOSS)
-               *unit_config = &(telm_conf->ioss_config);
-       else
-               return -EINVAL;
-
-       return 0;
-
-}
-
-static int telemetry_check_evtid(enum telemetry_unit telem_unit,
-                                u32 *evtmap, u8 len,
-                                enum telemetry_action action)
-{
-       struct telemetry_unit_config *unit_config;
-       int ret;
-
-       ret = telem_get_unitconfig(telem_unit, &unit_config);
-       if (ret < 0)
-               return ret;
-
-       switch (action) {
-       case TELEM_RESET:
-               if (len > TELEM_MAX_EVENTS_SRAM)
-                       return -EINVAL;
-
-               break;
-
-       case TELEM_UPDATE:
-               if (len > TELEM_MAX_EVENTS_SRAM)
-                       return -EINVAL;
-
-               if ((len > 0) && (evtmap == NULL))
-                       return -EINVAL;
-
-               break;
-
-       case TELEM_ADD:
-               if ((len + unit_config->ssram_evts_used) >
-                   TELEM_MAX_EVENTS_SRAM)
-                       return -EINVAL;
-
-               if ((len > 0) && (evtmap == NULL))
-                       return -EINVAL;
-
-               break;
-
-       default:
-               pr_err("Unknown Telemetry action specified %d\n", action);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-
-static inline int telemetry_plt_config_ioss_event(u32 evt_id, int index)
-{
-       u32 write_buf;
-
-       write_buf = evt_id | TELEM_EVENT_ENABLE;
-       write_buf <<= BITS_PER_BYTE;
-       write_buf |= index;
-
-       return intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
-                                        IOSS_TELEM_EVENT_WRITE, &write_buf,
-                                        IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0);
-}
-
-static inline int telemetry_plt_config_pss_event(u32 evt_id, int index)
-{
-       u32 write_buf;
-       int ret;
-
-       write_buf = evt_id | TELEM_EVENT_ENABLE;
-       ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT,
-                                     index, 0, &write_buf, NULL);
-
-       return ret;
-}
-
-static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
-                                        enum telemetry_action action)
-{
-       struct intel_scu_ipc_dev *scu = telm_conf->scu;
-       u8 num_ioss_evts, ioss_period;
-       int ret, index, idx;
-       u32 *ioss_evtmap;
-       u32 telem_ctrl;
-
-       num_ioss_evts = evtconfig.num_evts;
-       ioss_period = evtconfig.period;
-       ioss_evtmap = evtconfig.evtmap;
-
-       /* Get telemetry EVENT CTL */
-       ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
-                                   IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
-                                   &telem_ctrl, sizeof(telem_ctrl));
-       if (ret) {
-               pr_err("IOSS TELEM_CTRL Read Failed\n");
-               return ret;
-       }
-
-       /* Disable Telemetry */
-       TELEM_DISABLE(telem_ctrl);
-
-       ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
-                                   IOSS_TELEM_EVENT_CTL_WRITE, &telem_ctrl,
-                                   sizeof(telem_ctrl), NULL, 0);
-       if (ret) {
-               pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
-               return ret;
-       }
-
-
-       /* Reset Everything */
-       if (action == TELEM_RESET) {
-               /* Clear All Events */
-               TELEM_CLEAR_EVENTS(telem_ctrl);
-
-               ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
-                                           IOSS_TELEM_EVENT_CTL_WRITE,
-                                           &telem_ctrl, sizeof(telem_ctrl),
-                                           NULL, 0);
-               if (ret) {
-                       pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
-                       return ret;
-               }
-               telm_conf->ioss_config.ssram_evts_used = 0;
-
-               /* Configure Events */
-               for (idx = 0; idx < num_ioss_evts; idx++) {
-                       if (telemetry_plt_config_ioss_event(
-                           telm_conf->ioss_config.telem_evts[idx].evt_id,
-                           idx)) {
-                               pr_err("IOSS TELEM_RESET Fail for data: %x\n",
-                               telm_conf->ioss_config.telem_evts[idx].evt_id);
-                               continue;
-                       }
-                       telm_conf->ioss_config.ssram_evts_used++;
-               }
-       }
-
-       /* Re-Configure Everything */
-       if (action == TELEM_UPDATE) {
-               /* Clear All Events */
-               TELEM_CLEAR_EVENTS(telem_ctrl);
-
-               ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
-                                           IOSS_TELEM_EVENT_CTL_WRITE,
-                                           &telem_ctrl, sizeof(telem_ctrl),
-                                           NULL, 0);
-               if (ret) {
-                       pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
-                       return ret;
-               }
-               telm_conf->ioss_config.ssram_evts_used = 0;
-
-               /* Configure Events */
-               for (index = 0; index < num_ioss_evts; index++) {
-                       telm_conf->ioss_config.telem_evts[index].evt_id =
-                       ioss_evtmap[index];
-
-                       if (telemetry_plt_config_ioss_event(
-                           telm_conf->ioss_config.telem_evts[index].evt_id,
-                           index)) {
-                               pr_err("IOSS TELEM_UPDATE Fail for Evt%x\n",
-                                       ioss_evtmap[index]);
-                               continue;
-                       }
-                       telm_conf->ioss_config.ssram_evts_used++;
-               }
-       }
-
-       /* Add some Events */
-       if (action == TELEM_ADD) {
-               /* Configure Events */
-               for (index = telm_conf->ioss_config.ssram_evts_used, idx = 0;
-                    idx < num_ioss_evts; index++, idx++) {
-                       telm_conf->ioss_config.telem_evts[index].evt_id =
-                       ioss_evtmap[idx];
-
-                       if (telemetry_plt_config_ioss_event(
-                           telm_conf->ioss_config.telem_evts[index].evt_id,
-                           index)) {
-                               pr_err("IOSS TELEM_ADD Fail for Event %x\n",
-                                       ioss_evtmap[idx]);
-                               continue;
-                       }
-                       telm_conf->ioss_config.ssram_evts_used++;
-               }
-       }
-
-       /* Enable Periodic Telemetry Events and enable SRAM trace */
-       TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
-       TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
-       TELEM_ENABLE_PERIODIC(telem_ctrl);
-       telem_ctrl |= ioss_period;
-
-       ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
-                                   IOSS_TELEM_EVENT_CTL_WRITE,
-                                   &telem_ctrl, sizeof(telem_ctrl), NULL, 0);
-       if (ret) {
-               pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
-               return ret;
-       }
-
-       telm_conf->ioss_config.curr_period = ioss_period;
-
-       return 0;
-}
-
-
-static int telemetry_setup_pssevtconfig(struct telemetry_evtconfig evtconfig,
-                                       enum telemetry_action action)
-{
-       u8 num_pss_evts, pss_period;
-       int ret, index, idx;
-       u32 *pss_evtmap;
-       u32 telem_ctrl;
-
-       num_pss_evts = evtconfig.num_evts;
-       pss_period = evtconfig.period;
-       pss_evtmap = evtconfig.evtmap;
-
-       /* PSS Config */
-       /* Get telemetry EVENT CTL */
-       ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
-                                     0, 0, NULL, &telem_ctrl);
-       if (ret) {
-               pr_err("PSS TELEM_CTRL Read Failed\n");
-               return ret;
-       }
-
-       /* Disable Telemetry */
-       TELEM_DISABLE(telem_ctrl);
-       ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
-                                     0, 0, &telem_ctrl, NULL);
-       if (ret) {
-               pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
-               return ret;
-       }
-
-       /* Reset Everything */
-       if (action == TELEM_RESET) {
-               /* Clear All Events */
-               TELEM_CLEAR_EVENTS(telem_ctrl);
-
-               ret = intel_punit_ipc_command(
-                               IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
-                               0, 0, &telem_ctrl, NULL);
-               if (ret) {
-                       pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
-                       return ret;
-               }
-               telm_conf->pss_config.ssram_evts_used = 0;
-               /* Configure Events */
-               for (idx = 0; idx < num_pss_evts; idx++) {
-                       if (telemetry_plt_config_pss_event(
-                           telm_conf->pss_config.telem_evts[idx].evt_id,
-                           idx)) {
-                               pr_err("PSS TELEM_RESET Fail for Event %x\n",
-                               telm_conf->pss_config.telem_evts[idx].evt_id);
-                               continue;
-                       }
-                       telm_conf->pss_config.ssram_evts_used++;
-               }
-       }
-
-       /* Re-Configure Everything */
-       if (action == TELEM_UPDATE) {
-               /* Clear All Events */
-               TELEM_CLEAR_EVENTS(telem_ctrl);
-
-               ret = intel_punit_ipc_command(
-                               IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
-                               0, 0, &telem_ctrl, NULL);
-               if (ret) {
-                       pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
-                       return ret;
-               }
-               telm_conf->pss_config.ssram_evts_used = 0;
-
-               /* Configure Events */
-               for (index = 0; index < num_pss_evts; index++) {
-                       telm_conf->pss_config.telem_evts[index].evt_id =
-                       pss_evtmap[index];
-
-                       if (telemetry_plt_config_pss_event(
-                           telm_conf->pss_config.telem_evts[index].evt_id,
-                           index)) {
-                               pr_err("PSS TELEM_UPDATE Fail for Event %x\n",
-                                       pss_evtmap[index]);
-                               continue;
-                       }
-                       telm_conf->pss_config.ssram_evts_used++;
-               }
-       }
-
-       /* Add some Events */
-       if (action == TELEM_ADD) {
-               /* Configure Events */
-               for (index = telm_conf->pss_config.ssram_evts_used, idx = 0;
-                    idx < num_pss_evts; index++, idx++) {
-
-                       telm_conf->pss_config.telem_evts[index].evt_id =
-                       pss_evtmap[idx];
-
-                       if (telemetry_plt_config_pss_event(
-                           telm_conf->pss_config.telem_evts[index].evt_id,
-                           index)) {
-                               pr_err("PSS TELEM_ADD Fail for Event %x\n",
-                                       pss_evtmap[idx]);
-                               continue;
-                       }
-                       telm_conf->pss_config.ssram_evts_used++;
-               }
-       }
-
-       /* Enable Periodic Telemetry Events and enable SRAM trace */
-       TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
-       TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
-       TELEM_ENABLE_PERIODIC(telem_ctrl);
-       telem_ctrl |= pss_period;
-
-       ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
-                                     0, 0, &telem_ctrl, NULL);
-       if (ret) {
-               pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
-               return ret;
-       }
-
-       telm_conf->pss_config.curr_period = pss_period;
-
-       return 0;
-}
-
-static int telemetry_setup_evtconfig(struct telemetry_evtconfig pss_evtconfig,
-                                    struct telemetry_evtconfig ioss_evtconfig,
-                                    enum telemetry_action action)
-{
-       int ret;
-
-       mutex_lock(&(telm_conf->telem_lock));
-
-       if ((action == TELEM_UPDATE) && (telm_conf->telem_in_use)) {
-               ret = -EBUSY;
-               goto out;
-       }
-
-       ret = telemetry_check_evtid(TELEM_PSS, pss_evtconfig.evtmap,
-                                   pss_evtconfig.num_evts, action);
-       if (ret)
-               goto out;
-
-       ret = telemetry_check_evtid(TELEM_IOSS, ioss_evtconfig.evtmap,
-                                   ioss_evtconfig.num_evts, action);
-       if (ret)
-               goto out;
-
-       if (ioss_evtconfig.num_evts) {
-               ret = telemetry_setup_iossevtconfig(ioss_evtconfig, action);
-               if (ret)
-                       goto out;
-       }
-
-       if (pss_evtconfig.num_evts) {
-               ret = telemetry_setup_pssevtconfig(pss_evtconfig, action);
-               if (ret)
-                       goto out;
-       }
-
-       if ((action == TELEM_UPDATE) || (action == TELEM_ADD))
-               telm_conf->telem_in_use = true;
-       else
-               telm_conf->telem_in_use = false;
-
-out:
-       mutex_unlock(&(telm_conf->telem_lock));
-       return ret;
-}
-
-static int telemetry_setup(struct platform_device *pdev)
-{
-       struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
-       u32 read_buf, events, event_regs;
-       int ret;
-
-       ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
-                                       IOSS_TELEM_INFO_READ, NULL, 0,
-                                       &read_buf, sizeof(read_buf));
-       if (ret) {
-               dev_err(&pdev->dev, "IOSS TELEM_INFO Read Failed\n");
-               return ret;
-       }
-
-       /* Get telemetry Info */
-       events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
-                 TELEM_INFO_SRAMEVTS_SHIFT;
-       event_regs = read_buf & TELEM_INFO_NENABLES_MASK;
-       if ((events < TELEM_MAX_EVENTS_SRAM) ||
-           (event_regs < TELEM_MAX_EVENTS_SRAM)) {
-               dev_err(&pdev->dev, "IOSS:Insufficient Space for SRAM Trace\n");
-               dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
-                       events, event_regs);
-               return -ENOMEM;
-       }
-
-       telm_conf->ioss_config.min_period = TELEM_MIN_PERIOD(read_buf);
-       telm_conf->ioss_config.max_period = TELEM_MAX_PERIOD(read_buf);
-
-       /* PUNIT Mailbox Setup */
-       ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_INFO, 0, 0,
-                                     NULL, &read_buf);
-       if (ret) {
-               dev_err(&pdev->dev, "PSS TELEM_INFO Read Failed\n");
-               return ret;
-       }
-
-       /* Get telemetry Info */
-       events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
-                 TELEM_INFO_SRAMEVTS_SHIFT;
-       event_regs = read_buf & TELEM_INFO_SRAMEVTS_MASK;
-       if ((events < TELEM_MAX_EVENTS_SRAM) ||
-           (event_regs < TELEM_MAX_EVENTS_SRAM)) {
-               dev_err(&pdev->dev, "PSS:Insufficient Space for SRAM Trace\n");
-               dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
-                       events, event_regs);
-               return -ENOMEM;
-       }
-
-       telm_conf->pss_config.min_period = TELEM_MIN_PERIOD(read_buf);
-       telm_conf->pss_config.max_period = TELEM_MAX_PERIOD(read_buf);
-
-       pss_evtconfig.evtmap = NULL;
-       pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
-       pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
-
-       ioss_evtconfig.evtmap = NULL;
-       ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
-       ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
-
-       ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
-                                       TELEM_RESET);
-       if (ret) {
-               dev_err(&pdev->dev, "TELEMETRY Setup Failed\n");
-               return ret;
-       }
-       return 0;
-}
-
-static int telemetry_plt_update_events(struct telemetry_evtconfig pss_evtconfig,
-                               struct telemetry_evtconfig ioss_evtconfig)
-{
-       int ret;
-
-       if ((pss_evtconfig.num_evts > 0) &&
-           (TELEM_SAMPLE_PERIOD_INVALID(pss_evtconfig.period))) {
-               pr_err("PSS Sampling Period Out of Range\n");
-               return -EINVAL;
-       }
-
-       if ((ioss_evtconfig.num_evts > 0) &&
-           (TELEM_SAMPLE_PERIOD_INVALID(ioss_evtconfig.period))) {
-               pr_err("IOSS Sampling Period Out of Range\n");
-               return -EINVAL;
-       }
-
-       ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
-                                       TELEM_UPDATE);
-       if (ret)
-               pr_err("TELEMETRY Config Failed\n");
-
-       return ret;
-}
-
-
-static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
-{
-       u32 telem_ctrl = 0;
-       int ret = 0;
-
-       mutex_lock(&(telm_conf->telem_lock));
-       if (ioss_period) {
-               struct intel_scu_ipc_dev *scu = telm_conf->scu;
-
-               if (TELEM_SAMPLE_PERIOD_INVALID(ioss_period)) {
-                       pr_err("IOSS Sampling Period Out of Range\n");
-                       ret = -EINVAL;
-                       goto out;
-               }
-
-               /* Get telemetry EVENT CTL */
-               ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
-                                           IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
-                                           &telem_ctrl, sizeof(telem_ctrl));
-               if (ret) {
-                       pr_err("IOSS TELEM_CTRL Read Failed\n");
-                       goto out;
-               }
-
-               /* Disable Telemetry */
-               TELEM_DISABLE(telem_ctrl);
-
-               ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
-                                               IOSS_TELEM_EVENT_CTL_WRITE,
-                                               &telem_ctrl, sizeof(telem_ctrl),
-                                               NULL, 0);
-               if (ret) {
-                       pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
-                       goto out;
-               }
-
-               /* Enable Periodic Telemetry Events and enable SRAM trace */
-               TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
-               TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
-               TELEM_ENABLE_PERIODIC(telem_ctrl);
-               telem_ctrl |= ioss_period;
-
-               ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
-                                               IOSS_TELEM_EVENT_CTL_WRITE,
-                                               &telem_ctrl, sizeof(telem_ctrl),
-                                               NULL, 0);
-               if (ret) {
-                       pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
-                       goto out;
-               }
-               telm_conf->ioss_config.curr_period = ioss_period;
-       }
-
-       if (pss_period) {
-               if (TELEM_SAMPLE_PERIOD_INVALID(pss_period)) {
-                       pr_err("PSS Sampling Period Out of Range\n");
-                       ret = -EINVAL;
-                       goto out;
-               }
-
-               /* Get telemetry EVENT CTL */
-               ret = intel_punit_ipc_command(
-                               IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
-                               0, 0, NULL, &telem_ctrl);
-               if (ret) {
-                       pr_err("PSS TELEM_CTRL Read Failed\n");
-                       goto out;
-               }
-
-               /* Disable Telemetry */
-               TELEM_DISABLE(telem_ctrl);
-               ret = intel_punit_ipc_command(
-                               IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
-                               0, 0, &telem_ctrl, NULL);
-               if (ret) {
-                       pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
-                       goto out;
-               }
-
-               /* Enable Periodic Telemetry Events and enable SRAM trace */
-               TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
-               TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
-               TELEM_ENABLE_PERIODIC(telem_ctrl);
-               telem_ctrl |= pss_period;
-
-               ret = intel_punit_ipc_command(
-                               IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
-                               0, 0, &telem_ctrl, NULL);
-               if (ret) {
-                       pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
-                       goto out;
-               }
-               telm_conf->pss_config.curr_period = pss_period;
-       }
-
-out:
-       mutex_unlock(&(telm_conf->telem_lock));
-       return ret;
-}
-
-
-static int telemetry_plt_get_sampling_period(u8 *pss_min_period,
-                                            u8 *pss_max_period,
-                                            u8 *ioss_min_period,
-                                            u8 *ioss_max_period)
-{
-       *pss_min_period = telm_conf->pss_config.min_period;
-       *pss_max_period = telm_conf->pss_config.max_period;
-       *ioss_min_period = telm_conf->ioss_config.min_period;
-       *ioss_max_period = telm_conf->ioss_config.max_period;
-
-       return 0;
-}
-
-
-static int telemetry_plt_reset_events(void)
-{
-       struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
-       int ret;
-
-       pss_evtconfig.evtmap = NULL;
-       pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
-       pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
-
-       ioss_evtconfig.evtmap = NULL;
-       ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
-       ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
-
-       ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
-                                       TELEM_RESET);
-       if (ret)
-               pr_err("TELEMETRY Reset Failed\n");
-
-       return ret;
-}
-
-
-static int telemetry_plt_get_eventconfig(struct telemetry_evtconfig *pss_config,
-                                       struct telemetry_evtconfig *ioss_config,
-                                       int pss_len, int ioss_len)
-{
-       u32 *pss_evtmap, *ioss_evtmap;
-       u32 index;
-
-       pss_evtmap = pss_config->evtmap;
-       ioss_evtmap = ioss_config->evtmap;
-
-       mutex_lock(&(telm_conf->telem_lock));
-       pss_config->num_evts = telm_conf->pss_config.ssram_evts_used;
-       ioss_config->num_evts = telm_conf->ioss_config.ssram_evts_used;
-
-       pss_config->period = telm_conf->pss_config.curr_period;
-       ioss_config->period = telm_conf->ioss_config.curr_period;
-
-       if ((pss_len < telm_conf->pss_config.ssram_evts_used) ||
-           (ioss_len < telm_conf->ioss_config.ssram_evts_used)) {
-               mutex_unlock(&(telm_conf->telem_lock));
-               return -EINVAL;
-       }
-
-       for (index = 0; index < telm_conf->pss_config.ssram_evts_used;
-            index++) {
-               pss_evtmap[index] =
-               telm_conf->pss_config.telem_evts[index].evt_id;
-       }
-
-       for (index = 0; index < telm_conf->ioss_config.ssram_evts_used;
-            index++) {
-               ioss_evtmap[index] =
-               telm_conf->ioss_config.telem_evts[index].evt_id;
-       }
-
-       mutex_unlock(&(telm_conf->telem_lock));
-       return 0;
-}
-
-
-static int telemetry_plt_add_events(u8 num_pss_evts, u8 num_ioss_evts,
-                                   u32 *pss_evtmap, u32 *ioss_evtmap)
-{
-       struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
-       int ret;
-
-       pss_evtconfig.evtmap = pss_evtmap;
-       pss_evtconfig.num_evts = num_pss_evts;
-       pss_evtconfig.period = telm_conf->pss_config.curr_period;
-
-       ioss_evtconfig.evtmap = ioss_evtmap;
-       ioss_evtconfig.num_evts = num_ioss_evts;
-       ioss_evtconfig.period = telm_conf->ioss_config.curr_period;
-
-       ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
-                                       TELEM_ADD);
-       if (ret)
-               pr_err("TELEMETRY ADD Failed\n");
-
-       return ret;
-}
-
-static int telem_evtlog_read(enum telemetry_unit telem_unit,
-                            struct telem_ssram_region *ssram_region, u8 len)
-{
-       struct telemetry_unit_config *unit_config;
-       u64 timestamp_prev, timestamp_next;
-       int ret, index, timeout = 0;
-
-       ret = telem_get_unitconfig(telem_unit, &unit_config);
-       if (ret < 0)
-               return ret;
-
-       if (len > unit_config->ssram_evts_used)
-               len = unit_config->ssram_evts_used;
-
-       do {
-               timestamp_prev = readq(unit_config->regmap);
-               if (!timestamp_prev) {
-                       pr_err("Ssram under update. Please Try Later\n");
-                       return -EBUSY;
-               }
-
-               ssram_region->start_time = readq(unit_config->regmap +
-                                                TELEM_SSRAM_STARTTIME_OFFSET);
-
-               for (index = 0; index < len; index++) {
-                       ssram_region->events[index] =
-                       readq(unit_config->regmap + TELEM_SSRAM_EVTLOG_OFFSET +
-                             BYTES_PER_LONG*index);
-               }
-
-               timestamp_next = readq(unit_config->regmap);
-               if (!timestamp_next) {
-                       pr_err("Ssram under update. Please Try Later\n");
-                       return -EBUSY;
-               }
-
-               if (timeout++ > TELEM_SSRAM_READ_TIMEOUT) {
-                       pr_err("Timeout while reading Events\n");
-                       return -EBUSY;
-               }
-
-       } while (timestamp_prev != timestamp_next);
-
-       ssram_region->timestamp = timestamp_next;
-
-       return len;
-}
-
-static int telemetry_plt_raw_read_eventlog(enum telemetry_unit telem_unit,
-                                          struct telemetry_evtlog *evtlog,
-                                          int len, int log_all_evts)
-{
-       int index, idx1, ret, readlen = len;
-       struct telem_ssram_region ssram_region;
-       struct telemetry_evtmap *evtmap;
-
-       switch (telem_unit)     {
-       case TELEM_PSS:
-               evtmap = telm_conf->pss_config.telem_evts;
-               break;
-
-       case TELEM_IOSS:
-               evtmap = telm_conf->ioss_config.telem_evts;
-               break;
-
-       default:
-               pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
-               return -EINVAL;
-       }
-
-       if (!log_all_evts)
-               readlen = TELEM_MAX_EVENTS_SRAM;
-
-       ret = telem_evtlog_read(telem_unit, &ssram_region, readlen);
-       if (ret < 0)
-               return ret;
-
-       /* Invalid evt-id array specified via length mismatch */
-       if ((!log_all_evts) && (len > ret))
-               return -EINVAL;
-
-       if (log_all_evts)
-               for (index = 0; index < ret; index++) {
-                       evtlog[index].telem_evtlog = ssram_region.events[index];
-                       evtlog[index].telem_evtid = evtmap[index].evt_id;
-               }
-       else
-               for (index = 0, readlen = 0; (index < ret) && (readlen < len);
-                    index++) {
-                       for (idx1 = 0; idx1 < len; idx1++) {
-                               /* Elements matched */
-                               if (evtmap[index].evt_id ==
-                                   evtlog[idx1].telem_evtid) {
-                                       evtlog[idx1].telem_evtlog =
-                                       ssram_region.events[index];
-                                       readlen++;
-
-                                       break;
-                               }
-                       }
-               }
-
-       return readlen;
-}
-
-static int telemetry_plt_read_eventlog(enum telemetry_unit telem_unit,
-               struct telemetry_evtlog *evtlog, int len, int log_all_evts)
-{
-       int ret;
-
-       mutex_lock(&(telm_conf->telem_lock));
-       ret = telemetry_plt_raw_read_eventlog(telem_unit, evtlog,
-                                             len, log_all_evts);
-       mutex_unlock(&(telm_conf->telem_lock));
-
-       return ret;
-}
-
-static int telemetry_plt_get_trace_verbosity(enum telemetry_unit telem_unit,
-                                            u32 *verbosity)
-{
-       u32 temp = 0;
-       int ret;
-
-       if (verbosity == NULL)
-               return -EINVAL;
-
-       mutex_lock(&(telm_conf->telem_trace_lock));
-       switch (telem_unit) {
-       case TELEM_PSS:
-               ret = intel_punit_ipc_command(
-                               IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
-                               0, 0, NULL, &temp);
-               if (ret) {
-                       pr_err("PSS TRACE_CTRL Read Failed\n");
-                       goto out;
-               }
-
-               break;
-
-       case TELEM_IOSS:
-               ret = intel_scu_ipc_dev_command(telm_conf->scu,
-                               IOSS_TELEM, IOSS_TELEM_TRACE_CTL_READ,
-                               NULL, 0, &temp, sizeof(temp));
-               if (ret) {
-                       pr_err("IOSS TRACE_CTL Read Failed\n");
-                       goto out;
-               }
-
-               break;
-
-       default:
-               pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
-               ret = -EINVAL;
-               break;
-       }
-       TELEM_EXTRACT_VERBOSITY(temp, *verbosity);
-
-out:
-       mutex_unlock(&(telm_conf->telem_trace_lock));
-       return ret;
-}
-
-static int telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit,
-                                            u32 verbosity)
-{
-       u32 temp = 0;
-       int ret;
-
-       verbosity &= TELEM_TRC_VERBOSITY_MASK;
-
-       mutex_lock(&(telm_conf->telem_trace_lock));
-       switch (telem_unit) {
-       case TELEM_PSS:
-               ret = intel_punit_ipc_command(
-                               IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
-                               0, 0, NULL, &temp);
-               if (ret) {
-                       pr_err("PSS TRACE_CTRL Read Failed\n");
-                       goto out;
-               }
-
-               TELEM_CLEAR_VERBOSITY_BITS(temp);
-               TELEM_SET_VERBOSITY_BITS(temp, verbosity);
-
-               ret = intel_punit_ipc_command(
-                               IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL,
-                               0, 0, &temp, NULL);
-               if (ret) {
-                       pr_err("PSS TRACE_CTRL Verbosity Set Failed\n");
-                       goto out;
-               }
-               break;
-
-       case TELEM_IOSS:
-               ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
-                                               IOSS_TELEM_TRACE_CTL_READ,
-                                               NULL, 0, &temp, sizeof(temp));
-               if (ret) {
-                       pr_err("IOSS TRACE_CTL Read Failed\n");
-                       goto out;
-               }
-
-               TELEM_CLEAR_VERBOSITY_BITS(temp);
-               TELEM_SET_VERBOSITY_BITS(temp, verbosity);
-
-               ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
-                                               IOSS_TELEM_TRACE_CTL_WRITE,
-                                               &temp, sizeof(temp), NULL, 0);
-               if (ret) {
-                       pr_err("IOSS TRACE_CTL Verbosity Set Failed\n");
-                       goto out;
-               }
-               break;
-
-       default:
-               pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
-               ret = -EINVAL;
-               break;
-       }
-
-out:
-       mutex_unlock(&(telm_conf->telem_trace_lock));
-       return ret;
-}
-
-static const struct telemetry_core_ops telm_pltops = {
-       .get_trace_verbosity = telemetry_plt_get_trace_verbosity,
-       .set_trace_verbosity = telemetry_plt_set_trace_verbosity,
-       .set_sampling_period = telemetry_plt_set_sampling_period,
-       .get_sampling_period = telemetry_plt_get_sampling_period,
-       .raw_read_eventlog = telemetry_plt_raw_read_eventlog,
-       .get_eventconfig = telemetry_plt_get_eventconfig,
-       .update_events = telemetry_plt_update_events,
-       .read_eventlog = telemetry_plt_read_eventlog,
-       .reset_events = telemetry_plt_reset_events,
-       .add_events = telemetry_plt_add_events,
-};
-
-static int telemetry_pltdrv_probe(struct platform_device *pdev)
-{
-       const struct x86_cpu_id *id;
-       void __iomem *mem;
-       int ret;
-
-       id = x86_match_cpu(telemetry_cpu_ids);
-       if (!id)
-               return -ENODEV;
-
-       telm_conf = (struct telemetry_plt_config *)id->driver_data;
-
-       telm_conf->pmc = dev_get_drvdata(pdev->dev.parent);
-
-       mem = devm_platform_ioremap_resource(pdev, 0);
-       if (IS_ERR(mem))
-               return PTR_ERR(mem);
-
-       telm_conf->pss_config.regmap = mem;
-
-       mem = devm_platform_ioremap_resource(pdev, 1);
-       if (IS_ERR(mem))
-               return PTR_ERR(mem);
-
-       telm_conf->ioss_config.regmap = mem;
-
-       telm_conf->scu = devm_intel_scu_ipc_dev_get(&pdev->dev);
-       if (!telm_conf->scu) {
-               ret = -EPROBE_DEFER;
-               goto out;
-       }
-
-       mutex_init(&telm_conf->telem_lock);
-       mutex_init(&telm_conf->telem_trace_lock);
-
-       ret = telemetry_setup(pdev);
-       if (ret)
-               goto out;
-
-       ret = telemetry_set_pltdata(&telm_pltops, telm_conf);
-       if (ret) {
-               dev_err(&pdev->dev, "TELEMETRY Set Pltops Failed.\n");
-               goto out;
-       }
-
-       return 0;
-
-out:
-       dev_err(&pdev->dev, "TELEMETRY Setup Failed.\n");
-
-       return ret;
-}
-
-static int telemetry_pltdrv_remove(struct platform_device *pdev)
-{
-       telemetry_clear_pltdata();
-       return 0;
-}
-
-static struct platform_driver telemetry_soc_driver = {
-       .probe          = telemetry_pltdrv_probe,
-       .remove         = telemetry_pltdrv_remove,
-       .driver         = {
-               .name   = DRIVER_NAME,
-       },
-};
-
-static int __init telemetry_module_init(void)
-{
-       return platform_driver_register(&telemetry_soc_driver);
-}
-
-static void __exit telemetry_module_exit(void)
-{
-       platform_driver_unregister(&telemetry_soc_driver);
-}
-
-device_initcall(telemetry_module_init);
-module_exit(telemetry_module_exit);
-
-MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
-MODULE_DESCRIPTION("Intel SoC Telemetry Platform Driver");
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL v2");