Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e271fd5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'platform-drivers-x86-v4.14-1' of git://git.infradead.org/linux-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
  ...
parents ee89252b 00ebbeb3
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -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
--------------
@@ -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.
+21 −19
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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;
@@ -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);
+2 −2
Original line number Diff line number Diff line
@@ -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))
@@ -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))
+39 −30
Original line number Diff line number Diff line
@@ -48,7 +48,6 @@ 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);
@@ -56,6 +55,7 @@ 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)
@@ -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;
@@ -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;

@@ -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;
}

/*
@@ -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);
}

+22 −8
Original line number Diff line number Diff line
@@ -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;
@@ -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
 *
@@ -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;
@@ -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;

Loading