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

Commit 33d519fe authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86

Pull x86 platform tree fixes from Matthew Garrett:
 "Small fixes to a couple of drivers plus a slightly larger number for
  sony-laptop that the maintainer thinks are appropriate, most of which
  fix problems with the earlier 3.5 updates.  These have been in -next
  for a while without complaint."

* 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86:
  intel_ips: blacklist HP ProBook laptops
  ideapad: uninitialized data in ideapad_acpi_add()
  sony-laptop: correct find_snc_handle failure checks
  sony-laptop: fix a couple signedness bugs
  sony-laptop: fix sony_nc_sysfs_store()
  sony-laptop: input initialization should be done before SNC
  sony-laptop: add lid backlight support for handle 0x143
  sony-laptop: store battery care limits on batteries
  sony-laptop: notify userspace of GFX switch position changes
  sony-laptop: use an enum for SNC event types
parents 05d290d6 88ca518b
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -694,10 +694,10 @@ MODULE_DEVICE_TABLE(acpi, ideapad_device_ids);
static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
{
	int ret, i;
	unsigned long cfg;
	int cfg;
	struct ideapad_private *priv;

	if (read_method_int(adevice->handle, "_CFG", (int *)&cfg))
	if (read_method_int(adevice->handle, "_CFG", &cfg))
		return -ENODEV;

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
@@ -721,7 +721,7 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
		goto input_failed;

	for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) {
		if (test_bit(ideapad_rfk_data[i].cfgbit, &cfg))
		if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg))
			ideapad_register_rfkill(adevice, i);
		else
			priv->rfk[i] = NULL;
+22 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@
#include <linux/string.h>
#include <linux/tick.h>
#include <linux/timer.h>
#include <linux/dmi.h>
#include <drm/i915_drm.h>
#include <asm/msr.h>
#include <asm/processor.h>
@@ -1485,6 +1486,24 @@ static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = {

MODULE_DEVICE_TABLE(pci, ips_id_table);

static int ips_blacklist_callback(const struct dmi_system_id *id)
{
	pr_info("Blacklisted intel_ips for %s\n", id->ident);
	return 1;
}

static const struct dmi_system_id ips_blacklist[] = {
	{
		.callback = ips_blacklist_callback,
		.ident = "HP ProBook",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
			DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook"),
		},
	},
	{ }	/* terminating entry */
};

static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	u64 platform_info;
@@ -1494,6 +1513,9 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
	u16 htshi, trc, trc_required_mask;
	u8 tse;

	if (dmi_check_system(ips_blacklist))
		return -ENODEV;

	ips = kzalloc(sizeof(struct ips_driver), GFP_KERNEL);
	if (!ips)
		return -ENOMEM;
+89 −47
Original line number Diff line number Diff line
@@ -973,7 +973,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev,
			       struct device_attribute *attr,
			       const char *buffer, size_t count)
{
	unsigned long value = 0;
	int value;
	int ret = 0;
	struct sony_nc_value *item =
	    container_of(attr, struct sony_nc_value, devattr);
@@ -984,7 +984,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev,
	if (count > 31)
		return -EINVAL;

	if (kstrtoul(buffer, 10, &value))
	if (kstrtoint(buffer, 10, &value))
		return -EINVAL;

	if (item->validate)
@@ -994,7 +994,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev,
		return value;

	ret = sony_nc_int_call(sony_nc_acpi_handle, *item->acpiset,
			(int *)&value, NULL);
			       &value, NULL);
	if (ret < 0)
		return -EIO;

@@ -1010,6 +1010,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev,
struct sony_backlight_props {
	struct backlight_device *dev;
	int			handle;
	int			cmd_base;
	u8			offset;
	u8			maxlvl;
};
@@ -1037,7 +1038,7 @@ static int sony_nc_get_brightness_ng(struct backlight_device *bd)
	struct sony_backlight_props *sdev =
		(struct sony_backlight_props *)bl_get_data(bd);

	sony_call_snc_handle(sdev->handle, 0x0200, &result);
	sony_call_snc_handle(sdev->handle, sdev->cmd_base + 0x100, &result);

	return (result & 0xff) - sdev->offset;
}
@@ -1049,7 +1050,8 @@ static int sony_nc_update_status_ng(struct backlight_device *bd)
		(struct sony_backlight_props *)bl_get_data(bd);

	value = bd->props.brightness + sdev->offset;
	if (sony_call_snc_handle(sdev->handle, 0x0100 | (value << 16), &result))
	if (sony_call_snc_handle(sdev->handle, sdev->cmd_base | (value << 0x10),
				&result))
		return -EIO;

	return value;
@@ -1172,6 +1174,11 @@ static int sony_nc_hotkeys_decode(u32 event, unsigned int handle)
/*
 * ACPI callbacks
 */
enum event_types {
	HOTKEY = 1,
	KILLSWITCH,
	GFX_SWITCH
};
static void sony_nc_notify(struct acpi_device *device, u32 event)
{
	u32 real_ev = event;
@@ -1196,7 +1203,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)
		/* hotkey event */
		case 0x0100:
		case 0x0127:
			ev_type = 1;
			ev_type = HOTKEY;
			real_ev = sony_nc_hotkeys_decode(event, handle);

			if (real_ev > 0)
@@ -1216,7 +1223,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)
			 * update the rfkill device status when the
			 * switch is moved.
			 */
			ev_type = 2;
			ev_type = KILLSWITCH;
			sony_call_snc_handle(handle, 0x0100, &result);
			real_ev = result & 0x03;

@@ -1226,6 +1233,24 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)

			break;

		case 0x0128:
		case 0x0146:
			/* Hybrid GFX switching */
			sony_call_snc_handle(handle, 0x0000, &result);
			dprintk("GFX switch event received (reason: %s)\n",
					(result & 0x01) ?
					"switch change" : "unknown");

			/* verify the switch state
			 * 1: discrete GFX
			 * 0: integrated GFX
			 */
			sony_call_snc_handle(handle, 0x0100, &result);

			ev_type = GFX_SWITCH;
			real_ev = result & 0xff;
			break;

		default:
			dprintk("Unknown event 0x%x for handle 0x%x\n",
					event, handle);
@@ -1238,7 +1263,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)

	} else {
		/* old style event */
		ev_type = 1;
		ev_type = HOTKEY;
		sony_laptop_report_input_event(real_ev);
	}

@@ -1893,32 +1918,33 @@ static ssize_t sony_nc_battery_care_limit_store(struct device *dev,
	 *  bits 4,5: store the limit into the EC
	 *  bits 6,7: store the limit into the battery
	 */
	cmd = 0;

	/*
	 * handle 0x0115 should allow storing on battery too;
	 * handle 0x0136 same as 0x0115 + health status;
	 * handle 0x013f, same as 0x0136 but no storing on the battery
	 *
	 * Store only inside the EC for now, regardless the handle number
	 */
	if (value == 0)
		/* disable limits */
		cmd = 0x0;

	else if (value <= 50)
		cmd = 0x21;
	if (value > 0) {
		if (value <= 50)
			cmd = 0x20;

		else if (value <= 80)
		cmd = 0x11;
			cmd = 0x10;

		else if (value <= 100)
		cmd = 0x31;
			cmd = 0x30;

		else
			return -EINVAL;

	if (sony_call_snc_handle(bcare_ctl->handle, (cmd << 0x10) | 0x0100,
				&result))
		/*
		 * handle 0x0115 should allow storing on battery too;
		 * handle 0x0136 same as 0x0115 + health status;
		 * handle 0x013f, same as 0x0136 but no storing on the battery
		 */
		if (bcare_ctl->handle != 0x013f)
			cmd = cmd | (cmd << 2);

		cmd = (cmd | 0x1) << 0x10;
	}

	if (sony_call_snc_handle(bcare_ctl->handle, cmd | 0x0100, &result))
		return -EIO;

	return count;
@@ -2113,7 +2139,7 @@ static ssize_t sony_nc_thermal_mode_show(struct device *dev,
		struct device_attribute *attr, char *buffer)
{
	ssize_t count = 0;
	unsigned int mode = sony_nc_thermal_mode_get();
	int mode = sony_nc_thermal_mode_get();

	if (mode < 0)
		return mode;
@@ -2472,6 +2498,7 @@ static void sony_nc_backlight_ng_read_limits(int handle,
{
	u64 offset;
	int i;
	int lvl_table_len = 0;
	u8 min = 0xff, max = 0x00;
	unsigned char buffer[32] = { 0 };

@@ -2480,8 +2507,6 @@ static void sony_nc_backlight_ng_read_limits(int handle,
	props->maxlvl = 0xff;

	offset = sony_find_snc_handle(handle);
	if (offset < 0)
		return;

	/* try to read the boundaries from ACPI tables, if we fail the above
	 * defaults should be reasonable
@@ -2491,11 +2516,21 @@ static void sony_nc_backlight_ng_read_limits(int handle,
	if (i < 0)
		return;

	switch (handle) {
	case 0x012f:
	case 0x0137:
		lvl_table_len = 9;
		break;
	case 0x143:
		lvl_table_len = 16;
		break;
	}

	/* the buffer lists brightness levels available, brightness levels are
	 * from position 0 to 8 in the array, other values are used by ALS
	 * control.
	 */
	for (i = 0; i < 9 && i < ARRAY_SIZE(buffer); i++) {
	for (i = 0; i < lvl_table_len && i < ARRAY_SIZE(buffer); i++) {

		dprintk("Brightness level: %d\n", buffer[i]);

@@ -2520,16 +2555,24 @@ static void sony_nc_backlight_setup(void)
	const struct backlight_ops *ops = NULL;
	struct backlight_properties props;

	if (sony_find_snc_handle(0x12f) != -1) {
	if (sony_find_snc_handle(0x12f) >= 0) {
		ops = &sony_backlight_ng_ops;
		sony_bl_props.cmd_base = 0x0100;
		sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props);
		max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset;

	} else if (sony_find_snc_handle(0x137) != -1) {
	} else if (sony_find_snc_handle(0x137) >= 0) {
		ops = &sony_backlight_ng_ops;
		sony_bl_props.cmd_base = 0x0100;
		sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props);
		max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset;

	} else if (sony_find_snc_handle(0x143) >= 0) {
		ops = &sony_backlight_ng_ops;
		sony_bl_props.cmd_base = 0x3000;
		sony_nc_backlight_ng_read_limits(0x143, &sony_bl_props);
		max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset;

	} else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
						&unused))) {
		ops = &sony_backlight_ops;
@@ -2597,6 +2640,12 @@ static int sony_nc_add(struct acpi_device *device)
		}
	}

	result = sony_laptop_setup_input(device);
	if (result) {
		pr_err("Unable to create input devices\n");
		goto outplatform;
	}

	if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
					 &handle))) {
		int arg = 1;
@@ -2614,12 +2663,6 @@ static int sony_nc_add(struct acpi_device *device)
	}

	/* setup input devices and helper fifo */
	result = sony_laptop_setup_input(device);
	if (result) {
		pr_err("Unable to create input devices\n");
		goto outsnc;
	}

	if (acpi_video_backlight_support()) {
		pr_info("brightness ignored, must be controlled by ACPI video driver\n");
	} else {
@@ -2672,13 +2715,12 @@ static int sony_nc_add(struct acpi_device *device)
		device_remove_file(&sony_pf_device->dev, &item->devattr);
	}
	sony_nc_backlight_cleanup();

	sony_laptop_remove_input();

      outsnc:
	sony_nc_function_cleanup(sony_pf_device);
	sony_nc_handles_cleanup(sony_pf_device);

outplatform:
	sony_laptop_remove_input();

outpresent:
	sony_pf_remove();