Skip to content

Commit

Permalink
Merge tag 'platform-drivers-x86-v4.14-1' of git://git.infradead.org/l…
Browse files Browse the repository at this point in the history
…inux-platform-drivers-x86

Pull x86 platform driver updates from Darren Hart:
 "Several fixes from static analysis and message noise reduction.
  Correct WMI core and related drivers to evaluate instance number 0x0
  in accordance with the documentation. Add intel-telemetry support for
  Gemini Lake. Various individual driver fixes noted below.

  dell-wmi:
   - Update dell_wmi_check_descriptor_buffer() to new model

  intel-vbtn:
   - reduce unnecessary messages for normal users
   - match power button on press rather than release

  intel-hid:
   - reduce unnecessary messages for normal users

  thinkpad_acpi:
   - Fix warning about deprecated hwmon_device_register

  wmi:
   - Fix check for method instance number

  ideapad-laptop:
   - Expose conservation mode switch

  intel_pmc_core:
   - Make the driver PCH family agnostic

  peaq-wmi:
   - Evaluate wmi method with instance number 0x0
   - silence a static checker warning

  mxm-wmi:
   - Evaluate wmi method with instance number 0x0

  asus-wmi:
   - Evaluate wmi method with instance number 0x0

  intel_scu_ipc:
   - make intel_scu_ipc_pdata_t const

  intel_mid_powerbtn:
   - make mid_pb_ddata const
   - fix error return code in mid_pb_probe()

  hp-wmi:
   - Remove unused macro helper
   - Correctly determine method id in WMI calls

  dell-wmi:
   - Fix driver interface version query

  intel_telemetry:
   - remove redundant macro definition
   - Add GLK PSS Event Table

  alienware-wmi:
   - fix format string overflow warning

  ibm_rtl:
   - remove unnecessary static in ibm_rtl_write()

  msi-wmi:
   - remove unnecessary static in msi_wmi_notify()"

* tag 'platform-drivers-x86-v4.14-1' of git://git.infradead.org/linux-platform-drivers-x86: (23 commits)
  platform/x86: dell-wmi: Update dell_wmi_check_descriptor_buffer() to new model
  platform/x86: intel-vbtn: reduce unnecessary messages for normal users
  platform/x86: intel-hid: reduce unnecessary messages for normal users
  platform/x86: thinkpad_acpi: Fix warning about deprecated hwmon_device_register
  platform/x86: wmi: Fix check for method instance number
  platform/x86: ideapad-laptop: Expose conservation mode switch
  platform/x86: intel_pmc_core: Make the driver PCH family agnostic
  platform/x86: peaq-wmi: Evaluate wmi method with instance number 0x0
  platform/x86: mxm-wmi: Evaluate wmi method with instance number 0x0
  platform/x86: asus-wmi: Evaluate wmi method with instance number 0x0
  platform/x86: intel_scu_ipc: make intel_scu_ipc_pdata_t const
  platform/x86: intel_mid_powerbtn: make mid_pb_ddata const
  platform/x86: intel_mid_powerbtn: fix error return code in mid_pb_probe()
  platform/x86: hp-wmi: Remove unused macro helper
  platform/x86: hp-wmi: Correctly determine method id in WMI calls
  platform/x86: intel-vbtn: match power button on press rather than release
  platform/x86: dell-wmi: Fix driver interface version query
  platform/x86: intel_telemetry: remove redundant macro definition
  platform/x86: intel_telemetry: Add GLK PSS Event Table
  platform/x86: alienware-wmi: fix format string overflow warning
  ...
  • Loading branch information
torvalds committed Sep 8, 2017
2 parents ee89252 + 00ebbeb commit 0e271fd
Show file tree
Hide file tree
Showing 20 changed files with 278 additions and 119 deletions.
9 changes: 7 additions & 2 deletions Documentation/laptops/thinkpad-acpi.txt
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,9 @@ space, for 2.6.23+ this is /sys/devices/platform/thinkpad_acpi/.
Sysfs device attributes for the sensors and fan are on the
thinkpad_hwmon device's sysfs attribute space, but you should locate it
looking for a hwmon device with the name attribute of "thinkpad", or
better yet, through libsensors.

better yet, through libsensors. For 4.14+ sysfs attributes were moved to the
hwmon device (/sys/bus/platform/devices/thinkpad_hwmon/hwmon/hwmon? or
/sys/class/hwmon/hwmon?).

Driver version
--------------
Expand Down Expand Up @@ -1478,3 +1479,7 @@ Sysfs interface changelog:
0x020700: Support for mute-only mixers.
Volume control in read-only mode by default.
Marker for ALSA mixer support.

0x030000: Thermal and fan sysfs attributes were moved to the hwmon
device instead of being attached to the backing platform
device.
40 changes: 21 additions & 19 deletions drivers/platform/x86/alienware-wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,12 +255,13 @@ static int parse_rgb(const char *buf, struct platform_zone *zone)

static struct platform_zone *match_zone(struct device_attribute *attr)
{
int i;
for (i = 0; i < quirks->num_zones; i++) {
if ((struct device_attribute *)zone_data[i].attr == attr) {
u8 zone;

for (zone = 0; zone < quirks->num_zones; zone++) {
if ((struct device_attribute *)zone_data[zone].attr == attr) {
pr_debug("alienware-wmi: matched zone location: %d\n",
zone_data[i].location);
return &zone_data[i];
zone_data[zone].location);
return &zone_data[zone];
}
}
return NULL;
Expand Down Expand Up @@ -420,7 +421,7 @@ static DEVICE_ATTR(lighting_control_state, 0644, show_control_state,

static int alienware_zone_init(struct platform_device *dev)
{
int i;
u8 zone;
char buffer[10];
char *name;

Expand Down Expand Up @@ -457,19 +458,19 @@ static int alienware_zone_init(struct platform_device *dev)
if (!zone_data)
return -ENOMEM;

for (i = 0; i < quirks->num_zones; i++) {
sprintf(buffer, "zone%02X", i);
for (zone = 0; zone < quirks->num_zones; zone++) {
sprintf(buffer, "zone%02hhX", zone);
name = kstrdup(buffer, GFP_KERNEL);
if (name == NULL)
return 1;
sysfs_attr_init(&zone_dev_attrs[i].attr);
zone_dev_attrs[i].attr.name = name;
zone_dev_attrs[i].attr.mode = 0644;
zone_dev_attrs[i].show = zone_show;
zone_dev_attrs[i].store = zone_set;
zone_data[i].location = i;
zone_attrs[i] = &zone_dev_attrs[i].attr;
zone_data[i].attr = &zone_dev_attrs[i];
sysfs_attr_init(&zone_dev_attrs[zone].attr);
zone_dev_attrs[zone].attr.name = name;
zone_dev_attrs[zone].attr.mode = 0644;
zone_dev_attrs[zone].show = zone_show;
zone_dev_attrs[zone].store = zone_set;
zone_data[zone].location = zone;
zone_attrs[zone] = &zone_dev_attrs[zone].attr;
zone_data[zone].attr = &zone_dev_attrs[zone];
}
zone_attrs[quirks->num_zones] = &dev_attr_lighting_control_state.attr;
zone_attribute_group.attrs = zone_attrs;
Expand All @@ -481,12 +482,13 @@ static int alienware_zone_init(struct platform_device *dev)

static void alienware_zone_exit(struct platform_device *dev)
{
u8 zone;

sysfs_remove_group(&dev->dev.kobj, &zone_attribute_group);
led_classdev_unregister(&global_led);
if (zone_dev_attrs) {
int i;
for (i = 0; i < quirks->num_zones; i++)
kfree(zone_dev_attrs[i].attr.name);
for (zone = 0; zone < quirks->num_zones; zone++)
kfree(zone_dev_attrs[zone].attr.name);
}
kfree(zone_dev_attrs);
kfree(zone_data);
Expand Down
4 changes: 2 additions & 2 deletions drivers/platform/x86/asus-wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
union acpi_object *obj;
u32 tmp = 0;

status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 1, method_id,
status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
&input, &output);

if (ACPI_FAILURE(status))
Expand Down Expand Up @@ -1946,7 +1946,7 @@ static int show_call(struct seq_file *m, void *data)
acpi_status status;

status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
1, asus->debug.method_id,
0, asus->debug.method_id,
&input, &output);

if (ACPI_FAILURE(status))
Expand Down
69 changes: 39 additions & 30 deletions drivers/platform/x86/dell-wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ MODULE_LICENSE("GPL");
#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
#define DELL_DESCRIPTOR_GUID "8D9DDCBC-A997-11DA-B012-B622A1EF5492"

static u32 dell_wmi_interface_version;
static bool wmi_requires_smbios_request;

MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
MODULE_ALIAS("wmi:"DELL_DESCRIPTOR_GUID);

struct dell_wmi_priv {
struct input_dev *input_dev;
u32 interface_version;
};

static int __init dmi_matched(const struct dmi_system_id *dmi)
Expand Down Expand Up @@ -348,6 +348,7 @@ static void dell_wmi_process_key(struct wmi_device *wdev, int type, int code)
static void dell_wmi_notify(struct wmi_device *wdev,
union acpi_object *obj)
{
struct dell_wmi_priv *priv = dev_get_drvdata(&wdev->dev);
u16 *buffer_entry, *buffer_end;
acpi_size buffer_size;
int len, i;
Expand Down Expand Up @@ -376,7 +377,7 @@ static void dell_wmi_notify(struct wmi_device *wdev,
* So to prevent reading garbage from buffer we will process only first
* one event on devices with WMI interface version 0.
*/
if (dell_wmi_interface_version == 0 && buffer_entry < buffer_end)
if (priv->interface_version == 0 && buffer_entry < buffer_end)
if (buffer_end > buffer_entry + buffer_entry[0] + 1)
buffer_end = buffer_entry + buffer_entry[0] + 1;

Expand Down Expand Up @@ -626,61 +627,67 @@ static void dell_wmi_input_destroy(struct wmi_device *wdev)
* WMI Interface Version 8 4 <version>
* WMI buffer length 12 4 4096
*/
static int dell_wmi_check_descriptor_buffer(void)
static int dell_wmi_check_descriptor_buffer(struct wmi_device *wdev)
{
struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
acpi_status status;
struct dell_wmi_priv *priv = dev_get_drvdata(&wdev->dev);
union acpi_object *obj = NULL;
struct wmi_device *desc_dev;
u32 *buffer;
int ret;

status = wmi_query_block(DELL_DESCRIPTOR_GUID, 0, &out);
if (ACPI_FAILURE(status)) {
pr_err("Cannot read Dell descriptor buffer - %d\n", status);
return status;
desc_dev = wmidev_get_other_guid(wdev, DELL_DESCRIPTOR_GUID);
if (!desc_dev) {
dev_err(&wdev->dev, "Dell WMI descriptor does not exist\n");
return -ENODEV;
}

obj = (union acpi_object *)out.pointer;
obj = wmidev_block_query(desc_dev, 0);
if (!obj) {
pr_err("Dell descriptor buffer is empty\n");
return -EINVAL;
dev_err(&wdev->dev, "failed to read Dell WMI descriptor\n");
ret = -EIO;
goto out;
}

if (obj->type != ACPI_TYPE_BUFFER) {
pr_err("Cannot read Dell descriptor buffer\n");
kfree(obj);
return -EINVAL;
dev_err(&wdev->dev, "Dell descriptor has wrong type\n");
ret = -EINVAL;
goto out;
}

if (obj->buffer.length != 128) {
pr_err("Dell descriptor buffer has invalid length (%d)\n",
dev_err(&wdev->dev,
"Dell descriptor buffer has invalid length (%d)\n",
obj->buffer.length);
if (obj->buffer.length < 16) {
kfree(obj);
return -EINVAL;
ret = -EINVAL;
goto out;
}
}

buffer = (u32 *)obj->buffer.pointer;

if (buffer[0] != 0x4C4C4544 && buffer[1] != 0x494D5720)
pr_warn("Dell descriptor buffer has invalid signature (%*ph)\n",
dev_warn(&wdev->dev, "Dell descriptor buffer has invalid signature (%*ph)\n",
8, buffer);

if (buffer[2] != 0 && buffer[2] != 1)
pr_warn("Dell descriptor buffer has unknown version (%d)\n",
dev_warn(&wdev->dev, "Dell descriptor buffer has unknown version (%d)\n",
buffer[2]);

if (buffer[3] != 4096)
pr_warn("Dell descriptor buffer has invalid buffer length (%d)\n",
dev_warn(&wdev->dev, "Dell descriptor buffer has invalid buffer length (%d)\n",
buffer[3]);

dell_wmi_interface_version = buffer[2];
priv->interface_version = buffer[2];
ret = 0;

pr_info("Detected Dell WMI interface version %u\n",
dell_wmi_interface_version);
dev_info(&wdev->dev, "Detected Dell WMI interface version %u\n",
priv->interface_version);

out:
kfree(obj);
return 0;
put_device(&desc_dev->dev);
return ret;
}

/*
Expand Down Expand Up @@ -717,17 +724,19 @@ static int dell_wmi_events_set_enabled(bool enable)

static int dell_wmi_probe(struct wmi_device *wdev)
{
struct dell_wmi_priv *priv;
int err;

struct dell_wmi_priv *priv = devm_kzalloc(
priv = devm_kzalloc(
&wdev->dev, sizeof(struct dell_wmi_priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
dev_set_drvdata(&wdev->dev, priv);

err = dell_wmi_check_descriptor_buffer();
err = dell_wmi_check_descriptor_buffer(wdev);
if (err)
return err;

dev_set_drvdata(&wdev->dev, priv);

return dell_wmi_input_setup(wdev);
}

Expand Down
30 changes: 22 additions & 8 deletions drivers/platform/x86/hp-wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,6 @@ enum hp_wmi_hardware_mask {
HPWMI_TABLET_MASK = 0x04,
};

#define BIOS_ARGS_INIT(write, ctype, size) \
(struct bios_args) { .signature = 0x55434553, \
.command = (write) ? 0x2 : 0x1, \
.commandtype = (ctype), \
.datasize = (size), \
.data = 0 }

struct bios_return {
u32 sigpass;
u32 return_code;
Expand Down Expand Up @@ -188,6 +181,22 @@ struct rfkill2_device {
static int rfkill2_count;
static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];

/* map output size to the corresponding WMI method id */
static inline int encode_outsize_for_pvsz(int outsize)
{
if (outsize > 4096)
return -EINVAL;
if (outsize > 1024)
return 5;
if (outsize > 128)
return 4;
if (outsize > 4)
return 3;
if (outsize > 0)
return 2;
return 1;
}

/*
* hp_wmi_perform_query
*
Expand All @@ -211,6 +220,7 @@ static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
void *buffer, int insize, int outsize)
{
int mid;
struct bios_return *bios_return;
int actual_outsize;
union acpi_object *obj;
Expand All @@ -225,11 +235,15 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
int ret = 0;

mid = encode_outsize_for_pvsz(outsize);
if (WARN_ON(mid < 0))
return mid;

if (WARN_ON(insize > sizeof(args.data)))
return -EINVAL;
memcpy(&args.data, buffer, insize);

wmi_evaluate_method(HPWMI_BIOS_GUID, 0, 0x3, &input, &output);
wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output);

obj = output.pointer;

Expand Down
2 changes: 1 addition & 1 deletion drivers/platform/x86/ibm_rtl.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ static void rtl_port_unmap(void __iomem *addr)
static int ibm_rtl_write(u8 value)
{
int ret = 0, count = 0;
static u32 cmd_port_val;
u32 cmd_port_val;

RTL_DEBUG("%s(%d)\n", __func__, value);

Expand Down
Loading

0 comments on commit 0e271fd

Please sign in to comment.