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

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
...@@ -71,7 +71,6 @@ struct silead_ts_data { ...@@ -71,7 +71,6 @@ struct silead_ts_data {
struct regulator_bulk_data regulators[2]; struct regulator_bulk_data regulators[2];
char fw_name[64]; char fw_name[64];
struct touchscreen_properties prop; struct touchscreen_properties prop;
u32 max_fingers;
u32 chip_id; u32 chip_id;
struct input_mt_pos pos[SILEAD_MAX_FINGERS]; struct input_mt_pos pos[SILEAD_MAX_FINGERS];
int slots[SILEAD_MAX_FINGERS]; int slots[SILEAD_MAX_FINGERS];
...@@ -136,7 +135,7 @@ static int silead_ts_request_input_dev(struct silead_ts_data *data) ...@@ -136,7 +135,7 @@ static int silead_ts_request_input_dev(struct silead_ts_data *data)
touchscreen_parse_properties(data->input, true, &data->prop); touchscreen_parse_properties(data->input, true, &data->prop);
silead_apply_efi_fw_min_max(data); 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_DIRECT | INPUT_MT_DROP_UNUSED |
INPUT_MT_TRACK); INPUT_MT_TRACK);
...@@ -256,10 +255,10 @@ static void silead_ts_read_data(struct i2c_client *client) ...@@ -256,10 +255,10 @@ static void silead_ts_read_data(struct i2c_client *client)
return; return;
} }
if (buf[0] > data->max_fingers) { if (buf[0] > SILEAD_MAX_FINGERS) {
dev_warn(dev, "More touches reported then supported %d > %d\n", dev_warn(dev, "More touches reported then supported %d > %d\n",
buf[0], data->max_fingers); buf[0], SILEAD_MAX_FINGERS);
buf[0] = data->max_fingers; buf[0] = SILEAD_MAX_FINGERS;
} }
if (silead_ts_handle_pen_data(data, buf)) if (silead_ts_handle_pen_data(data, buf))
...@@ -315,7 +314,6 @@ static void silead_ts_read_data(struct i2c_client *client) ...@@ -315,7 +314,6 @@ static void silead_ts_read_data(struct i2c_client *client)
static int silead_ts_init(struct i2c_client *client) static int silead_ts_init(struct i2c_client *client)
{ {
struct silead_ts_data *data = i2c_get_clientdata(client);
int error; int error;
error = i2c_smbus_write_byte_data(client, SILEAD_REG_RESET, error = i2c_smbus_write_byte_data(client, SILEAD_REG_RESET,
...@@ -325,7 +323,7 @@ static int silead_ts_init(struct i2c_client *client) ...@@ -325,7 +323,7 @@ static int silead_ts_init(struct i2c_client *client)
usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
error = i2c_smbus_write_byte_data(client, SILEAD_REG_TOUCH_NR, error = i2c_smbus_write_byte_data(client, SILEAD_REG_TOUCH_NR,
data->max_fingers); SILEAD_MAX_FINGERS);
if (error) if (error)
goto i2c_write_err; goto i2c_write_err;
usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
...@@ -591,13 +589,6 @@ static void silead_ts_read_props(struct i2c_client *client) ...@@ -591,13 +589,6 @@ static void silead_ts_read_props(struct i2c_client *client)
const char *str; const char *str;
int error; 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); error = device_property_read_string(dev, "firmware-name", &str);
if (!error) if (!error)
snprintf(data->fw_name, sizeof(data->fw_name), snprintf(data->fw_name, sizeof(data->fw_name),
......
...@@ -136,6 +136,7 @@ config YOGABOOK ...@@ -136,6 +136,7 @@ config YOGABOOK
config YT2_1380 config YT2_1380
tristate "Lenovo Yoga Tablet 2 1380 fast charge driver" tristate "Lenovo Yoga Tablet 2 1380 fast charge driver"
depends on SERIAL_DEV_BUS depends on SERIAL_DEV_BUS
depends on EXTCON
depends on ACPI depends on ACPI
help help
Say Y here to enable support for the custom fast charging protocol Say Y here to enable support for the custom fast charging protocol
......
...@@ -907,16 +907,44 @@ static int hsmp_plat_dev_register(void) ...@@ -907,16 +907,44 @@ static int hsmp_plat_dev_register(void)
return ret; return ret;
} }
/*
* 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)
{
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
return false;
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) static int __init hsmp_plt_init(void)
{ {
int ret = -ENODEV; int ret = -ENODEV;
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;
}
/* /*
* amd_nb_num() returns number of SMN/DF interfaces present in the system * 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 * if we have N SMN/DF interfaces that ideally means N sockets
...@@ -930,7 +958,15 @@ static int __init hsmp_plt_init(void) ...@@ -930,7 +958,15 @@ static int __init hsmp_plt_init(void)
return ret; return ret;
if (!plat_dev.is_acpi_device) { if (!plat_dev.is_acpi_device) {
ret = hsmp_plat_dev_register(); 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) if (ret)
platform_driver_unregister(&amd_hsmp_driver); platform_driver_unregister(&amd_hsmp_driver);
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/container_of.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/capability.h> #include <linux/capability.h>
...@@ -25,11 +26,16 @@ static u32 da_supported_commands; ...@@ -25,11 +26,16 @@ static u32 da_supported_commands;
static int da_num_tokens; static int da_num_tokens;
static struct platform_device *platform_device; static struct platform_device *platform_device;
static struct calling_interface_token *da_tokens; static struct calling_interface_token *da_tokens;
static struct device_attribute *token_location_attrs; static struct token_sysfs_data *token_entries;
static struct device_attribute *token_value_attrs;
static struct attribute **token_attrs; static struct attribute **token_attrs;
static DEFINE_MUTEX(smbios_mutex); 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 smbios_device {
struct list_head list; struct list_head list;
struct device *device; struct device *device;
...@@ -416,47 +422,26 @@ static void __init find_tokens(const struct dmi_header *dm, void *dummy) ...@@ -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, static ssize_t location_show(struct device *dev,
struct device_attribute *attr, char *buf) 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)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
i = match_attribute(dev, attr); return sysfs_emit(buf, "%08x", data->token->location);
if (i > 0)
return sysfs_emit(buf, "%08x", da_tokens[i].location);
return 0;
} }
static ssize_t value_show(struct device *dev, static ssize_t value_show(struct device *dev,
struct device_attribute *attr, char *buf) 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)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
i = match_attribute(dev, attr); return sysfs_emit(buf, "%08x", data->token->value);
if (i > 0)
return sysfs_emit(buf, "%08x", da_tokens[i].value);
return 0;
} }
static struct attribute_group smbios_attribute_group = { static struct attribute_group smbios_attribute_group = {
...@@ -473,22 +458,15 @@ static int build_tokens_sysfs(struct platform_device *dev) ...@@ -473,22 +458,15 @@ static int build_tokens_sysfs(struct platform_device *dev)
{ {
char *location_name; char *location_name;
char *value_name; char *value_name;
size_t size;
int ret; int ret;
int i, j; int i, j;
/* (number of tokens + 1 for null terminated */ token_entries = kcalloc(da_num_tokens, sizeof(*token_entries), GFP_KERNEL);
size = sizeof(struct device_attribute) * (da_num_tokens + 1); if (!token_entries)
token_location_attrs = kzalloc(size, GFP_KERNEL);
if (!token_location_attrs)
return -ENOMEM; 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*/ /* need to store both location and value + terminator*/
size = sizeof(struct attribute *) * ((2 * da_num_tokens) + 1); token_attrs = kcalloc((2 * da_num_tokens) + 1, sizeof(*token_attrs), GFP_KERNEL);
token_attrs = kzalloc(size, GFP_KERNEL);
if (!token_attrs) if (!token_attrs)
goto out_allocate_attrs; goto out_allocate_attrs;
...@@ -496,32 +474,34 @@ static int build_tokens_sysfs(struct platform_device *dev) ...@@ -496,32 +474,34 @@ static int build_tokens_sysfs(struct platform_device *dev)
/* skip empty */ /* skip empty */
if (da_tokens[i].tokenID == 0) if (da_tokens[i].tokenID == 0)
continue; continue;
token_entries[i].token = &da_tokens[i];
/* add location */ /* add location */
location_name = kasprintf(GFP_KERNEL, "%04x_location", location_name = kasprintf(GFP_KERNEL, "%04x_location",
da_tokens[i].tokenID); da_tokens[i].tokenID);
if (location_name == NULL) if (location_name == NULL)
goto out_unwind_strings; goto out_unwind_strings;
sysfs_attr_init(&token_location_attrs[i].attr);
token_location_attrs[i].attr.name = location_name; sysfs_attr_init(&token_entries[i].location_attr.attr);
token_location_attrs[i].attr.mode = 0444; token_entries[i].location_attr.attr.name = location_name;
token_location_attrs[i].show = location_show; token_entries[i].location_attr.attr.mode = 0444;
token_attrs[j++] = &token_location_attrs[i].attr; token_entries[i].location_attr.show = location_show;
token_attrs[j++] = &token_entries[i].location_attr.attr;
/* add value */ /* add value */
value_name = kasprintf(GFP_KERNEL, "%04x_value", value_name = kasprintf(GFP_KERNEL, "%04x_value",
da_tokens[i].tokenID); da_tokens[i].tokenID);
if (value_name == NULL) if (!value_name) {
goto loop_fail_create_value; kfree(location_name);
sysfs_attr_init(&token_value_attrs[i].attr); goto out_unwind_strings;
token_value_attrs[i].attr.name = value_name; }
token_value_attrs[i].attr.mode = 0444;
token_value_attrs[i].show = value_show; sysfs_attr_init(&token_entries[i].value_attr.attr);
token_attrs[j++] = &token_value_attrs[i].attr; token_entries[i].value_attr.attr.name = value_name;
continue; token_entries[i].value_attr.attr.mode = 0444;
token_entries[i].value_attr.show = value_show;
loop_fail_create_value: token_attrs[j++] = &token_entries[i].value_attr.attr;
kfree(location_name);
goto out_unwind_strings;
} }
smbios_attribute_group.attrs = token_attrs; smbios_attribute_group.attrs = token_attrs;
...@@ -532,14 +512,12 @@ static int build_tokens_sysfs(struct platform_device *dev) ...@@ -532,14 +512,12 @@ static int build_tokens_sysfs(struct platform_device *dev)
out_unwind_strings: out_unwind_strings:
while (i--) { while (i--) {
kfree(token_location_attrs[i].attr.name); kfree(token_entries[i].location_attr.attr.name);
kfree(token_value_attrs[i].attr.name); kfree(token_entries[i].value_attr.attr.name);
} }
kfree(token_attrs); kfree(token_attrs);
out_allocate_attrs: out_allocate_attrs:
kfree(token_value_attrs); kfree(token_entries);
out_allocate_value:
kfree(token_location_attrs);
return -ENOMEM; return -ENOMEM;
} }
...@@ -551,12 +529,11 @@ static void free_group(struct platform_device *pdev) ...@@ -551,12 +529,11 @@ static void free_group(struct platform_device *pdev)
sysfs_remove_group(&pdev->dev.kobj, sysfs_remove_group(&pdev->dev.kobj,
&smbios_attribute_group); &smbios_attribute_group);
for (i = 0; i < da_num_tokens; i++) { for (i = 0; i < da_num_tokens; i++) {
kfree(token_location_attrs[i].attr.name); kfree(token_entries[i].location_attr.attr.name);
kfree(token_value_attrs[i].attr.name); kfree(token_entries[i].value_attr.attr.name);
} }
kfree(token_attrs); kfree(token_attrs);
kfree(token_value_attrs); kfree(token_entries);
kfree(token_location_attrs);
} }
static int __init dell_smbios_init(void) static int __init dell_smbios_init(void)
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment