diff options
Diffstat (limited to 'drivers/platform')
| -rw-r--r-- | drivers/platform/x86/amd/hsmp/hsmp.c | 14 | ||||
| -rw-r--r-- | drivers/platform/x86/amd/pmc/pmc-quirks.c | 9 | ||||
| -rw-r--r-- | drivers/platform/x86/amd/pmc/pmc.c | 2 | ||||
| -rw-r--r-- | drivers/platform/x86/amd/pmf/core.c | 3 | ||||
| -rw-r--r-- | drivers/platform/x86/amd/pmf/tee-if.c | 108 | ||||
| -rw-r--r-- | drivers/platform/x86/dell/alienware-wmi-wmax.c | 2 | ||||
| -rw-r--r-- | drivers/platform/x86/dell/dell_rbu.c | 10 | ||||
| -rw-r--r-- | drivers/platform/x86/ideapad-laptop.c | 19 | ||||
| -rw-r--r-- | drivers/platform/x86/intel/pmc/core.h | 7 | ||||
| -rw-r--r-- | drivers/platform/x86/intel/pmc/ssram_telemetry.c | 3 | ||||
| -rw-r--r-- | drivers/platform/x86/intel/tpmi_power_domains.c | 4 | ||||
| -rw-r--r-- | drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c | 2 | ||||
| -rw-r--r-- | drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c | 9 | ||||
| -rw-r--r-- | drivers/platform/x86/samsung-galaxybook.c | 1 | 
14 files changed, 100 insertions, 93 deletions
| diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c index 538b36b97095..885e2f8136fd 100644 --- a/drivers/platform/x86/amd/hsmp/hsmp.c +++ b/drivers/platform/x86/amd/hsmp/hsmp.c @@ -97,7 +97,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms  	short_sleep = jiffies + msecs_to_jiffies(HSMP_SHORT_SLEEP);  	timeout	= jiffies + msecs_to_jiffies(HSMP_MSG_TIMEOUT); -	while (time_before(jiffies, timeout)) { +	while (true) {  		ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_RD);  		if (ret) {  			dev_err(sock->dev, "Error %d reading mailbox status\n", ret); @@ -106,6 +106,10 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms  		if (mbox_status != HSMP_STATUS_NOT_READY)  			break; + +		if (!time_before(jiffies, timeout)) +			break; +  		if (time_before(jiffies, short_sleep))  			usleep_range(50, 100);  		else @@ -210,13 +214,7 @@ int hsmp_send_message(struct hsmp_message *msg)  		return -ENODEV;  	sock = &hsmp_pdev.sock[msg->sock_ind]; -	/* -	 * The time taken by smu operation to complete is between -	 * 10us to 1ms. Sometime it may take more time. -	 * In SMP system timeout of 100 millisecs should -	 * be enough for the previous thread to finish the operation -	 */ -	ret = down_timeout(&sock->hsmp_sem, msecs_to_jiffies(HSMP_MSG_TIMEOUT)); +	ret = down_interruptible(&sock->hsmp_sem);  	if (ret < 0)  		return ret; diff --git a/drivers/platform/x86/amd/pmc/pmc-quirks.c b/drivers/platform/x86/amd/pmc/pmc-quirks.c index 5c7c01f66cde..f292111bd065 100644 --- a/drivers/platform/x86/amd/pmc/pmc-quirks.c +++ b/drivers/platform/x86/amd/pmc/pmc-quirks.c @@ -225,6 +225,15 @@ static const struct dmi_system_id fwbug_list[] = {  			DMI_MATCH(DMI_BOARD_NAME, "WUJIE14-GX4HRXL"),  		}  	}, +	/* https://bugzilla.kernel.org/show_bug.cgi?id=220116 */ +	{ +		.ident = "PCSpecialist Lafite Pro V 14M", +		.driver_data = &quirk_spurious_8042, +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "PCSpecialist"), +			DMI_MATCH(DMI_PRODUCT_NAME, "Lafite Pro V 14M"), +		} +	},  	{}  }; diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c index 37c7a57afee5..0b9b23eb7c2c 100644 --- a/drivers/platform/x86/amd/pmc/pmc.c +++ b/drivers/platform/x86/amd/pmc/pmc.c @@ -157,6 +157,8 @@ static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev)  			return -ENOMEM;  	} +	memset_io(dev->smu_virt_addr, 0, sizeof(struct smu_metrics)); +  	/* Start the logging */  	amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_RESET, false);  	amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_START, false); diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c index 76910601cac8..ef988605c4da 100644 --- a/drivers/platform/x86/amd/pmf/core.c +++ b/drivers/platform/x86/amd/pmf/core.c @@ -280,7 +280,7 @@ int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev, bool alloc_buffer)  			dev_err(dev->dev, "Invalid CPU id: 0x%x", dev->cpu_id);  		} -		dev->buf = kzalloc(dev->mtable_size, GFP_KERNEL); +		dev->buf = devm_kzalloc(dev->dev, dev->mtable_size, GFP_KERNEL);  		if (!dev->buf)  			return -ENOMEM;  	} @@ -493,7 +493,6 @@ static void amd_pmf_remove(struct platform_device *pdev)  	mutex_destroy(&dev->lock);  	mutex_destroy(&dev->update_mutex);  	mutex_destroy(&dev->cb_mutex); -	kfree(dev->buf);  }  static const struct attribute_group *amd_pmf_driver_groups[] = { diff --git a/drivers/platform/x86/amd/pmf/tee-if.c b/drivers/platform/x86/amd/pmf/tee-if.c index d3bd12ad036a..4f626ebcb619 100644 --- a/drivers/platform/x86/amd/pmf/tee-if.c +++ b/drivers/platform/x86/amd/pmf/tee-if.c @@ -358,30 +358,28 @@ static ssize_t amd_pmf_get_pb_data(struct file *filp, const char __user *buf,  		return -EINVAL;  	/* re-alloc to the new buffer length of the policy binary */ -	new_policy_buf = memdup_user(buf, length); -	if (IS_ERR(new_policy_buf)) -		return PTR_ERR(new_policy_buf); +	new_policy_buf = devm_kzalloc(dev->dev, length, GFP_KERNEL); +	if (!new_policy_buf) +		return -ENOMEM; + +	if (copy_from_user(new_policy_buf, buf, length)) { +		devm_kfree(dev->dev, new_policy_buf); +		return -EFAULT; +	} -	kfree(dev->policy_buf); +	devm_kfree(dev->dev, dev->policy_buf);  	dev->policy_buf = new_policy_buf;  	dev->policy_sz = length; -	if (!amd_pmf_pb_valid(dev)) { -		ret = -EINVAL; -		goto cleanup; -	} +	if (!amd_pmf_pb_valid(dev)) +		return -EINVAL;  	amd_pmf_hex_dump_pb(dev);  	ret = amd_pmf_start_policy_engine(dev);  	if (ret < 0) -		goto cleanup; +		return ret;  	return length; - -cleanup: -	kfree(dev->policy_buf); -	dev->policy_buf = NULL; -	return ret;  }  static const struct file_operations pb_fops = { @@ -422,12 +420,12 @@ static int amd_pmf_ta_open_session(struct tee_context *ctx, u32 *id, const uuid_  	rc = tee_client_open_session(ctx, &sess_arg, NULL);  	if (rc < 0 || sess_arg.ret != 0) {  		pr_err("Failed to open TEE session err:%#x, rc:%d\n", sess_arg.ret, rc); -		return rc; +		return rc ?: -EINVAL;  	}  	*id = sess_arg.session; -	return rc; +	return 0;  }  static int amd_pmf_register_input_device(struct amd_pmf_dev *dev) @@ -462,7 +460,9 @@ static int amd_pmf_tee_init(struct amd_pmf_dev *dev, const uuid_t *uuid)  	dev->tee_ctx = tee_client_open_context(NULL, amd_pmf_amdtee_ta_match, NULL, NULL);  	if (IS_ERR(dev->tee_ctx)) {  		dev_err(dev->dev, "Failed to open TEE context\n"); -		return PTR_ERR(dev->tee_ctx); +		ret = PTR_ERR(dev->tee_ctx); +		dev->tee_ctx = NULL; +		return ret;  	}  	ret = amd_pmf_ta_open_session(dev->tee_ctx, &dev->session_id, uuid); @@ -502,9 +502,12 @@ out_ctx:  static void amd_pmf_tee_deinit(struct amd_pmf_dev *dev)  { +	if (!dev->tee_ctx) +		return;  	tee_shm_free(dev->fw_shm_pool);  	tee_client_close_session(dev->tee_ctx, dev->session_id);  	tee_client_close_context(dev->tee_ctx); +	dev->tee_ctx = NULL;  }  int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev) @@ -527,64 +530,45 @@ int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev)  	ret = amd_pmf_set_dram_addr(dev, true);  	if (ret) -		goto err_cancel_work; +		return ret;  	dev->policy_base = devm_ioremap_resource(dev->dev, dev->res); -	if (IS_ERR(dev->policy_base)) { -		ret = PTR_ERR(dev->policy_base); -		goto err_free_dram_buf; -	} +	if (IS_ERR(dev->policy_base)) +		return PTR_ERR(dev->policy_base); -	dev->policy_buf = kzalloc(dev->policy_sz, GFP_KERNEL); -	if (!dev->policy_buf) { -		ret = -ENOMEM; -		goto err_free_dram_buf; -	} +	dev->policy_buf = devm_kzalloc(dev->dev, dev->policy_sz, GFP_KERNEL); +	if (!dev->policy_buf) +		return -ENOMEM;  	memcpy_fromio(dev->policy_buf, dev->policy_base, dev->policy_sz);  	if (!amd_pmf_pb_valid(dev)) {  		dev_info(dev->dev, "No Smart PC policy present\n"); -		ret = -EINVAL; -		goto err_free_policy; +		return -EINVAL;  	}  	amd_pmf_hex_dump_pb(dev); -	dev->prev_data = kzalloc(sizeof(*dev->prev_data), GFP_KERNEL); -	if (!dev->prev_data) { -		ret = -ENOMEM; -		goto err_free_policy; -	} +	dev->prev_data = devm_kzalloc(dev->dev, sizeof(*dev->prev_data), GFP_KERNEL); +	if (!dev->prev_data) +		return -ENOMEM;  	for (i = 0; i < ARRAY_SIZE(amd_pmf_ta_uuid); i++) {  		ret = amd_pmf_tee_init(dev, &amd_pmf_ta_uuid[i]);  		if (ret) -			goto err_free_prev_data; +			return ret;  		ret = amd_pmf_start_policy_engine(dev); -		switch (ret) { -		case TA_PMF_TYPE_SUCCESS: -			status = true; -			break; -		case TA_ERROR_CRYPTO_INVALID_PARAM: -		case TA_ERROR_CRYPTO_BIN_TOO_LARGE: -			amd_pmf_tee_deinit(dev); -			status = false; -			break; -		default: -			ret = -EINVAL; -			amd_pmf_tee_deinit(dev); -			goto err_free_prev_data; -		} - +		dev_dbg(dev->dev, "start policy engine ret: %d\n", ret); +		status = ret == TA_PMF_TYPE_SUCCESS;  		if (status)  			break; +		amd_pmf_tee_deinit(dev);  	}  	if (!status && !pb_side_load) {  		ret = -EINVAL; -		goto err_free_prev_data; +		goto err;  	}  	if (pb_side_load) @@ -592,22 +576,12 @@ int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev)  	ret = amd_pmf_register_input_device(dev);  	if (ret) -		goto err_pmf_remove_pb; +		goto err;  	return 0; -err_pmf_remove_pb: -	if (pb_side_load && dev->esbin) -		amd_pmf_remove_pb(dev); -	amd_pmf_tee_deinit(dev); -err_free_prev_data: -	kfree(dev->prev_data); -err_free_policy: -	kfree(dev->policy_buf); -err_free_dram_buf: -	kfree(dev->buf); -err_cancel_work: -	cancel_delayed_work_sync(&dev->pb_work); +err: +	amd_pmf_deinit_smart_pc(dev);  	return ret;  } @@ -621,11 +595,5 @@ void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev)  		amd_pmf_remove_pb(dev);  	cancel_delayed_work_sync(&dev->pb_work); -	kfree(dev->prev_data); -	dev->prev_data = NULL; -	kfree(dev->policy_buf); -	dev->policy_buf = NULL; -	kfree(dev->buf); -	dev->buf = NULL;  	amd_pmf_tee_deinit(dev);  } diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platform/x86/dell/alienware-wmi-wmax.c index c42f9228b0b2..20ec122a9fe0 100644 --- a/drivers/platform/x86/dell/alienware-wmi-wmax.c +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c @@ -119,7 +119,7 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = {  			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),  			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1 AMD"),  		}, -		.driver_data = &g_series_quirks, +		.driver_data = &generic_quirks,  	},  	{  		.ident = "Alienware m16 R2", diff --git a/drivers/platform/x86/dell/dell_rbu.c b/drivers/platform/x86/dell/dell_rbu.c index e30ca325938c..9dd9f2cb074f 100644 --- a/drivers/platform/x86/dell/dell_rbu.c +++ b/drivers/platform/x86/dell/dell_rbu.c @@ -45,7 +45,7 @@  MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>");  MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems");  MODULE_LICENSE("GPL"); -MODULE_VERSION("3.2"); +MODULE_VERSION("3.3");  #define BIOS_SCAN_LIMIT 0xffffffff  #define MAX_IMAGE_LENGTH 16 @@ -91,7 +91,7 @@ static void init_packet_head(void)  	rbu_data.imagesize = 0;  } -static int create_packet(void *data, size_t length) +static int create_packet(void *data, size_t length) __must_hold(&rbu_data.lock)  {  	struct packet_data *newpacket;  	int ordernum = 0; @@ -292,7 +292,7 @@ static int packet_read_list(char *data, size_t * pread_length)  	remaining_bytes = *pread_length;  	bytes_read = rbu_data.packet_read_count; -	list_for_each_entry(newpacket, (&packet_data_head.list)->next, list) { +	list_for_each_entry(newpacket, &packet_data_head.list, list) {  		bytes_copied = do_packet_read(pdest, newpacket,  			remaining_bytes, bytes_read, &temp_count);  		remaining_bytes -= bytes_copied; @@ -315,14 +315,14 @@ static void packet_empty_list(void)  {  	struct packet_data *newpacket, *tmp; -	list_for_each_entry_safe(newpacket, tmp, (&packet_data_head.list)->next, list) { +	list_for_each_entry_safe(newpacket, tmp, &packet_data_head.list, list) {  		list_del(&newpacket->list);  		/*  		 * zero out the RBU packet memory before freeing  		 * to make sure there are no stale RBU packets left in memory  		 */ -		memset(newpacket->data, 0, rbu_data.packetsize); +		memset(newpacket->data, 0, newpacket->length);  		set_memory_wb((unsigned long)newpacket->data,  			1 << newpacket->ordernum);  		free_pages((unsigned long) newpacket->data, diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index ede483573fe0..b5e4da6a6779 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -15,6 +15,7 @@  #include <linux/bug.h>  #include <linux/cleanup.h>  #include <linux/debugfs.h> +#include <linux/delay.h>  #include <linux/device.h>  #include <linux/dmi.h>  #include <linux/i8042.h> @@ -267,6 +268,20 @@ static void ideapad_shared_exit(struct ideapad_private *priv)   */  #define IDEAPAD_EC_TIMEOUT 200 /* in ms */ +/* + * Some models (e.g., ThinkBook since 2024) have a low tolerance for being + * polled too frequently. Doing so may break the state machine in the EC, + * resulting in a hard shutdown. + * + * It is also observed that frequent polls may disturb the ongoing operation + * and notably delay the availability of EC response. + * + * These values are used as the delay before the first poll and the interval + * between subsequent polls to solve the above issues. + */ +#define IDEAPAD_EC_POLL_MIN_US 150 +#define IDEAPAD_EC_POLL_MAX_US 300 +  static int eval_int(acpi_handle handle, const char *name, unsigned long *res)  {  	unsigned long long result; @@ -383,7 +398,7 @@ static int read_ec_data(acpi_handle handle, unsigned long cmd, unsigned long *da  	end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1;  	while (time_before(jiffies, end_jiffies)) { -		schedule(); +		usleep_range(IDEAPAD_EC_POLL_MIN_US, IDEAPAD_EC_POLL_MAX_US);  		err = eval_vpcr(handle, 1, &val);  		if (err) @@ -414,7 +429,7 @@ static int write_ec_cmd(acpi_handle handle, unsigned long cmd, unsigned long dat  	end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1;  	while (time_before(jiffies, end_jiffies)) { -		schedule(); +		usleep_range(IDEAPAD_EC_POLL_MIN_US, IDEAPAD_EC_POLL_MAX_US);  		err = eval_vpcr(handle, 1, &val);  		if (err) diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h index e136d18b1d38..4a94a4ee031e 100644 --- a/drivers/platform/x86/intel/pmc/core.h +++ b/drivers/platform/x86/intel/pmc/core.h @@ -299,6 +299,13 @@ enum ppfear_regs {  #define PTL_PCD_PMC_MMIO_REG_LEN		0x31A8  /* SSRAM PMC Device ID */ +/* LNL */ +#define PMC_DEVID_LNL_SOCM	0xa87f + +/* PTL */ +#define PMC_DEVID_PTL_PCDH	0xe37f +#define PMC_DEVID_PTL_PCDP	0xe47f +  /* ARL */  #define PMC_DEVID_ARL_SOCM	0x777f  #define PMC_DEVID_ARL_SOCS	0xae7f diff --git a/drivers/platform/x86/intel/pmc/ssram_telemetry.c b/drivers/platform/x86/intel/pmc/ssram_telemetry.c index b207247eb5dd..93579152188e 100644 --- a/drivers/platform/x86/intel/pmc/ssram_telemetry.c +++ b/drivers/platform/x86/intel/pmc/ssram_telemetry.c @@ -187,6 +187,9 @@ static const struct pci_device_id intel_pmc_ssram_telemetry_pci_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_MTL_SOCM) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCS) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_ARL_SOCM) }, +	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_LNL_SOCM) }, +	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_PTL_PCDH) }, +	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PMC_DEVID_PTL_PCDP) },  	{ }  };  MODULE_DEVICE_TABLE(pci, intel_pmc_ssram_telemetry_pci_ids); diff --git a/drivers/platform/x86/intel/tpmi_power_domains.c b/drivers/platform/x86/intel/tpmi_power_domains.c index 0c5c88eb7baf..9d8247bb9cfa 100644 --- a/drivers/platform/x86/intel/tpmi_power_domains.c +++ b/drivers/platform/x86/intel/tpmi_power_domains.c @@ -228,8 +228,10 @@ static int __init tpmi_init(void)  	domain_die_map = kcalloc(size_mul(topology_max_packages(), MAX_POWER_DOMAINS),  				 sizeof(*domain_die_map), GFP_KERNEL); -	if (!domain_die_map) +	if (!domain_die_map) { +		ret = -ENOMEM;  		goto free_domain_mask; +	}  	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,  				"platform/x86/tpmi_power_domains:online", diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c index 0f8aea18275b..65897fae17df 100644 --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c @@ -58,7 +58,7 @@ static ssize_t show_agent_types(struct kobject *kobj, struct kobj_attribute *att  		if (length)  			length += sysfs_emit_at(buf, length, " "); -		length += sysfs_emit_at(buf, length, agent_name[agent]); +		length += sysfs_emit_at(buf, length, "%s", agent_name[agent]);  	}  	length += sysfs_emit_at(buf, length, "\n"); diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c index 1c7b2f2716ca..44d9948ed224 100644 --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c @@ -511,10 +511,13 @@ static int uncore_probe(struct auxiliary_device *auxdev, const struct auxiliary_  	/* Get the package ID from the TPMI core */  	plat_info = tpmi_get_platform_data(auxdev); -	if (plat_info) -		pkg = plat_info->package_id; -	else +	if (unlikely(!plat_info)) {  		dev_info(&auxdev->dev, "Platform information is NULL\n"); +		ret = -ENODEV; +		goto err_rem_common; +	} + +	pkg = plat_info->package_id;  	for (i = 0; i < num_resources; ++i) {  		struct tpmi_uncore_power_domain_info *pd_info; diff --git a/drivers/platform/x86/samsung-galaxybook.c b/drivers/platform/x86/samsung-galaxybook.c index 5878a351993e..3c13e13d4885 100644 --- a/drivers/platform/x86/samsung-galaxybook.c +++ b/drivers/platform/x86/samsung-galaxybook.c @@ -1403,6 +1403,7 @@ static int galaxybook_probe(struct platform_device *pdev)  }  static const struct acpi_device_id galaxybook_device_ids[] = { +	{ "SAM0426" },  	{ "SAM0427" },  	{ "SAM0428" },  	{ "SAM0429" }, | 
