From a3c8f906ed5fc1d4895b5e1a5c6ad6e942d6c0ca Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Tue, 7 Dec 2021 17:50:12 -0800 Subject: platform/x86/intel: Move intel_pmt from MFD to Auxiliary Bus Intel Platform Monitoring Technology (PMT) support is indicated by presence of an Intel defined PCIe Designated Vendor Specific Extended Capabilities (DVSEC) structure with a PMT specific ID. The current MFD implementation creates child devices for each PMT feature, currently telemetry, watcher, and crashlog. However DVSEC structures may also be used by Intel to indicate support for other features. The Out Of Band Management Services Module (OOBMSM) uses DVSEC to enumerate several features, including PMT. In order to support them it is necessary to modify the intel_pmt driver to handle the creation of the child devices more generically. To that end, modify the driver to create child devices for any VSEC/DVSEC features on supported devices (indicated by PCI ID). Additionally, move the implementation from MFD to the Auxiliary bus. VSEC/DVSEC features are really multifunctional PCI devices, not platform devices as MFD was designed for. Auxiliary bus gives more flexibility by allowing the definition of custom structures that can be shared between associated auxiliary devices and the parent device. Also, rename the driver from intel_pmt to intel_vsec to better reflect the purpose. This series also removes the current runtime pm support which was not complete to begin with. None of the current devices require runtime pm. However the support will be replaced when a device is added that requires it. Reviewed-by: Mark Gross Acked-by: Hans de Goede Signed-off-by: David E. Box Link: https://lore.kernel.org/r/20211208015015.891275-4-david.e.box@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/mfd/Kconfig | 10 -- drivers/mfd/Makefile | 1 - drivers/mfd/intel_pmt.c | 261 ------------------------------------------------ 3 files changed, 272 deletions(-) delete mode 100644 drivers/mfd/intel_pmt.c (limited to 'drivers/mfd') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 3fb480818599..ac7b23eb62c2 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -692,16 +692,6 @@ 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 X86 && 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 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 0b1b629aef3e..31734d9318e2 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -211,7 +211,6 @@ obj-$(CONFIG_MFD_INTEL_LPSS) += intel-lpss.o obj-$(CONFIG_MFD_INTEL_LPSS_PCI) += intel-lpss-pci.o obj-$(CONFIG_MFD_INTEL_LPSS_ACPI) += intel-lpss-acpi.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_NTXEC) += ntxec.o diff --git a/drivers/mfd/intel_pmt.c b/drivers/mfd/intel_pmt.c deleted file mode 100644 index dd7eb614c28e..000000000000 --- a/drivers/mfd/intel_pmt.c +++ /dev/null @@ -1,261 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Intel Platform Monitoring Technology PMT driver - * - * Copyright (c) 2020, Intel Corporation. - * All Rights Reserved. - * - * Author: David E. Box - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* 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), - - /* DVSEC not present (provided in driver data) */ - PMT_QUIRK_NO_DVSEC = BIT(3), -}; - -struct pmt_platform_info { - unsigned long quirks; - struct intel_dvsec_header **capabilities; -}; - -static const struct pmt_platform_info tgl_info = { - .quirks = PMT_QUIRK_NO_WATCHER | PMT_QUIRK_NO_CRASHLOG | - PMT_QUIRK_TABLE_SHIFT, -}; - -/* DG1 Platform with DVSEC quirk*/ -static struct intel_dvsec_header dg1_telemetry = { - .length = 0x10, - .id = 2, - .num_entries = 1, - .entry_size = 3, - .tbir = 0, - .offset = 0x466000, -}; - -static struct intel_dvsec_header *dg1_capabilities[] = { - &dg1_telemetry, - NULL -}; - -static const struct pmt_platform_info dg1_info = { - .quirks = PMT_QUIRK_NO_DVSEC, - .capabilities = dg1_capabilities, -}; - -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 -EINVAL; - } - name = "pmt_watcher"; - break; - case DVSEC_INTEL_ID_CRASHLOG: - if (quirks & PMT_QUIRK_NO_CRASHLOG) { - dev_info(dev, "Crashlog not supported\n"); - return -EINVAL; - } - name = "pmt_crashlog"; - break; - default: - 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; - - if (info && (info->quirks & PMT_QUIRK_NO_DVSEC)) { - struct intel_dvsec_header **header; - - header = info->capabilities; - while (*header) { - ret = pmt_add_dev(pdev, *header, quirks); - if (ret) - dev_warn(&pdev->dev, - "Failed to add device for DVSEC id %d\n", - (*header)->id); - else - found_devices = true; - - ++header; - } - } else { - 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) - 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_DG1 0x490e -#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_DG1, &dg1_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 "); -MODULE_DESCRIPTION("Intel Platform Monitoring Technology PMT driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3