aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-10 12:27:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-10 12:27:40 -0400
commita77c005887a6d6f318117176791efa0ef7fcca80 (patch)
tree5f00f4ec2b1ee24616f79f14b4418954da96601e
parent3644bc2ec7655a249612ea500e2be1c13052c4c2 (diff)
parenta1ec56ed9f42fb5374cd2add373811c9527c0995 (diff)
Merge branch 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86
Pull x86 platform drivers from Matthew Garrett: "Small set of updates, mainly trivial bugfixes and some small updates to deal with newer hardware. There's also a new driver that allows qemu guests to notify the hypervisor that they've just paniced, which seems useful." * 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86: Add support for fan button on Ideapad Z580 pvpanic: pvpanic device driver asus-nb-wmi: set wapf=4 for ASUSTeK COMPUTER INC. X75A drivers: platform: x86: Use PTR_RET function sony-laptop: SVS151290S kbd backlight and gfx switch support hp-wmi: add more definitions for new event_id's dell-laptop: Fix krealloc() misuse in parse_da_table() hp_accel: Ignore the error from lis3lv02d_poweron() at resume dell: add new dell WMI format for the AIO machines
-rw-r--r--drivers/platform/x86/Kconfig8
-rw-r--r--drivers/platform/x86/Makefile2
-rw-r--r--drivers/platform/x86/asus-nb-wmi.c9
-rw-r--r--drivers/platform/x86/dell-wmi-aio.c53
-rw-r--r--drivers/platform/x86/hp-wmi.c24
-rw-r--r--drivers/platform/x86/hp_accel.c3
-rw-r--r--drivers/platform/x86/ideapad-laptop.c6
-rw-r--r--drivers/platform/x86/pvpanic.c124
-rw-r--r--drivers/platform/x86/samsung-q10.c5
-rw-r--r--drivers/platform/x86/sony-laptop.c20
10 files changed, 242 insertions, 12 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 3338437b559b..85772616efbf 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -781,4 +781,12 @@ config APPLE_GMUX
781 graphics as well as the backlight. Currently only backlight 781 graphics as well as the backlight. Currently only backlight
782 control is supported by the driver. 782 control is supported by the driver.
783 783
784config PVPANIC
785 tristate "pvpanic device support"
786 depends on ACPI
787 ---help---
788 This driver provides support for the pvpanic device. pvpanic is
789 a paravirtualized device provided by QEMU; it lets a virtual machine
790 (guest) communicate panic events to the host.
791
784endif # X86_PLATFORM_DEVICES 792endif # X86_PLATFORM_DEVICES
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index ace2b38942fe..ef0ec746f78c 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -51,3 +51,5 @@ 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
54
55obj-$(CONFIG_PVPANIC) += pvpanic.o
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 210b5b872125..8fcb41e18b9c 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -171,6 +171,15 @@ static struct dmi_system_id asus_quirks[] = {
171 }, 171 },
172 .driver_data = &quirk_asus_x401u, 172 .driver_data = &quirk_asus_x401u,
173 }, 173 },
174 {
175 .callback = dmi_matched,
176 .ident = "ASUSTeK COMPUTER INC. X75A",
177 .matches = {
178 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
179 DMI_MATCH(DMI_PRODUCT_NAME, "X75A"),
180 },
181 .driver_data = &quirk_asus_x401u,
182 },
174 {}, 183 {},
175}; 184};
176 185
diff --git a/drivers/platform/x86/dell-wmi-aio.c b/drivers/platform/x86/dell-wmi-aio.c
index 3f945457f71c..bcf8cc6b5537 100644
--- a/drivers/platform/x86/dell-wmi-aio.c
+++ b/drivers/platform/x86/dell-wmi-aio.c
@@ -34,6 +34,14 @@ MODULE_LICENSE("GPL");
34#define EVENT_GUID1 "284A0E6B-380E-472A-921F-E52786257FB4" 34#define EVENT_GUID1 "284A0E6B-380E-472A-921F-E52786257FB4"
35#define EVENT_GUID2 "02314822-307C-4F66-BF0E-48AEAEB26CC8" 35#define EVENT_GUID2 "02314822-307C-4F66-BF0E-48AEAEB26CC8"
36 36
37struct dell_wmi_event {
38 u16 length;
39 /* 0x000: A hot key pressed or an event occurred
40 * 0x00F: A sequence of hot keys are pressed */
41 u16 type;
42 u16 event[];
43};
44
37static const char *dell_wmi_aio_guids[] = { 45static const char *dell_wmi_aio_guids[] = {
38 EVENT_GUID1, 46 EVENT_GUID1,
39 EVENT_GUID2, 47 EVENT_GUID2,
@@ -46,15 +54,41 @@ MODULE_ALIAS("wmi:"EVENT_GUID2);
46static const struct key_entry dell_wmi_aio_keymap[] = { 54static const struct key_entry dell_wmi_aio_keymap[] = {
47 { KE_KEY, 0xc0, { KEY_VOLUMEUP } }, 55 { KE_KEY, 0xc0, { KEY_VOLUMEUP } },
48 { KE_KEY, 0xc1, { KEY_VOLUMEDOWN } }, 56 { KE_KEY, 0xc1, { KEY_VOLUMEDOWN } },
57 { KE_KEY, 0xe030, { KEY_VOLUMEUP } },
58 { KE_KEY, 0xe02e, { KEY_VOLUMEDOWN } },
59 { KE_KEY, 0xe020, { KEY_MUTE } },
60 { KE_KEY, 0xe027, { KEY_DISPLAYTOGGLE } },
61 { KE_KEY, 0xe006, { KEY_BRIGHTNESSUP } },
62 { KE_KEY, 0xe005, { KEY_BRIGHTNESSDOWN } },
63 { KE_KEY, 0xe00b, { KEY_SWITCHVIDEOMODE } },
49 { KE_END, 0 } 64 { KE_END, 0 }
50}; 65};
51 66
52static struct input_dev *dell_wmi_aio_input_dev; 67static struct input_dev *dell_wmi_aio_input_dev;
53 68
69/*
70 * The new WMI event data format will follow the dell_wmi_event structure
71 * So, we will check if the buffer matches the format
72 */
73static bool dell_wmi_aio_event_check(u8 *buffer, int length)
74{
75 struct dell_wmi_event *event = (struct dell_wmi_event *)buffer;
76
77 if (event == NULL || length < 6)
78 return false;
79
80 if ((event->type == 0 || event->type == 0xf) &&
81 event->length >= 2)
82 return true;
83
84 return false;
85}
86
54static void dell_wmi_aio_notify(u32 value, void *context) 87static void dell_wmi_aio_notify(u32 value, void *context)
55{ 88{
56 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; 89 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
57 union acpi_object *obj; 90 union acpi_object *obj;
91 struct dell_wmi_event *event;
58 acpi_status status; 92 acpi_status status;
59 93
60 status = wmi_get_event_data(value, &response); 94 status = wmi_get_event_data(value, &response);
@@ -65,7 +99,7 @@ static void dell_wmi_aio_notify(u32 value, void *context)
65 99
66 obj = (union acpi_object *)response.pointer; 100 obj = (union acpi_object *)response.pointer;
67 if (obj) { 101 if (obj) {
68 unsigned int scancode; 102 unsigned int scancode = 0;
69 103
70 switch (obj->type) { 104 switch (obj->type) {
71 case ACPI_TYPE_INTEGER: 105 case ACPI_TYPE_INTEGER:
@@ -75,13 +109,22 @@ static void dell_wmi_aio_notify(u32 value, void *context)
75 scancode, 1, true); 109 scancode, 1, true);
76 break; 110 break;
77 case ACPI_TYPE_BUFFER: 111 case ACPI_TYPE_BUFFER:
78 /* Broken machines return the scancode in a buffer */ 112 if (dell_wmi_aio_event_check(obj->buffer.pointer,
79 if (obj->buffer.pointer && obj->buffer.length > 0) { 113 obj->buffer.length)) {
80 scancode = obj->buffer.pointer[0]; 114 event = (struct dell_wmi_event *)
115 obj->buffer.pointer;
116 scancode = event->event[0];
117 } else {
118 /* Broken machines return the scancode in a
119 buffer */
120 if (obj->buffer.pointer &&
121 obj->buffer.length > 0)
122 scancode = obj->buffer.pointer[0];
123 }
124 if (scancode)
81 sparse_keymap_report_event( 125 sparse_keymap_report_event(
82 dell_wmi_aio_input_dev, 126 dell_wmi_aio_input_dev,
83 scancode, 1, true); 127 scancode, 1, true);
84 }
85 break; 128 break;
86 } 129 }
87 } 130 }
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index 1a779bbfb87d..8df0c5a21be2 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -71,6 +71,14 @@ enum hp_wmi_event_ids {
71 HPWMI_WIRELESS = 5, 71 HPWMI_WIRELESS = 5,
72 HPWMI_CPU_BATTERY_THROTTLE = 6, 72 HPWMI_CPU_BATTERY_THROTTLE = 6,
73 HPWMI_LOCK_SWITCH = 7, 73 HPWMI_LOCK_SWITCH = 7,
74 HPWMI_LID_SWITCH = 8,
75 HPWMI_SCREEN_ROTATION = 9,
76 HPWMI_COOLSENSE_SYSTEM_MOBILE = 0x0A,
77 HPWMI_COOLSENSE_SYSTEM_HOT = 0x0B,
78 HPWMI_PROXIMITY_SENSOR = 0x0C,
79 HPWMI_BACKLIT_KB_BRIGHTNESS = 0x0D,
80 HPWMI_PEAKSHIFT_PERIOD = 0x0F,
81 HPWMI_BATTERY_CHARGE_PERIOD = 0x10,
74}; 82};
75 83
76struct bios_args { 84struct bios_args {
@@ -536,6 +544,22 @@ static void hp_wmi_notify(u32 value, void *context)
536 break; 544 break;
537 case HPWMI_LOCK_SWITCH: 545 case HPWMI_LOCK_SWITCH:
538 break; 546 break;
547 case HPWMI_LID_SWITCH:
548 break;
549 case HPWMI_SCREEN_ROTATION:
550 break;
551 case HPWMI_COOLSENSE_SYSTEM_MOBILE:
552 break;
553 case HPWMI_COOLSENSE_SYSTEM_HOT:
554 break;
555 case HPWMI_PROXIMITY_SENSOR:
556 break;
557 case HPWMI_BACKLIT_KB_BRIGHTNESS:
558 break;
559 case HPWMI_PEAKSHIFT_PERIOD:
560 break;
561 case HPWMI_BATTERY_CHARGE_PERIOD:
562 break;
539 default: 563 default:
540 pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data); 564 pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
541 break; 565 break;
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c
index e64a7a870d42..a8e43cf70fac 100644
--- a/drivers/platform/x86/hp_accel.c
+++ b/drivers/platform/x86/hp_accel.c
@@ -362,7 +362,8 @@ static int lis3lv02d_suspend(struct device *dev)
362 362
363static int lis3lv02d_resume(struct device *dev) 363static int lis3lv02d_resume(struct device *dev)
364{ 364{
365 return lis3lv02d_poweron(&lis3_dev); 365 lis3lv02d_poweron(&lis3_dev);
366 return 0;
366} 367}
367 368
368static SIMPLE_DEV_PM_OPS(hp_accel_pm, lis3lv02d_suspend, lis3lv02d_resume); 369static SIMPLE_DEV_PM_OPS(hp_accel_pm, lis3lv02d_suspend, lis3lv02d_resume);
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 17f00b8dc5cb..89c4519d48ac 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -640,7 +640,8 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv)
640 for (bit = 0; bit < 16; bit++) { 640 for (bit = 0; bit < 16; bit++) {
641 if (test_bit(bit, &value)) { 641 if (test_bit(bit, &value)) {
642 switch (bit) { 642 switch (bit) {
643 case 6: 643 case 0: /* Z580 */
644 case 6: /* Z570 */
644 /* Thermal Management button */ 645 /* Thermal Management button */
645 ideapad_input_report(priv, 65); 646 ideapad_input_report(priv, 65);
646 break; 647 break;
@@ -648,6 +649,9 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv)
648 /* OneKey Theater button */ 649 /* OneKey Theater button */
649 ideapad_input_report(priv, 64); 650 ideapad_input_report(priv, 64);
650 break; 651 break;
652 default:
653 pr_info("Unknown special button: %lu\n", bit);
654 break;
651 } 655 }
652 } 656 }
653 } 657 }
diff --git a/drivers/platform/x86/pvpanic.c b/drivers/platform/x86/pvpanic.c
new file mode 100644
index 000000000000..47ae0c47d4b5
--- /dev/null
+++ b/drivers/platform/x86/pvpanic.c
@@ -0,0 +1,124 @@
1/*
2 * pvpanic.c - pvpanic Device Support
3 *
4 * Copyright (C) 2013 Fujitsu.
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 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/types.h>
27#include <acpi/acpi_bus.h>
28#include <acpi/acpi_drivers.h>
29
30MODULE_AUTHOR("Hu Tao <hutao@cn.fujitsu.com>");
31MODULE_DESCRIPTION("pvpanic device driver");
32MODULE_LICENSE("GPL");
33
34static int pvpanic_add(struct acpi_device *device);
35static int pvpanic_remove(struct acpi_device *device);
36
37static const struct acpi_device_id pvpanic_device_ids[] = {
38 { "QEMU0001", 0 },
39 { "", 0 },
40};
41MODULE_DEVICE_TABLE(acpi, pvpanic_device_ids);
42
43#define PVPANIC_PANICKED (1 << 0)
44
45static u16 port;
46
47static struct acpi_driver pvpanic_driver = {
48 .name = "pvpanic",
49 .class = "QEMU",
50 .ids = pvpanic_device_ids,
51 .ops = {
52 .add = pvpanic_add,
53 .remove = pvpanic_remove,
54 },
55 .owner = THIS_MODULE,
56};
57
58static void
59pvpanic_send_event(unsigned int event)
60{
61 outb(event, port);
62}
63
64static int
65pvpanic_panic_notify(struct notifier_block *nb, unsigned long code,
66 void *unused)
67{
68 pvpanic_send_event(PVPANIC_PANICKED);
69 return NOTIFY_DONE;
70}
71
72static struct notifier_block pvpanic_panic_nb = {
73 .notifier_call = pvpanic_panic_notify,
74};
75
76
77static acpi_status
78pvpanic_walk_resources(struct acpi_resource *res, void *context)
79{
80 switch (res->type) {
81 case ACPI_RESOURCE_TYPE_END_TAG:
82 return AE_OK;
83
84 case ACPI_RESOURCE_TYPE_IO:
85 port = res->data.io.minimum;
86 return AE_OK;
87
88 default:
89 return AE_ERROR;
90 }
91}
92
93static int pvpanic_add(struct acpi_device *device)
94{
95 acpi_status status;
96 u64 ret;
97
98 status = acpi_evaluate_integer(device->handle, "_STA", NULL,
99 &ret);
100
101 if (ACPI_FAILURE(status) || (ret & 0x0B) != 0x0B)
102 return -ENODEV;
103
104 acpi_walk_resources(device->handle, METHOD_NAME__CRS,
105 pvpanic_walk_resources, NULL);
106
107 if (!port)
108 return -ENODEV;
109
110 atomic_notifier_chain_register(&panic_notifier_list,
111 &pvpanic_panic_nb);
112
113 return 0;
114}
115
116static int pvpanic_remove(struct acpi_device *device)
117{
118
119 atomic_notifier_chain_unregister(&panic_notifier_list,
120 &pvpanic_panic_nb);
121 return 0;
122}
123
124module_acpi_driver(pvpanic_driver);
diff --git a/drivers/platform/x86/samsung-q10.c b/drivers/platform/x86/samsung-q10.c
index 5f770059fd4d..1a90b62a71c6 100644
--- a/drivers/platform/x86/samsung-q10.c
+++ b/drivers/platform/x86/samsung-q10.c
@@ -176,10 +176,7 @@ static int __init samsungq10_init(void)
176 samsungq10_probe, 176 samsungq10_probe,
177 NULL, 0, NULL, 0); 177 NULL, 0, NULL, 0);
178 178
179 if (IS_ERR(samsungq10_device)) 179 return PTR_RET(samsungq10_device);
180 return PTR_ERR(samsungq10_device);
181
182 return 0;
183} 180}
184 181
185static void __exit samsungq10_exit(void) 182static void __exit samsungq10_exit(void)
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index d544e3aaf761..2ac045f27f10 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -1255,6 +1255,11 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)
1255 real_ev = __sony_nc_gfx_switch_status_get(); 1255 real_ev = __sony_nc_gfx_switch_status_get();
1256 break; 1256 break;
1257 1257
1258 case 0x015B:
1259 /* Hybrid GFX switching SVS151290S */
1260 ev_type = GFX_SWITCH;
1261 real_ev = __sony_nc_gfx_switch_status_get();
1262 break;
1258 default: 1263 default:
1259 dprintk("Unknown event 0x%x for handle 0x%x\n", 1264 dprintk("Unknown event 0x%x for handle 0x%x\n",
1260 event, handle); 1265 event, handle);
@@ -1353,6 +1358,7 @@ static void sony_nc_function_setup(struct acpi_device *device,
1353 break; 1358 break;
1354 case 0x0128: 1359 case 0x0128:
1355 case 0x0146: 1360 case 0x0146:
1361 case 0x015B:
1356 result = sony_nc_gfx_switch_setup(pf_device, handle); 1362 result = sony_nc_gfx_switch_setup(pf_device, handle);
1357 if (result) 1363 if (result)
1358 pr_err("couldn't set up GFX Switch status (%d)\n", 1364 pr_err("couldn't set up GFX Switch status (%d)\n",
@@ -1375,6 +1381,7 @@ static void sony_nc_function_setup(struct acpi_device *device,
1375 case 0x0143: 1381 case 0x0143:
1376 case 0x014b: 1382 case 0x014b:
1377 case 0x014c: 1383 case 0x014c:
1384 case 0x0163:
1378 result = sony_nc_kbd_backlight_setup(pf_device, handle); 1385 result = sony_nc_kbd_backlight_setup(pf_device, handle);
1379 if (result) 1386 if (result)
1380 pr_err("couldn't set up keyboard backlight function (%d)\n", 1387 pr_err("couldn't set up keyboard backlight function (%d)\n",
@@ -1426,6 +1433,7 @@ static void sony_nc_function_cleanup(struct platform_device *pd)
1426 break; 1433 break;
1427 case 0x0128: 1434 case 0x0128:
1428 case 0x0146: 1435 case 0x0146:
1436 case 0x015B:
1429 sony_nc_gfx_switch_cleanup(pd); 1437 sony_nc_gfx_switch_cleanup(pd);
1430 break; 1438 break;
1431 case 0x0131: 1439 case 0x0131:
@@ -1439,6 +1447,7 @@ static void sony_nc_function_cleanup(struct platform_device *pd)
1439 case 0x0143: 1447 case 0x0143:
1440 case 0x014b: 1448 case 0x014b:
1441 case 0x014c: 1449 case 0x014c:
1450 case 0x0163:
1442 sony_nc_kbd_backlight_cleanup(pd); 1451 sony_nc_kbd_backlight_cleanup(pd);
1443 break; 1452 break;
1444 default: 1453 default:
@@ -1485,6 +1494,7 @@ static void sony_nc_function_resume(void)
1485 case 0x0143: 1494 case 0x0143:
1486 case 0x014b: 1495 case 0x014b:
1487 case 0x014c: 1496 case 0x014c:
1497 case 0x0163:
1488 sony_nc_kbd_backlight_resume(); 1498 sony_nc_kbd_backlight_resume();
1489 break; 1499 break;
1490 default: 1500 default:
@@ -2390,7 +2400,9 @@ static int __sony_nc_gfx_switch_status_get(void)
2390{ 2400{
2391 unsigned int result; 2401 unsigned int result;
2392 2402
2393 if (sony_call_snc_handle(gfxs_ctl->handle, 0x0100, &result)) 2403 if (sony_call_snc_handle(gfxs_ctl->handle,
2404 gfxs_ctl->handle == 0x015B ? 0x0000 : 0x0100,
2405 &result))
2394 return -EIO; 2406 return -EIO;
2395 2407
2396 switch (gfxs_ctl->handle) { 2408 switch (gfxs_ctl->handle) {
@@ -2400,6 +2412,12 @@ static int __sony_nc_gfx_switch_status_get(void)
2400 */ 2412 */
2401 return result & 0x1 ? SPEED : STAMINA; 2413 return result & 0x1 ? SPEED : STAMINA;
2402 break; 2414 break;
2415 case 0x015B:
2416 /* 0: discrete GFX (speed)
2417 * 1: integrated GFX (stamina)
2418 */
2419 return result & 0x1 ? STAMINA : SPEED;
2420 break;
2403 case 0x0128: 2421 case 0x0128:
2404 /* it's a more elaborated bitmask, for now: 2422 /* it's a more elaborated bitmask, for now:
2405 * 2: integrated GFX (stamina) 2423 * 2: integrated GFX (stamina)