diff options
Diffstat (limited to 'drivers/platform/x86/intel/tpmi.c')
| -rw-r--r-- | drivers/platform/x86/intel/tpmi.c | 39 | 
1 files changed, 32 insertions, 7 deletions
| diff --git a/drivers/platform/x86/intel/tpmi.c b/drivers/platform/x86/intel/tpmi.c index 910df7c654f4..6c0cbccd80bb 100644 --- a/drivers/platform/x86/intel/tpmi.c +++ b/drivers/platform/x86/intel/tpmi.c @@ -128,6 +128,9 @@ struct intel_tpmi_info {   * @dev:	PCI device number   * @bus:	PCI bus number   * @pkg:	CPU Package id + * @segment:	PCI segment id + * @partition:	Package Partition id + * @cdie_mask:	Bitmap of compute dies in the current partition   * @reserved:	Reserved for future use   * @lock:	When set to 1 the register is locked and becomes read-only   *		until next reset. Not for use by the OS driver. @@ -139,7 +142,10 @@ struct tpmi_info_header {  	u64 dev:5;  	u64 bus:8;  	u64 pkg:8; -	u64 reserved:39; +	u64 segment:8; +	u64 partition:2; +	u64 cdie_mask:16; +	u64 reserved:13;  	u64 lock:1;  } __packed; @@ -666,28 +672,44 @@ static int tpmi_create_devices(struct intel_tpmi_info *tpmi_info)  }  #define TPMI_INFO_BUS_INFO_OFFSET	0x08 +#define TPMI_INFO_MAJOR_VERSION		0x00 +#define TPMI_INFO_MINOR_VERSION		0x02  static int tpmi_process_info(struct intel_tpmi_info *tpmi_info,  			     struct intel_tpmi_pm_feature *pfs)  {  	struct tpmi_info_header header;  	void __iomem *info_mem; +	u64 feature_header; +	int ret = 0; -	info_mem = ioremap(pfs->vsec_offset + TPMI_INFO_BUS_INFO_OFFSET, -			   pfs->pfs_header.entry_size * sizeof(u32) - TPMI_INFO_BUS_INFO_OFFSET); +	info_mem = ioremap(pfs->vsec_offset, pfs->pfs_header.entry_size * sizeof(u32));  	if (!info_mem)  		return -ENOMEM; -	memcpy_fromio(&header, info_mem, sizeof(header)); +	feature_header = readq(info_mem); +	if (TPMI_MAJOR_VERSION(feature_header) != TPMI_INFO_MAJOR_VERSION) { +		ret = -ENODEV; +		goto error_info_header; +	} + +	memcpy_fromio(&header, info_mem + TPMI_INFO_BUS_INFO_OFFSET, sizeof(header));  	tpmi_info->plat_info.package_id = header.pkg;  	tpmi_info->plat_info.bus_number = header.bus;  	tpmi_info->plat_info.device_number = header.dev;  	tpmi_info->plat_info.function_number = header.fn; +	if (TPMI_MINOR_VERSION(feature_header) >= TPMI_INFO_MINOR_VERSION) { +		tpmi_info->plat_info.cdie_mask = header.cdie_mask; +		tpmi_info->plat_info.partition = header.partition; +		tpmi_info->plat_info.segment = header.segment; +	} + +error_info_header:  	iounmap(info_mem); -	return 0; +	return ret;  }  static int tpmi_fetch_pfs_header(struct intel_tpmi_pm_feature *pfs, u64 start, int size) @@ -763,8 +785,11 @@ static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev)  		 * when actual device nodes created outside this  		 * loop via tpmi_create_devices().  		 */ -		if (pfs->pfs_header.tpmi_id == TPMI_INFO_ID) -			tpmi_process_info(tpmi_info, pfs); +		if (pfs->pfs_header.tpmi_id == TPMI_INFO_ID) { +			ret = tpmi_process_info(tpmi_info, pfs); +			if (ret) +				return ret; +		}  		if (pfs->pfs_header.tpmi_id == TPMI_CONTROL_ID)  			tpmi_set_control_base(auxdev, tpmi_info, pfs); | 
