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

Pull x86 platform driver updates from Matthew Garrett:
 "Nothing overly exciting here - a couple of new drivers that don't do a
  great deal, along with some miscellaneous fixes and a couple of small
  feature enablement patches"

* 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86:
  x86 platform drivers: fix gpio leak
  toshiba_acpi: Add dependency on SERIO_I8042
  asus-nb-wmi: set wapf=4 for ASUSTeK COMPUTER INC. 1015E/U
  Add trivial driver to disable Intel Smart Connect
  Add support driver for Intel Rapid Start Technology
  hp-wmi: add supports for POST code error
  asus-wmi: control wlan-led only if wapf == 4
  drivers/platform/x86/intel_ips: Convert to module_pci_driver
  asus-nb-wmi: ignore ALS notification key code
  asus-wmi: append newline to messages
  x86: asus-laptop: fix invalid point access
  x86: msi-laptop: fix memleak
  amilo-rfkill: Add dependency on SERIO_I8042
  dell-laptop: fix error return code in dell_init()
  hp-wmi: Enable hotkeys on some systems
diff --git a/Documentation/ABI/testing/sysfs-driver-intel-rapid-start b/Documentation/ABI/testing/sysfs-driver-intel-rapid-start
new file mode 100644
index 0000000..5a7d2e2
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-intel-rapid-start
@@ -0,0 +1,21 @@
+What:		/sys/bus/acpi/intel-rapid-start/wakeup_events
+Date:		July 2, 2013
+KernelVersion:	3.11
+Contact:	Matthew Garrett <mjg59@srcf.ucam.org>
+Description:	An integer representing a set of wakeup events as follows:
+		1: Wake to enter hibernation when the wakeup timer expires
+		2: Wake to enter hibernation when the battery reaches a
+		critical level
+
+		These values are ORed together. For example, a value of 3
+		indicates that the system will wake to enter hibernation when
+		either the wakeup timer expires or the battery reaches a
+		critical level.
+
+What:		/sys/bus/acpi/intel-rapid-start/wakeup_time
+Date:		July 2, 2013
+KernelVersion:	3.11
+Contact:	Matthew Garrett <mjg59@srcf.ucam.org>
+Description:	An integer representing the length of time the system will
+		remain asleep before waking up to enter hibernation.
+		This value is in minutes.
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 8577261..36a9e60 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -176,6 +176,7 @@
 config AMILO_RFKILL
 	tristate "Fujitsu-Siemens Amilo rfkill support"
 	depends on RFKILL
+	depends on SERIO_I8042
 	---help---
 	  This is a driver for enabling wifi on some Fujitsu-Siemens Amilo
 	  laptops.
@@ -591,6 +592,7 @@
 	depends on BACKLIGHT_CLASS_DEVICE
 	depends on INPUT
 	depends on RFKILL || RFKILL = n
+	depends on SERIO_I8042 || SERIO_I8042 = n
 	select INPUT_POLLDEV
 	select INPUT_SPARSEKMAP
 	---help---
@@ -781,6 +783,32 @@
 	  graphics as well as the backlight. Currently only backlight
 	  control is supported by the driver.
 
+config INTEL_RST
+        tristate "Intel Rapid Start Technology Driver"
+	depends on ACPI
+	---help---
+	  This driver provides support for modifying paramaters on systems
+	  equipped with Intel's Rapid Start Technology. When put in an ACPI
+	  sleep state, these devices will wake after either a configured
+	  timeout or when the system battery reaches a critical state,
+	  automatically copying memory contents to disk. On resume, the
+	  firmware will copy the memory contents back to RAM and resume the OS
+	  as usual.
+
+config INTEL_SMARTCONNECT
+        tristate "Intel Smart Connect disabling driver"
+	depends on ACPI
+	---help---
+	  Intel Smart Connect is a technology intended to permit devices to
+	  update state by resuming for a short period of time at regular
+	  intervals. If a user enables this functionality under Windows and
+	  then reboots into Linux, the system may remain configured to resume
+	  on suspend. In the absence of any userspace to support it, the system
+	  will then remain awake until something triggers another suspend.
+
+	  This driver checks to determine whether the device has Intel Smart
+	  Connect enabled, and if so disables it.
+
 config PVPANIC
 	tristate "pvpanic device support"
 	depends on ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index ef0ec74..5dbe1932 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -51,5 +51,7 @@
 obj-$(CONFIG_SAMSUNG_Q10)	+= samsung-q10.o
 obj-$(CONFIG_APPLE_GMUX)	+= apple-gmux.o
 obj-$(CONFIG_CHROMEOS_LAPTOP)	+= chromeos_laptop.o
+obj-$(CONFIG_INTEL_RST)		+= intel-rst.o
+obj-$(CONFIG_INTEL_SMARTCONNECT)	+= intel-smartconnect.o
 
 obj-$(CONFIG_PVPANIC)           += pvpanic.o
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index 0eea09c..8e268da 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -1935,7 +1935,6 @@
 fail_backlight:
 	asus_platform_exit(asus);
 fail_platform:
-	kfree(asus->name);
 	kfree(asus);
 
 	return result;
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 8fcb41e..563f59e 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -180,6 +180,24 @@
 		},
 		.driver_data = &quirk_asus_x401u,
 	},
+	{
+		.callback = dmi_matched,
+		.ident = "ASUSTeK COMPUTER INC. 1015E",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "1015E"),
+		},
+		.driver_data = &quirk_asus_x401u,
+	},
+	{
+		.callback = dmi_matched,
+		.ident = "ASUSTeK COMPUTER INC. 1015U",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "1015U"),
+		},
+		.driver_data = &quirk_asus_x401u,
+	},
 	{},
 };
 
@@ -256,6 +274,7 @@
 	{ KE_KEY, 0xB5, { KEY_CALC } },
 	{ KE_KEY, 0xC4, { KEY_KBDILLUMUP } },
 	{ KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } },
+	{ KE_IGNORE, 0xC6, },  /* Ambient Light Sensor notification */
 	{ KE_END, 0},
 };
 
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index c11b242..19c313b 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -558,7 +558,7 @@
 			goto error;
 	}
 
-	if (wlan_led_presence(asus)) {
+	if (wlan_led_presence(asus) && (asus->driver->quirks->wapf == 4)) {
 		INIT_WORK(&asus->wlan_led_work, wlan_led_update);
 
 		asus->wlan_led.name = "asus::wlan";
@@ -886,7 +886,8 @@
 	if (!*rfkill)
 		return -EINVAL;
 
-	if (dev_id == ASUS_WMI_DEVID_WLAN)
+	if ((dev_id == ASUS_WMI_DEVID_WLAN) &&
+			(asus->driver->quirks->wapf == 4))
 		rfkill_set_led_trigger_name(*rfkill, "asus-wlan");
 
 	rfkill_init_sw_state(*rfkill, !result);
@@ -1045,7 +1046,7 @@
 	else if (value == 3)
 		value = 255;
 	else if (value != 0) {
-		pr_err("Unknown fan speed %#x", value);
+		pr_err("Unknown fan speed %#x\n", value);
 		value = -1;
 	}
 
@@ -1557,11 +1558,11 @@
 
 	/* INIT enable hotkeys on some models */
 	if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv))
-		pr_info("Initialization: %#x", rv);
+		pr_info("Initialization: %#x\n", rv);
 
 	/* We don't know yet what to do with this version... */
 	if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) {
-		pr_info("BIOS WMI version: %d.%d", rv >> 16, rv & 0xFF);
+		pr_info("BIOS WMI version: %d.%d\n", rv >> 16, rv & 0xFF);
 		asus->spec = rv;
 	}
 
@@ -1572,7 +1573,7 @@
 	 * The significance of others is yet to be found.
 	 */
 	if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) {
-		pr_info("SFUN value: %#x", rv);
+		pr_info("SFUN value: %#x\n", rv);
 		asus->sfun = rv;
 	}
 
@@ -1712,7 +1713,7 @@
 
 	asus->debug.root = debugfs_create_dir(asus->driver->name, NULL);
 	if (!asus->debug.root) {
-		pr_err("failed to create debugfs directory");
+		pr_err("failed to create debugfs directory\n");
 		goto error_debugfs;
 	}
 
@@ -1985,17 +1986,17 @@
 static int __init asus_wmi_init(void)
 {
 	if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
-		pr_info("Asus Management GUID not found");
+		pr_info("Asus Management GUID not found\n");
 		return -ENODEV;
 	}
 
-	pr_info("ASUS WMI generic driver loaded");
+	pr_info("ASUS WMI generic driver loaded\n");
 	return 0;
 }
 
 static void __exit asus_wmi_exit(void)
 {
-	pr_info("ASUS WMI generic driver unloaded");
+	pr_info("ASUS WMI generic driver unloaded\n");
 }
 
 module_init(asus_wmi_init);
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 1134119..bb77e18 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -551,9 +551,10 @@
 	 * is passed to SMI handler.
 	 */
 	bufferpage = alloc_page(GFP_KERNEL | GFP_DMA32);
-
-	if (!bufferpage)
+	if (!bufferpage) {
+		ret = -ENOMEM;
 		goto fail_buffer;
+	}
 	buffer = page_address(bufferpage);
 
 	if (quirks && quirks->touchpad_led)
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index d111c86..97bb05e 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -53,8 +53,10 @@
 #define HPWMI_ALS_QUERY 0x3
 #define HPWMI_HARDWARE_QUERY 0x4
 #define HPWMI_WIRELESS_QUERY 0x5
+#define HPWMI_BIOS_QUERY 0x9
 #define HPWMI_HOTKEY_QUERY 0xc
 #define HPWMI_WIRELESS2_QUERY 0x1b
+#define HPWMI_POSTCODEERROR_QUERY 0x2a
 
 enum hp_wmi_radio {
 	HPWMI_WIFI = 0,
@@ -291,6 +293,19 @@
 	return (state & 0x4) ? 1 : 0;
 }
 
+static int hp_wmi_enable_hotkeys(void)
+{
+	int ret;
+	int query = 0x6e;
+
+	ret = hp_wmi_perform_query(HPWMI_BIOS_QUERY, 1, &query, sizeof(query),
+				   0);
+
+	if (ret)
+		return -EINVAL;
+	return 0;
+}
+
 static int hp_wmi_set_block(void *data, bool blocked)
 {
 	enum hp_wmi_radio r = (enum hp_wmi_radio) data;
@@ -386,6 +401,16 @@
 	return 0;
 }
 
+static int hp_wmi_post_code_state(void)
+{
+	int state = 0;
+	int ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, 0, &state,
+				       sizeof(state), sizeof(state));
+	if (ret)
+		return -EINVAL;
+	return state;
+}
+
 static ssize_t show_display(struct device *dev, struct device_attribute *attr,
 			    char *buf)
 {
@@ -431,6 +456,16 @@
 	return sprintf(buf, "%d\n", value);
 }
 
+static ssize_t show_postcode(struct device *dev, struct device_attribute *attr,
+			 char *buf)
+{
+	/* Get the POST error code of previous boot failure. */
+	int value = hp_wmi_post_code_state();
+	if (value < 0)
+		return -EINVAL;
+	return sprintf(buf, "0x%x\n", value);
+}
+
 static ssize_t set_als(struct device *dev, struct device_attribute *attr,
 		       const char *buf, size_t count)
 {
@@ -443,11 +478,33 @@
 	return count;
 }
 
+static ssize_t set_postcode(struct device *dev, struct device_attribute *attr,
+		       const char *buf, size_t count)
+{
+	int ret;
+	u32 tmp;
+	long unsigned int tmp2;
+
+	ret = kstrtoul(buf, 10, &tmp2);
+	if (ret || tmp2 != 1)
+		return -EINVAL;
+
+	/* Clear the POST error code. It is kept until until cleared. */
+	tmp = (u32) tmp2;
+	ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, 1, &tmp,
+				       sizeof(tmp), sizeof(tmp));
+	if (ret)
+		return -EINVAL;
+
+	return count;
+}
+
 static DEVICE_ATTR(display, S_IRUGO, show_display, NULL);
 static DEVICE_ATTR(hddtemp, S_IRUGO, show_hddtemp, NULL);
 static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als);
 static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL);
 static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL);
+static DEVICE_ATTR(postcode, S_IRUGO | S_IWUSR, show_postcode, set_postcode);
 
 static void hp_wmi_notify(u32 value, void *context)
 {
@@ -628,6 +685,7 @@
 	device_remove_file(&device->dev, &dev_attr_als);
 	device_remove_file(&device->dev, &dev_attr_dock);
 	device_remove_file(&device->dev, &dev_attr_tablet);
+	device_remove_file(&device->dev, &dev_attr_postcode);
 }
 
 static int hp_wmi_rfkill_setup(struct platform_device *device)
@@ -845,6 +903,9 @@
 	err = device_create_file(&device->dev, &dev_attr_tablet);
 	if (err)
 		goto add_sysfs_error;
+	err = device_create_file(&device->dev, &dev_attr_postcode);
+	if (err)
+		goto add_sysfs_error;
 	return 0;
 
 add_sysfs_error:
@@ -948,6 +1009,8 @@
 		err = hp_wmi_input_setup();
 		if (err)
 			return err;
+
+		hp_wmi_enable_hotkeys();
 	}
 
 	if (bios_capable) {
diff --git a/drivers/platform/x86/intel-rst.c b/drivers/platform/x86/intel-rst.c
new file mode 100644
index 0000000..9385afd
--- /dev/null
+++ b/drivers/platform/x86/intel-rst.c
@@ -0,0 +1,209 @@
+/*
+ *  Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <acpi/acpi_drivers.h>
+
+MODULE_LICENSE("GPL");
+
+static ssize_t irst_show_wakeup_events(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	struct acpi_device *acpi;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *result;
+	acpi_status status;
+
+	acpi = to_acpi_device(dev);
+
+	status = acpi_evaluate_object(acpi->handle, "GFFS", NULL, &output);
+	if (!ACPI_SUCCESS(status))
+		return -EINVAL;
+
+	result = output.pointer;
+
+	if (result->type != ACPI_TYPE_INTEGER) {
+		kfree(result);
+		return -EINVAL;
+	}
+
+	return sprintf(buf, "%lld\n", result->integer.value);
+}
+
+static ssize_t irst_store_wakeup_events(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	struct acpi_device *acpi;
+	struct acpi_object_list input;
+	union acpi_object param;
+	acpi_status status;
+	unsigned long value;
+	int error;
+
+	acpi = to_acpi_device(dev);
+
+	error = kstrtoul(buf, 0, &value);
+
+	if (error)
+		return error;
+
+	param.type = ACPI_TYPE_INTEGER;
+	param.integer.value = value;
+
+	input.count = 1;
+	input.pointer = &param;
+
+	status = acpi_evaluate_object(acpi->handle, "SFFS", &input, NULL);
+
+	if (!ACPI_SUCCESS(status))
+		return -EINVAL;
+
+	return count;
+}
+
+static struct device_attribute irst_wakeup_attr = {
+	.attr = { .name = "wakeup_events", .mode = 0600 },
+	.show = irst_show_wakeup_events,
+	.store = irst_store_wakeup_events
+};
+
+static ssize_t irst_show_wakeup_time(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct acpi_device *acpi;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *result;
+	acpi_status status;
+
+	acpi = to_acpi_device(dev);
+
+	status = acpi_evaluate_object(acpi->handle, "GFTV", NULL, &output);
+	if (!ACPI_SUCCESS(status))
+		return -EINVAL;
+
+	result = output.pointer;
+
+	if (result->type != ACPI_TYPE_INTEGER) {
+		kfree(result);
+		return -EINVAL;
+	}
+
+	return sprintf(buf, "%lld\n", result->integer.value);
+}
+
+static ssize_t irst_store_wakeup_time(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	struct acpi_device *acpi;
+	struct acpi_object_list input;
+	union acpi_object param;
+	acpi_status status;
+	unsigned long value;
+	int error;
+
+	acpi = to_acpi_device(dev);
+
+	error = kstrtoul(buf, 0, &value);
+
+	if (error)
+		return error;
+
+	param.type = ACPI_TYPE_INTEGER;
+	param.integer.value = value;
+
+	input.count = 1;
+	input.pointer = &param;
+
+	status = acpi_evaluate_object(acpi->handle, "SFTV", &input, NULL);
+
+	if (!ACPI_SUCCESS(status))
+		return -EINVAL;
+
+	return count;
+}
+
+static struct device_attribute irst_timeout_attr = {
+	.attr = { .name = "wakeup_time", .mode = 0600 },
+	.show = irst_show_wakeup_time,
+	.store = irst_store_wakeup_time
+};
+
+static int irst_add(struct acpi_device *acpi)
+{
+	int error = 0;
+
+	error = device_create_file(&acpi->dev, &irst_timeout_attr);
+	if (error)
+		goto out;
+
+	error = device_create_file(&acpi->dev, &irst_wakeup_attr);
+	if (error)
+		goto out_timeout;
+
+	return 0;
+
+out_timeout:
+	device_remove_file(&acpi->dev, &irst_timeout_attr);
+out:
+	return error;
+}
+
+static int irst_remove(struct acpi_device *acpi)
+{
+	device_remove_file(&acpi->dev, &irst_wakeup_attr);
+	device_remove_file(&acpi->dev, &irst_timeout_attr);
+
+	return 0;
+}
+
+static const struct acpi_device_id irst_ids[] = {
+	{"INT3392", 0},
+	{"", 0}
+};
+
+static struct acpi_driver irst_driver = {
+	.owner = THIS_MODULE,
+	.name = "intel_rapid_start",
+	.class = "intel_rapid_start",
+	.ids = irst_ids,
+	.ops = {
+		.add = irst_add,
+		.remove = irst_remove,
+	},
+};
+
+static int irst_init(void)
+{
+	return acpi_bus_register_driver(&irst_driver);
+}
+
+static void irst_exit(void)
+{
+	acpi_bus_unregister_driver(&irst_driver);
+}
+
+module_init(irst_init);
+module_exit(irst_exit);
+
+MODULE_DEVICE_TABLE(acpi, irst_ids);
diff --git a/drivers/platform/x86/intel-smartconnect.c b/drivers/platform/x86/intel-smartconnect.c
new file mode 100644
index 0000000..f74e93d
--- /dev/null
+++ b/drivers/platform/x86/intel-smartconnect.c
@@ -0,0 +1,90 @@
+/*
+ *  Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <acpi/acpi_drivers.h>
+
+MODULE_LICENSE("GPL");
+
+static int smartconnect_acpi_init(struct acpi_device *acpi)
+{
+	struct acpi_object_list input;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *result;
+	union acpi_object param;
+	acpi_status status;
+
+	status = acpi_evaluate_object(acpi->handle, "GAOS", NULL, &output);
+	if (!ACPI_SUCCESS(status))
+		return -EINVAL;
+
+	result = output.pointer;
+
+	if (result->type != ACPI_TYPE_INTEGER) {
+		kfree(result);
+		return -EINVAL;
+	}
+
+	if (result->integer.value & 0x1) {
+		param.type = ACPI_TYPE_INTEGER;
+		param.integer.value = 0;
+
+		input.count = 1;
+		input.pointer = &param;
+
+		dev_info(&acpi->dev, "Disabling Intel Smart Connect\n");
+		status = acpi_evaluate_object(acpi->handle, "SAOS", &input,
+					      NULL);
+	}
+
+	kfree(result);
+
+	return 0;
+}
+
+static const struct acpi_device_id smartconnect_ids[] = {
+	{"INT33A0", 0},
+	{"", 0}
+};
+
+static struct acpi_driver smartconnect_driver = {
+	.owner = THIS_MODULE,
+	.name = "intel_smart_connect",
+	.class = "intel_smart_connect",
+	.ids = smartconnect_ids,
+	.ops = {
+		.add = smartconnect_acpi_init,
+	},
+};
+
+static int smartconnect_init(void)
+{
+	return acpi_bus_register_driver(&smartconnect_driver);
+}
+
+static void smartconnect_exit(void)
+{
+	acpi_bus_unregister_driver(&smartconnect_driver);
+}
+
+module_init(smartconnect_init);
+module_exit(smartconnect_exit);
+
+MODULE_DEVICE_TABLE(acpi, smartconnect_ids);
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 5051aa9..18dcb58 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -1731,18 +1731,7 @@
 	.shutdown = ips_shutdown,
 };
 
-static int __init ips_init(void)
-{
-	return pci_register_driver(&ips_pci_driver);
-}
-module_init(ips_init);
-
-static void ips_exit(void)
-{
-	pci_unregister_driver(&ips_pci_driver);
-	return;
-}
-module_exit(ips_exit);
+module_pci_driver(ips_pci_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jesse Barnes <jbarnes@virtuousgeek.org>");
diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c
index 6f4b728..2805988 100644
--- a/drivers/platform/x86/intel_pmic_gpio.c
+++ b/drivers/platform/x86/intel_pmic_gpio.c
@@ -288,7 +288,7 @@
 	retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg);
 	if (retval) {
 		pr_warn("Interrupt request failed\n");
-		goto err;
+		goto fail_request_irq;
 	}
 
 	for (i = 0; i < 8; i++) {
@@ -299,6 +299,10 @@
 		irq_set_chip_data(i + pg->irq_base, pg);
 	}
 	return 0;
+
+fail_request_irq:
+	if (gpiochip_remove(&pg->chip))
+		pr_err("gpiochip_remove failed\n");
 err:
 	iounmap(pg->gpiointr);
 err2:
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c
index 6b22938..62f8030 100644
--- a/drivers/platform/x86/msi-laptop.c
+++ b/drivers/platform/x86/msi-laptop.c
@@ -1098,29 +1098,29 @@
 
 	ret = platform_device_add(msipf_device);
 	if (ret)
-		goto fail_platform_device1;
+		goto fail_device_add;
 
 	if (quirks->load_scm_model && (load_scm_model_init(msipf_device) < 0)) {
 		ret = -EINVAL;
-		goto fail_platform_device1;
+		goto fail_scm_model_init;
 	}
 
 	ret = sysfs_create_group(&msipf_device->dev.kobj,
 				 &msipf_attribute_group);
 	if (ret)
-		goto fail_platform_device2;
+		goto fail_create_group;
 
 	if (!quirks->old_ec_model) {
 		if (threeg_exists)
 			ret = device_create_file(&msipf_device->dev,
 						&dev_attr_threeg);
 		if (ret)
-			goto fail_platform_device2;
+			goto fail_create_attr;
 	} else {
 		ret = sysfs_create_group(&msipf_device->dev.kobj,
 					 &msipf_old_attribute_group);
 		if (ret)
-			goto fail_platform_device2;
+			goto fail_create_attr;
 
 		/* Disable automatic brightness control by default because
 		 * this module was probably loaded to do brightness control in
@@ -1134,26 +1134,22 @@
 
 	return 0;
 
-fail_platform_device2:
-
+fail_create_attr:
+	sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
+fail_create_group:
 	if (quirks->load_scm_model) {
 		i8042_remove_filter(msi_laptop_i8042_filter);
 		cancel_delayed_work_sync(&msi_rfkill_dwork);
 		cancel_work_sync(&msi_rfkill_work);
 		rfkill_cleanup();
 	}
+fail_scm_model_init:
 	platform_device_del(msipf_device);
-
-fail_platform_device1:
-
+fail_device_add:
 	platform_device_put(msipf_device);
-
 fail_platform_driver:
-
 	platform_driver_unregister(&msipf_driver);
-
 fail_backlight:
-
 	backlight_device_unregister(msibl_device);
 
 	return ret;