diff options
author | Linus Torvalds | 2013-01-10 09:09:41 -0800 |
---|---|---|
committer | Linus Torvalds | 2013-01-10 09:09:41 -0800 |
commit | ecf02a607bd801e742d7bb35c6e40f7ca15edf03 (patch) | |
tree | 1cef9c9ad7f7d0dcd26b5ab7072e3289e02ec50b /drivers | |
parent | ccae663cd4f62890d862c660e5ed762eb9821c14 (diff) | |
parent | 9f89748463f13c9657496b12820f09a988ce77ff (diff) |
Merge branch 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86
Pull x86 platform driver bugfixes from Matthew Garrett.
* 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86:
asus-laptop: Fix potential invalid pointer dereference
Update MAINTAINERS entry
asus-laptop: Do not call HWRS on init
sony-laptop: fix SNC buffer calls when SN06 returns Integers
samsung-laptop: Add quirk for broken acpi_video backlight on N250P
acer-wmi: add Aspire 5741G touchpad toggle key
acer-wmi: change to emit touchpad on off key
acer-wmi: fix obj is NULL but dereferenced
MAINTAINERS: change the mail address of acer-wmi/msi-laptop maintainer
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/platform/x86/acer-wmi.c | 60 | ||||
-rw-r--r-- | drivers/platform/x86/asus-laptop.c | 19 | ||||
-rw-r--r-- | drivers/platform/x86/samsung-laptop.c | 10 | ||||
-rw-r--r-- | drivers/platform/x86/sony-laptop.c | 15 |
4 files changed, 59 insertions, 45 deletions
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 06f4eb7ab87e..afed7018a2b5 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -125,8 +125,11 @@ static const struct key_entry acer_wmi_keymap[] = { {KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} }, {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ {KE_IGNORE, 0x81, {KEY_SLEEP} }, - {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad On/Off */ + {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad Toggle */ + {KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} }, + {KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} }, {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} }, + {KE_KEY, 0x85, {KEY_TOUCHPAD_TOGGLE} }, {KE_END, 0} }; @@ -147,6 +150,7 @@ struct event_return_value { #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */ #define ACER_WMID3_GDS_WIMAX (1<<7) /* WiMAX */ #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */ +#define ACER_WMID3_GDS_TOUCHPAD (1<<1) /* Touchpad */ struct lm_input_params { u8 function_num; /* Function Number */ @@ -875,7 +879,7 @@ WMI_execute_u32(u32 method_id, u32 in, u32 *out) struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) }; struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; - u32 tmp; + u32 tmp = 0; acpi_status status; status = wmi_evaluate_method(WMID_GUID1, 1, method_id, &input, &result); @@ -884,14 +888,14 @@ WMI_execute_u32(u32 method_id, u32 in, u32 *out) return status; obj = (union acpi_object *) result.pointer; - if (obj && obj->type == ACPI_TYPE_BUFFER && - (obj->buffer.length == sizeof(u32) || - obj->buffer.length == sizeof(u64))) { - tmp = *((u32 *) obj->buffer.pointer); - } else if (obj->type == ACPI_TYPE_INTEGER) { - tmp = (u32) obj->integer.value; - } else { - tmp = 0; + if (obj) { + if (obj->type == ACPI_TYPE_BUFFER && + (obj->buffer.length == sizeof(u32) || + obj->buffer.length == sizeof(u64))) { + tmp = *((u32 *) obj->buffer.pointer); + } else if (obj->type == ACPI_TYPE_INTEGER) { + tmp = (u32) obj->integer.value; + } } if (out) @@ -1193,12 +1197,14 @@ static acpi_status WMID_set_capabilities(void) return status; obj = (union acpi_object *) out.pointer; - if (obj && obj->type == ACPI_TYPE_BUFFER && - (obj->buffer.length == sizeof(u32) || - obj->buffer.length == sizeof(u64))) { - devices = *((u32 *) obj->buffer.pointer); - } else if (obj->type == ACPI_TYPE_INTEGER) { - devices = (u32) obj->integer.value; + if (obj) { + if (obj->type == ACPI_TYPE_BUFFER && + (obj->buffer.length == sizeof(u32) || + obj->buffer.length == sizeof(u64))) { + devices = *((u32 *) obj->buffer.pointer); + } else if (obj->type == ACPI_TYPE_INTEGER) { + devices = (u32) obj->integer.value; + } } else { kfree(out.pointer); return AE_ERROR; @@ -1676,6 +1682,7 @@ static void acer_wmi_notify(u32 value, void *context) acpi_status status; u16 device_state; const struct key_entry *key; + u32 scancode; status = wmi_get_event_data(value, &response); if (status != AE_OK) { @@ -1712,6 +1719,7 @@ static void acer_wmi_notify(u32 value, void *context) pr_warn("Unknown key number - 0x%x\n", return_value.key_num); } else { + scancode = return_value.key_num; switch (key->keycode) { case KEY_WLAN: case KEY_BLUETOOTH: @@ -1725,9 +1733,11 @@ static void acer_wmi_notify(u32 value, void *context) rfkill_set_sw_state(bluetooth_rfkill, !(device_state & ACER_WMID3_GDS_BLUETOOTH)); break; + case KEY_TOUCHPAD_TOGGLE: + scancode = (device_state & ACER_WMID3_GDS_TOUCHPAD) ? + KEY_TOUCHPAD_ON : KEY_TOUCHPAD_OFF; } - sparse_keymap_report_entry(acer_wmi_input_dev, key, - 1, true); + sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true); } break; case WMID_ACCEL_EVENT: @@ -1946,12 +1956,14 @@ static u32 get_wmid_devices(void) return 0; obj = (union acpi_object *) out.pointer; - if (obj && obj->type == ACPI_TYPE_BUFFER && - (obj->buffer.length == sizeof(u32) || - obj->buffer.length == sizeof(u64))) { - devices = *((u32 *) obj->buffer.pointer); - } else if (obj->type == ACPI_TYPE_INTEGER) { - devices = (u32) obj->integer.value; + if (obj) { + if (obj->type == ACPI_TYPE_BUFFER && + (obj->buffer.length == sizeof(u32) || + obj->buffer.length == sizeof(u64))) { + devices = *((u32 *) obj->buffer.pointer); + } else if (obj->type == ACPI_TYPE_INTEGER) { + devices = (u32) obj->integer.value; + } } kfree(out.pointer); diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index ec1d3bc2dbe2..fcde4e528819 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -860,8 +860,10 @@ static ssize_t show_infos(struct device *dev, /* * The HWRS method return informations about the hardware. * 0x80 bit is for WLAN, 0x100 for Bluetooth. + * 0x40 for WWAN, 0x10 for WIMAX. * The significance of others is yet to be found. - * If we don't find the method, we assume the device are present. + * We don't currently use this for device detection, and it + * takes several seconds to run on some systems. */ rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp); if (!ACPI_FAILURE(rv)) @@ -1682,7 +1684,7 @@ static int asus_laptop_get_info(struct asus_laptop *asus) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *model = NULL; - unsigned long long bsts_result, hwrs_result; + unsigned long long bsts_result; char *string = NULL; acpi_status status; @@ -1741,20 +1743,9 @@ static int asus_laptop_get_info(struct asus_laptop *asus) return -ENOMEM; } - if (*string) + if (string) pr_notice(" %s model detected\n", string); - /* - * The HWRS method return informations about the hardware. - * 0x80 bit is for WLAN, 0x100 for Bluetooth, - * 0x40 for WWAN, 0x10 for WIMAX. - * The significance of others is yet to be found. - */ - status = - acpi_evaluate_integer(asus->handle, "HWRS", NULL, &hwrs_result); - if (!ACPI_FAILURE(status)) - pr_notice(" HWRS returned %x", (int)hwrs_result); - if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) asus->have_rsts = true; diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index dd90d15f5210..71623a2ff3e8 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c @@ -1523,6 +1523,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .driver_data = &samsung_broken_acpi_video, }, + { + .callback = samsung_dmi_matched, + .ident = "N250P", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "N250P"), + DMI_MATCH(DMI_BOARD_NAME, "N250P"), + }, + .driver_data = &samsung_broken_acpi_video, + }, { }, }; MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index daaddec68def..b8ad71f7863f 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -786,28 +786,29 @@ static int sony_nc_int_call(acpi_handle handle, char *name, int *value, static int sony_nc_buffer_call(acpi_handle handle, char *name, u64 *value, void *buffer, size_t buflen) { + int ret = 0; size_t len = len; union acpi_object *object = __call_snc_method(handle, name, value); if (!object) return -EINVAL; - if (object->type == ACPI_TYPE_BUFFER) + if (object->type == ACPI_TYPE_BUFFER) { len = MIN(buflen, object->buffer.length); + memcpy(buffer, object->buffer.pointer, len); - else if (object->type == ACPI_TYPE_INTEGER) + } else if (object->type == ACPI_TYPE_INTEGER) { len = MIN(buflen, sizeof(object->integer.value)); + memcpy(buffer, &object->integer.value, len); - else { + } else { pr_warn("Invalid acpi_object: expected 0x%x got 0x%x\n", ACPI_TYPE_BUFFER, object->type); - kfree(object); - return -EINVAL; + ret = -EINVAL; } - memcpy(buffer, object->buffer.pointer, len); kfree(object); - return 0; + return ret; } struct sony_nc_handles { |