Commit ecf02a60 authored by Linus Torvalds's avatar Linus Torvalds

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
parents ccae663c 9f897484
...@@ -228,7 +228,7 @@ S: Maintained ...@@ -228,7 +228,7 @@ S: Maintained
F: drivers/platform/x86/acerhdf.c F: drivers/platform/x86/acerhdf.c
ACER WMI LAPTOP EXTRAS ACER WMI LAPTOP EXTRAS
M: Joey Lee <jlee@novell.com> M: "Lee, Chun-Yi" <jlee@suse.com>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
S: Maintained S: Maintained
F: drivers/platform/x86/acer-wmi.c F: drivers/platform/x86/acer-wmi.c
...@@ -5077,7 +5077,7 @@ S: Maintained ...@@ -5077,7 +5077,7 @@ S: Maintained
F: drivers/media/radio/radio-mr800.c F: drivers/media/radio/radio-mr800.c
MSI LAPTOP SUPPORT MSI LAPTOP SUPPORT
M: "Lee, Chun-Yi" <jlee@novell.com> M: "Lee, Chun-Yi" <jlee@suse.com>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
S: Maintained S: Maintained
F: drivers/platform/x86/msi-laptop.c F: drivers/platform/x86/msi-laptop.c
...@@ -8526,7 +8526,7 @@ F: Documentation/x86/ ...@@ -8526,7 +8526,7 @@ F: Documentation/x86/
F: arch/x86/ F: arch/x86/
X86 PLATFORM DRIVERS X86 PLATFORM DRIVERS
M: Matthew Garrett <mjg@redhat.com> M: Matthew Garrett <matthew.garrett@nebula.com>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git
S: Maintained S: Maintained
......
...@@ -125,8 +125,11 @@ static const struct key_entry acer_wmi_keymap[] = { ...@@ -125,8 +125,11 @@ static const struct key_entry acer_wmi_keymap[] = {
{KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} }, {KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} },
{KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */
{KE_IGNORE, 0x81, {KEY_SLEEP} }, {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_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} },
{KE_KEY, 0x85, {KEY_TOUCHPAD_TOGGLE} },
{KE_END, 0} {KE_END, 0}
}; };
...@@ -147,6 +150,7 @@ struct event_return_value { ...@@ -147,6 +150,7 @@ struct event_return_value {
#define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */ #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */
#define ACER_WMID3_GDS_WIMAX (1<<7) /* WiMAX */ #define ACER_WMID3_GDS_WIMAX (1<<7) /* WiMAX */
#define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */ #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */
#define ACER_WMID3_GDS_TOUCHPAD (1<<1) /* Touchpad */
struct lm_input_params { struct lm_input_params {
u8 function_num; /* Function Number */ u8 function_num; /* Function Number */
...@@ -875,7 +879,7 @@ WMI_execute_u32(u32 method_id, u32 in, u32 *out) ...@@ -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 input = { (acpi_size) sizeof(u32), (void *)(&in) };
struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj; union acpi_object *obj;
u32 tmp; u32 tmp = 0;
acpi_status status; acpi_status status;
status = wmi_evaluate_method(WMID_GUID1, 1, method_id, &input, &result); 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) ...@@ -884,14 +888,14 @@ WMI_execute_u32(u32 method_id, u32 in, u32 *out)
return status; return status;
obj = (union acpi_object *) result.pointer; obj = (union acpi_object *) result.pointer;
if (obj && obj->type == ACPI_TYPE_BUFFER && if (obj) {
(obj->buffer.length == sizeof(u32) || if (obj->type == ACPI_TYPE_BUFFER &&
obj->buffer.length == sizeof(u64))) { (obj->buffer.length == sizeof(u32) ||
tmp = *((u32 *) obj->buffer.pointer); obj->buffer.length == sizeof(u64))) {
} else if (obj->type == ACPI_TYPE_INTEGER) { tmp = *((u32 *) obj->buffer.pointer);
tmp = (u32) obj->integer.value; } else if (obj->type == ACPI_TYPE_INTEGER) {
} else { tmp = (u32) obj->integer.value;
tmp = 0; }
} }
if (out) if (out)
...@@ -1193,12 +1197,14 @@ static acpi_status WMID_set_capabilities(void) ...@@ -1193,12 +1197,14 @@ static acpi_status WMID_set_capabilities(void)
return status; return status;
obj = (union acpi_object *) out.pointer; obj = (union acpi_object *) out.pointer;
if (obj && obj->type == ACPI_TYPE_BUFFER && if (obj) {
(obj->buffer.length == sizeof(u32) || if (obj->type == ACPI_TYPE_BUFFER &&
obj->buffer.length == sizeof(u64))) { (obj->buffer.length == sizeof(u32) ||
devices = *((u32 *) obj->buffer.pointer); obj->buffer.length == sizeof(u64))) {
} else if (obj->type == ACPI_TYPE_INTEGER) { devices = *((u32 *) obj->buffer.pointer);
devices = (u32) obj->integer.value; } else if (obj->type == ACPI_TYPE_INTEGER) {
devices = (u32) obj->integer.value;
}
} else { } else {
kfree(out.pointer); kfree(out.pointer);
return AE_ERROR; return AE_ERROR;
...@@ -1676,6 +1682,7 @@ static void acer_wmi_notify(u32 value, void *context) ...@@ -1676,6 +1682,7 @@ static void acer_wmi_notify(u32 value, void *context)
acpi_status status; acpi_status status;
u16 device_state; u16 device_state;
const struct key_entry *key; const struct key_entry *key;
u32 scancode;
status = wmi_get_event_data(value, &response); status = wmi_get_event_data(value, &response);
if (status != AE_OK) { if (status != AE_OK) {
...@@ -1712,6 +1719,7 @@ static void acer_wmi_notify(u32 value, void *context) ...@@ -1712,6 +1719,7 @@ static void acer_wmi_notify(u32 value, void *context)
pr_warn("Unknown key number - 0x%x\n", pr_warn("Unknown key number - 0x%x\n",
return_value.key_num); return_value.key_num);
} else { } else {
scancode = return_value.key_num;
switch (key->keycode) { switch (key->keycode) {
case KEY_WLAN: case KEY_WLAN:
case KEY_BLUETOOTH: case KEY_BLUETOOTH:
...@@ -1725,9 +1733,11 @@ static void acer_wmi_notify(u32 value, void *context) ...@@ -1725,9 +1733,11 @@ static void acer_wmi_notify(u32 value, void *context)
rfkill_set_sw_state(bluetooth_rfkill, rfkill_set_sw_state(bluetooth_rfkill,
!(device_state & ACER_WMID3_GDS_BLUETOOTH)); !(device_state & ACER_WMID3_GDS_BLUETOOTH));
break; 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, sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true);
1, true);
} }
break; break;
case WMID_ACCEL_EVENT: case WMID_ACCEL_EVENT:
...@@ -1946,12 +1956,14 @@ static u32 get_wmid_devices(void) ...@@ -1946,12 +1956,14 @@ static u32 get_wmid_devices(void)
return 0; return 0;
obj = (union acpi_object *) out.pointer; obj = (union acpi_object *) out.pointer;
if (obj && obj->type == ACPI_TYPE_BUFFER && if (obj) {
(obj->buffer.length == sizeof(u32) || if (obj->type == ACPI_TYPE_BUFFER &&
obj->buffer.length == sizeof(u64))) { (obj->buffer.length == sizeof(u32) ||
devices = *((u32 *) obj->buffer.pointer); obj->buffer.length == sizeof(u64))) {
} else if (obj->type == ACPI_TYPE_INTEGER) { devices = *((u32 *) obj->buffer.pointer);
devices = (u32) obj->integer.value; } else if (obj->type == ACPI_TYPE_INTEGER) {
devices = (u32) obj->integer.value;
}
} }
kfree(out.pointer); kfree(out.pointer);
......
...@@ -860,8 +860,10 @@ static ssize_t show_infos(struct device *dev, ...@@ -860,8 +860,10 @@ static ssize_t show_infos(struct device *dev,
/* /*
* The HWRS method return informations about the hardware. * The HWRS method return informations about the hardware.
* 0x80 bit is for WLAN, 0x100 for Bluetooth. * 0x80 bit is for WLAN, 0x100 for Bluetooth.
* 0x40 for WWAN, 0x10 for WIMAX.
* The significance of others is yet to be found. * 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); rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp);
if (!ACPI_FAILURE(rv)) if (!ACPI_FAILURE(rv))
...@@ -1682,7 +1684,7 @@ static int asus_laptop_get_info(struct asus_laptop *asus) ...@@ -1682,7 +1684,7 @@ static int asus_laptop_get_info(struct asus_laptop *asus)
{ {
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *model = NULL; union acpi_object *model = NULL;
unsigned long long bsts_result, hwrs_result; unsigned long long bsts_result;
char *string = NULL; char *string = NULL;
acpi_status status; acpi_status status;
...@@ -1741,20 +1743,9 @@ static int asus_laptop_get_info(struct asus_laptop *asus) ...@@ -1741,20 +1743,9 @@ static int asus_laptop_get_info(struct asus_laptop *asus)
return -ENOMEM; return -ENOMEM;
} }
if (*string) if (string)
pr_notice(" %s model detected\n", 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)) if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL))
asus->have_rsts = true; asus->have_rsts = true;
......
...@@ -1523,6 +1523,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { ...@@ -1523,6 +1523,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
}, },
.driver_data = &samsung_broken_acpi_video, .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); MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);
......
...@@ -786,28 +786,29 @@ static int sony_nc_int_call(acpi_handle handle, char *name, int *value, ...@@ -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, static int sony_nc_buffer_call(acpi_handle handle, char *name, u64 *value,
void *buffer, size_t buflen) void *buffer, size_t buflen)
{ {
int ret = 0;
size_t len = len; size_t len = len;
union acpi_object *object = __call_snc_method(handle, name, value); union acpi_object *object = __call_snc_method(handle, name, value);
if (!object) if (!object)
return -EINVAL; return -EINVAL;
if (object->type == ACPI_TYPE_BUFFER) if (object->type == ACPI_TYPE_BUFFER) {
len = MIN(buflen, object->buffer.length); 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)); 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", pr_warn("Invalid acpi_object: expected 0x%x got 0x%x\n",
ACPI_TYPE_BUFFER, object->type); ACPI_TYPE_BUFFER, object->type);
kfree(object); ret = -EINVAL;
return -EINVAL;
} }
memcpy(buffer, object->buffer.pointer, len);
kfree(object); kfree(object);
return 0; return ret;
} }
struct sony_nc_handles { struct sony_nc_handles {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment