Loading drivers/mfd/intel_pmt.c +75 −37 Original line number Diff line number Diff line Loading @@ -49,10 +49,14 @@ enum pmt_quirks { /* 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 = { Loading @@ -60,6 +64,26 @@ static const struct pmt_platform_info tgl_info = { 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) { Loading @@ -79,19 +103,18 @@ static int pmt_add_dev(struct pci_dev *pdev, struct intel_dvsec_header *header, case DVSEC_INTEL_ID_WATCHER: if (quirks & PMT_QUIRK_NO_WATCHER) { dev_info(dev, "Watcher not supported\n"); return 0; 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 0; return -EINVAL; } name = "pmt_crashlog"; break; default: dev_err(dev, "Unrecognized PMT capability: %d\n", id); return -EINVAL; } Loading Loading @@ -148,6 +171,22 @@ static int pmt_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 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; Loading @@ -174,15 +213,12 @@ static int pmt_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 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); if (ret) continue; } found_devices = true; } while (true); } if (!found_devices) return -ENODEV; Loading @@ -200,10 +236,12 @@ static void pmt_pci_remove(struct pci_dev *pdev) } #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) }, { } Loading drivers/platform/x86/intel_pmt_class.c +46 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,28 @@ #define PMT_XA_MAX INT_MAX #define PMT_XA_LIMIT XA_LIMIT(PMT_XA_START, PMT_XA_MAX) /* * Early implementations of PMT on client platforms have some * differences from the server platforms (which use the Out Of Band * Management Services Module OOBMSM). This list tracks those * platforms as needed to handle those differences. Newer client * platforms are expected to be fully compatible with server. */ static const struct pci_device_id pmt_telem_early_client_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x467d) }, /* ADL */ { PCI_VDEVICE(INTEL, 0x490e) }, /* DG1 */ { PCI_VDEVICE(INTEL, 0x9a0d) }, /* TGL */ { } }; bool intel_pmt_is_early_client_hw(struct device *dev) { struct pci_dev *parent = to_pci_dev(dev->parent); return !!pci_match_id(pmt_telem_early_client_pci_ids, parent); } EXPORT_SYMBOL_GPL(intel_pmt_is_early_client_hw); /* * sysfs */ Loading Loading @@ -147,6 +169,30 @@ static int intel_pmt_populate_entry(struct intel_pmt_entry *entry, * base address = end of discovery region + base offset */ entry->base_addr = disc_res->end + 1 + header->base_offset; /* * Some hardware use a different calculation for the base address * when access_type == ACCESS_LOCAL. On the these systems * ACCCESS_LOCAL refers to an address in the same BAR as the * header but at a fixed offset. But as the header address was * supplied to the driver, we don't know which BAR it was in. * So search for the bar whose range includes the header address. */ if (intel_pmt_is_early_client_hw(dev)) { int i; entry->base_addr = 0; for (i = 0; i < 6; i++) if (disc_res->start >= pci_resource_start(pci_dev, i) && (disc_res->start <= pci_resource_end(pci_dev, i))) { entry->base_addr = pci_resource_start(pci_dev, i) + header->base_offset; break; } if (!entry->base_addr) return -EINVAL; } break; case ACCESS_BARID: /* Loading drivers/platform/x86/intel_pmt_class.h +1 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ struct intel_pmt_namespace { struct device *dev); }; bool intel_pmt_is_early_client_hw(struct device *dev); int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespace *ns, struct platform_device *pdev, int idx); Loading drivers/platform/x86/intel_pmt_telemetry.c +0 −20 Original line number Diff line number Diff line Loading @@ -34,26 +34,6 @@ struct pmt_telem_priv { struct intel_pmt_entry entry[]; }; /* * Early implementations of PMT on client platforms have some * differences from the server platforms (which use the Out Of Band * Management Services Module OOBMSM). This list tracks those * platforms as needed to handle those differences. Newer client * platforms are expected to be fully compatible with server. */ static const struct pci_device_id pmt_telem_early_client_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x9a0d) }, /* TGL */ { PCI_VDEVICE(INTEL, 0x467d) }, /* ADL */ { } }; static bool intel_pmt_is_early_client_hw(struct device *dev) { struct pci_dev *parent = to_pci_dev(dev->parent); return !!pci_match_id(pmt_telem_early_client_pci_ids, parent); } static bool pmt_telem_region_overlaps(struct intel_pmt_entry *entry, struct device *dev) { Loading Loading
drivers/mfd/intel_pmt.c +75 −37 Original line number Diff line number Diff line Loading @@ -49,10 +49,14 @@ enum pmt_quirks { /* 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 = { Loading @@ -60,6 +64,26 @@ static const struct pmt_platform_info tgl_info = { 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) { Loading @@ -79,19 +103,18 @@ static int pmt_add_dev(struct pci_dev *pdev, struct intel_dvsec_header *header, case DVSEC_INTEL_ID_WATCHER: if (quirks & PMT_QUIRK_NO_WATCHER) { dev_info(dev, "Watcher not supported\n"); return 0; 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 0; return -EINVAL; } name = "pmt_crashlog"; break; default: dev_err(dev, "Unrecognized PMT capability: %d\n", id); return -EINVAL; } Loading Loading @@ -148,6 +171,22 @@ static int pmt_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 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; Loading @@ -174,15 +213,12 @@ static int pmt_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 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); if (ret) continue; } found_devices = true; } while (true); } if (!found_devices) return -ENODEV; Loading @@ -200,10 +236,12 @@ static void pmt_pci_remove(struct pci_dev *pdev) } #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) }, { } Loading
drivers/platform/x86/intel_pmt_class.c +46 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,28 @@ #define PMT_XA_MAX INT_MAX #define PMT_XA_LIMIT XA_LIMIT(PMT_XA_START, PMT_XA_MAX) /* * Early implementations of PMT on client platforms have some * differences from the server platforms (which use the Out Of Band * Management Services Module OOBMSM). This list tracks those * platforms as needed to handle those differences. Newer client * platforms are expected to be fully compatible with server. */ static const struct pci_device_id pmt_telem_early_client_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x467d) }, /* ADL */ { PCI_VDEVICE(INTEL, 0x490e) }, /* DG1 */ { PCI_VDEVICE(INTEL, 0x9a0d) }, /* TGL */ { } }; bool intel_pmt_is_early_client_hw(struct device *dev) { struct pci_dev *parent = to_pci_dev(dev->parent); return !!pci_match_id(pmt_telem_early_client_pci_ids, parent); } EXPORT_SYMBOL_GPL(intel_pmt_is_early_client_hw); /* * sysfs */ Loading Loading @@ -147,6 +169,30 @@ static int intel_pmt_populate_entry(struct intel_pmt_entry *entry, * base address = end of discovery region + base offset */ entry->base_addr = disc_res->end + 1 + header->base_offset; /* * Some hardware use a different calculation for the base address * when access_type == ACCESS_LOCAL. On the these systems * ACCCESS_LOCAL refers to an address in the same BAR as the * header but at a fixed offset. But as the header address was * supplied to the driver, we don't know which BAR it was in. * So search for the bar whose range includes the header address. */ if (intel_pmt_is_early_client_hw(dev)) { int i; entry->base_addr = 0; for (i = 0; i < 6; i++) if (disc_res->start >= pci_resource_start(pci_dev, i) && (disc_res->start <= pci_resource_end(pci_dev, i))) { entry->base_addr = pci_resource_start(pci_dev, i) + header->base_offset; break; } if (!entry->base_addr) return -EINVAL; } break; case ACCESS_BARID: /* Loading
drivers/platform/x86/intel_pmt_class.h +1 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ struct intel_pmt_namespace { struct device *dev); }; bool intel_pmt_is_early_client_hw(struct device *dev); int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespace *ns, struct platform_device *pdev, int idx); Loading
drivers/platform/x86/intel_pmt_telemetry.c +0 −20 Original line number Diff line number Diff line Loading @@ -34,26 +34,6 @@ struct pmt_telem_priv { struct intel_pmt_entry entry[]; }; /* * Early implementations of PMT on client platforms have some * differences from the server platforms (which use the Out Of Band * Management Services Module OOBMSM). This list tracks those * platforms as needed to handle those differences. Newer client * platforms are expected to be fully compatible with server. */ static const struct pci_device_id pmt_telem_early_client_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x9a0d) }, /* TGL */ { PCI_VDEVICE(INTEL, 0x467d) }, /* ADL */ { } }; static bool intel_pmt_is_early_client_hw(struct device *dev) { struct pci_dev *parent = to_pci_dev(dev->parent); return !!pci_match_id(pmt_telem_early_client_pci_ids, parent); } static bool pmt_telem_region_overlaps(struct intel_pmt_entry *entry, struct device *dev) { Loading