Loading Documentation/ABI/testing/sysfs-class-intel_pmt 0 → 100644 +119 −0 Original line number Diff line number Diff line What: /sys/class/intel_pmt/ Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: The intel_pmt/ class directory contains information for devices that expose hardware telemetry using Intel Platform Monitoring Technology (PMT) What: /sys/class/intel_pmt/telem<x> Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: The telem<x> directory contains files describing an instance of a PMT telemetry device that exposes hardware telemetry. Each telem<x> directory has an associated telem file. This file may be opened and mapped or read to access the telemetry space of the device. The register layout of the telemetry space is determined from an XML file that matches the PCI device id and GUID for the device. What: /sys/class/intel_pmt/telem<x>/telem Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: (RO) The telemetry data for this telemetry device. This file may be mapped or read to obtain the data. What: /sys/class/intel_pmt/telem<x>/guid Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: (RO) The GUID for this telemetry device. The GUID identifies the version of the XML file for the parent device that is to be used to get the register layout. What: /sys/class/intel_pmt/telem<x>/size Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: (RO) The size of telemetry region in bytes that corresponds to the mapping size for the telem file. What: /sys/class/intel_pmt/telem<x>/offset Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: (RO) The offset of telemetry region in bytes that corresponds to the mapping for the telem file. What: /sys/class/intel_pmt/crashlog<x> Date: October 2020 KernelVersion: 5.10 Contact: Alexander Duyck <alexander.h.duyck@linux.intel.com> Description: The crashlog<x> directory contains files for configuring an instance of a PMT crashlog device that can perform crash data recording. Each crashlog<x> device has an associated crashlog file. This file can be opened and mapped or read to access the resulting crashlog buffer. The register layout for the buffer can be determined from an XML file of specified GUID for the parent device. What: /sys/class/intel_pmt/crashlog<x>/crashlog Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: (RO) The crashlog buffer for this crashlog device. This file may be mapped or read to obtain the data. What: /sys/class/intel_pmt/crashlog<x>/guid Date: October 2020 KernelVersion: 5.10 Contact: Alexander Duyck <alexander.h.duyck@linux.intel.com> Description: (RO) The GUID for this crashlog device. The GUID identifies the version of the XML file for the parent device that should be used to determine the register layout. What: /sys/class/intel_pmt/crashlog<x>/size Date: October 2020 KernelVersion: 5.10 Contact: Alexander Duyck <alexander.h.duyck@linux.intel.com> Description: (RO) The length of the result buffer in bytes that corresponds to the size for the crashlog buffer. What: /sys/class/intel_pmt/crashlog<x>/offset Date: October 2020 KernelVersion: 5.10 Contact: Alexander Duyck <alexander.h.duyck@linux.intel.com> Description: (RO) The offset of the buffer in bytes that corresponds to the mapping for the crashlog device. What: /sys/class/intel_pmt/crashlog<x>/enable Date: October 2020 KernelVersion: 5.10 Contact: Alexander Duyck <alexander.h.duyck@linux.intel.com> Description: (RW) Boolean value controlling if the crashlog functionality is enabled for the crashlog device. What: /sys/class/intel_pmt/crashlog<x>/trigger Date: October 2020 KernelVersion: 5.10 Contact: Alexander Duyck <alexander.h.duyck@linux.intel.com> Description: (RW) Boolean value controlling the triggering of the crashlog device node. When read it provides data on if the crashlog has been triggered. When written to it can be used to either clear the current trigger by writing false, or to trigger a new event if the trigger is not currently set. MAINTAINERS +6 −0 Original line number Diff line number Diff line Loading @@ -9030,6 +9030,12 @@ F: drivers/mfd/intel_soc_pmic* F: include/linux/mfd/intel_msic.h F: include/linux/mfd/intel_soc_pmic* INTEL PMT DRIVER M: "David E. Box" <david.e.box@linux.intel.com> S: Maintained F: drivers/mfd/intel_pmt.c F: drivers/platform/x86/intel_pmt_* INTEL PRO/WIRELESS 2100, 2200BG, 2915ABG NETWORK CONNECTION SUPPORT M: Stanislav Yakovlev <stas.yakovlev@gmail.com> L: linux-wireless@vger.kernel.org Loading drivers/mfd/Kconfig +10 −0 Original line number Diff line number Diff line Loading @@ -682,6 +682,16 @@ config MFD_INTEL_PMC_BXT Register and P-unit access. In addition this creates devices for iTCO watchdog and telemetry that are part of the PMC. config MFD_INTEL_PMT tristate "Intel Platform Monitoring Technology (PMT) support" depends on PCI select MFD_CORE help The Intel Platform Monitoring Technology (PMT) is an interface that provides access to hardware monitor registers. This driver supports Telemetry, Watcher, and Crashlog PMT capabilities/devices for platforms starting from Tiger Lake. config MFD_IPAQ_MICRO bool "Atmel Micro ASIC (iPAQ h3100/h3600/h3700) Support" depends on SA1100_H3100 || SA1100_H3600 Loading drivers/mfd/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,7 @@ obj-$(CONFIG_MFD_INTEL_LPSS_PCI) += intel-lpss-pci.o obj-$(CONFIG_MFD_INTEL_LPSS_ACPI) += intel-lpss-acpi.o obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o obj-$(CONFIG_MFD_INTEL_PMC_BXT) += intel_pmc_bxt.o obj-$(CONFIG_MFD_INTEL_PMT) += intel_pmt.o obj-$(CONFIG_MFD_PALMAS) += palmas.o obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o Loading drivers/mfd/intel_pmt.c 0 → 100644 +223 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0 /* * Intel Platform Monitoring Technology PMT driver * * Copyright (c) 2020, Intel Corporation. * All Rights Reserved. * * Author: David E. Box <david.e.box@linux.intel.com> */ #include <linux/bits.h> #include <linux/kernel.h> #include <linux/mfd/core.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/platform_device.h> #include <linux/pm.h> #include <linux/pm_runtime.h> #include <linux/types.h> /* Intel DVSEC capability vendor space offsets */ #define INTEL_DVSEC_ENTRIES 0xA #define INTEL_DVSEC_SIZE 0xB #define INTEL_DVSEC_TABLE 0xC #define INTEL_DVSEC_TABLE_BAR(x) ((x) & GENMASK(2, 0)) #define INTEL_DVSEC_TABLE_OFFSET(x) ((x) & GENMASK(31, 3)) #define INTEL_DVSEC_ENTRY_SIZE 4 /* PMT capabilities */ #define DVSEC_INTEL_ID_TELEMETRY 2 #define DVSEC_INTEL_ID_WATCHER 3 #define DVSEC_INTEL_ID_CRASHLOG 4 struct intel_dvsec_header { u16 length; u16 id; u8 num_entries; u8 entry_size; u8 tbir; u32 offset; }; enum pmt_quirks { /* Watcher capability not supported */ PMT_QUIRK_NO_WATCHER = BIT(0), /* Crashlog capability not supported */ PMT_QUIRK_NO_CRASHLOG = BIT(1), /* Use shift instead of mask to read discovery table offset */ PMT_QUIRK_TABLE_SHIFT = BIT(2), }; struct pmt_platform_info { unsigned long quirks; }; static const struct pmt_platform_info tgl_info = { .quirks = PMT_QUIRK_NO_WATCHER | PMT_QUIRK_NO_CRASHLOG | PMT_QUIRK_TABLE_SHIFT, }; static int pmt_add_dev(struct pci_dev *pdev, struct intel_dvsec_header *header, unsigned long quirks) { struct device *dev = &pdev->dev; struct resource *res, *tmp; struct mfd_cell *cell; const char *name; int count = header->num_entries; int size = header->entry_size; int id = header->id; int i; switch (id) { case DVSEC_INTEL_ID_TELEMETRY: name = "pmt_telemetry"; break; case DVSEC_INTEL_ID_WATCHER: if (quirks & PMT_QUIRK_NO_WATCHER) { dev_info(dev, "Watcher not supported\n"); return 0; } name = "pmt_watcher"; break; case DVSEC_INTEL_ID_CRASHLOG: if (quirks & PMT_QUIRK_NO_CRASHLOG) { dev_info(dev, "Crashlog not supported\n"); return 0; } name = "pmt_crashlog"; break; default: dev_err(dev, "Unrecognized PMT capability: %d\n", id); return -EINVAL; } if (!header->num_entries || !header->entry_size) { dev_err(dev, "Invalid count or size for %s header\n", name); return -EINVAL; } cell = devm_kzalloc(dev, sizeof(*cell), GFP_KERNEL); if (!cell) return -ENOMEM; res = devm_kcalloc(dev, count, sizeof(*res), GFP_KERNEL); if (!res) return -ENOMEM; if (quirks & PMT_QUIRK_TABLE_SHIFT) header->offset >>= 3; /* * The PMT DVSEC contains the starting offset and count for a block of * discovery tables, each providing access to monitoring facilities for * a section of the device. Create a resource list of these tables to * provide to the driver. */ for (i = 0, tmp = res; i < count; i++, tmp++) { tmp->start = pdev->resource[header->tbir].start + header->offset + i * (size << 2); tmp->end = tmp->start + (size << 2) - 1; tmp->flags = IORESOURCE_MEM; } cell->resources = res; cell->num_resources = count; cell->name = name; return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cell, 1, NULL, 0, NULL); } static int pmt_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct pmt_platform_info *info; unsigned long quirks = 0; bool found_devices = false; int ret, pos = 0; ret = pcim_enable_device(pdev); if (ret) return ret; info = (struct pmt_platform_info *)id->driver_data; if (info) quirks = info->quirks; do { struct intel_dvsec_header header; u32 table; u16 vid; pos = pci_find_next_ext_capability(pdev, pos, PCI_EXT_CAP_ID_DVSEC); if (!pos) break; pci_read_config_word(pdev, pos + PCI_DVSEC_HEADER1, &vid); if (vid != PCI_VENDOR_ID_INTEL) continue; pci_read_config_word(pdev, pos + PCI_DVSEC_HEADER2, &header.id); pci_read_config_byte(pdev, pos + INTEL_DVSEC_ENTRIES, &header.num_entries); pci_read_config_byte(pdev, pos + INTEL_DVSEC_SIZE, &header.entry_size); pci_read_config_dword(pdev, pos + INTEL_DVSEC_TABLE, &table); header.tbir = INTEL_DVSEC_TABLE_BAR(table); header.offset = INTEL_DVSEC_TABLE_OFFSET(table); ret = pmt_add_dev(pdev, &header, quirks); if (ret) { dev_warn(&pdev->dev, "Failed to add device for DVSEC id %d\n", header.id); continue; } found_devices = true; } while (true); if (!found_devices) return -ENODEV; pm_runtime_put(&pdev->dev); pm_runtime_allow(&pdev->dev); return 0; } static void pmt_pci_remove(struct pci_dev *pdev) { pm_runtime_forbid(&pdev->dev); pm_runtime_get_sync(&pdev->dev); } #define PCI_DEVICE_ID_INTEL_PMT_ADL 0x467d #define PCI_DEVICE_ID_INTEL_PMT_OOBMSM 0x09a7 #define PCI_DEVICE_ID_INTEL_PMT_TGL 0x9a0d static const struct pci_device_id pmt_pci_ids[] = { { PCI_DEVICE_DATA(INTEL, PMT_ADL, &tgl_info) }, { PCI_DEVICE_DATA(INTEL, PMT_OOBMSM, NULL) }, { PCI_DEVICE_DATA(INTEL, PMT_TGL, &tgl_info) }, { } }; MODULE_DEVICE_TABLE(pci, pmt_pci_ids); static struct pci_driver pmt_pci_driver = { .name = "intel-pmt", .id_table = pmt_pci_ids, .probe = pmt_pci_probe, .remove = pmt_pci_remove, }; module_pci_driver(pmt_pci_driver); MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>"); MODULE_DESCRIPTION("Intel Platform Monitoring Technology PMT driver"); MODULE_LICENSE("GPL v2"); Loading
Documentation/ABI/testing/sysfs-class-intel_pmt 0 → 100644 +119 −0 Original line number Diff line number Diff line What: /sys/class/intel_pmt/ Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: The intel_pmt/ class directory contains information for devices that expose hardware telemetry using Intel Platform Monitoring Technology (PMT) What: /sys/class/intel_pmt/telem<x> Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: The telem<x> directory contains files describing an instance of a PMT telemetry device that exposes hardware telemetry. Each telem<x> directory has an associated telem file. This file may be opened and mapped or read to access the telemetry space of the device. The register layout of the telemetry space is determined from an XML file that matches the PCI device id and GUID for the device. What: /sys/class/intel_pmt/telem<x>/telem Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: (RO) The telemetry data for this telemetry device. This file may be mapped or read to obtain the data. What: /sys/class/intel_pmt/telem<x>/guid Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: (RO) The GUID for this telemetry device. The GUID identifies the version of the XML file for the parent device that is to be used to get the register layout. What: /sys/class/intel_pmt/telem<x>/size Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: (RO) The size of telemetry region in bytes that corresponds to the mapping size for the telem file. What: /sys/class/intel_pmt/telem<x>/offset Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: (RO) The offset of telemetry region in bytes that corresponds to the mapping for the telem file. What: /sys/class/intel_pmt/crashlog<x> Date: October 2020 KernelVersion: 5.10 Contact: Alexander Duyck <alexander.h.duyck@linux.intel.com> Description: The crashlog<x> directory contains files for configuring an instance of a PMT crashlog device that can perform crash data recording. Each crashlog<x> device has an associated crashlog file. This file can be opened and mapped or read to access the resulting crashlog buffer. The register layout for the buffer can be determined from an XML file of specified GUID for the parent device. What: /sys/class/intel_pmt/crashlog<x>/crashlog Date: October 2020 KernelVersion: 5.10 Contact: David Box <david.e.box@linux.intel.com> Description: (RO) The crashlog buffer for this crashlog device. This file may be mapped or read to obtain the data. What: /sys/class/intel_pmt/crashlog<x>/guid Date: October 2020 KernelVersion: 5.10 Contact: Alexander Duyck <alexander.h.duyck@linux.intel.com> Description: (RO) The GUID for this crashlog device. The GUID identifies the version of the XML file for the parent device that should be used to determine the register layout. What: /sys/class/intel_pmt/crashlog<x>/size Date: October 2020 KernelVersion: 5.10 Contact: Alexander Duyck <alexander.h.duyck@linux.intel.com> Description: (RO) The length of the result buffer in bytes that corresponds to the size for the crashlog buffer. What: /sys/class/intel_pmt/crashlog<x>/offset Date: October 2020 KernelVersion: 5.10 Contact: Alexander Duyck <alexander.h.duyck@linux.intel.com> Description: (RO) The offset of the buffer in bytes that corresponds to the mapping for the crashlog device. What: /sys/class/intel_pmt/crashlog<x>/enable Date: October 2020 KernelVersion: 5.10 Contact: Alexander Duyck <alexander.h.duyck@linux.intel.com> Description: (RW) Boolean value controlling if the crashlog functionality is enabled for the crashlog device. What: /sys/class/intel_pmt/crashlog<x>/trigger Date: October 2020 KernelVersion: 5.10 Contact: Alexander Duyck <alexander.h.duyck@linux.intel.com> Description: (RW) Boolean value controlling the triggering of the crashlog device node. When read it provides data on if the crashlog has been triggered. When written to it can be used to either clear the current trigger by writing false, or to trigger a new event if the trigger is not currently set.
MAINTAINERS +6 −0 Original line number Diff line number Diff line Loading @@ -9030,6 +9030,12 @@ F: drivers/mfd/intel_soc_pmic* F: include/linux/mfd/intel_msic.h F: include/linux/mfd/intel_soc_pmic* INTEL PMT DRIVER M: "David E. Box" <david.e.box@linux.intel.com> S: Maintained F: drivers/mfd/intel_pmt.c F: drivers/platform/x86/intel_pmt_* INTEL PRO/WIRELESS 2100, 2200BG, 2915ABG NETWORK CONNECTION SUPPORT M: Stanislav Yakovlev <stas.yakovlev@gmail.com> L: linux-wireless@vger.kernel.org Loading
drivers/mfd/Kconfig +10 −0 Original line number Diff line number Diff line Loading @@ -682,6 +682,16 @@ config MFD_INTEL_PMC_BXT Register and P-unit access. In addition this creates devices for iTCO watchdog and telemetry that are part of the PMC. config MFD_INTEL_PMT tristate "Intel Platform Monitoring Technology (PMT) support" depends on PCI select MFD_CORE help The Intel Platform Monitoring Technology (PMT) is an interface that provides access to hardware monitor registers. This driver supports Telemetry, Watcher, and Crashlog PMT capabilities/devices for platforms starting from Tiger Lake. config MFD_IPAQ_MICRO bool "Atmel Micro ASIC (iPAQ h3100/h3600/h3700) Support" depends on SA1100_H3100 || SA1100_H3600 Loading
drivers/mfd/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,7 @@ obj-$(CONFIG_MFD_INTEL_LPSS_PCI) += intel-lpss-pci.o obj-$(CONFIG_MFD_INTEL_LPSS_ACPI) += intel-lpss-acpi.o obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o obj-$(CONFIG_MFD_INTEL_PMC_BXT) += intel_pmc_bxt.o obj-$(CONFIG_MFD_INTEL_PMT) += intel_pmt.o obj-$(CONFIG_MFD_PALMAS) += palmas.o obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o Loading
drivers/mfd/intel_pmt.c 0 → 100644 +223 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0 /* * Intel Platform Monitoring Technology PMT driver * * Copyright (c) 2020, Intel Corporation. * All Rights Reserved. * * Author: David E. Box <david.e.box@linux.intel.com> */ #include <linux/bits.h> #include <linux/kernel.h> #include <linux/mfd/core.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/platform_device.h> #include <linux/pm.h> #include <linux/pm_runtime.h> #include <linux/types.h> /* Intel DVSEC capability vendor space offsets */ #define INTEL_DVSEC_ENTRIES 0xA #define INTEL_DVSEC_SIZE 0xB #define INTEL_DVSEC_TABLE 0xC #define INTEL_DVSEC_TABLE_BAR(x) ((x) & GENMASK(2, 0)) #define INTEL_DVSEC_TABLE_OFFSET(x) ((x) & GENMASK(31, 3)) #define INTEL_DVSEC_ENTRY_SIZE 4 /* PMT capabilities */ #define DVSEC_INTEL_ID_TELEMETRY 2 #define DVSEC_INTEL_ID_WATCHER 3 #define DVSEC_INTEL_ID_CRASHLOG 4 struct intel_dvsec_header { u16 length; u16 id; u8 num_entries; u8 entry_size; u8 tbir; u32 offset; }; enum pmt_quirks { /* Watcher capability not supported */ PMT_QUIRK_NO_WATCHER = BIT(0), /* Crashlog capability not supported */ PMT_QUIRK_NO_CRASHLOG = BIT(1), /* Use shift instead of mask to read discovery table offset */ PMT_QUIRK_TABLE_SHIFT = BIT(2), }; struct pmt_platform_info { unsigned long quirks; }; static const struct pmt_platform_info tgl_info = { .quirks = PMT_QUIRK_NO_WATCHER | PMT_QUIRK_NO_CRASHLOG | PMT_QUIRK_TABLE_SHIFT, }; static int pmt_add_dev(struct pci_dev *pdev, struct intel_dvsec_header *header, unsigned long quirks) { struct device *dev = &pdev->dev; struct resource *res, *tmp; struct mfd_cell *cell; const char *name; int count = header->num_entries; int size = header->entry_size; int id = header->id; int i; switch (id) { case DVSEC_INTEL_ID_TELEMETRY: name = "pmt_telemetry"; break; case DVSEC_INTEL_ID_WATCHER: if (quirks & PMT_QUIRK_NO_WATCHER) { dev_info(dev, "Watcher not supported\n"); return 0; } name = "pmt_watcher"; break; case DVSEC_INTEL_ID_CRASHLOG: if (quirks & PMT_QUIRK_NO_CRASHLOG) { dev_info(dev, "Crashlog not supported\n"); return 0; } name = "pmt_crashlog"; break; default: dev_err(dev, "Unrecognized PMT capability: %d\n", id); return -EINVAL; } if (!header->num_entries || !header->entry_size) { dev_err(dev, "Invalid count or size for %s header\n", name); return -EINVAL; } cell = devm_kzalloc(dev, sizeof(*cell), GFP_KERNEL); if (!cell) return -ENOMEM; res = devm_kcalloc(dev, count, sizeof(*res), GFP_KERNEL); if (!res) return -ENOMEM; if (quirks & PMT_QUIRK_TABLE_SHIFT) header->offset >>= 3; /* * The PMT DVSEC contains the starting offset and count for a block of * discovery tables, each providing access to monitoring facilities for * a section of the device. Create a resource list of these tables to * provide to the driver. */ for (i = 0, tmp = res; i < count; i++, tmp++) { tmp->start = pdev->resource[header->tbir].start + header->offset + i * (size << 2); tmp->end = tmp->start + (size << 2) - 1; tmp->flags = IORESOURCE_MEM; } cell->resources = res; cell->num_resources = count; cell->name = name; return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cell, 1, NULL, 0, NULL); } static int pmt_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct pmt_platform_info *info; unsigned long quirks = 0; bool found_devices = false; int ret, pos = 0; ret = pcim_enable_device(pdev); if (ret) return ret; info = (struct pmt_platform_info *)id->driver_data; if (info) quirks = info->quirks; do { struct intel_dvsec_header header; u32 table; u16 vid; pos = pci_find_next_ext_capability(pdev, pos, PCI_EXT_CAP_ID_DVSEC); if (!pos) break; pci_read_config_word(pdev, pos + PCI_DVSEC_HEADER1, &vid); if (vid != PCI_VENDOR_ID_INTEL) continue; pci_read_config_word(pdev, pos + PCI_DVSEC_HEADER2, &header.id); pci_read_config_byte(pdev, pos + INTEL_DVSEC_ENTRIES, &header.num_entries); pci_read_config_byte(pdev, pos + INTEL_DVSEC_SIZE, &header.entry_size); pci_read_config_dword(pdev, pos + INTEL_DVSEC_TABLE, &table); header.tbir = INTEL_DVSEC_TABLE_BAR(table); header.offset = INTEL_DVSEC_TABLE_OFFSET(table); ret = pmt_add_dev(pdev, &header, quirks); if (ret) { dev_warn(&pdev->dev, "Failed to add device for DVSEC id %d\n", header.id); continue; } found_devices = true; } while (true); if (!found_devices) return -ENODEV; pm_runtime_put(&pdev->dev); pm_runtime_allow(&pdev->dev); return 0; } static void pmt_pci_remove(struct pci_dev *pdev) { pm_runtime_forbid(&pdev->dev); pm_runtime_get_sync(&pdev->dev); } #define PCI_DEVICE_ID_INTEL_PMT_ADL 0x467d #define PCI_DEVICE_ID_INTEL_PMT_OOBMSM 0x09a7 #define PCI_DEVICE_ID_INTEL_PMT_TGL 0x9a0d static const struct pci_device_id pmt_pci_ids[] = { { PCI_DEVICE_DATA(INTEL, PMT_ADL, &tgl_info) }, { PCI_DEVICE_DATA(INTEL, PMT_OOBMSM, NULL) }, { PCI_DEVICE_DATA(INTEL, PMT_TGL, &tgl_info) }, { } }; MODULE_DEVICE_TABLE(pci, pmt_pci_ids); static struct pci_driver pmt_pci_driver = { .name = "intel-pmt", .id_table = pmt_pci_ids, .probe = pmt_pci_probe, .remove = pmt_pci_remove, }; module_pci_driver(pmt_pci_driver); MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>"); MODULE_DESCRIPTION("Intel Platform Monitoring Technology PMT driver"); MODULE_LICENSE("GPL v2");