Commit 96e09b8f authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'platform-drivers-x86-v6.10-3' of...

Merge tag 'platform-drivers-x86-v6.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86

Pull x86 platform driver fixes from Hans de Goede:

 -  Default silead touchscreen driver to 10 fingers and drop 10 finger
    setting from all DMI quirks. More of a cleanup then a pure fix, but
    since the DMI quirks always get updated through the fixes branch
    this avoids conflicts.

 -  Kconfig fix for randconfig builds

 -  dell-smbios: Fix wrong token data in sysfs

 -  amd-hsmp: Fix driver poking unsupported hw when loaded manually

* tag 'platform-drivers-x86-v6.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86:
  platform/x86/amd/hsmp: Check HSMP support on AMD family of processors
  platform/x86: dell-smbios: Simplify error handling
  platform/x86: dell-smbios: Fix wrong token data in sysfs
  platform/x86: yt2-1380: add CONFIG_EXTCON dependency
  platform/x86: touchscreen_dmi: Use 2-argument strscpy()
  platform/x86: touchscreen_dmi: Drop "silead,max-fingers" property
  Input: silead - Always support 10 fingers
parents f24b46ea 77f1972b
Loading
Loading
Loading
Loading
+5 −14
Original line number Diff line number Diff line
@@ -71,7 +71,6 @@ struct silead_ts_data {
	struct regulator_bulk_data regulators[2];
	char fw_name[64];
	struct touchscreen_properties prop;
	u32 max_fingers;
	u32 chip_id;
	struct input_mt_pos pos[SILEAD_MAX_FINGERS];
	int slots[SILEAD_MAX_FINGERS];
@@ -136,7 +135,7 @@ static int silead_ts_request_input_dev(struct silead_ts_data *data)
	touchscreen_parse_properties(data->input, true, &data->prop);
	silead_apply_efi_fw_min_max(data);

	input_mt_init_slots(data->input, data->max_fingers,
	input_mt_init_slots(data->input, SILEAD_MAX_FINGERS,
			    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED |
			    INPUT_MT_TRACK);

@@ -256,10 +255,10 @@ static void silead_ts_read_data(struct i2c_client *client)
		return;
	}

	if (buf[0] > data->max_fingers) {
	if (buf[0] > SILEAD_MAX_FINGERS) {
		dev_warn(dev, "More touches reported then supported %d > %d\n",
			 buf[0], data->max_fingers);
		buf[0] = data->max_fingers;
			 buf[0], SILEAD_MAX_FINGERS);
		buf[0] = SILEAD_MAX_FINGERS;
	}

	if (silead_ts_handle_pen_data(data, buf))
@@ -315,7 +314,6 @@ static void silead_ts_read_data(struct i2c_client *client)

static int silead_ts_init(struct i2c_client *client)
{
	struct silead_ts_data *data = i2c_get_clientdata(client);
	int error;

	error = i2c_smbus_write_byte_data(client, SILEAD_REG_RESET,
@@ -325,7 +323,7 @@ static int silead_ts_init(struct i2c_client *client)
	usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);

	error = i2c_smbus_write_byte_data(client, SILEAD_REG_TOUCH_NR,
					data->max_fingers);
					  SILEAD_MAX_FINGERS);
	if (error)
		goto i2c_write_err;
	usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
@@ -591,13 +589,6 @@ static void silead_ts_read_props(struct i2c_client *client)
	const char *str;
	int error;

	error = device_property_read_u32(dev, "silead,max-fingers",
					 &data->max_fingers);
	if (error) {
		dev_dbg(dev, "Max fingers read error %d\n", error);
		data->max_fingers = 5; /* Most devices handle up-to 5 fingers */
	}

	error = device_property_read_string(dev, "firmware-name", &str);
	if (!error)
		snprintf(data->fw_name, sizeof(data->fw_name),
+1 −0
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@ config YOGABOOK
config YT2_1380
	tristate "Lenovo Yoga Tablet 2 1380 fast charge driver"
	depends on SERIAL_DEV_BUS
	depends on EXTCON
	depends on ACPI
	help
	  Say Y here to enable support for the custom fast charging protocol
+43 −7
Original line number Diff line number Diff line
@@ -907,16 +907,44 @@ static int hsmp_plat_dev_register(void)
	return ret;
}

static int __init hsmp_plt_init(void)
/*
 * This check is only needed for backward compatibility of previous platforms.
 * All new platforms are expected to support ACPI based probing.
 */
static bool legacy_hsmp_support(void)
{
	int ret = -ENODEV;
	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
		return false;

	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD || boot_cpu_data.x86 < 0x19) {
		pr_err("HSMP is not supported on Family:%x model:%x\n",
		       boot_cpu_data.x86, boot_cpu_data.x86_model);
		return ret;
	switch (boot_cpu_data.x86) {
	case 0x19:
		switch (boot_cpu_data.x86_model) {
		case 0x00 ... 0x1F:
		case 0x30 ... 0x3F:
		case 0x90 ... 0x9F:
		case 0xA0 ... 0xAF:
			return true;
		default:
			return false;
		}
	case 0x1A:
		switch (boot_cpu_data.x86_model) {
		case 0x00 ... 0x1F:
			return true;
		default:
			return false;
		}
	default:
		return false;
	}

	return false;
}

static int __init hsmp_plt_init(void)
{
	int ret = -ENODEV;

	/*
	 * amd_nb_num() returns number of SMN/DF interfaces present in the system
	 * if we have N SMN/DF interfaces that ideally means N sockets
@@ -930,7 +958,15 @@ static int __init hsmp_plt_init(void)
		return ret;

	if (!plat_dev.is_acpi_device) {
		if (legacy_hsmp_support()) {
			/* Not ACPI device, but supports HSMP, register a plat_dev */
			ret = hsmp_plat_dev_register();
		} else {
			/* Not ACPI, Does not support HSMP */
			pr_info("HSMP is not supported on Family:%x model:%x\n",
				boot_cpu_data.x86, boot_cpu_data.x86_model);
			ret = -ENODEV;
		}
		if (ret)
			platform_driver_unregister(&amd_hsmp_driver);
	}
+40 −63
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
 */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/container_of.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/capability.h>
@@ -25,11 +26,16 @@ static u32 da_supported_commands;
static int da_num_tokens;
static struct platform_device *platform_device;
static struct calling_interface_token *da_tokens;
static struct device_attribute *token_location_attrs;
static struct device_attribute *token_value_attrs;
static struct token_sysfs_data *token_entries;
static struct attribute **token_attrs;
static DEFINE_MUTEX(smbios_mutex);

struct token_sysfs_data {
	struct device_attribute location_attr;
	struct device_attribute value_attr;
	struct calling_interface_token *token;
};

struct smbios_device {
	struct list_head list;
	struct device *device;
@@ -416,47 +422,26 @@ static void __init find_tokens(const struct dmi_header *dm, void *dummy)
	}
}

static int match_attribute(struct device *dev,
			   struct device_attribute *attr)
{
	int i;

	for (i = 0; i < da_num_tokens * 2; i++) {
		if (!token_attrs[i])
			continue;
		if (strcmp(token_attrs[i]->name, attr->attr.name) == 0)
			return i/2;
	}
	dev_dbg(dev, "couldn't match: %s\n", attr->attr.name);
	return -EINVAL;
}

static ssize_t location_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	int i;
	struct token_sysfs_data *data = container_of(attr, struct token_sysfs_data, location_attr);

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	i = match_attribute(dev, attr);
	if (i > 0)
		return sysfs_emit(buf, "%08x", da_tokens[i].location);
	return 0;
	return sysfs_emit(buf, "%08x", data->token->location);
}

static ssize_t value_show(struct device *dev,
			  struct device_attribute *attr, char *buf)
{
	int i;
	struct token_sysfs_data *data = container_of(attr, struct token_sysfs_data, value_attr);

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	i = match_attribute(dev, attr);
	if (i > 0)
		return sysfs_emit(buf, "%08x", da_tokens[i].value);
	return 0;
	return sysfs_emit(buf, "%08x", data->token->value);
}

static struct attribute_group smbios_attribute_group = {
@@ -473,22 +458,15 @@ static int build_tokens_sysfs(struct platform_device *dev)
{
	char *location_name;
	char *value_name;
	size_t size;
	int ret;
	int i, j;

	/* (number of tokens  + 1 for null terminated */
	size = sizeof(struct device_attribute) * (da_num_tokens + 1);
	token_location_attrs = kzalloc(size, GFP_KERNEL);
	if (!token_location_attrs)
	token_entries = kcalloc(da_num_tokens, sizeof(*token_entries), GFP_KERNEL);
	if (!token_entries)
		return -ENOMEM;
	token_value_attrs = kzalloc(size, GFP_KERNEL);
	if (!token_value_attrs)
		goto out_allocate_value;

	/* need to store both location and value + terminator*/
	size = sizeof(struct attribute *) * ((2 * da_num_tokens) + 1);
	token_attrs = kzalloc(size, GFP_KERNEL);
	token_attrs = kcalloc((2 * da_num_tokens) + 1, sizeof(*token_attrs), GFP_KERNEL);
	if (!token_attrs)
		goto out_allocate_attrs;

@@ -496,33 +474,35 @@ static int build_tokens_sysfs(struct platform_device *dev)
		/* skip empty */
		if (da_tokens[i].tokenID == 0)
			continue;

		token_entries[i].token = &da_tokens[i];

		/* add location */
		location_name = kasprintf(GFP_KERNEL, "%04x_location",
					  da_tokens[i].tokenID);
		if (location_name == NULL)
			goto out_unwind_strings;
		sysfs_attr_init(&token_location_attrs[i].attr);
		token_location_attrs[i].attr.name = location_name;
		token_location_attrs[i].attr.mode = 0444;
		token_location_attrs[i].show = location_show;
		token_attrs[j++] = &token_location_attrs[i].attr;

		sysfs_attr_init(&token_entries[i].location_attr.attr);
		token_entries[i].location_attr.attr.name = location_name;
		token_entries[i].location_attr.attr.mode = 0444;
		token_entries[i].location_attr.show = location_show;
		token_attrs[j++] = &token_entries[i].location_attr.attr;

		/* add value */
		value_name = kasprintf(GFP_KERNEL, "%04x_value",
				       da_tokens[i].tokenID);
		if (value_name == NULL)
			goto loop_fail_create_value;
		sysfs_attr_init(&token_value_attrs[i].attr);
		token_value_attrs[i].attr.name = value_name;
		token_value_attrs[i].attr.mode = 0444;
		token_value_attrs[i].show = value_show;
		token_attrs[j++] = &token_value_attrs[i].attr;
		continue;

loop_fail_create_value:
		if (!value_name) {
			kfree(location_name);
			goto out_unwind_strings;
		}

		sysfs_attr_init(&token_entries[i].value_attr.attr);
		token_entries[i].value_attr.attr.name = value_name;
		token_entries[i].value_attr.attr.mode = 0444;
		token_entries[i].value_attr.show = value_show;
		token_attrs[j++] = &token_entries[i].value_attr.attr;
	}
	smbios_attribute_group.attrs = token_attrs;

	ret = sysfs_create_group(&dev->dev.kobj, &smbios_attribute_group);
@@ -532,14 +512,12 @@ static int build_tokens_sysfs(struct platform_device *dev)

out_unwind_strings:
	while (i--) {
		kfree(token_location_attrs[i].attr.name);
		kfree(token_value_attrs[i].attr.name);
		kfree(token_entries[i].location_attr.attr.name);
		kfree(token_entries[i].value_attr.attr.name);
	}
	kfree(token_attrs);
out_allocate_attrs:
	kfree(token_value_attrs);
out_allocate_value:
	kfree(token_location_attrs);
	kfree(token_entries);

	return -ENOMEM;
}
@@ -551,12 +529,11 @@ static void free_group(struct platform_device *pdev)
	sysfs_remove_group(&pdev->dev.kobj,
				&smbios_attribute_group);
	for (i = 0; i < da_num_tokens; i++) {
		kfree(token_location_attrs[i].attr.name);
		kfree(token_value_attrs[i].attr.name);
		kfree(token_entries[i].location_attr.attr.name);
		kfree(token_entries[i].value_attr.attr.name);
	}
	kfree(token_attrs);
	kfree(token_value_attrs);
	kfree(token_location_attrs);
	kfree(token_entries);
}

static int __init dell_smbios_init(void)
+1 −58

File changed.

Preview size limit exceeded, changes collapsed.