aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-13 21:08:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-13 21:08:23 -0400
commit63345b4794aef4ebe16502cfe35b02bc9822d763 (patch)
tree758a127bad6b1035d4878c9a7a1cc7fac167b3b3
parent18fb38e2f58ff7a66e30cbb71af81425edf1c9a1 (diff)
parentfef8ce166b2d5cdba8bbf85fa48c4cb8d75ffec4 (diff)
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
-rw-r--r--Documentation/ABI/testing/sysfs-driver-intel-rapid-start21
-rw-r--r--drivers/platform/x86/Kconfig28
-rw-r--r--drivers/platform/x86/Makefile2
-rw-r--r--drivers/platform/x86/asus-laptop.c1
-rw-r--r--drivers/platform/x86/asus-nb-wmi.c19
-rw-r--r--drivers/platform/x86/asus-wmi.c21
-rw-r--r--drivers/platform/x86/dell-laptop.c5
-rw-r--r--drivers/platform/x86/hp-wmi.c63
-rw-r--r--drivers/platform/x86/intel-rst.c209
-rw-r--r--drivers/platform/x86/intel-smartconnect.c90
-rw-r--r--drivers/platform/x86/intel_ips.c13
-rw-r--r--drivers/platform/x86/intel_pmic_gpio.c6
-rw-r--r--drivers/platform/x86/msi-laptop.c24
13 files changed, 462 insertions, 40 deletions
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 000000000000..5a7d2e217d40
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-intel-rapid-start
@@ -0,0 +1,21 @@
1What: /sys/bus/acpi/intel-rapid-start/wakeup_events
2Date: July 2, 2013
3KernelVersion: 3.11
4Contact: Matthew Garrett <mjg59@srcf.ucam.org>
5Description: An integer representing a set of wakeup events as follows:
6 1: Wake to enter hibernation when the wakeup timer expires
7 2: Wake to enter hibernation when the battery reaches a
8 critical level
9
10 These values are ORed together. For example, a value of 3
11 indicates that the system will wake to enter hibernation when
12 either the wakeup timer expires or the battery reaches a
13 critical level.
14
15What: /sys/bus/acpi/intel-rapid-start/wakeup_time
16Date: July 2, 2013
17KernelVersion: 3.11
18Contact: Matthew Garrett <mjg59@srcf.ucam.org>
19Description: An integer representing the length of time the system will
20 remain asleep before waking up to enter hibernation.
21 This value is in minutes.
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 85772616efbf..36a9e6023395 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -176,6 +176,7 @@ config FUJITSU_TABLET
176config AMILO_RFKILL 176config AMILO_RFKILL
177 tristate "Fujitsu-Siemens Amilo rfkill support" 177 tristate "Fujitsu-Siemens Amilo rfkill support"
178 depends on RFKILL 178 depends on RFKILL
179 depends on SERIO_I8042
179 ---help--- 180 ---help---
180 This is a driver for enabling wifi on some Fujitsu-Siemens Amilo 181 This is a driver for enabling wifi on some Fujitsu-Siemens Amilo
181 laptops. 182 laptops.
@@ -591,6 +592,7 @@ config ACPI_TOSHIBA
591 depends on BACKLIGHT_CLASS_DEVICE 592 depends on BACKLIGHT_CLASS_DEVICE
592 depends on INPUT 593 depends on INPUT
593 depends on RFKILL || RFKILL = n 594 depends on RFKILL || RFKILL = n
595 depends on SERIO_I8042 || SERIO_I8042 = n
594 select INPUT_POLLDEV 596 select INPUT_POLLDEV
595 select INPUT_SPARSEKMAP 597 select INPUT_SPARSEKMAP
596 ---help--- 598 ---help---
@@ -781,6 +783,32 @@ config APPLE_GMUX
781 graphics as well as the backlight. Currently only backlight 783 graphics as well as the backlight. Currently only backlight
782 control is supported by the driver. 784 control is supported by the driver.
783 785
786config INTEL_RST
787 tristate "Intel Rapid Start Technology Driver"
788 depends on ACPI
789 ---help---
790 This driver provides support for modifying paramaters on systems
791 equipped with Intel's Rapid Start Technology. When put in an ACPI
792 sleep state, these devices will wake after either a configured
793 timeout or when the system battery reaches a critical state,
794 automatically copying memory contents to disk. On resume, the
795 firmware will copy the memory contents back to RAM and resume the OS
796 as usual.
797
798config INTEL_SMARTCONNECT
799 tristate "Intel Smart Connect disabling driver"
800 depends on ACPI
801 ---help---
802 Intel Smart Connect is a technology intended to permit devices to
803 update state by resuming for a short period of time at regular
804 intervals. If a user enables this functionality under Windows and
805 then reboots into Linux, the system may remain configured to resume
806 on suspend. In the absence of any userspace to support it, the system
807 will then remain awake until something triggers another suspend.
808
809 This driver checks to determine whether the device has Intel Smart
810 Connect enabled, and if so disables it.
811
784config PVPANIC 812config PVPANIC
785 tristate "pvpanic device support" 813 tristate "pvpanic device support"
786 depends on ACPI 814 depends on ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index ef0ec746f78c..5dbe19324351 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -51,5 +51,7 @@ obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o
51obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o 51obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o
52obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o 52obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o
53obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o 53obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o
54obj-$(CONFIG_INTEL_RST) += intel-rst.o
55obj-$(CONFIG_INTEL_SMARTCONNECT) += intel-smartconnect.o
54 56
55obj-$(CONFIG_PVPANIC) += pvpanic.o 57obj-$(CONFIG_PVPANIC) += pvpanic.o
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index 0eea09c1c134..8e268da6fdbd 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -1935,7 +1935,6 @@ fail_input:
1935fail_backlight: 1935fail_backlight:
1936 asus_platform_exit(asus); 1936 asus_platform_exit(asus);
1937fail_platform: 1937fail_platform:
1938 kfree(asus->name);
1939 kfree(asus); 1938 kfree(asus);
1940 1939
1941 return result; 1940 return result;
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 8fcb41e18b9c..563f59efa669 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -180,6 +180,24 @@ static struct dmi_system_id asus_quirks[] = {
180 }, 180 },
181 .driver_data = &quirk_asus_x401u, 181 .driver_data = &quirk_asus_x401u,
182 }, 182 },
183 {
184 .callback = dmi_matched,
185 .ident = "ASUSTeK COMPUTER INC. 1015E",
186 .matches = {
187 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
188 DMI_MATCH(DMI_PRODUCT_NAME, "1015E"),
189 },
190 .driver_data = &quirk_asus_x401u,
191 },
192 {
193 .callback = dmi_matched,
194 .ident = "ASUSTeK COMPUTER INC. 1015U",
195 .matches = {
196 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
197 DMI_MATCH(DMI_PRODUCT_NAME, "1015U"),
198 },
199 .driver_data = &quirk_asus_x401u,
200 },
183 {}, 201 {},
184}; 202};
185 203
@@ -256,6 +274,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
256 { KE_KEY, 0xB5, { KEY_CALC } }, 274 { KE_KEY, 0xB5, { KEY_CALC } },
257 { KE_KEY, 0xC4, { KEY_KBDILLUMUP } }, 275 { KE_KEY, 0xC4, { KEY_KBDILLUMUP } },
258 { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } }, 276 { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } },
277 { KE_IGNORE, 0xC6, }, /* Ambient Light Sensor notification */
259 { KE_END, 0}, 278 { KE_END, 0},
260}; 279};
261 280
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index c11b2426dac1..19c313b056c3 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -558,7 +558,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
558 goto error; 558 goto error;
559 } 559 }
560 560
561 if (wlan_led_presence(asus)) { 561 if (wlan_led_presence(asus) && (asus->driver->quirks->wapf == 4)) {
562 INIT_WORK(&asus->wlan_led_work, wlan_led_update); 562 INIT_WORK(&asus->wlan_led_work, wlan_led_update);
563 563
564 asus->wlan_led.name = "asus::wlan"; 564 asus->wlan_led.name = "asus::wlan";
@@ -886,7 +886,8 @@ static int asus_new_rfkill(struct asus_wmi *asus,
886 if (!*rfkill) 886 if (!*rfkill)
887 return -EINVAL; 887 return -EINVAL;
888 888
889 if (dev_id == ASUS_WMI_DEVID_WLAN) 889 if ((dev_id == ASUS_WMI_DEVID_WLAN) &&
890 (asus->driver->quirks->wapf == 4))
890 rfkill_set_led_trigger_name(*rfkill, "asus-wlan"); 891 rfkill_set_led_trigger_name(*rfkill, "asus-wlan");
891 892
892 rfkill_init_sw_state(*rfkill, !result); 893 rfkill_init_sw_state(*rfkill, !result);
@@ -1045,7 +1046,7 @@ static ssize_t asus_hwmon_pwm1(struct device *dev,
1045 else if (value == 3) 1046 else if (value == 3)
1046 value = 255; 1047 value = 255;
1047 else if (value != 0) { 1048 else if (value != 0) {
1048 pr_err("Unknown fan speed %#x", value); 1049 pr_err("Unknown fan speed %#x\n", value);
1049 value = -1; 1050 value = -1;
1050 } 1051 }
1051 1052
@@ -1557,11 +1558,11 @@ static int asus_wmi_platform_init(struct asus_wmi *asus)
1557 1558
1558 /* INIT enable hotkeys on some models */ 1559 /* INIT enable hotkeys on some models */
1559 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv)) 1560 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv))
1560 pr_info("Initialization: %#x", rv); 1561 pr_info("Initialization: %#x\n", rv);
1561 1562
1562 /* We don't know yet what to do with this version... */ 1563 /* We don't know yet what to do with this version... */
1563 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) { 1564 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) {
1564 pr_info("BIOS WMI version: %d.%d", rv >> 16, rv & 0xFF); 1565 pr_info("BIOS WMI version: %d.%d\n", rv >> 16, rv & 0xFF);
1565 asus->spec = rv; 1566 asus->spec = rv;
1566 } 1567 }
1567 1568
@@ -1572,7 +1573,7 @@ static int asus_wmi_platform_init(struct asus_wmi *asus)
1572 * The significance of others is yet to be found. 1573 * The significance of others is yet to be found.
1573 */ 1574 */
1574 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) { 1575 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) {
1575 pr_info("SFUN value: %#x", rv); 1576 pr_info("SFUN value: %#x\n", rv);
1576 asus->sfun = rv; 1577 asus->sfun = rv;
1577 } 1578 }
1578 1579
@@ -1712,7 +1713,7 @@ static int asus_wmi_debugfs_init(struct asus_wmi *asus)
1712 1713
1713 asus->debug.root = debugfs_create_dir(asus->driver->name, NULL); 1714 asus->debug.root = debugfs_create_dir(asus->driver->name, NULL);
1714 if (!asus->debug.root) { 1715 if (!asus->debug.root) {
1715 pr_err("failed to create debugfs directory"); 1716 pr_err("failed to create debugfs directory\n");
1716 goto error_debugfs; 1717 goto error_debugfs;
1717 } 1718 }
1718 1719
@@ -1985,17 +1986,17 @@ EXPORT_SYMBOL_GPL(asus_wmi_unregister_driver);
1985static int __init asus_wmi_init(void) 1986static int __init asus_wmi_init(void)
1986{ 1987{
1987 if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) { 1988 if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
1988 pr_info("Asus Management GUID not found"); 1989 pr_info("Asus Management GUID not found\n");
1989 return -ENODEV; 1990 return -ENODEV;
1990 } 1991 }
1991 1992
1992 pr_info("ASUS WMI generic driver loaded"); 1993 pr_info("ASUS WMI generic driver loaded\n");
1993 return 0; 1994 return 0;
1994} 1995}
1995 1996
1996static void __exit asus_wmi_exit(void) 1997static void __exit asus_wmi_exit(void)
1997{ 1998{
1998 pr_info("ASUS WMI generic driver unloaded"); 1999 pr_info("ASUS WMI generic driver unloaded\n");
1999} 2000}
2000 2001
2001module_init(asus_wmi_init); 2002module_init(asus_wmi_init);
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 1134119521ac..bb77e18b3dd4 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -551,9 +551,10 @@ static int __init dell_init(void)
551 * is passed to SMI handler. 551 * is passed to SMI handler.
552 */ 552 */
553 bufferpage = alloc_page(GFP_KERNEL | GFP_DMA32); 553 bufferpage = alloc_page(GFP_KERNEL | GFP_DMA32);
554 554 if (!bufferpage) {
555 if (!bufferpage) 555 ret = -ENOMEM;
556 goto fail_buffer; 556 goto fail_buffer;
557 }
557 buffer = page_address(bufferpage); 558 buffer = page_address(bufferpage);
558 559
559 if (quirks && quirks->touchpad_led) 560 if (quirks && quirks->touchpad_led)
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index d111c8687f9b..97bb05edcb5a 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -53,8 +53,10 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
53#define HPWMI_ALS_QUERY 0x3 53#define HPWMI_ALS_QUERY 0x3
54#define HPWMI_HARDWARE_QUERY 0x4 54#define HPWMI_HARDWARE_QUERY 0x4
55#define HPWMI_WIRELESS_QUERY 0x5 55#define HPWMI_WIRELESS_QUERY 0x5
56#define HPWMI_BIOS_QUERY 0x9
56#define HPWMI_HOTKEY_QUERY 0xc 57#define HPWMI_HOTKEY_QUERY 0xc
57#define HPWMI_WIRELESS2_QUERY 0x1b 58#define HPWMI_WIRELESS2_QUERY 0x1b
59#define HPWMI_POSTCODEERROR_QUERY 0x2a
58 60
59enum hp_wmi_radio { 61enum hp_wmi_radio {
60 HPWMI_WIFI = 0, 62 HPWMI_WIFI = 0,
@@ -291,6 +293,19 @@ static int hp_wmi_tablet_state(void)
291 return (state & 0x4) ? 1 : 0; 293 return (state & 0x4) ? 1 : 0;
292} 294}
293 295
296static int hp_wmi_enable_hotkeys(void)
297{
298 int ret;
299 int query = 0x6e;
300
301 ret = hp_wmi_perform_query(HPWMI_BIOS_QUERY, 1, &query, sizeof(query),
302 0);
303
304 if (ret)
305 return -EINVAL;
306 return 0;
307}
308
294static int hp_wmi_set_block(void *data, bool blocked) 309static int hp_wmi_set_block(void *data, bool blocked)
295{ 310{
296 enum hp_wmi_radio r = (enum hp_wmi_radio) data; 311 enum hp_wmi_radio r = (enum hp_wmi_radio) data;
@@ -386,6 +401,16 @@ static int hp_wmi_rfkill2_refresh(void)
386 return 0; 401 return 0;
387} 402}
388 403
404static int hp_wmi_post_code_state(void)
405{
406 int state = 0;
407 int ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, 0, &state,
408 sizeof(state), sizeof(state));
409 if (ret)
410 return -EINVAL;
411 return state;
412}
413
389static ssize_t show_display(struct device *dev, struct device_attribute *attr, 414static ssize_t show_display(struct device *dev, struct device_attribute *attr,
390 char *buf) 415 char *buf)
391{ 416{
@@ -431,6 +456,16 @@ static ssize_t show_tablet(struct device *dev, struct device_attribute *attr,
431 return sprintf(buf, "%d\n", value); 456 return sprintf(buf, "%d\n", value);
432} 457}
433 458
459static ssize_t show_postcode(struct device *dev, struct device_attribute *attr,
460 char *buf)
461{
462 /* Get the POST error code of previous boot failure. */
463 int value = hp_wmi_post_code_state();
464 if (value < 0)
465 return -EINVAL;
466 return sprintf(buf, "0x%x\n", value);
467}
468
434static ssize_t set_als(struct device *dev, struct device_attribute *attr, 469static ssize_t set_als(struct device *dev, struct device_attribute *attr,
435 const char *buf, size_t count) 470 const char *buf, size_t count)
436{ 471{
@@ -443,11 +478,33 @@ static ssize_t set_als(struct device *dev, struct device_attribute *attr,
443 return count; 478 return count;
444} 479}
445 480
481static ssize_t set_postcode(struct device *dev, struct device_attribute *attr,
482 const char *buf, size_t count)
483{
484 int ret;
485 u32 tmp;
486 long unsigned int tmp2;
487
488 ret = kstrtoul(buf, 10, &tmp2);
489 if (ret || tmp2 != 1)
490 return -EINVAL;
491
492 /* Clear the POST error code. It is kept until until cleared. */
493 tmp = (u32) tmp2;
494 ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, 1, &tmp,
495 sizeof(tmp), sizeof(tmp));
496 if (ret)
497 return -EINVAL;
498
499 return count;
500}
501
446static DEVICE_ATTR(display, S_IRUGO, show_display, NULL); 502static DEVICE_ATTR(display, S_IRUGO, show_display, NULL);
447static DEVICE_ATTR(hddtemp, S_IRUGO, show_hddtemp, NULL); 503static DEVICE_ATTR(hddtemp, S_IRUGO, show_hddtemp, NULL);
448static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als); 504static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als);
449static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL); 505static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL);
450static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL); 506static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL);
507static DEVICE_ATTR(postcode, S_IRUGO | S_IWUSR, show_postcode, set_postcode);
451 508
452static void hp_wmi_notify(u32 value, void *context) 509static void hp_wmi_notify(u32 value, void *context)
453{ 510{
@@ -628,6 +685,7 @@ static void cleanup_sysfs(struct platform_device *device)
628 device_remove_file(&device->dev, &dev_attr_als); 685 device_remove_file(&device->dev, &dev_attr_als);
629 device_remove_file(&device->dev, &dev_attr_dock); 686 device_remove_file(&device->dev, &dev_attr_dock);
630 device_remove_file(&device->dev, &dev_attr_tablet); 687 device_remove_file(&device->dev, &dev_attr_tablet);
688 device_remove_file(&device->dev, &dev_attr_postcode);
631} 689}
632 690
633static int hp_wmi_rfkill_setup(struct platform_device *device) 691static int hp_wmi_rfkill_setup(struct platform_device *device)
@@ -845,6 +903,9 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
845 err = device_create_file(&device->dev, &dev_attr_tablet); 903 err = device_create_file(&device->dev, &dev_attr_tablet);
846 if (err) 904 if (err)
847 goto add_sysfs_error; 905 goto add_sysfs_error;
906 err = device_create_file(&device->dev, &dev_attr_postcode);
907 if (err)
908 goto add_sysfs_error;
848 return 0; 909 return 0;
849 910
850add_sysfs_error: 911add_sysfs_error:
@@ -948,6 +1009,8 @@ static int __init hp_wmi_init(void)
948 err = hp_wmi_input_setup(); 1009 err = hp_wmi_input_setup();
949 if (err) 1010 if (err)
950 return err; 1011 return err;
1012
1013 hp_wmi_enable_hotkeys();
951 } 1014 }
952 1015
953 if (bios_capable) { 1016 if (bios_capable) {
diff --git a/drivers/platform/x86/intel-rst.c b/drivers/platform/x86/intel-rst.c
new file mode 100644
index 000000000000..9385afd9b558
--- /dev/null
+++ b/drivers/platform/x86/intel-rst.c
@@ -0,0 +1,209 @@
1/*
2 * Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <acpi/acpi_drivers.h>
24
25MODULE_LICENSE("GPL");
26
27static ssize_t irst_show_wakeup_events(struct device *dev,
28 struct device_attribute *attr,
29 char *buf)
30{
31 struct acpi_device *acpi;
32 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
33 union acpi_object *result;
34 acpi_status status;
35
36 acpi = to_acpi_device(dev);
37
38 status = acpi_evaluate_object(acpi->handle, "GFFS", NULL, &output);
39 if (!ACPI_SUCCESS(status))
40 return -EINVAL;
41
42 result = output.pointer;
43
44 if (result->type != ACPI_TYPE_INTEGER) {
45 kfree(result);
46 return -EINVAL;
47 }
48
49 return sprintf(buf, "%lld\n", result->integer.value);
50}
51
52static ssize_t irst_store_wakeup_events(struct device *dev,
53 struct device_attribute *attr,
54 const char *buf, size_t count)
55{
56 struct acpi_device *acpi;
57 struct acpi_object_list input;
58 union acpi_object param;
59 acpi_status status;
60 unsigned long value;
61 int error;
62
63 acpi = to_acpi_device(dev);
64
65 error = kstrtoul(buf, 0, &value);
66
67 if (error)
68 return error;
69
70 param.type = ACPI_TYPE_INTEGER;
71 param.integer.value = value;
72
73 input.count = 1;
74 input.pointer = &param;
75
76 status = acpi_evaluate_object(acpi->handle, "SFFS", &input, NULL);
77
78 if (!ACPI_SUCCESS(status))
79 return -EINVAL;
80
81 return count;
82}
83
84static struct device_attribute irst_wakeup_attr = {
85 .attr = { .name = "wakeup_events", .mode = 0600 },
86 .show = irst_show_wakeup_events,
87 .store = irst_store_wakeup_events
88};
89
90static ssize_t irst_show_wakeup_time(struct device *dev,
91 struct device_attribute *attr, char *buf)
92{
93 struct acpi_device *acpi;
94 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
95 union acpi_object *result;
96 acpi_status status;
97
98 acpi = to_acpi_device(dev);
99
100 status = acpi_evaluate_object(acpi->handle, "GFTV", NULL, &output);
101 if (!ACPI_SUCCESS(status))
102 return -EINVAL;
103
104 result = output.pointer;
105
106 if (result->type != ACPI_TYPE_INTEGER) {
107 kfree(result);
108 return -EINVAL;
109 }
110
111 return sprintf(buf, "%lld\n", result->integer.value);
112}
113
114static ssize_t irst_store_wakeup_time(struct device *dev,
115 struct device_attribute *attr,
116 const char *buf, size_t count)
117{
118 struct acpi_device *acpi;
119 struct acpi_object_list input;
120 union acpi_object param;
121 acpi_status status;
122 unsigned long value;
123 int error;
124
125 acpi = to_acpi_device(dev);
126
127 error = kstrtoul(buf, 0, &value);
128
129 if (error)
130 return error;
131
132 param.type = ACPI_TYPE_INTEGER;
133 param.integer.value = value;
134
135 input.count = 1;
136 input.pointer = &param;
137
138 status = acpi_evaluate_object(acpi->handle, "SFTV", &input, NULL);
139
140 if (!ACPI_SUCCESS(status))
141 return -EINVAL;
142
143 return count;
144}
145
146static struct device_attribute irst_timeout_attr = {
147 .attr = { .name = "wakeup_time", .mode = 0600 },
148 .show = irst_show_wakeup_time,
149 .store = irst_store_wakeup_time
150};
151
152static int irst_add(struct acpi_device *acpi)
153{
154 int error = 0;
155
156 error = device_create_file(&acpi->dev, &irst_timeout_attr);
157 if (error)
158 goto out;
159
160 error = device_create_file(&acpi->dev, &irst_wakeup_attr);
161 if (error)
162 goto out_timeout;
163
164 return 0;
165
166out_timeout:
167 device_remove_file(&acpi->dev, &irst_timeout_attr);
168out:
169 return error;
170}
171
172static int irst_remove(struct acpi_device *acpi)
173{
174 device_remove_file(&acpi->dev, &irst_wakeup_attr);
175 device_remove_file(&acpi->dev, &irst_timeout_attr);
176
177 return 0;
178}
179
180static const struct acpi_device_id irst_ids[] = {
181 {"INT3392", 0},
182 {"", 0}
183};
184
185static struct acpi_driver irst_driver = {
186 .owner = THIS_MODULE,
187 .name = "intel_rapid_start",
188 .class = "intel_rapid_start",
189 .ids = irst_ids,
190 .ops = {
191 .add = irst_add,
192 .remove = irst_remove,
193 },
194};
195
196static int irst_init(void)
197{
198 return acpi_bus_register_driver(&irst_driver);
199}
200
201static void irst_exit(void)
202{
203 acpi_bus_unregister_driver(&irst_driver);
204}
205
206module_init(irst_init);
207module_exit(irst_exit);
208
209MODULE_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 000000000000..f74e93d096bc
--- /dev/null
+++ b/drivers/platform/x86/intel-smartconnect.c
@@ -0,0 +1,90 @@
1/*
2 * Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19
20#include <linux/init.h>
21#include <linux/module.h>
22#include <acpi/acpi_drivers.h>
23
24MODULE_LICENSE("GPL");
25
26static int smartconnect_acpi_init(struct acpi_device *acpi)
27{
28 struct acpi_object_list input;
29 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
30 union acpi_object *result;
31 union acpi_object param;
32 acpi_status status;
33
34 status = acpi_evaluate_object(acpi->handle, "GAOS", NULL, &output);
35 if (!ACPI_SUCCESS(status))
36 return -EINVAL;
37
38 result = output.pointer;
39
40 if (result->type != ACPI_TYPE_INTEGER) {
41 kfree(result);
42 return -EINVAL;
43 }
44
45 if (result->integer.value & 0x1) {
46 param.type = ACPI_TYPE_INTEGER;
47 param.integer.value = 0;
48
49 input.count = 1;
50 input.pointer = &param;
51
52 dev_info(&acpi->dev, "Disabling Intel Smart Connect\n");
53 status = acpi_evaluate_object(acpi->handle, "SAOS", &input,
54 NULL);
55 }
56
57 kfree(result);
58
59 return 0;
60}
61
62static const struct acpi_device_id smartconnect_ids[] = {
63 {"INT33A0", 0},
64 {"", 0}
65};
66
67static struct acpi_driver smartconnect_driver = {
68 .owner = THIS_MODULE,
69 .name = "intel_smart_connect",
70 .class = "intel_smart_connect",
71 .ids = smartconnect_ids,
72 .ops = {
73 .add = smartconnect_acpi_init,
74 },
75};
76
77static int smartconnect_init(void)
78{
79 return acpi_bus_register_driver(&smartconnect_driver);
80}
81
82static void smartconnect_exit(void)
83{
84 acpi_bus_unregister_driver(&smartconnect_driver);
85}
86
87module_init(smartconnect_init);
88module_exit(smartconnect_exit);
89
90MODULE_DEVICE_TABLE(acpi, smartconnect_ids);
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 5051aa970e0a..18dcb58ba965 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -1731,18 +1731,7 @@ static struct pci_driver ips_pci_driver = {
1731 .shutdown = ips_shutdown, 1731 .shutdown = ips_shutdown,
1732}; 1732};
1733 1733
1734static int __init ips_init(void) 1734module_pci_driver(ips_pci_driver);
1735{
1736 return pci_register_driver(&ips_pci_driver);
1737}
1738module_init(ips_init);
1739
1740static void ips_exit(void)
1741{
1742 pci_unregister_driver(&ips_pci_driver);
1743 return;
1744}
1745module_exit(ips_exit);
1746 1735
1747MODULE_LICENSE("GPL"); 1736MODULE_LICENSE("GPL");
1748MODULE_AUTHOR("Jesse Barnes <jbarnes@virtuousgeek.org>"); 1737MODULE_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 6f4b7289a059..2805988485f6 100644
--- a/drivers/platform/x86/intel_pmic_gpio.c
+++ b/drivers/platform/x86/intel_pmic_gpio.c
@@ -288,7 +288,7 @@ static int platform_pmic_gpio_probe(struct platform_device *pdev)
288 retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg); 288 retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg);
289 if (retval) { 289 if (retval) {
290 pr_warn("Interrupt request failed\n"); 290 pr_warn("Interrupt request failed\n");
291 goto err; 291 goto fail_request_irq;
292 } 292 }
293 293
294 for (i = 0; i < 8; i++) { 294 for (i = 0; i < 8; i++) {
@@ -299,6 +299,10 @@ static int platform_pmic_gpio_probe(struct platform_device *pdev)
299 irq_set_chip_data(i + pg->irq_base, pg); 299 irq_set_chip_data(i + pg->irq_base, pg);
300 } 300 }
301 return 0; 301 return 0;
302
303fail_request_irq:
304 if (gpiochip_remove(&pg->chip))
305 pr_err("gpiochip_remove failed\n");
302err: 306err:
303 iounmap(pg->gpiointr); 307 iounmap(pg->gpiointr);
304err2: 308err2:
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c
index 6b2293875672..62f8030b9e77 100644
--- a/drivers/platform/x86/msi-laptop.c
+++ b/drivers/platform/x86/msi-laptop.c
@@ -1098,29 +1098,29 @@ static int __init msi_init(void)
1098 1098
1099 ret = platform_device_add(msipf_device); 1099 ret = platform_device_add(msipf_device);
1100 if (ret) 1100 if (ret)
1101 goto fail_platform_device1; 1101 goto fail_device_add;
1102 1102
1103 if (quirks->load_scm_model && (load_scm_model_init(msipf_device) < 0)) { 1103 if (quirks->load_scm_model && (load_scm_model_init(msipf_device) < 0)) {
1104 ret = -EINVAL; 1104 ret = -EINVAL;
1105 goto fail_platform_device1; 1105 goto fail_scm_model_init;
1106 } 1106 }
1107 1107
1108 ret = sysfs_create_group(&msipf_device->dev.kobj, 1108 ret = sysfs_create_group(&msipf_device->dev.kobj,
1109 &msipf_attribute_group); 1109 &msipf_attribute_group);
1110 if (ret) 1110 if (ret)
1111 goto fail_platform_device2; 1111 goto fail_create_group;
1112 1112
1113 if (!quirks->old_ec_model) { 1113 if (!quirks->old_ec_model) {
1114 if (threeg_exists) 1114 if (threeg_exists)
1115 ret = device_create_file(&msipf_device->dev, 1115 ret = device_create_file(&msipf_device->dev,
1116 &dev_attr_threeg); 1116 &dev_attr_threeg);
1117 if (ret) 1117 if (ret)
1118 goto fail_platform_device2; 1118 goto fail_create_attr;
1119 } else { 1119 } else {
1120 ret = sysfs_create_group(&msipf_device->dev.kobj, 1120 ret = sysfs_create_group(&msipf_device->dev.kobj,
1121 &msipf_old_attribute_group); 1121 &msipf_old_attribute_group);
1122 if (ret) 1122 if (ret)
1123 goto fail_platform_device2; 1123 goto fail_create_attr;
1124 1124
1125 /* Disable automatic brightness control by default because 1125 /* Disable automatic brightness control by default because
1126 * this module was probably loaded to do brightness control in 1126 * this module was probably loaded to do brightness control in
@@ -1134,26 +1134,22 @@ static int __init msi_init(void)
1134 1134
1135 return 0; 1135 return 0;
1136 1136
1137fail_platform_device2: 1137fail_create_attr:
1138 1138 sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
1139fail_create_group:
1139 if (quirks->load_scm_model) { 1140 if (quirks->load_scm_model) {
1140 i8042_remove_filter(msi_laptop_i8042_filter); 1141 i8042_remove_filter(msi_laptop_i8042_filter);
1141 cancel_delayed_work_sync(&msi_rfkill_dwork); 1142 cancel_delayed_work_sync(&msi_rfkill_dwork);
1142 cancel_work_sync(&msi_rfkill_work); 1143 cancel_work_sync(&msi_rfkill_work);
1143 rfkill_cleanup(); 1144 rfkill_cleanup();
1144 } 1145 }
1146fail_scm_model_init:
1145 platform_device_del(msipf_device); 1147 platform_device_del(msipf_device);
1146 1148fail_device_add:
1147fail_platform_device1:
1148
1149 platform_device_put(msipf_device); 1149 platform_device_put(msipf_device);
1150
1151fail_platform_driver: 1150fail_platform_driver:
1152
1153 platform_driver_unregister(&msipf_driver); 1151 platform_driver_unregister(&msipf_driver);
1154
1155fail_backlight: 1152fail_backlight:
1156
1157 backlight_device_unregister(msibl_device); 1153 backlight_device_unregister(msibl_device);
1158 1154
1159 return ret; 1155 return ret;