aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86')
-rw-r--r--drivers/platform/x86/Kconfig19
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/acer-wmi.c54
-rw-r--r--drivers/platform/x86/alienware-wmi.c26
-rw-r--r--drivers/platform/x86/asus-nb-wmi.c80
-rw-r--r--drivers/platform/x86/asus-wmi.c16
-rw-r--r--drivers/platform/x86/compal-laptop.c2
-rw-r--r--drivers/platform/x86/dell-laptop.c6
-rw-r--r--drivers/platform/x86/eeepc-laptop.c8
-rw-r--r--drivers/platform/x86/eeepc-wmi.c2
-rw-r--r--drivers/platform/x86/fujitsu-laptop.c19
-rw-r--r--drivers/platform/x86/fujitsu-tablet.c6
-rw-r--r--drivers/platform/x86/hp-wmi.c6
-rw-r--r--drivers/platform/x86/hp_accel.c4
-rw-r--r--drivers/platform/x86/ideapad-laptop.c72
-rw-r--r--drivers/platform/x86/intel_ips.c6
-rw-r--r--drivers/platform/x86/sony-laptop.c2
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c8
-rw-r--r--drivers/platform/x86/toshiba_acpi.c30
-rw-r--r--drivers/platform/x86/toshiba_haps.c265
-rw-r--r--drivers/platform/x86/wmi.c4
21 files changed, 529 insertions, 107 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 172f26ce59ac..3bbcbf12c1fb 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -652,6 +652,25 @@ config TOSHIBA_BT_RFKILL
652 If you have a modern Toshiba laptop with a Bluetooth and an 652 If you have a modern Toshiba laptop with a Bluetooth and an
653 RFKill switch (such as the Portege R500), say Y. 653 RFKill switch (such as the Portege R500), say Y.
654 654
655config TOSHIBA_HAPS
656 tristate "Toshiba HDD Active Protection Sensor"
657 depends on ACPI
658 ---help---
659 This driver adds support for the built-in accelerometer
660 found on recent Toshiba laptops equiped with HID TOS620A
661 device.
662
663 This driver receives ACPI notify events 0x80 when the sensor
664 detects a sudden move or a harsh vibration, as well as an
665 ACPI notify event 0x81 whenever the movement or vibration has
666 been stabilized.
667
668 Also provides sysfs entries to get/set the desired protection
669 level and reseting the HDD protection interface.
670
671 If you have a recent Toshiba laptop with a built-in accelerometer
672 device, say Y.
673
655config ACPI_CMPC 674config ACPI_CMPC
656 tristate "CMPC Laptop Extras" 675 tristate "CMPC Laptop Extras"
657 depends on X86 && ACPI 676 depends on X86 && ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index c4ca428fd3db..f82232b1fc4d 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o
38obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o 38obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
39 39
40obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o 40obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o
41obj-$(CONFIG_TOSHIBA_HAPS) += toshiba_haps.o
41obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o 42obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o
42obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o 43obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o
43obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o 44obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index bbf78b2d6d93..96a0b75c52c9 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -96,7 +96,7 @@ enum acer_wmi_event_ids {
96 WMID_ACCEL_EVENT = 0x5, 96 WMID_ACCEL_EVENT = 0x5,
97}; 97};
98 98
99static const struct key_entry acer_wmi_keymap[] = { 99static const struct key_entry acer_wmi_keymap[] __initconst = {
100 {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */ 100 {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */
101 {KE_KEY, 0x03, {KEY_WLAN} }, /* WiFi */ 101 {KE_KEY, 0x03, {KEY_WLAN} }, /* WiFi */
102 {KE_KEY, 0x04, {KEY_WLAN} }, /* WiFi */ 102 {KE_KEY, 0x04, {KEY_WLAN} }, /* WiFi */
@@ -294,7 +294,7 @@ struct quirk_entry {
294 294
295static struct quirk_entry *quirks; 295static struct quirk_entry *quirks;
296 296
297static void set_quirks(void) 297static void __init set_quirks(void)
298{ 298{
299 if (!interface) 299 if (!interface)
300 return; 300 return;
@@ -306,7 +306,7 @@ static void set_quirks(void)
306 interface->capability |= ACER_CAP_BRIGHTNESS; 306 interface->capability |= ACER_CAP_BRIGHTNESS;
307} 307}
308 308
309static int dmi_matched(const struct dmi_system_id *dmi) 309static int __init dmi_matched(const struct dmi_system_id *dmi)
310{ 310{
311 quirks = dmi->driver_data; 311 quirks = dmi->driver_data;
312 return 1; 312 return 1;
@@ -337,7 +337,7 @@ static struct quirk_entry quirk_lenovo_ideapad_s205 = {
337}; 337};
338 338
339/* The Aspire One has a dummy ACPI-WMI interface - disable it */ 339/* The Aspire One has a dummy ACPI-WMI interface - disable it */
340static struct dmi_system_id acer_blacklist[] = { 340static const struct dmi_system_id acer_blacklist[] __initconst = {
341 { 341 {
342 .ident = "Acer Aspire One (SSD)", 342 .ident = "Acer Aspire One (SSD)",
343 .matches = { 343 .matches = {
@@ -355,7 +355,7 @@ static struct dmi_system_id acer_blacklist[] = {
355 {} 355 {}
356}; 356};
357 357
358static struct dmi_system_id acer_quirks[] = { 358static const struct dmi_system_id acer_quirks[] __initconst = {
359 { 359 {
360 .callback = dmi_matched, 360 .callback = dmi_matched,
361 .ident = "Acer Aspire 1360", 361 .ident = "Acer Aspire 1360",
@@ -530,14 +530,15 @@ static struct dmi_system_id acer_quirks[] = {
530 {} 530 {}
531}; 531};
532 532
533static int video_set_backlight_video_vendor(const struct dmi_system_id *d) 533static int __init
534video_set_backlight_video_vendor(const struct dmi_system_id *d)
534{ 535{
535 interface->capability &= ~ACER_CAP_BRIGHTNESS; 536 interface->capability &= ~ACER_CAP_BRIGHTNESS;
536 pr_info("Brightness must be controlled by generic video driver\n"); 537 pr_info("Brightness must be controlled by generic video driver\n");
537 return 0; 538 return 0;
538} 539}
539 540
540static const struct dmi_system_id video_vendor_dmi_table[] = { 541static const struct dmi_system_id video_vendor_dmi_table[] __initconst = {
541 { 542 {
542 .callback = video_set_backlight_video_vendor, 543 .callback = video_set_backlight_video_vendor,
543 .ident = "Acer TravelMate 4750", 544 .ident = "Acer TravelMate 4750",
@@ -582,7 +583,7 @@ static const struct dmi_system_id video_vendor_dmi_table[] = {
582}; 583};
583 584
584/* Find which quirks are needed for a particular vendor/ model pair */ 585/* Find which quirks are needed for a particular vendor/ model pair */
585static void find_quirks(void) 586static void __init find_quirks(void)
586{ 587{
587 if (!force_series) { 588 if (!force_series) {
588 dmi_check_system(acer_quirks); 589 dmi_check_system(acer_quirks);
@@ -749,7 +750,7 @@ static acpi_status AMW0_set_u32(u32 value, u32 cap)
749 return wmab_execute(&args, NULL); 750 return wmab_execute(&args, NULL);
750} 751}
751 752
752static acpi_status AMW0_find_mailled(void) 753static acpi_status __init AMW0_find_mailled(void)
753{ 754{
754 struct wmab_args args; 755 struct wmab_args args;
755 struct wmab_ret ret; 756 struct wmab_ret ret;
@@ -781,16 +782,16 @@ static acpi_status AMW0_find_mailled(void)
781 return AE_OK; 782 return AE_OK;
782} 783}
783 784
784static int AMW0_set_cap_acpi_check_device_found; 785static int AMW0_set_cap_acpi_check_device_found __initdata;
785 786
786static acpi_status AMW0_set_cap_acpi_check_device_cb(acpi_handle handle, 787static acpi_status __init AMW0_set_cap_acpi_check_device_cb(acpi_handle handle,
787 u32 level, void *context, void **retval) 788 u32 level, void *context, void **retval)
788{ 789{
789 AMW0_set_cap_acpi_check_device_found = 1; 790 AMW0_set_cap_acpi_check_device_found = 1;
790 return AE_OK; 791 return AE_OK;
791} 792}
792 793
793static const struct acpi_device_id norfkill_ids[] = { 794static const struct acpi_device_id norfkill_ids[] __initconst = {
794 { "VPC2004", 0}, 795 { "VPC2004", 0},
795 { "IBM0068", 0}, 796 { "IBM0068", 0},
796 { "LEN0068", 0}, 797 { "LEN0068", 0},
@@ -798,7 +799,7 @@ static const struct acpi_device_id norfkill_ids[] = {
798 { "", 0}, 799 { "", 0},
799}; 800};
800 801
801static int AMW0_set_cap_acpi_check_device(void) 802static int __init AMW0_set_cap_acpi_check_device(void)
802{ 803{
803 const struct acpi_device_id *id; 804 const struct acpi_device_id *id;
804 805
@@ -808,7 +809,7 @@ static int AMW0_set_cap_acpi_check_device(void)
808 return AMW0_set_cap_acpi_check_device_found; 809 return AMW0_set_cap_acpi_check_device_found;
809} 810}
810 811
811static acpi_status AMW0_set_capabilities(void) 812static acpi_status __init AMW0_set_capabilities(void)
812{ 813{
813 struct wmab_args args; 814 struct wmab_args args;
814 struct wmab_ret ret; 815 struct wmab_ret ret;
@@ -1184,7 +1185,7 @@ static acpi_status wmid_v2_set_u32(u32 value, u32 cap)
1184 return wmid3_set_device_status(value, device); 1185 return wmid3_set_device_status(value, device);
1185} 1186}
1186 1187
1187static void type_aa_dmi_decode(const struct dmi_header *header, void *dummy) 1188static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d)
1188{ 1189{
1189 struct hotkey_function_type_aa *type_aa; 1190 struct hotkey_function_type_aa *type_aa;
1190 1191
@@ -1209,7 +1210,7 @@ static void type_aa_dmi_decode(const struct dmi_header *header, void *dummy)
1209 commun_fn_key_number = type_aa->commun_fn_key_number; 1210 commun_fn_key_number = type_aa->commun_fn_key_number;
1210} 1211}
1211 1212
1212static acpi_status WMID_set_capabilities(void) 1213static acpi_status __init WMID_set_capabilities(void)
1213{ 1214{
1214 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; 1215 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
1215 union acpi_object *obj; 1216 union acpi_object *obj;
@@ -1658,7 +1659,7 @@ static ssize_t show_bool_threeg(struct device *dev,
1658 u32 result; \ 1659 u32 result; \
1659 acpi_status status; 1660 acpi_status status;
1660 1661
1661 pr_info("This threeg sysfs will be removed in 2012 - used by: %s\n", 1662 pr_info("This threeg sysfs will be removed in 2014 - used by: %s\n",
1662 current->comm); 1663 current->comm);
1663 status = get_u32(&result, ACER_CAP_THREEG); 1664 status = get_u32(&result, ACER_CAP_THREEG);
1664 if (ACPI_SUCCESS(status)) 1665 if (ACPI_SUCCESS(status))
@@ -1671,7 +1672,7 @@ static ssize_t set_bool_threeg(struct device *dev,
1671{ 1672{
1672 u32 tmp = simple_strtoul(buf, NULL, 10); 1673 u32 tmp = simple_strtoul(buf, NULL, 10);
1673 acpi_status status = set_u32(tmp, ACER_CAP_THREEG); 1674 acpi_status status = set_u32(tmp, ACER_CAP_THREEG);
1674 pr_info("This threeg sysfs will be removed in 2012 - used by: %s\n", 1675 pr_info("This threeg sysfs will be removed in 2014 - used by: %s\n",
1675 current->comm); 1676 current->comm);
1676 if (ACPI_FAILURE(status)) 1677 if (ACPI_FAILURE(status))
1677 return -EINVAL; 1678 return -EINVAL;
@@ -1683,7 +1684,7 @@ static DEVICE_ATTR(threeg, S_IRUGO | S_IWUSR, show_bool_threeg,
1683static ssize_t show_interface(struct device *dev, struct device_attribute *attr, 1684static ssize_t show_interface(struct device *dev, struct device_attribute *attr,
1684 char *buf) 1685 char *buf)
1685{ 1686{
1686 pr_info("This interface sysfs will be removed in 2012 - used by: %s\n", 1687 pr_info("This interface sysfs will be removed in 2014 - used by: %s\n",
1687 current->comm); 1688 current->comm);
1688 switch (interface->type) { 1689 switch (interface->type) {
1689 case ACER_AMW0: 1690 case ACER_AMW0:
@@ -1777,7 +1778,7 @@ static void acer_wmi_notify(u32 value, void *context)
1777 } 1778 }
1778} 1779}
1779 1780
1780static acpi_status 1781static acpi_status __init
1781wmid3_set_lm_mode(struct lm_input_params *params, 1782wmid3_set_lm_mode(struct lm_input_params *params,
1782 struct lm_return_value *return_value) 1783 struct lm_return_value *return_value)
1783{ 1784{
@@ -1811,7 +1812,7 @@ wmid3_set_lm_mode(struct lm_input_params *params,
1811 return status; 1812 return status;
1812} 1813}
1813 1814
1814static int acer_wmi_enable_ec_raw(void) 1815static int __init acer_wmi_enable_ec_raw(void)
1815{ 1816{
1816 struct lm_return_value return_value; 1817 struct lm_return_value return_value;
1817 acpi_status status; 1818 acpi_status status;
@@ -1834,7 +1835,7 @@ static int acer_wmi_enable_ec_raw(void)
1834 return status; 1835 return status;
1835} 1836}
1836 1837
1837static int acer_wmi_enable_lm(void) 1838static int __init acer_wmi_enable_lm(void)
1838{ 1839{
1839 struct lm_return_value return_value; 1840 struct lm_return_value return_value;
1840 acpi_status status; 1841 acpi_status status;
@@ -2043,6 +2044,7 @@ static int acer_platform_remove(struct platform_device *device)
2043 return 0; 2044 return 0;
2044} 2045}
2045 2046
2047#ifdef CONFIG_PM_SLEEP
2046static int acer_suspend(struct device *dev) 2048static int acer_suspend(struct device *dev)
2047{ 2049{
2048 u32 value; 2050 u32 value;
@@ -2083,6 +2085,10 @@ static int acer_resume(struct device *dev)
2083 2085
2084 return 0; 2086 return 0;
2085} 2087}
2088#else
2089#define acer_suspend NULL
2090#define acer_resume NULL
2091#endif
2086 2092
2087static SIMPLE_DEV_PM_OPS(acer_pm, acer_suspend, acer_resume); 2093static SIMPLE_DEV_PM_OPS(acer_pm, acer_suspend, acer_resume);
2088 2094
@@ -2120,7 +2126,7 @@ static int remove_sysfs(struct platform_device *device)
2120 return 0; 2126 return 0;
2121} 2127}
2122 2128
2123static int create_sysfs(void) 2129static int __init create_sysfs(void)
2124{ 2130{
2125 int retval = -ENOMEM; 2131 int retval = -ENOMEM;
2126 2132
@@ -2149,7 +2155,7 @@ static void remove_debugfs(void)
2149 debugfs_remove(interface->debug.root); 2155 debugfs_remove(interface->debug.root);
2150} 2156}
2151 2157
2152static int create_debugfs(void) 2158static int __init create_debugfs(void)
2153{ 2159{
2154 interface->debug.root = debugfs_create_dir("acer-wmi", NULL); 2160 interface->debug.root = debugfs_create_dir("acer-wmi", NULL);
2155 if (!interface->debug.root) { 2161 if (!interface->debug.root) {
diff --git a/drivers/platform/x86/alienware-wmi.c b/drivers/platform/x86/alienware-wmi.c
index 297b6640213f..c5af23b64438 100644
--- a/drivers/platform/x86/alienware-wmi.c
+++ b/drivers/platform/x86/alienware-wmi.c
@@ -59,25 +59,33 @@ enum WMAX_CONTROL_STATES {
59 59
60struct quirk_entry { 60struct quirk_entry {
61 u8 num_zones; 61 u8 num_zones;
62 u8 hdmi_mux;
62}; 63};
63 64
64static struct quirk_entry *quirks; 65static struct quirk_entry *quirks;
65 66
66static struct quirk_entry quirk_unknown = { 67static struct quirk_entry quirk_unknown = {
67 .num_zones = 2, 68 .num_zones = 2,
69 .hdmi_mux = 0,
68}; 70};
69 71
70static struct quirk_entry quirk_x51_family = { 72static struct quirk_entry quirk_x51_family = {
71 .num_zones = 3, 73 .num_zones = 3,
74 .hdmi_mux = 0.
72}; 75};
73 76
74static int dmi_matched(const struct dmi_system_id *dmi) 77static struct quirk_entry quirk_asm100 = {
78 .num_zones = 2,
79 .hdmi_mux = 1,
80};
81
82static int __init dmi_matched(const struct dmi_system_id *dmi)
75{ 83{
76 quirks = dmi->driver_data; 84 quirks = dmi->driver_data;
77 return 1; 85 return 1;
78} 86}
79 87
80static struct dmi_system_id alienware_quirks[] = { 88static const struct dmi_system_id alienware_quirks[] __initconst = {
81 { 89 {
82 .callback = dmi_matched, 90 .callback = dmi_matched,
83 .ident = "Alienware X51 R1", 91 .ident = "Alienware X51 R1",
@@ -96,6 +104,15 @@ static struct dmi_system_id alienware_quirks[] = {
96 }, 104 },
97 .driver_data = &quirk_x51_family, 105 .driver_data = &quirk_x51_family,
98 }, 106 },
107 {
108 .callback = dmi_matched,
109 .ident = "Alienware ASM100",
110 .matches = {
111 DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
112 DMI_MATCH(DMI_PRODUCT_NAME, "ASM100"),
113 },
114 .driver_data = &quirk_asm100,
115 },
99 {} 116 {}
100}; 117};
101 118
@@ -537,7 +554,8 @@ static struct attribute_group hdmi_attribute_group = {
537 554
538static void remove_hdmi(struct platform_device *dev) 555static void remove_hdmi(struct platform_device *dev)
539{ 556{
540 sysfs_remove_group(&dev->dev.kobj, &hdmi_attribute_group); 557 if (quirks->hdmi_mux > 0)
558 sysfs_remove_group(&dev->dev.kobj, &hdmi_attribute_group);
541} 559}
542 560
543static int create_hdmi(struct platform_device *dev) 561static int create_hdmi(struct platform_device *dev)
@@ -583,7 +601,7 @@ static int __init alienware_wmi_init(void)
583 if (ret) 601 if (ret)
584 goto fail_platform_device2; 602 goto fail_platform_device2;
585 603
586 if (interface == WMAX) { 604 if (quirks->hdmi_mux > 0) {
587 ret = create_hdmi(platform_device); 605 ret = create_hdmi(platform_device);
588 if (ret) 606 if (ret)
589 goto fail_prep_hdmi; 607 goto fail_prep_hdmi;
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index ddf0eefd862c..3a4951f46065 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -70,17 +70,35 @@ static struct quirk_entry quirk_asus_x55u = {
70 .no_display_toggle = true, 70 .no_display_toggle = true,
71}; 71};
72 72
73static struct quirk_entry quirk_asus_x401u = { 73static struct quirk_entry quirk_asus_wapf4 = {
74 .wapf = 4, 74 .wapf = 4,
75}; 75};
76 76
77static struct quirk_entry quirk_asus_x200ca = {
78 .wapf = 2,
79};
80
77static int dmi_matched(const struct dmi_system_id *dmi) 81static int dmi_matched(const struct dmi_system_id *dmi)
78{ 82{
79 quirks = dmi->driver_data; 83 quirks = dmi->driver_data;
80 return 1; 84 return 1;
81} 85}
82 86
83static struct dmi_system_id asus_quirks[] = { 87static const struct dmi_system_id asus_quirks[] = {
88 {
89 .callback = dmi_matched,
90 .ident = "ASUSTeK COMPUTER INC. U32U",
91 .matches = {
92 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
93 DMI_MATCH(DMI_PRODUCT_NAME, "U32U"),
94 },
95 /*
96 * Note this machine has a Brazos APU, and most Brazos Asus
97 * machines need quirk_asus_x55u / wmi_backlight_power but
98 * here acpi-video seems to work fine for backlight control.
99 */
100 .driver_data = &quirk_asus_wapf4,
101 },
84 { 102 {
85 .callback = dmi_matched, 103 .callback = dmi_matched,
86 .ident = "ASUSTeK COMPUTER INC. X401U", 104 .ident = "ASUSTeK COMPUTER INC. X401U",
@@ -97,7 +115,7 @@ static struct dmi_system_id asus_quirks[] = {
97 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 115 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
98 DMI_MATCH(DMI_PRODUCT_NAME, "X401A"), 116 DMI_MATCH(DMI_PRODUCT_NAME, "X401A"),
99 }, 117 },
100 .driver_data = &quirk_asus_x401u, 118 .driver_data = &quirk_asus_wapf4,
101 }, 119 },
102 { 120 {
103 .callback = dmi_matched, 121 .callback = dmi_matched,
@@ -106,7 +124,7 @@ static struct dmi_system_id asus_quirks[] = {
106 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 124 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
107 DMI_MATCH(DMI_PRODUCT_NAME, "X401A1"), 125 DMI_MATCH(DMI_PRODUCT_NAME, "X401A1"),
108 }, 126 },
109 .driver_data = &quirk_asus_x401u, 127 .driver_data = &quirk_asus_wapf4,
110 }, 128 },
111 { 129 {
112 .callback = dmi_matched, 130 .callback = dmi_matched,
@@ -124,7 +142,7 @@ static struct dmi_system_id asus_quirks[] = {
124 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 142 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
125 DMI_MATCH(DMI_PRODUCT_NAME, "X501A"), 143 DMI_MATCH(DMI_PRODUCT_NAME, "X501A"),
126 }, 144 },
127 .driver_data = &quirk_asus_x401u, 145 .driver_data = &quirk_asus_wapf4,
128 }, 146 },
129 { 147 {
130 .callback = dmi_matched, 148 .callback = dmi_matched,
@@ -133,7 +151,7 @@ static struct dmi_system_id asus_quirks[] = {
133 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 151 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
134 DMI_MATCH(DMI_PRODUCT_NAME, "X501A1"), 152 DMI_MATCH(DMI_PRODUCT_NAME, "X501A1"),
135 }, 153 },
136 .driver_data = &quirk_asus_x401u, 154 .driver_data = &quirk_asus_wapf4,
137 }, 155 },
138 { 156 {
139 .callback = dmi_matched, 157 .callback = dmi_matched,
@@ -142,7 +160,25 @@ static struct dmi_system_id asus_quirks[] = {
142 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 160 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
143 DMI_MATCH(DMI_PRODUCT_NAME, "X550CA"), 161 DMI_MATCH(DMI_PRODUCT_NAME, "X550CA"),
144 }, 162 },
145 .driver_data = &quirk_asus_x401u, 163 .driver_data = &quirk_asus_wapf4,
164 },
165 {
166 .callback = dmi_matched,
167 .ident = "ASUSTeK COMPUTER INC. X550CC",
168 .matches = {
169 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
170 DMI_MATCH(DMI_PRODUCT_NAME, "X550CC"),
171 },
172 .driver_data = &quirk_asus_wapf4,
173 },
174 {
175 .callback = dmi_matched,
176 .ident = "ASUSTeK COMPUTER INC. X550CL",
177 .matches = {
178 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
179 DMI_MATCH(DMI_PRODUCT_NAME, "X550CL"),
180 },
181 .driver_data = &quirk_asus_wapf4,
146 }, 182 },
147 { 183 {
148 .callback = dmi_matched, 184 .callback = dmi_matched,
@@ -151,7 +187,7 @@ static struct dmi_system_id asus_quirks[] = {
151 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 187 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
152 DMI_MATCH(DMI_PRODUCT_NAME, "X55A"), 188 DMI_MATCH(DMI_PRODUCT_NAME, "X55A"),
153 }, 189 },
154 .driver_data = &quirk_asus_x401u, 190 .driver_data = &quirk_asus_wapf4,
155 }, 191 },
156 { 192 {
157 .callback = dmi_matched, 193 .callback = dmi_matched,
@@ -160,7 +196,7 @@ static struct dmi_system_id asus_quirks[] = {
160 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 196 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
161 DMI_MATCH(DMI_PRODUCT_NAME, "X55C"), 197 DMI_MATCH(DMI_PRODUCT_NAME, "X55C"),
162 }, 198 },
163 .driver_data = &quirk_asus_x401u, 199 .driver_data = &quirk_asus_wapf4,
164 }, 200 },
165 { 201 {
166 .callback = dmi_matched, 202 .callback = dmi_matched,
@@ -178,7 +214,7 @@ static struct dmi_system_id asus_quirks[] = {
178 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 214 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
179 DMI_MATCH(DMI_PRODUCT_NAME, "X55VD"), 215 DMI_MATCH(DMI_PRODUCT_NAME, "X55VD"),
180 }, 216 },
181 .driver_data = &quirk_asus_x401u, 217 .driver_data = &quirk_asus_wapf4,
182 }, 218 },
183 { 219 {
184 .callback = dmi_matched, 220 .callback = dmi_matched,
@@ -187,7 +223,16 @@ static struct dmi_system_id asus_quirks[] = {
187 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 223 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
188 DMI_MATCH(DMI_PRODUCT_NAME, "X75A"), 224 DMI_MATCH(DMI_PRODUCT_NAME, "X75A"),
189 }, 225 },
190 .driver_data = &quirk_asus_x401u, 226 .driver_data = &quirk_asus_wapf4,
227 },
228 {
229 .callback = dmi_matched,
230 .ident = "ASUSTeK COMPUTER INC. X75VBP",
231 .matches = {
232 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
233 DMI_MATCH(DMI_PRODUCT_NAME, "X75VBP"),
234 },
235 .driver_data = &quirk_asus_wapf4,
191 }, 236 },
192 { 237 {
193 .callback = dmi_matched, 238 .callback = dmi_matched,
@@ -196,7 +241,7 @@ static struct dmi_system_id asus_quirks[] = {
196 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 241 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
197 DMI_MATCH(DMI_PRODUCT_NAME, "1015E"), 242 DMI_MATCH(DMI_PRODUCT_NAME, "1015E"),
198 }, 243 },
199 .driver_data = &quirk_asus_x401u, 244 .driver_data = &quirk_asus_wapf4,
200 }, 245 },
201 { 246 {
202 .callback = dmi_matched, 247 .callback = dmi_matched,
@@ -205,7 +250,16 @@ static struct dmi_system_id asus_quirks[] = {
205 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 250 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
206 DMI_MATCH(DMI_PRODUCT_NAME, "1015U"), 251 DMI_MATCH(DMI_PRODUCT_NAME, "1015U"),
207 }, 252 },
208 .driver_data = &quirk_asus_x401u, 253 .driver_data = &quirk_asus_wapf4,
254 },
255 {
256 .callback = dmi_matched,
257 .ident = "ASUSTeK COMPUTER INC. X200CA",
258 .matches = {
259 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
260 DMI_MATCH(DMI_PRODUCT_NAME, "X200CA"),
261 },
262 .driver_data = &quirk_asus_x200ca,
209 }, 263 },
210 {}, 264 {},
211}; 265};
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 3c6ccedc82b6..21fc932da3a1 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -46,6 +46,7 @@
46#include <linux/platform_device.h> 46#include <linux/platform_device.h>
47#include <linux/thermal.h> 47#include <linux/thermal.h>
48#include <linux/acpi.h> 48#include <linux/acpi.h>
49#include <linux/dmi.h>
49#include <acpi/video.h> 50#include <acpi/video.h>
50 51
51#include "asus-wmi.h" 52#include "asus-wmi.h"
@@ -554,7 +555,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
554 goto error; 555 goto error;
555 } 556 }
556 557
557 if (wlan_led_presence(asus) && (asus->driver->quirks->wapf == 4)) { 558 if (wlan_led_presence(asus) && (asus->driver->quirks->wapf > 0)) {
558 INIT_WORK(&asus->wlan_led_work, wlan_led_update); 559 INIT_WORK(&asus->wlan_led_work, wlan_led_update);
559 560
560 asus->wlan_led.name = "asus::wlan"; 561 asus->wlan_led.name = "asus::wlan";
@@ -884,7 +885,7 @@ static int asus_new_rfkill(struct asus_wmi *asus,
884 return -EINVAL; 885 return -EINVAL;
885 886
886 if ((dev_id == ASUS_WMI_DEVID_WLAN) && 887 if ((dev_id == ASUS_WMI_DEVID_WLAN) &&
887 (asus->driver->quirks->wapf == 4)) 888 (asus->driver->quirks->wapf > 0))
888 rfkill_set_led_trigger_name(*rfkill, "asus-wlan"); 889 rfkill_set_led_trigger_name(*rfkill, "asus-wlan");
889 890
890 rfkill_init_sw_state(*rfkill, !result); 891 rfkill_init_sw_state(*rfkill, !result);
@@ -1270,10 +1271,7 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus)
1270 int power; 1271 int power;
1271 1272
1272 max = read_brightness_max(asus); 1273 max = read_brightness_max(asus);
1273 1274 if (max < 0)
1274 if (max == -ENODEV)
1275 max = 0;
1276 else if (max < 0)
1277 return max; 1275 return max;
1278 1276
1279 power = read_backlight_power(asus); 1277 power = read_backlight_power(asus);
@@ -1734,6 +1732,7 @@ static int asus_wmi_add(struct platform_device *pdev)
1734 struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver); 1732 struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
1735 struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv); 1733 struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
1736 struct asus_wmi *asus; 1734 struct asus_wmi *asus;
1735 const char *chassis_type;
1737 acpi_status status; 1736 acpi_status status;
1738 int err; 1737 int err;
1739 u32 result; 1738 u32 result;
@@ -1770,6 +1769,11 @@ static int asus_wmi_add(struct platform_device *pdev)
1770 if (err) 1769 if (err)
1771 goto fail_rfkill; 1770 goto fail_rfkill;
1772 1771
1772 /* Some Asus desktop boards export an acpi-video backlight interface,
1773 stop this from showing up */
1774 chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
1775 if (chassis_type && !strcmp(chassis_type, "3"))
1776 acpi_video_dmi_promote_vendor();
1773 if (asus->driver->quirks->wmi_backlight_power) 1777 if (asus->driver->quirks->wmi_backlight_power)
1774 acpi_video_dmi_promote_vendor(); 1778 acpi_video_dmi_promote_vendor();
1775 if (!acpi_video_backlight_support()) { 1779 if (!acpi_video_backlight_support()) {
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c
index 7297df2ebf50..26bfd7bb5c13 100644
--- a/drivers/platform/x86/compal-laptop.c
+++ b/drivers/platform/x86/compal-laptop.c
@@ -1028,7 +1028,7 @@ static int compal_probe(struct platform_device *pdev)
1028 return err; 1028 return err;
1029 1029
1030 hwmon_dev = hwmon_device_register_with_groups(&pdev->dev, 1030 hwmon_dev = hwmon_device_register_with_groups(&pdev->dev,
1031 DRIVER_NAME, data, 1031 "compal", data,
1032 compal_hwmon_groups); 1032 compal_hwmon_groups);
1033 if (IS_ERR(hwmon_dev)) { 1033 if (IS_ERR(hwmon_dev)) {
1034 err = PTR_ERR(hwmon_dev); 1034 err = PTR_ERR(hwmon_dev);
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index fed4111ac31a..233d2ee598a6 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -70,7 +70,7 @@ static struct quirk_entry quirk_dell_vostro_v130 = {
70 .touchpad_led = 1, 70 .touchpad_led = 1,
71}; 71};
72 72
73static int dmi_matched(const struct dmi_system_id *dmi) 73static int __init dmi_matched(const struct dmi_system_id *dmi)
74{ 74{
75 quirks = dmi->driver_data; 75 quirks = dmi->driver_data;
76 return 1; 76 return 1;
@@ -123,7 +123,7 @@ static const struct dmi_system_id dell_device_table[] __initconst = {
123}; 123};
124MODULE_DEVICE_TABLE(dmi, dell_device_table); 124MODULE_DEVICE_TABLE(dmi, dell_device_table);
125 125
126static struct dmi_system_id dell_quirks[] = { 126static const struct dmi_system_id dell_quirks[] __initconst = {
127 { 127 {
128 .callback = dmi_matched, 128 .callback = dmi_matched,
129 .ident = "Dell Vostro V130", 129 .ident = "Dell Vostro V130",
@@ -780,7 +780,7 @@ static struct led_classdev touchpad_led = {
780 .flags = LED_CORE_SUSPENDRESUME, 780 .flags = LED_CORE_SUSPENDRESUME,
781}; 781};
782 782
783static int touchpad_led_init(struct device *dev) 783static int __init touchpad_led_init(struct device *dev)
784{ 784{
785 return led_classdev_register(dev, &touchpad_led); 785 return led_classdev_register(dev, &touchpad_led);
786} 786}
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 9b0c57cd1d4a..bd533c22be57 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -1053,20 +1053,20 @@ static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
1053 return sprintf(buf, "%d\n", get()); 1053 return sprintf(buf, "%d\n", get());
1054} 1054}
1055 1055
1056#define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \ 1056#define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _get, _set) \
1057 static ssize_t show_##_name(struct device *dev, \ 1057 static ssize_t show_##_name(struct device *dev, \
1058 struct device_attribute *attr, \ 1058 struct device_attribute *attr, \
1059 char *buf) \ 1059 char *buf) \
1060 { \ 1060 { \
1061 return show_sys_hwmon(_set, buf); \ 1061 return show_sys_hwmon(_get, buf); \
1062 } \ 1062 } \
1063 static ssize_t store_##_name(struct device *dev, \ 1063 static ssize_t store_##_name(struct device *dev, \
1064 struct device_attribute *attr, \ 1064 struct device_attribute *attr, \
1065 const char *buf, size_t count) \ 1065 const char *buf, size_t count) \
1066 { \ 1066 { \
1067 return store_sys_hwmon(_get, buf, count); \ 1067 return store_sys_hwmon(_set, buf, count); \
1068 } \ 1068 } \
1069 static DEVICE_ATTR(_name, _mode, show_##_name, store_##_name); 1069 static DEVICE_ATTR(_name, _mode, show_##_name, store_##_name)
1070 1070
1071EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL); 1071EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
1072EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR, 1072EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 6112933f6278..14fd2ecb06a1 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -145,7 +145,7 @@ static int dmi_matched(const struct dmi_system_id *dmi)
145 return 1; 145 return 1;
146} 146}
147 147
148static struct dmi_system_id asus_quirks[] = { 148static const struct dmi_system_id asus_quirks[] = {
149 { 149 {
150 .callback = dmi_matched, 150 .callback = dmi_matched,
151 .ident = "ASUSTeK Computer INC. 1000H", 151 .ident = "ASUSTeK Computer INC. 1000H",
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index e6f336270c21..87aa28c4280f 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -129,15 +129,14 @@
129#define FUJLAPTOP_DBG_INFO 0x0004 129#define FUJLAPTOP_DBG_INFO 0x0004
130#define FUJLAPTOP_DBG_TRACE 0x0008 130#define FUJLAPTOP_DBG_TRACE 0x0008
131 131
132#define dbg_printk(a_dbg_level, format, arg...) \ 132#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
133#define vdbg_printk(a_dbg_level, format, arg...) \
133 do { if (dbg_level & a_dbg_level) \ 134 do { if (dbg_level & a_dbg_level) \
134 printk(FUJLAPTOP_DEBUG "%s: " format, __func__ , ## arg); \ 135 printk(FUJLAPTOP_DEBUG "%s: " format, __func__ , ## arg); \
135 } while (0) 136 } while (0)
136#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
137#define vdbg_printk(a_dbg_level, format, arg...) \
138 dbg_printk(a_dbg_level, format, ## arg)
139#else 137#else
140#define vdbg_printk(a_dbg_level, format, arg...) 138#define vdbg_printk(a_dbg_level, format, arg...) \
139 do { } while (0)
141#endif 140#endif
142 141
143/* Device controlling the backlight and associated keys */ 142/* Device controlling the backlight and associated keys */
@@ -564,7 +563,7 @@ static struct platform_driver fujitsupf_driver = {
564 } 563 }
565}; 564};
566 565
567static void dmi_check_cb_common(const struct dmi_system_id *id) 566static void __init dmi_check_cb_common(const struct dmi_system_id *id)
568{ 567{
569 pr_info("Identified laptop model '%s'\n", id->ident); 568 pr_info("Identified laptop model '%s'\n", id->ident);
570 if (use_alt_lcd_levels == -1) { 569 if (use_alt_lcd_levels == -1) {
@@ -578,7 +577,7 @@ static void dmi_check_cb_common(const struct dmi_system_id *id)
578 } 577 }
579} 578}
580 579
581static int dmi_check_cb_s6410(const struct dmi_system_id *id) 580static int __init dmi_check_cb_s6410(const struct dmi_system_id *id)
582{ 581{
583 dmi_check_cb_common(id); 582 dmi_check_cb_common(id);
584 fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */ 583 fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */
@@ -586,7 +585,7 @@ static int dmi_check_cb_s6410(const struct dmi_system_id *id)
586 return 1; 585 return 1;
587} 586}
588 587
589static int dmi_check_cb_s6420(const struct dmi_system_id *id) 588static int __init dmi_check_cb_s6420(const struct dmi_system_id *id)
590{ 589{
591 dmi_check_cb_common(id); 590 dmi_check_cb_common(id);
592 fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */ 591 fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */
@@ -594,7 +593,7 @@ static int dmi_check_cb_s6420(const struct dmi_system_id *id)
594 return 1; 593 return 1;
595} 594}
596 595
597static int dmi_check_cb_p8010(const struct dmi_system_id *id) 596static int __init dmi_check_cb_p8010(const struct dmi_system_id *id)
598{ 597{
599 dmi_check_cb_common(id); 598 dmi_check_cb_common(id);
600 fujitsu->keycode1 = KEY_HELP; /* "Support" */ 599 fujitsu->keycode1 = KEY_HELP; /* "Support" */
@@ -603,7 +602,7 @@ static int dmi_check_cb_p8010(const struct dmi_system_id *id)
603 return 1; 602 return 1;
604} 603}
605 604
606static struct dmi_system_id fujitsu_dmi_table[] = { 605static const struct dmi_system_id fujitsu_dmi_table[] __initconst = {
607 { 606 {
608 .ident = "Fujitsu Siemens S6410", 607 .ident = "Fujitsu Siemens S6410",
609 .matches = { 608 .matches = {
diff --git a/drivers/platform/x86/fujitsu-tablet.c b/drivers/platform/x86/fujitsu-tablet.c
index c3784baceae3..53bdbb01bd3f 100644
--- a/drivers/platform/x86/fujitsu-tablet.c
+++ b/drivers/platform/x86/fujitsu-tablet.c
@@ -315,21 +315,21 @@ static irqreturn_t fujitsu_interrupt(int irq, void *dev_id)
315 return IRQ_HANDLED; 315 return IRQ_HANDLED;
316} 316}
317 317
318static void fujitsu_dmi_common(const struct dmi_system_id *dmi) 318static void __init fujitsu_dmi_common(const struct dmi_system_id *dmi)
319{ 319{
320 pr_info("%s\n", dmi->ident); 320 pr_info("%s\n", dmi->ident);
321 memcpy(fujitsu.config.keymap, dmi->driver_data, 321 memcpy(fujitsu.config.keymap, dmi->driver_data,
322 sizeof(fujitsu.config.keymap)); 322 sizeof(fujitsu.config.keymap));
323} 323}
324 324
325static int fujitsu_dmi_lifebook(const struct dmi_system_id *dmi) 325static int __init fujitsu_dmi_lifebook(const struct dmi_system_id *dmi)
326{ 326{
327 fujitsu_dmi_common(dmi); 327 fujitsu_dmi_common(dmi);
328 fujitsu.config.quirks |= INVERT_TABLET_MODE_BIT; 328 fujitsu.config.quirks |= INVERT_TABLET_MODE_BIT;
329 return 1; 329 return 1;
330} 330}
331 331
332static int fujitsu_dmi_stylistic(const struct dmi_system_id *dmi) 332static int __init fujitsu_dmi_stylistic(const struct dmi_system_id *dmi)
333{ 333{
334 fujitsu_dmi_common(dmi); 334 fujitsu_dmi_common(dmi);
335 fujitsu.config.quirks |= FORCE_TABLET_MODE_IF_UNDOCK; 335 fujitsu.config.quirks |= FORCE_TABLET_MODE_IF_UNDOCK;
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index 484a8673b835..4c559640dcba 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -295,7 +295,7 @@ static int hp_wmi_tablet_state(void)
295 return (state & 0x4) ? 1 : 0; 295 return (state & 0x4) ? 1 : 0;
296} 296}
297 297
298static int hp_wmi_bios_2009_later(void) 298static int __init hp_wmi_bios_2009_later(void)
299{ 299{
300 int state = 0; 300 int state = 0;
301 int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, 0, &state, 301 int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, 0, &state,
@@ -704,7 +704,7 @@ static void cleanup_sysfs(struct platform_device *device)
704 device_remove_file(&device->dev, &dev_attr_postcode); 704 device_remove_file(&device->dev, &dev_attr_postcode);
705} 705}
706 706
707static int hp_wmi_rfkill_setup(struct platform_device *device) 707static int __init hp_wmi_rfkill_setup(struct platform_device *device)
708{ 708{
709 int err; 709 int err;
710 int wireless = 0; 710 int wireless = 0;
@@ -806,7 +806,7 @@ register_wifi_error:
806 return err; 806 return err;
807} 807}
808 808
809static int hp_wmi_rfkill2_setup(struct platform_device *device) 809static int __init hp_wmi_rfkill2_setup(struct platform_device *device)
810{ 810{
811 int err, i; 811 int err, i;
812 struct bios_rfkill2_state state; 812 struct bios_rfkill2_state state;
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c
index 3dc934438c28..13e14ec1d3d7 100644
--- a/drivers/platform/x86/hp_accel.c
+++ b/drivers/platform/x86/hp_accel.c
@@ -74,7 +74,7 @@ static inline void delayed_sysfs_set(struct led_classdev *led_cdev,
74/* HP-specific accelerometer driver ------------------------------------ */ 74/* HP-specific accelerometer driver ------------------------------------ */
75 75
76/* For automatic insertion of the module */ 76/* For automatic insertion of the module */
77static struct acpi_device_id lis3lv02d_device_ids[] = { 77static const struct acpi_device_id lis3lv02d_device_ids[] = {
78 {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */ 78 {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */
79 {"HPQ6000", 0}, /* HP Mobile Data Protection System PNP */ 79 {"HPQ6000", 0}, /* HP Mobile Data Protection System PNP */
80 {"HPQ6007", 0}, /* HP Mobile Data Protection System PNP */ 80 {"HPQ6007", 0}, /* HP Mobile Data Protection System PNP */
@@ -192,7 +192,7 @@ DEFINE_CONV(xy_swap_yz_inverted, 2, -1, -3);
192 }, \ 192 }, \
193 .driver_data = &lis3lv02d_axis_##_axis \ 193 .driver_data = &lis3lv02d_axis_##_axis \
194} 194}
195static struct dmi_system_id lis3lv02d_dmi_ids[] = { 195static const struct dmi_system_id lis3lv02d_dmi_ids[] = {
196 /* product names are truncated to match all kinds of a same model */ 196 /* product names are truncated to match all kinds of a same model */
197 AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted), 197 AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted),
198 AXIS_DMI_MATCH("NC84x0", "HP Compaq nc84", z_inverted), 198 AXIS_DMI_MATCH("NC84x0", "HP Compaq nc84", z_inverted),
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index b4c495a62eec..fc468a3d95ce 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -87,6 +87,8 @@ struct ideapad_private {
87 struct backlight_device *blightdev; 87 struct backlight_device *blightdev;
88 struct dentry *debug; 88 struct dentry *debug;
89 unsigned long cfg; 89 unsigned long cfg;
90 bool has_hw_rfkill_switch;
91 bool has_touchpad_control;
90}; 92};
91 93
92static bool no_bt_rfkill; 94static bool no_bt_rfkill;
@@ -439,7 +441,7 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
439 return supported ? attr->mode : 0; 441 return supported ? attr->mode : 0;
440} 442}
441 443
442static struct attribute_group ideapad_attribute_group = { 444static const struct attribute_group ideapad_attribute_group = {
443 .is_visible = ideapad_is_visible, 445 .is_visible = ideapad_is_visible,
444 .attrs = ideapad_attributes 446 .attrs = ideapad_attributes
445}; 447};
@@ -454,7 +456,7 @@ struct ideapad_rfk_data {
454 int type; 456 int type;
455}; 457};
456 458
457const struct ideapad_rfk_data ideapad_rfk_data[] = { 459const const struct ideapad_rfk_data ideapad_rfk_data[] = {
458 { "ideapad_wlan", CFG_WIFI_BIT, VPCCMD_W_WIFI, RFKILL_TYPE_WLAN }, 460 { "ideapad_wlan", CFG_WIFI_BIT, VPCCMD_W_WIFI, RFKILL_TYPE_WLAN },
459 { "ideapad_bluetooth", CFG_BT_BIT, VPCCMD_W_BT, RFKILL_TYPE_BLUETOOTH }, 461 { "ideapad_bluetooth", CFG_BT_BIT, VPCCMD_W_BT, RFKILL_TYPE_BLUETOOTH },
460 { "ideapad_3g", CFG_3G_BIT, VPCCMD_W_3G, RFKILL_TYPE_WWAN }, 462 { "ideapad_3g", CFG_3G_BIT, VPCCMD_W_3G, RFKILL_TYPE_WWAN },
@@ -473,12 +475,14 @@ static struct rfkill_ops ideapad_rfk_ops = {
473 475
474static void ideapad_sync_rfk_state(struct ideapad_private *priv) 476static void ideapad_sync_rfk_state(struct ideapad_private *priv)
475{ 477{
476 unsigned long hw_blocked; 478 unsigned long hw_blocked = 0;
477 int i; 479 int i;
478 480
479 if (read_ec_data(priv->adev->handle, VPCCMD_R_RF, &hw_blocked)) 481 if (priv->has_hw_rfkill_switch) {
480 return; 482 if (read_ec_data(priv->adev->handle, VPCCMD_R_RF, &hw_blocked))
481 hw_blocked = !hw_blocked; 483 return;
484 hw_blocked = !hw_blocked;
485 }
482 486
483 for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) 487 for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++)
484 if (priv->rfk[i]) 488 if (priv->rfk[i])
@@ -763,6 +767,9 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv)
763{ 767{
764 unsigned long value; 768 unsigned long value;
765 769
770 if (!priv->has_touchpad_control)
771 return;
772
766 /* Without reading from EC touchpad LED doesn't switch state */ 773 /* Without reading from EC touchpad LED doesn't switch state */
767 if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { 774 if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) {
768 /* Some IdeaPads don't really turn off touchpad - they only 775 /* Some IdeaPads don't really turn off touchpad - they only
@@ -821,14 +828,39 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data)
821 } 828 }
822} 829}
823 830
824/* Blacklist for devices where the ideapad rfkill interface does not work */ 831/*
825static struct dmi_system_id rfkill_blacklist[] = { 832 * Some ideapads don't have a hardware rfkill switch, reading VPCCMD_R_RF
826 /* The Lenovo Yoga 2 11 always reports everything as blocked */ 833 * always results in 0 on these models, causing ideapad_laptop to wrongly
834 * report all radios as hardware-blocked.
835 */
836static struct dmi_system_id no_hw_rfkill_list[] = {
827 { 837 {
828 .ident = "Lenovo Yoga 2 11", 838 .ident = "Lenovo Yoga 2 11 / 13 / Pro",
829 .matches = { 839 .matches = {
830 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 840 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
831 DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2 11"), 841 DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2"),
842 },
843 },
844 {}
845};
846
847/*
848 * Some models don't offer touchpad ctrl through the ideapad interface, causing
849 * ideapad_sync_touchpad_state to send wrong touchpad enable/disable events.
850 */
851static struct dmi_system_id no_touchpad_ctrl_list[] = {
852 {
853 .ident = "Lenovo Yoga 1 series",
854 .matches = {
855 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
856 DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Yoga"),
857 },
858 },
859 {
860 .ident = "Lenovo Yoga 2 11 / 13 / Pro",
861 .matches = {
862 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
863 DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2"),
832 }, 864 },
833 }, 865 },
834 {} 866 {}
@@ -856,6 +888,8 @@ static int ideapad_acpi_add(struct platform_device *pdev)
856 priv->cfg = cfg; 888 priv->cfg = cfg;
857 priv->adev = adev; 889 priv->adev = adev;
858 priv->platform_device = pdev; 890 priv->platform_device = pdev;
891 priv->has_hw_rfkill_switch = !dmi_check_system(no_hw_rfkill_list);
892 priv->has_touchpad_control = !dmi_check_system(no_touchpad_ctrl_list);
859 893
860 ret = ideapad_sysfs_init(priv); 894 ret = ideapad_sysfs_init(priv);
861 if (ret) 895 if (ret)
@@ -869,11 +903,17 @@ static int ideapad_acpi_add(struct platform_device *pdev)
869 if (ret) 903 if (ret)
870 goto input_failed; 904 goto input_failed;
871 905
872 if (!dmi_check_system(rfkill_blacklist)) { 906 /*
873 for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) 907 * On some models without a hw-switch (the yoga 2 13 at least)
874 if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) 908 * VPCCMD_W_RF must be explicitly set to 1 for the wifi to work.
875 ideapad_register_rfkill(priv, i); 909 */
876 } 910 if (!priv->has_hw_rfkill_switch)
911 write_ec_cmd(priv->adev->handle, VPCCMD_W_RF, 1);
912
913 for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++)
914 if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg))
915 ideapad_register_rfkill(priv, i);
916
877 ideapad_sync_rfk_state(priv); 917 ideapad_sync_rfk_state(priv);
878 ideapad_sync_touchpad_state(priv); 918 ideapad_sync_touchpad_state(priv);
879 919
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index a0d1f576cf40..c0242ed13d9e 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -269,7 +269,7 @@ struct ips_mcp_limits {
269 269
270/* Max temps are -10 degrees C to avoid PROCHOT# */ 270/* Max temps are -10 degrees C to avoid PROCHOT# */
271 271
272struct ips_mcp_limits ips_sv_limits = { 272static struct ips_mcp_limits ips_sv_limits = {
273 .mcp_power_limit = 35000, 273 .mcp_power_limit = 35000,
274 .core_power_limit = 29000, 274 .core_power_limit = 29000,
275 .mch_power_limit = 20000, 275 .mch_power_limit = 20000,
@@ -277,7 +277,7 @@ struct ips_mcp_limits ips_sv_limits = {
277 .mch_temp_limit = 90 277 .mch_temp_limit = 90
278}; 278};
279 279
280struct ips_mcp_limits ips_lv_limits = { 280static struct ips_mcp_limits ips_lv_limits = {
281 .mcp_power_limit = 25000, 281 .mcp_power_limit = 25000,
282 .core_power_limit = 21000, 282 .core_power_limit = 21000,
283 .mch_power_limit = 13000, 283 .mch_power_limit = 13000,
@@ -285,7 +285,7 @@ struct ips_mcp_limits ips_lv_limits = {
285 .mch_temp_limit = 90 285 .mch_temp_limit = 90
286}; 286};
287 287
288struct ips_mcp_limits ips_ulv_limits = { 288static struct ips_mcp_limits ips_ulv_limits = {
289 .mcp_power_limit = 18000, 289 .mcp_power_limit = 18000,
290 .core_power_limit = 14000, 290 .core_power_limit = 14000,
291 .mch_power_limit = 11000, 291 .mch_power_limit = 11000,
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 9c5a07417b2b..26ad9ff12ac5 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -2389,7 +2389,7 @@ static int sony_nc_lid_resume_setup(struct platform_device *pd,
2389 lid_ctl->attrs[LID_RESUME_S3].store = sony_nc_lid_resume_store; 2389 lid_ctl->attrs[LID_RESUME_S3].store = sony_nc_lid_resume_store;
2390 } 2390 }
2391 for (i = 0; i < LID_RESUME_MAX && 2391 for (i = 0; i < LID_RESUME_MAX &&
2392 lid_ctl->attrs[LID_RESUME_S3].attr.name; i++) { 2392 lid_ctl->attrs[i].attr.name; i++) {
2393 result = device_create_file(&pd->dev, &lid_ctl->attrs[i]); 2393 result = device_create_file(&pd->dev, &lid_ctl->attrs[i]);
2394 if (result) 2394 if (result)
2395 goto liderror; 2395 goto liderror;
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index d82f196e3cfe..3bbc6eb60de5 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -3174,7 +3174,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3174 KEY_UNKNOWN, 3174 KEY_UNKNOWN,
3175 3175
3176 /* Extra keys in use since the X240 / T440 / T540 */ 3176 /* Extra keys in use since the X240 / T440 / T540 */
3177 KEY_CONFIG, KEY_SEARCH, KEY_SCALE, KEY_COMPUTER, 3177 KEY_CONFIG, KEY_SEARCH, KEY_SCALE, KEY_FILE,
3178 }, 3178 },
3179 }; 3179 };
3180 3180
@@ -6144,7 +6144,7 @@ static int brightness_set(unsigned int value)
6144{ 6144{
6145 int res; 6145 int res;
6146 6146
6147 if (value > bright_maxlvl || value < 0) 6147 if (value > bright_maxlvl)
6148 return -EINVAL; 6148 return -EINVAL;
6149 6149
6150 vdbg_printk(TPACPI_DBG_BRGHT, 6150 vdbg_printk(TPACPI_DBG_BRGHT,
@@ -6860,7 +6860,7 @@ static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol,
6860 return volume_alsa_set_mute(!ucontrol->value.integer.value[0]); 6860 return volume_alsa_set_mute(!ucontrol->value.integer.value[0]);
6861} 6861}
6862 6862
6863static struct snd_kcontrol_new volume_alsa_control_vol = { 6863static struct snd_kcontrol_new volume_alsa_control_vol __initdata = {
6864 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6864 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6865 .name = "Console Playback Volume", 6865 .name = "Console Playback Volume",
6866 .index = 0, 6866 .index = 0,
@@ -6869,7 +6869,7 @@ static struct snd_kcontrol_new volume_alsa_control_vol = {
6869 .get = volume_alsa_vol_get, 6869 .get = volume_alsa_vol_get,
6870}; 6870};
6871 6871
6872static struct snd_kcontrol_new volume_alsa_control_mute = { 6872static struct snd_kcontrol_new volume_alsa_control_mute __initdata = {
6873 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6873 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6874 .name = "Console Playback Switch", 6874 .name = "Console Playback Switch",
6875 .index = 0, 6875 .index = 0,
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 76441dcbe5ff..e4da61bcbf8b 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -222,6 +222,12 @@ static const struct dmi_system_id toshiba_alt_keymap_dmi[] = {
222 DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M840"), 222 DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M840"),
223 }, 223 },
224 }, 224 },
225 {
226 .matches = {
227 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
228 DMI_MATCH(DMI_PRODUCT_NAME, "Qosmio X75-A"),
229 },
230 },
225 {} 231 {}
226}; 232};
227 233
@@ -229,6 +235,7 @@ static const struct key_entry toshiba_acpi_alt_keymap[] = {
229 { KE_KEY, 0x157, { KEY_MUTE } }, 235 { KE_KEY, 0x157, { KEY_MUTE } },
230 { KE_KEY, 0x102, { KEY_ZOOMOUT } }, 236 { KE_KEY, 0x102, { KEY_ZOOMOUT } },
231 { KE_KEY, 0x103, { KEY_ZOOMIN } }, 237 { KE_KEY, 0x103, { KEY_ZOOMIN } },
238 { KE_KEY, 0x12c, { KEY_KBDILLUMTOGGLE } },
232 { KE_KEY, 0x139, { KEY_ZOOMRESET } }, 239 { KE_KEY, 0x139, { KEY_ZOOMRESET } },
233 { KE_KEY, 0x13e, { KEY_SWITCHVIDEOMODE } }, 240 { KE_KEY, 0x13e, { KEY_SWITCHVIDEOMODE } },
234 { KE_KEY, 0x13c, { KEY_BRIGHTNESSDOWN } }, 241 { KE_KEY, 0x13c, { KEY_BRIGHTNESSDOWN } },
@@ -872,7 +879,9 @@ static int lcd_proc_open(struct inode *inode, struct file *file)
872 879
873static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) 880static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value)
874{ 881{
875 u32 hci_result; 882 u32 in[HCI_WORDS] = { HCI_SET, HCI_LCD_BRIGHTNESS, 0, 0, 0, 0 };
883 u32 out[HCI_WORDS];
884 acpi_status status;
876 885
877 if (dev->tr_backlight_supported) { 886 if (dev->tr_backlight_supported) {
878 bool enable = !value; 887 bool enable = !value;
@@ -883,9 +892,20 @@ static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value)
883 value--; 892 value--;
884 } 893 }
885 894
886 value = value << HCI_LCD_BRIGHTNESS_SHIFT; 895 in[2] = value << HCI_LCD_BRIGHTNESS_SHIFT;
887 hci_write1(dev, HCI_LCD_BRIGHTNESS, value, &hci_result); 896 status = hci_raw(dev, in, out);
888 return hci_result == HCI_SUCCESS ? 0 : -EIO; 897 if (ACPI_FAILURE(status) || out[0] == HCI_FAILURE) {
898 pr_err("ACPI call to set brightness failed");
899 return -EIO;
900 }
901 /* Extra check for "incomplete" backlight method, where the AML code
902 * doesn't check for HCI_SET or HCI_GET and returns HCI_SUCCESS,
903 * the actual brightness, and in some cases the max brightness.
904 */
905 if (out[2] > 0 || out[3] == 0xE000)
906 return -ENODEV;
907
908 return out[0] == HCI_SUCCESS ? 0 : -EIO;
889} 909}
890 910
891static int set_lcd_status(struct backlight_device *bd) 911static int set_lcd_status(struct backlight_device *bd)
@@ -1238,7 +1258,7 @@ static ssize_t toshiba_kbd_bl_mode_store(struct device *dev,
1238 int mode = -1; 1258 int mode = -1;
1239 int time = -1; 1259 int time = -1;
1240 1260
1241 if (sscanf(buf, "%i", &mode) != 1 && (mode != 2 || mode != 1)) 1261 if (sscanf(buf, "%i", &mode) != 1 || (mode != 2 || mode != 1))
1242 return -EINVAL; 1262 return -EINVAL;
1243 1263
1244 /* Set the Keyboard Backlight Mode where: 1264 /* Set the Keyboard Backlight Mode where:
diff --git a/drivers/platform/x86/toshiba_haps.c b/drivers/platform/x86/toshiba_haps.c
new file mode 100644
index 000000000000..65300b6a84b9
--- /dev/null
+++ b/drivers/platform/x86/toshiba_haps.c
@@ -0,0 +1,265 @@
1/*
2 * Toshiba HDD Active Protection Sensor (HAPS) driver
3 *
4 * Copyright (C) 2014 Azael Avalos <coproscefalo@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/types.h>
24#include <linux/acpi.h>
25
26MODULE_AUTHOR("Azael Avalos <coproscefalo@gmail.com>");
27MODULE_DESCRIPTION("Toshiba HDD Active Protection Sensor");
28MODULE_LICENSE("GPL");
29
30struct toshiba_haps_dev {
31 struct acpi_device *acpi_dev;
32
33 int protection_level;
34};
35
36static struct toshiba_haps_dev *toshiba_haps;
37
38/* HAPS functions */
39static int toshiba_haps_reset_protection(acpi_handle handle)
40{
41 acpi_status status;
42
43 status = acpi_evaluate_object(handle, "RSSS", NULL, NULL);
44 if (ACPI_FAILURE(status)) {
45 pr_err("Unable to reset the HDD protection\n");
46 return -EIO;
47 }
48
49 return 0;
50}
51
52static int toshiba_haps_protection_level(acpi_handle handle, int level)
53{
54 acpi_status status;
55
56 status = acpi_execute_simple_method(handle, "PTLV", level);
57 if (ACPI_FAILURE(status)) {
58 pr_err("Error while setting the protection level\n");
59 return -EIO;
60 }
61
62 pr_info("HDD protection level set to: %d\n", level);
63
64 return 0;
65}
66
67/* sysfs files */
68static ssize_t protection_level_show(struct device *dev,
69 struct device_attribute *attr, char *buf)
70{
71 struct toshiba_haps_dev *haps = dev_get_drvdata(dev);
72
73 return sprintf(buf, "%i\n", haps->protection_level);
74}
75
76static ssize_t protection_level_store(struct device *dev,
77 struct device_attribute *attr,
78 const char *buf, size_t count)
79{
80 struct toshiba_haps_dev *haps = dev_get_drvdata(dev);
81 int level, ret;
82
83 if (sscanf(buf, "%d", &level) != 1 || level < 0 || level > 3)
84 return -EINVAL;
85
86 /* Set the sensor level.
87 * Acceptable levels are:
88 * 0 - Disabled | 1 - Low | 2 - Medium | 3 - High
89 */
90 ret = toshiba_haps_protection_level(haps->acpi_dev->handle, level);
91 if (ret != 0)
92 return ret;
93
94 haps->protection_level = level;
95
96 return count;
97}
98
99static ssize_t reset_protection_store(struct device *dev,
100 struct device_attribute *attr,
101 const char *buf, size_t count)
102{
103 struct toshiba_haps_dev *haps = dev_get_drvdata(dev);
104 int reset, ret;
105
106 if (sscanf(buf, "%d", &reset) != 1 || reset != 1)
107 return -EINVAL;
108
109 /* Reset the protection interface */
110 ret = toshiba_haps_reset_protection(haps->acpi_dev->handle);
111 if (ret != 0)
112 return ret;
113
114 return count;
115}
116
117static DEVICE_ATTR(protection_level, S_IRUGO | S_IWUSR,
118 protection_level_show, protection_level_store);
119static DEVICE_ATTR(reset_protection, S_IWUSR, NULL, reset_protection_store);
120
121static struct attribute *haps_attributes[] = {
122 &dev_attr_protection_level.attr,
123 &dev_attr_reset_protection.attr,
124 NULL,
125};
126
127static struct attribute_group haps_attr_group = {
128 .attrs = haps_attributes,
129};
130
131/*
132 * ACPI stuff
133 */
134static void toshiba_haps_notify(struct acpi_device *device, u32 event)
135{
136 pr_info("Received event: 0x%x", event);
137
138 acpi_bus_generate_netlink_event(device->pnp.device_class,
139 dev_name(&device->dev),
140 event, 0);
141}
142
143static int toshiba_haps_remove(struct acpi_device *device)
144{
145 sysfs_remove_group(&device->dev.kobj, &haps_attr_group);
146
147 if (toshiba_haps)
148 toshiba_haps = NULL;
149
150 return 0;
151}
152
153/* Helper function */
154static int toshiba_haps_available(acpi_handle handle)
155{
156 acpi_status status;
157 u64 hdd_present;
158
159 /*
160 * A non existent device as well as having (only)
161 * Solid State Drives can cause the call to fail.
162 */
163 status = acpi_evaluate_integer(handle, "_STA", NULL,
164 &hdd_present);
165 if (ACPI_FAILURE(status) || !hdd_present) {
166 pr_info("HDD protection not available or using SSD\n");
167 return 0;
168 }
169
170 return 1;
171}
172
173static int toshiba_haps_add(struct acpi_device *acpi_dev)
174{
175 struct toshiba_haps_dev *haps;
176 int ret;
177
178 if (toshiba_haps)
179 return -EBUSY;
180
181 if (!toshiba_haps_available(acpi_dev->handle))
182 return -ENODEV;
183
184 pr_info("Toshiba HDD Active Protection Sensor device\n");
185
186 haps = kzalloc(sizeof(struct toshiba_haps_dev), GFP_KERNEL);
187 if (!haps)
188 return -ENOMEM;
189
190 haps->acpi_dev = acpi_dev;
191 haps->protection_level = 2;
192 acpi_dev->driver_data = haps;
193 dev_set_drvdata(&acpi_dev->dev, haps);
194
195 /* Set the protection level, currently at level 2 (Medium) */
196 ret = toshiba_haps_protection_level(acpi_dev->handle, 2);
197 if (ret != 0)
198 return ret;
199
200 ret = sysfs_create_group(&acpi_dev->dev.kobj, &haps_attr_group);
201 if (ret)
202 return ret;
203
204 toshiba_haps = haps;
205
206 return 0;
207}
208
209#ifdef CONFIG_PM_SLEEP
210static int toshiba_haps_suspend(struct device *device)
211{
212 struct toshiba_haps_dev *haps;
213 int ret;
214
215 haps = acpi_driver_data(to_acpi_device(device));
216
217 /* Deactivate the protection on suspend */
218 ret = toshiba_haps_protection_level(haps->acpi_dev->handle, 0);
219
220 return ret;
221}
222
223static int toshiba_haps_resume(struct device *device)
224{
225 struct toshiba_haps_dev *haps;
226 int ret;
227
228 haps = acpi_driver_data(to_acpi_device(device));
229
230 /* Set the stored protection level */
231 ret = toshiba_haps_protection_level(haps->acpi_dev->handle,
232 haps->protection_level);
233
234 /* Reset the protection on resume */
235 ret = toshiba_haps_reset_protection(haps->acpi_dev->handle);
236 if (ret != 0)
237 return ret;
238
239 return ret;
240}
241#endif
242
243static SIMPLE_DEV_PM_OPS(toshiba_haps_pm,
244 toshiba_haps_suspend, toshiba_haps_resume);
245
246static const struct acpi_device_id haps_device_ids[] = {
247 {"TOS620A", 0},
248 {"", 0},
249};
250MODULE_DEVICE_TABLE(acpi, haps_device_ids);
251
252static struct acpi_driver toshiba_haps_driver = {
253 .name = "Toshiba HAPS",
254 .owner = THIS_MODULE,
255 .ids = haps_device_ids,
256 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
257 .ops = {
258 .add = toshiba_haps_add,
259 .remove = toshiba_haps_remove,
260 .notify = toshiba_haps_notify,
261 },
262 .drv.pm = &toshiba_haps_pm,
263};
264
265module_acpi_driver(toshiba_haps_driver);
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 43d13295e63d..737e56d46f61 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -256,10 +256,6 @@ static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable)
256 block = &wblock->gblock; 256 block = &wblock->gblock;
257 handle = wblock->handle; 257 handle = wblock->handle;
258 258
259 if (!block)
260 return AE_NOT_EXIST;
261
262
263 snprintf(method, 5, "WE%02X", block->notify_id); 259 snprintf(method, 5, "WE%02X", block->notify_id);
264 status = acpi_execute_simple_method(handle, method, enable); 260 status = acpi_execute_simple_method(handle, method, enable);
265 261