Immutable branch between MFD and Platform/x86 due for the v5.13 merge window

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAmBIpbAACgkQUa+KL4f8
 d2H/NA//bVtt5HlRE0LE8QYOrP2+KmAOOOmIH4eU4eTfn82xMWVmsX+1AsC7ANx0
 eq2pPB3BDQU2MkT9YvtZCud5/3TKYPJfzDl5qppkYTxS7BgRPPnFMXLSi5CofiH9
 dDYSE1Iv0XMPBboJoce/RaBck/yWm5DLWHUR2w8Nc3n61uHCFrPBZeI058ZZXYnh
 DZyiItaVIHDs1jIrVjS87SGcIoSXjfWgBFQkTS9jLneZcC0HRebGA78raEHzeBVK
 Zpx5syisRoPkT+Hxb+Qe28ffqf9Qc/RyOpRnhmCDA0xxskembakati/XhnHtbHaT
 kXmSvsC+OeDXZw8jeVTPz8ZGEmd4H2GLXuVAMuQbOlfuPZgFP+9V5C4LFu2oiT9v
 t9USjr3VgqjGocVntP9B1PgqiDlHuzLinvB614WYPFIXiHJa0xKoEzTQlUbUTn22
 v9Tvyfgx5oczktpavCm3YzgWRyFxphaE++vSIBOJlACoqYQT6At0wnn2qr2+mTL0
 dZy6H/vEXLQFGRcwDmHWDRBoU9D1QTQzWIsl8u8+Pq9SGoa12YmpwOjsuK3WP3wS
 iRl1q35AuyEp6zaclowlW4qcTGlwRMN5rUzReMmRbfg3xqwxj6FwxY87fYtDc7Uu
 E3dklJjeZeSGw3rAJSRQzm0JMhlkRWyFdZ6KPxfnWzsPmrza2vY=
 =340a
 -----END PGP SIGNATURE-----

Merge tag 'ib-mfd-platform-x86-v5.13' into review-hans

Immutable branch between MFD and Platform/x86 due for the v5.13 merge window
This commit is contained in:
Hans de Goede 2021-03-18 11:59:44 +01:00
commit 309d984bcf
4 changed files with 119 additions and 54 deletions

View File

@ -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 = {
@ -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)
{
@ -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;
}
@ -148,41 +171,54 @@ static int pmt_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (info)
quirks = info->quirks;
do {
struct intel_dvsec_header header;
u32 table;
u16 vid;
if (info && (info->quirks & PMT_QUIRK_NO_DVSEC)) {
struct intel_dvsec_header **header;
pos = pci_find_next_ext_capability(pdev, pos, PCI_EXT_CAP_ID_DVSEC);
if (!pos)
break;
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;
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;
++header;
}
} else {
do {
struct intel_dvsec_header header;
u32 table;
u16 vid;
found_devices = true;
} while (true);
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;
@ -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) },
{ }

View File

@ -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
*/
@ -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:
/*

View File

@ -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);

View File

@ -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)
{