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

+462 -40
+21
Documentation/ABI/testing/sysfs-driver-intel-rapid-start
···
··· 1 + What: /sys/bus/acpi/intel-rapid-start/wakeup_events 2 + Date: July 2, 2013 3 + KernelVersion: 3.11 4 + Contact: Matthew Garrett <mjg59@srcf.ucam.org> 5 + Description: 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 + 15 + What: /sys/bus/acpi/intel-rapid-start/wakeup_time 16 + Date: July 2, 2013 17 + KernelVersion: 3.11 18 + Contact: Matthew Garrett <mjg59@srcf.ucam.org> 19 + Description: 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.
+28
drivers/platform/x86/Kconfig
··· 176 config AMILO_RFKILL 177 tristate "Fujitsu-Siemens Amilo rfkill support" 178 depends on RFKILL 179 ---help--- 180 This is a driver for enabling wifi on some Fujitsu-Siemens Amilo 181 laptops. ··· 592 depends on BACKLIGHT_CLASS_DEVICE 593 depends on INPUT 594 depends on RFKILL || RFKILL = n 595 select INPUT_POLLDEV 596 select INPUT_SPARSEKMAP 597 ---help--- ··· 782 Apple laptops, which controls the display mux for the hybrid 783 graphics as well as the backlight. Currently only backlight 784 control is supported by the driver. 785 786 config PVPANIC 787 tristate "pvpanic device support"
··· 176 config AMILO_RFKILL 177 tristate "Fujitsu-Siemens Amilo rfkill support" 178 depends on RFKILL 179 + depends on SERIO_I8042 180 ---help--- 181 This is a driver for enabling wifi on some Fujitsu-Siemens Amilo 182 laptops. ··· 591 depends on BACKLIGHT_CLASS_DEVICE 592 depends on INPUT 593 depends on RFKILL || RFKILL = n 594 + depends on SERIO_I8042 || SERIO_I8042 = n 595 select INPUT_POLLDEV 596 select INPUT_SPARSEKMAP 597 ---help--- ··· 780 Apple laptops, which controls the display mux for the hybrid 781 graphics as well as the backlight. Currently only backlight 782 control is supported by the driver. 783 + 784 + config INTEL_RST 785 + tristate "Intel Rapid Start Technology Driver" 786 + depends on ACPI 787 + ---help--- 788 + This driver provides support for modifying paramaters on systems 789 + equipped with Intel's Rapid Start Technology. When put in an ACPI 790 + sleep state, these devices will wake after either a configured 791 + timeout or when the system battery reaches a critical state, 792 + automatically copying memory contents to disk. On resume, the 793 + firmware will copy the memory contents back to RAM and resume the OS 794 + as usual. 795 + 796 + config INTEL_SMARTCONNECT 797 + tristate "Intel Smart Connect disabling driver" 798 + depends on ACPI 799 + ---help--- 800 + Intel Smart Connect is a technology intended to permit devices to 801 + update state by resuming for a short period of time at regular 802 + intervals. If a user enables this functionality under Windows and 803 + then reboots into Linux, the system may remain configured to resume 804 + on suspend. In the absence of any userspace to support it, the system 805 + will then remain awake until something triggers another suspend. 806 + 807 + This driver checks to determine whether the device has Intel Smart 808 + Connect enabled, and if so disables it. 809 810 config PVPANIC 811 tristate "pvpanic device support"
+2
drivers/platform/x86/Makefile
··· 51 obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o 52 obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o 53 obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o 54 55 obj-$(CONFIG_PVPANIC) += pvpanic.o
··· 51 obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o 52 obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o 53 obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o 54 + obj-$(CONFIG_INTEL_RST) += intel-rst.o 55 + obj-$(CONFIG_INTEL_SMARTCONNECT) += intel-smartconnect.o 56 57 obj-$(CONFIG_PVPANIC) += pvpanic.o
-1
drivers/platform/x86/asus-laptop.c
··· 1935 fail_backlight: 1936 asus_platform_exit(asus); 1937 fail_platform: 1938 - kfree(asus->name); 1939 kfree(asus); 1940 1941 return result;
··· 1935 fail_backlight: 1936 asus_platform_exit(asus); 1937 fail_platform: 1938 kfree(asus); 1939 1940 return result;
+19
drivers/platform/x86/asus-nb-wmi.c
··· 180 }, 181 .driver_data = &quirk_asus_x401u, 182 }, 183 {}, 184 }; 185 ··· 274 { KE_KEY, 0xB5, { KEY_CALC } }, 275 { KE_KEY, 0xC4, { KEY_KBDILLUMUP } }, 276 { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } }, 277 { KE_END, 0}, 278 }; 279
··· 180 }, 181 .driver_data = &quirk_asus_x401u, 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 + }, 201 {}, 202 }; 203 ··· 256 { KE_KEY, 0xB5, { KEY_CALC } }, 257 { KE_KEY, 0xC4, { KEY_KBDILLUMUP } }, 258 { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } }, 259 + { KE_IGNORE, 0xC6, }, /* Ambient Light Sensor notification */ 260 { KE_END, 0}, 261 }; 262
+11 -10
drivers/platform/x86/asus-wmi.c
··· 558 goto error; 559 } 560 561 - if (wlan_led_presence(asus)) { 562 INIT_WORK(&asus->wlan_led_work, wlan_led_update); 563 564 asus->wlan_led.name = "asus::wlan"; ··· 886 if (!*rfkill) 887 return -EINVAL; 888 889 - if (dev_id == ASUS_WMI_DEVID_WLAN) 890 rfkill_set_led_trigger_name(*rfkill, "asus-wlan"); 891 892 rfkill_init_sw_state(*rfkill, !result); ··· 1046 else if (value == 3) 1047 value = 255; 1048 else if (value != 0) { 1049 - pr_err("Unknown fan speed %#x", value); 1050 value = -1; 1051 } 1052 ··· 1558 1559 /* INIT enable hotkeys on some models */ 1560 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv)) 1561 - pr_info("Initialization: %#x", rv); 1562 1563 /* We don't know yet what to do with this version... */ 1564 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) { 1565 - pr_info("BIOS WMI version: %d.%d", rv >> 16, rv & 0xFF); 1566 asus->spec = rv; 1567 } 1568 ··· 1573 * The significance of others is yet to be found. 1574 */ 1575 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) { 1576 - pr_info("SFUN value: %#x", rv); 1577 asus->sfun = rv; 1578 } 1579 ··· 1713 1714 asus->debug.root = debugfs_create_dir(asus->driver->name, NULL); 1715 if (!asus->debug.root) { 1716 - pr_err("failed to create debugfs directory"); 1717 goto error_debugfs; 1718 } 1719 ··· 1986 static int __init asus_wmi_init(void) 1987 { 1988 if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) { 1989 - pr_info("Asus Management GUID not found"); 1990 return -ENODEV; 1991 } 1992 1993 - pr_info("ASUS WMI generic driver loaded"); 1994 return 0; 1995 } 1996 1997 static void __exit asus_wmi_exit(void) 1998 { 1999 - pr_info("ASUS WMI generic driver unloaded"); 2000 } 2001 2002 module_init(asus_wmi_init);
··· 558 goto error; 559 } 560 561 + if (wlan_led_presence(asus) && (asus->driver->quirks->wapf == 4)) { 562 INIT_WORK(&asus->wlan_led_work, wlan_led_update); 563 564 asus->wlan_led.name = "asus::wlan"; ··· 886 if (!*rfkill) 887 return -EINVAL; 888 889 + if ((dev_id == ASUS_WMI_DEVID_WLAN) && 890 + (asus->driver->quirks->wapf == 4)) 891 rfkill_set_led_trigger_name(*rfkill, "asus-wlan"); 892 893 rfkill_init_sw_state(*rfkill, !result); ··· 1045 else if (value == 3) 1046 value = 255; 1047 else if (value != 0) { 1048 + pr_err("Unknown fan speed %#x\n", value); 1049 value = -1; 1050 } 1051 ··· 1557 1558 /* INIT enable hotkeys on some models */ 1559 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv)) 1560 + pr_info("Initialization: %#x\n", rv); 1561 1562 /* 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 + pr_info("BIOS WMI version: %d.%d\n", rv >> 16, rv & 0xFF); 1565 asus->spec = rv; 1566 } 1567 ··· 1572 * The significance of others is yet to be found. 1573 */ 1574 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) { 1575 + pr_info("SFUN value: %#x\n", rv); 1576 asus->sfun = rv; 1577 } 1578 ··· 1712 1713 asus->debug.root = debugfs_create_dir(asus->driver->name, NULL); 1714 if (!asus->debug.root) { 1715 + pr_err("failed to create debugfs directory\n"); 1716 goto error_debugfs; 1717 } 1718 ··· 1985 static int __init asus_wmi_init(void) 1986 { 1987 if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) { 1988 + pr_info("Asus Management GUID not found\n"); 1989 return -ENODEV; 1990 } 1991 1992 + pr_info("ASUS WMI generic driver loaded\n"); 1993 return 0; 1994 } 1995 1996 static void __exit asus_wmi_exit(void) 1997 { 1998 + pr_info("ASUS WMI generic driver unloaded\n"); 1999 } 2000 2001 module_init(asus_wmi_init);
+3 -2
drivers/platform/x86/dell-laptop.c
··· 551 * is passed to SMI handler. 552 */ 553 bufferpage = alloc_page(GFP_KERNEL | GFP_DMA32); 554 - 555 - if (!bufferpage) 556 goto fail_buffer; 557 buffer = page_address(bufferpage); 558 559 if (quirks && quirks->touchpad_led)
··· 551 * is passed to SMI handler. 552 */ 553 bufferpage = alloc_page(GFP_KERNEL | GFP_DMA32); 554 + if (!bufferpage) { 555 + ret = -ENOMEM; 556 goto fail_buffer; 557 + } 558 buffer = page_address(bufferpage); 559 560 if (quirks && quirks->touchpad_led)
+63
drivers/platform/x86/hp-wmi.c
··· 53 #define HPWMI_ALS_QUERY 0x3 54 #define HPWMI_HARDWARE_QUERY 0x4 55 #define HPWMI_WIRELESS_QUERY 0x5 56 #define HPWMI_HOTKEY_QUERY 0xc 57 #define HPWMI_WIRELESS2_QUERY 0x1b 58 59 enum hp_wmi_radio { 60 HPWMI_WIFI = 0, ··· 293 return (state & 0x4) ? 1 : 0; 294 } 295 296 static int hp_wmi_set_block(void *data, bool blocked) 297 { 298 enum hp_wmi_radio r = (enum hp_wmi_radio) data; ··· 401 return 0; 402 } 403 404 static ssize_t show_display(struct device *dev, struct device_attribute *attr, 405 char *buf) 406 { ··· 456 return sprintf(buf, "%d\n", value); 457 } 458 459 static ssize_t set_als(struct device *dev, struct device_attribute *attr, 460 const char *buf, size_t count) 461 { ··· 478 return count; 479 } 480 481 static DEVICE_ATTR(display, S_IRUGO, show_display, NULL); 482 static DEVICE_ATTR(hddtemp, S_IRUGO, show_hddtemp, NULL); 483 static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als); 484 static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL); 485 static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL); 486 487 static void hp_wmi_notify(u32 value, void *context) 488 { ··· 685 device_remove_file(&device->dev, &dev_attr_als); 686 device_remove_file(&device->dev, &dev_attr_dock); 687 device_remove_file(&device->dev, &dev_attr_tablet); 688 } 689 690 static int hp_wmi_rfkill_setup(struct platform_device *device) ··· 903 err = device_create_file(&device->dev, &dev_attr_tablet); 904 if (err) 905 goto add_sysfs_error; 906 return 0; 907 908 add_sysfs_error: ··· 1009 err = hp_wmi_input_setup(); 1010 if (err) 1011 return err; 1012 } 1013 1014 if (bios_capable) {
··· 53 #define HPWMI_ALS_QUERY 0x3 54 #define HPWMI_HARDWARE_QUERY 0x4 55 #define HPWMI_WIRELESS_QUERY 0x5 56 + #define HPWMI_BIOS_QUERY 0x9 57 #define HPWMI_HOTKEY_QUERY 0xc 58 #define HPWMI_WIRELESS2_QUERY 0x1b 59 + #define HPWMI_POSTCODEERROR_QUERY 0x2a 60 61 enum hp_wmi_radio { 62 HPWMI_WIFI = 0, ··· 291 return (state & 0x4) ? 1 : 0; 292 } 293 294 + static int hp_wmi_enable_hotkeys(void) 295 + { 296 + int ret; 297 + int query = 0x6e; 298 + 299 + ret = hp_wmi_perform_query(HPWMI_BIOS_QUERY, 1, &query, sizeof(query), 300 + 0); 301 + 302 + if (ret) 303 + return -EINVAL; 304 + return 0; 305 + } 306 + 307 static int hp_wmi_set_block(void *data, bool blocked) 308 { 309 enum hp_wmi_radio r = (enum hp_wmi_radio) data; ··· 386 return 0; 387 } 388 389 + static int hp_wmi_post_code_state(void) 390 + { 391 + int state = 0; 392 + int ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, 0, &state, 393 + sizeof(state), sizeof(state)); 394 + if (ret) 395 + return -EINVAL; 396 + return state; 397 + } 398 + 399 static ssize_t show_display(struct device *dev, struct device_attribute *attr, 400 char *buf) 401 { ··· 431 return sprintf(buf, "%d\n", value); 432 } 433 434 + static ssize_t show_postcode(struct device *dev, struct device_attribute *attr, 435 + char *buf) 436 + { 437 + /* Get the POST error code of previous boot failure. */ 438 + int value = hp_wmi_post_code_state(); 439 + if (value < 0) 440 + return -EINVAL; 441 + return sprintf(buf, "0x%x\n", value); 442 + } 443 + 444 static ssize_t set_als(struct device *dev, struct device_attribute *attr, 445 const char *buf, size_t count) 446 { ··· 443 return count; 444 } 445 446 + static ssize_t set_postcode(struct device *dev, struct device_attribute *attr, 447 + const char *buf, size_t count) 448 + { 449 + int ret; 450 + u32 tmp; 451 + long unsigned int tmp2; 452 + 453 + ret = kstrtoul(buf, 10, &tmp2); 454 + if (ret || tmp2 != 1) 455 + return -EINVAL; 456 + 457 + /* Clear the POST error code. It is kept until until cleared. */ 458 + tmp = (u32) tmp2; 459 + ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, 1, &tmp, 460 + sizeof(tmp), sizeof(tmp)); 461 + if (ret) 462 + return -EINVAL; 463 + 464 + return count; 465 + } 466 + 467 static DEVICE_ATTR(display, S_IRUGO, show_display, NULL); 468 static DEVICE_ATTR(hddtemp, S_IRUGO, show_hddtemp, NULL); 469 static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als); 470 static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL); 471 static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL); 472 + static DEVICE_ATTR(postcode, S_IRUGO | S_IWUSR, show_postcode, set_postcode); 473 474 static void hp_wmi_notify(u32 value, void *context) 475 { ··· 628 device_remove_file(&device->dev, &dev_attr_als); 629 device_remove_file(&device->dev, &dev_attr_dock); 630 device_remove_file(&device->dev, &dev_attr_tablet); 631 + device_remove_file(&device->dev, &dev_attr_postcode); 632 } 633 634 static int hp_wmi_rfkill_setup(struct platform_device *device) ··· 845 err = device_create_file(&device->dev, &dev_attr_tablet); 846 if (err) 847 goto add_sysfs_error; 848 + err = device_create_file(&device->dev, &dev_attr_postcode); 849 + if (err) 850 + goto add_sysfs_error; 851 return 0; 852 853 add_sysfs_error: ··· 948 err = hp_wmi_input_setup(); 949 if (err) 950 return err; 951 + 952 + hp_wmi_enable_hotkeys(); 953 } 954 955 if (bios_capable) {
+209
drivers/platform/x86/intel-rst.c
···
··· 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 + 25 + MODULE_LICENSE("GPL"); 26 + 27 + static 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 + 52 + static 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 + 84 + static 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 + 90 + static 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 + 114 + static 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 + 146 + static 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 + 152 + static 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 + 166 + out_timeout: 167 + device_remove_file(&acpi->dev, &irst_timeout_attr); 168 + out: 169 + return error; 170 + } 171 + 172 + static 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 + 180 + static const struct acpi_device_id irst_ids[] = { 181 + {"INT3392", 0}, 182 + {"", 0} 183 + }; 184 + 185 + static 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 + 196 + static int irst_init(void) 197 + { 198 + return acpi_bus_register_driver(&irst_driver); 199 + } 200 + 201 + static void irst_exit(void) 202 + { 203 + acpi_bus_unregister_driver(&irst_driver); 204 + } 205 + 206 + module_init(irst_init); 207 + module_exit(irst_exit); 208 + 209 + MODULE_DEVICE_TABLE(acpi, irst_ids);
+90
drivers/platform/x86/intel-smartconnect.c
···
··· 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 + 24 + MODULE_LICENSE("GPL"); 25 + 26 + static 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 + 62 + static const struct acpi_device_id smartconnect_ids[] = { 63 + {"INT33A0", 0}, 64 + {"", 0} 65 + }; 66 + 67 + static 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 + 77 + static int smartconnect_init(void) 78 + { 79 + return acpi_bus_register_driver(&smartconnect_driver); 80 + } 81 + 82 + static void smartconnect_exit(void) 83 + { 84 + acpi_bus_unregister_driver(&smartconnect_driver); 85 + } 86 + 87 + module_init(smartconnect_init); 88 + module_exit(smartconnect_exit); 89 + 90 + MODULE_DEVICE_TABLE(acpi, smartconnect_ids);
+1 -12
drivers/platform/x86/intel_ips.c
··· 1731 .shutdown = ips_shutdown, 1732 }; 1733 1734 - static int __init ips_init(void) 1735 - { 1736 - return pci_register_driver(&ips_pci_driver); 1737 - } 1738 - module_init(ips_init); 1739 - 1740 - static void ips_exit(void) 1741 - { 1742 - pci_unregister_driver(&ips_pci_driver); 1743 - return; 1744 - } 1745 - module_exit(ips_exit); 1746 1747 MODULE_LICENSE("GPL"); 1748 MODULE_AUTHOR("Jesse Barnes <jbarnes@virtuousgeek.org>");
··· 1731 .shutdown = ips_shutdown, 1732 }; 1733 1734 + module_pci_driver(ips_pci_driver); 1735 1736 MODULE_LICENSE("GPL"); 1737 MODULE_AUTHOR("Jesse Barnes <jbarnes@virtuousgeek.org>");
+5 -1
drivers/platform/x86/intel_pmic_gpio.c
··· 288 retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg); 289 if (retval) { 290 pr_warn("Interrupt request failed\n"); 291 - goto err; 292 } 293 294 for (i = 0; i < 8; i++) { ··· 299 irq_set_chip_data(i + pg->irq_base, pg); 300 } 301 return 0; 302 err: 303 iounmap(pg->gpiointr); 304 err2:
··· 288 retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg); 289 if (retval) { 290 pr_warn("Interrupt request failed\n"); 291 + goto fail_request_irq; 292 } 293 294 for (i = 0; i < 8; i++) { ··· 299 irq_set_chip_data(i + pg->irq_base, pg); 300 } 301 return 0; 302 + 303 + fail_request_irq: 304 + if (gpiochip_remove(&pg->chip)) 305 + pr_err("gpiochip_remove failed\n"); 306 err: 307 iounmap(pg->gpiointr); 308 err2:
+10 -14
drivers/platform/x86/msi-laptop.c
··· 1098 1099 ret = platform_device_add(msipf_device); 1100 if (ret) 1101 - goto fail_platform_device1; 1102 1103 if (quirks->load_scm_model && (load_scm_model_init(msipf_device) < 0)) { 1104 ret = -EINVAL; 1105 - goto fail_platform_device1; 1106 } 1107 1108 ret = sysfs_create_group(&msipf_device->dev.kobj, 1109 &msipf_attribute_group); 1110 if (ret) 1111 - goto fail_platform_device2; 1112 1113 if (!quirks->old_ec_model) { 1114 if (threeg_exists) 1115 ret = device_create_file(&msipf_device->dev, 1116 &dev_attr_threeg); 1117 if (ret) 1118 - goto fail_platform_device2; 1119 } else { 1120 ret = sysfs_create_group(&msipf_device->dev.kobj, 1121 &msipf_old_attribute_group); 1122 if (ret) 1123 - goto fail_platform_device2; 1124 1125 /* Disable automatic brightness control by default because 1126 * this module was probably loaded to do brightness control in ··· 1134 1135 return 0; 1136 1137 - fail_platform_device2: 1138 - 1139 if (quirks->load_scm_model) { 1140 i8042_remove_filter(msi_laptop_i8042_filter); 1141 cancel_delayed_work_sync(&msi_rfkill_dwork); 1142 cancel_work_sync(&msi_rfkill_work); 1143 rfkill_cleanup(); 1144 } 1145 platform_device_del(msipf_device); 1146 - 1147 - fail_platform_device1: 1148 - 1149 platform_device_put(msipf_device); 1150 - 1151 fail_platform_driver: 1152 - 1153 platform_driver_unregister(&msipf_driver); 1154 - 1155 fail_backlight: 1156 - 1157 backlight_device_unregister(msibl_device); 1158 1159 return ret;
··· 1098 1099 ret = platform_device_add(msipf_device); 1100 if (ret) 1101 + goto fail_device_add; 1102 1103 if (quirks->load_scm_model && (load_scm_model_init(msipf_device) < 0)) { 1104 ret = -EINVAL; 1105 + goto fail_scm_model_init; 1106 } 1107 1108 ret = sysfs_create_group(&msipf_device->dev.kobj, 1109 &msipf_attribute_group); 1110 if (ret) 1111 + goto fail_create_group; 1112 1113 if (!quirks->old_ec_model) { 1114 if (threeg_exists) 1115 ret = device_create_file(&msipf_device->dev, 1116 &dev_attr_threeg); 1117 if (ret) 1118 + goto fail_create_attr; 1119 } else { 1120 ret = sysfs_create_group(&msipf_device->dev.kobj, 1121 &msipf_old_attribute_group); 1122 if (ret) 1123 + goto fail_create_attr; 1124 1125 /* Disable automatic brightness control by default because 1126 * this module was probably loaded to do brightness control in ··· 1134 1135 return 0; 1136 1137 + fail_create_attr: 1138 + sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group); 1139 + fail_create_group: 1140 if (quirks->load_scm_model) { 1141 i8042_remove_filter(msi_laptop_i8042_filter); 1142 cancel_delayed_work_sync(&msi_rfkill_dwork); 1143 cancel_work_sync(&msi_rfkill_work); 1144 rfkill_cleanup(); 1145 } 1146 + fail_scm_model_init: 1147 platform_device_del(msipf_device); 1148 + fail_device_add: 1149 platform_device_put(msipf_device); 1150 fail_platform_driver: 1151 platform_driver_unregister(&msipf_driver); 1152 fail_backlight: 1153 backlight_device_unregister(msibl_device); 1154 1155 return ret;