aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/chrome/cros_ec_proto.c9
-rw-r--r--drivers/platform/x86/Kconfig1
-rw-r--r--drivers/platform/x86/acer-wmi.c170
-rw-r--r--drivers/platform/x86/apple-gmux.c2
-rw-r--r--drivers/platform/x86/asus-nb-wmi.c24
-rw-r--r--drivers/platform/x86/hp-wireless.c2
-rw-r--r--drivers/platform/x86/hp-wmi.c24
-rw-r--r--drivers/platform/x86/hp_accel.c24
-rw-r--r--drivers/platform/x86/intel-hid.c2
-rw-r--r--drivers/platform/x86/intel-vbtn.c2
-rw-r--r--drivers/platform/x86/intel_punit_ipc.c1
-rw-r--r--drivers/platform/x86/intel_scu_ipc.c2
-rw-r--r--drivers/platform/x86/pmc_atom.c28
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c59
-rw-r--r--drivers/platform/x86/toshiba_acpi.c4
-rw-r--r--drivers/platform/x86/wmi.c9
16 files changed, 269 insertions, 94 deletions
diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
index dbad14716da4..b8e90c1a5e26 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -217,6 +217,15 @@ static int cros_ec_host_command_proto_query(struct cros_ec_device *ec_dev,
msg->insize = sizeof(struct ec_response_get_protocol_info);
ret = send_command(ec_dev, msg);
+ /*
+ * Send command once again when timeout occurred.
+ * Fingerprint MCU (FPMCU) is restarted during system boot which
+ * introduces small window in which FPMCU won't respond for any
+ * messages sent by kernel. There is no need to wait before next
+ * attempt because we waited at least EC_MSG_DEADLINE_MS.
+ */
+ if (ret == -ETIMEDOUT)
+ ret = send_command(ec_dev, msg);
if (ret < 0) {
dev_dbg(ec_dev->dev,
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 09035705d0a0..4f872e62508a 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -183,6 +183,7 @@ config FUJITSU_LAPTOP
depends on BACKLIGHT_CLASS_DEVICE
depends on ACPI_VIDEO || ACPI_VIDEO = n
select INPUT_SPARSEKMAP
+ select NEW_LEDS
select LEDS_CLASS
---help---
This is a driver for laptops built by Fujitsu:
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 1be71f956d5c..5ddc359135a8 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -43,6 +43,7 @@
#include <linux/input/sparse-keymap.h>
#include <acpi/video.h>
+ACPI_MODULE_NAME(KBUILD_MODNAME);
MODULE_AUTHOR("Carlos Corbacho");
MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver");
MODULE_LICENSE("GPL");
@@ -93,7 +94,7 @@ MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
enum acer_wmi_event_ids {
WMID_HOTKEY_EVENT = 0x1,
- WMID_ACCEL_EVENT = 0x5,
+ WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5,
};
static const struct key_entry acer_wmi_keymap[] __initconst = {
@@ -124,6 +125,7 @@ static const struct key_entry acer_wmi_keymap[] __initconst = {
{KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */
{KE_IGNORE, 0x81, {KEY_SLEEP} },
{KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad Toggle */
+ {KE_IGNORE, 0x84, {KEY_KBDILLUMTOGGLE} }, /* Automatic Keyboard background light toggle */
{KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} },
{KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} },
{KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} },
@@ -139,7 +141,9 @@ struct event_return_value {
u8 function;
u8 key_num;
u16 device_state;
- u32 reserved;
+ u16 reserved1;
+ u8 kbd_dock_state;
+ u8 reserved2;
} __attribute__((packed));
/*
@@ -217,14 +221,13 @@ struct hotkey_function_type_aa {
/*
* Interface capability flags
*/
-#define ACER_CAP_MAILLED (1<<0)
-#define ACER_CAP_WIRELESS (1<<1)
-#define ACER_CAP_BLUETOOTH (1<<2)
-#define ACER_CAP_BRIGHTNESS (1<<3)
-#define ACER_CAP_THREEG (1<<4)
-#define ACER_CAP_ACCEL (1<<5)
-#define ACER_CAP_RFBTN (1<<6)
-#define ACER_CAP_ANY (0xFFFFFFFF)
+#define ACER_CAP_MAILLED BIT(0)
+#define ACER_CAP_WIRELESS BIT(1)
+#define ACER_CAP_BLUETOOTH BIT(2)
+#define ACER_CAP_BRIGHTNESS BIT(3)
+#define ACER_CAP_THREEG BIT(4)
+#define ACER_CAP_SET_FUNCTION_MODE BIT(5)
+#define ACER_CAP_KBD_DOCK BIT(6)
/*
* Interface type flags
@@ -247,6 +250,7 @@ static int mailled = -1;
static int brightness = -1;
static int threeg = -1;
static int force_series;
+static int force_caps = -1;
static bool ec_raw_mode;
static bool has_type_aa;
static u16 commun_func_bitmap;
@@ -256,11 +260,13 @@ module_param(mailled, int, 0444);
module_param(brightness, int, 0444);
module_param(threeg, int, 0444);
module_param(force_series, int, 0444);
+module_param(force_caps, int, 0444);
module_param(ec_raw_mode, bool, 0444);
MODULE_PARM_DESC(mailled, "Set initial state of Mail LED");
MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness");
MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware");
MODULE_PARM_DESC(force_series, "Force a different laptop series");
+MODULE_PARM_DESC(force_caps, "Force the capability bitmask to this value");
MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode");
struct acer_data {
@@ -331,6 +337,15 @@ static int __init dmi_matched(const struct dmi_system_id *dmi)
return 1;
}
+static int __init set_force_caps(const struct dmi_system_id *dmi)
+{
+ if (force_caps == -1) {
+ force_caps = (uintptr_t)dmi->driver_data;
+ pr_info("Found %s, set force_caps to 0x%x\n", dmi->ident, force_caps);
+ }
+ return 1;
+}
+
static struct quirk_entry quirk_unknown = {
};
@@ -509,6 +524,33 @@ static const struct dmi_system_id acer_quirks[] __initconst = {
},
.driver_data = &quirk_acer_travelmate_2490,
},
+ {
+ .callback = set_force_caps,
+ .ident = "Acer Aspire Switch 10E SW3-016",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-016"),
+ },
+ .driver_data = (void *)ACER_CAP_KBD_DOCK,
+ },
+ {
+ .callback = set_force_caps,
+ .ident = "Acer Aspire Switch 10 SW5-012",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
+ },
+ .driver_data = (void *)ACER_CAP_KBD_DOCK,
+ },
+ {
+ .callback = set_force_caps,
+ .ident = "Acer One 10 (S1003)",
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"),
+ },
+ .driver_data = (void *)ACER_CAP_KBD_DOCK,
+ },
{}
};
@@ -1267,10 +1309,8 @@ static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d)
interface->capability |= ACER_CAP_THREEG;
if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH)
interface->capability |= ACER_CAP_BLUETOOTH;
- if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN) {
- interface->capability |= ACER_CAP_RFBTN;
+ if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN)
commun_func_bitmap &= ~ACER_WMID3_GDS_RFBTN;
- }
commun_fn_key_number = type_aa->commun_fn_key_number;
}
@@ -1531,7 +1571,7 @@ static int acer_gsensor_event(void)
struct acpi_buffer output;
union acpi_object out_obj[5];
- if (!has_cap(ACER_CAP_ACCEL))
+ if (!acer_wmi_accel_dev)
return -1;
output.length = sizeof(out_obj);
@@ -1555,6 +1595,71 @@ static int acer_gsensor_event(void)
}
/*
+ * Switch series keyboard dock status
+ */
+static int acer_kbd_dock_state_to_sw_tablet_mode(u8 kbd_dock_state)
+{
+ switch (kbd_dock_state) {
+ case 0x01: /* Docked, traditional clamshell laptop mode */
+ return 0;
+ case 0x04: /* Stand-alone tablet */
+ case 0x40: /* Docked, tent mode, keyboard not usable */
+ return 1;
+ default:
+ pr_warn("Unknown kbd_dock_state 0x%02x\n", kbd_dock_state);
+ }
+
+ return 0;
+}
+
+static void acer_kbd_dock_get_initial_state(void)
+{
+ u8 *output, input[8] = { 0x05, 0x00, };
+ struct acpi_buffer input_buf = { sizeof(input), input };
+ struct acpi_buffer output_buf = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ acpi_status status;
+ int sw_tablet_mode;
+
+ status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input_buf, &output_buf);
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status, "Error getting keyboard-dock initial status"));
+ return;
+ }
+
+ obj = output_buf.pointer;
+ if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) {
+ pr_err("Unexpected output format getting keyboard-dock initial status\n");
+ goto out_free_obj;
+ }
+
+ output = obj->buffer.pointer;
+ if (output[0] != 0x00 || (output[3] != 0x05 && output[3] != 0x45)) {
+ pr_err("Unexpected output [0]=0x%02x [3]=0x%02x getting keyboard-dock initial status\n",
+ output[0], output[3]);
+ goto out_free_obj;
+ }
+
+ sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(output[4]);
+ input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode);
+
+out_free_obj:
+ kfree(obj);
+}
+
+static void acer_kbd_dock_event(const struct event_return_value *event)
+{
+ int sw_tablet_mode;
+
+ if (!has_cap(ACER_CAP_KBD_DOCK))
+ return;
+
+ sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(event->kbd_dock_state);
+ input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode);
+ input_sync(acer_wmi_input_dev);
+}
+
+/*
* Rfkill devices
*/
static void acer_rfkill_update(struct work_struct *ignored);
@@ -1781,8 +1886,9 @@ static void acer_wmi_notify(u32 value, void *context)
sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true);
}
break;
- case WMID_ACCEL_EVENT:
+ case WMID_ACCEL_OR_KBD_DOCK_EVENT:
acer_gsensor_event();
+ acer_kbd_dock_event(&return_value);
break;
default:
pr_warn("Unknown function number - %d - %d\n",
@@ -1940,8 +2046,6 @@ static int __init acer_wmi_accel_setup(void)
if (err)
return err;
- interface->capability |= ACER_CAP_ACCEL;
-
acer_wmi_accel_dev = input_allocate_device();
if (!acer_wmi_accel_dev)
return -ENOMEM;
@@ -1967,11 +2071,6 @@ err_free_dev:
return err;
}
-static void acer_wmi_accel_destroy(void)
-{
- input_unregister_device(acer_wmi_accel_dev);
-}
-
static int __init acer_wmi_input_setup(void)
{
acpi_status status;
@@ -1989,6 +2088,9 @@ static int __init acer_wmi_input_setup(void)
if (err)
goto err_free_dev;
+ if (has_cap(ACER_CAP_KBD_DOCK))
+ input_set_capability(acer_wmi_input_dev, EV_SW, SW_TABLET_MODE);
+
status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
acer_wmi_notify, NULL);
if (ACPI_FAILURE(status)) {
@@ -1996,6 +2098,9 @@ static int __init acer_wmi_input_setup(void)
goto err_free_dev;
}
+ if (has_cap(ACER_CAP_KBD_DOCK))
+ acer_kbd_dock_get_initial_state();
+
err = input_register_device(acer_wmi_input_dev);
if (err)
goto err_uninstall_notifier;
@@ -2126,7 +2231,7 @@ static int acer_resume(struct device *dev)
if (has_cap(ACER_CAP_BRIGHTNESS))
set_u32(data->brightness, ACER_CAP_BRIGHTNESS);
- if (has_cap(ACER_CAP_ACCEL))
+ if (acer_wmi_accel_dev)
acer_gsensor_init();
return 0;
@@ -2241,7 +2346,7 @@ static int __init acer_wmi_init(void)
}
/* WMID always provides brightness methods */
interface->capability |= ACER_CAP_BRIGHTNESS;
- } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa) {
+ } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa && force_caps == -1) {
pr_err("No WMID device detection method found\n");
return -ENODEV;
}
@@ -2271,7 +2376,14 @@ static int __init acer_wmi_init(void)
if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
interface->capability &= ~ACER_CAP_BRIGHTNESS;
- if (wmi_has_guid(WMID_GUID3)) {
+ if (wmi_has_guid(WMID_GUID3))
+ interface->capability |= ACER_CAP_SET_FUNCTION_MODE;
+
+ if (force_caps != -1)
+ interface->capability = force_caps;
+
+ if (wmi_has_guid(WMID_GUID3) &&
+ (interface->capability & ACER_CAP_SET_FUNCTION_MODE)) {
if (ACPI_FAILURE(acer_wmi_enable_rf_button()))
pr_warn("Cannot enable RF Button Driver\n");
@@ -2334,8 +2446,8 @@ error_device_alloc:
error_platform_register:
if (wmi_has_guid(ACERWMID_EVENT_GUID))
acer_wmi_input_destroy();
- if (has_cap(ACER_CAP_ACCEL))
- acer_wmi_accel_destroy();
+ if (acer_wmi_accel_dev)
+ input_unregister_device(acer_wmi_accel_dev);
return err;
}
@@ -2345,8 +2457,8 @@ static void __exit acer_wmi_exit(void)
if (wmi_has_guid(ACERWMID_EVENT_GUID))
acer_wmi_input_destroy();
- if (has_cap(ACER_CAP_ACCEL))
- acer_wmi_accel_destroy();
+ if (acer_wmi_accel_dev)
+ input_unregister_device(acer_wmi_accel_dev);
remove_debugfs();
platform_device_unregister(acer_platform_device);
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c
index 7c4eb86c851e..5463d740f352 100644
--- a/drivers/platform/x86/apple-gmux.c
+++ b/drivers/platform/x86/apple-gmux.c
@@ -628,7 +628,7 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
}
gmux_data->iostart = res->start;
- gmux_data->iolen = res->end - res->start;
+ gmux_data->iolen = resource_size(res);
if (gmux_data->iolen < GMUX_MIN_IO_LEN) {
pr_err("gmux I/O region too small (%lu < %u)\n",
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 59f3a37a44d7..8db2dc05b8cf 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -517,9 +517,33 @@ static struct asus_wmi_driver asus_nb_wmi_driver = {
.detect_quirks = asus_nb_wmi_quirks,
};
+static const struct dmi_system_id asus_nb_wmi_blacklist[] __initconst = {
+ {
+ /*
+ * asus-nb-wm adds no functionality. The T100TA has a detachable
+ * USB kbd, so no hotkeys and it has no WMI rfkill; and loading
+ * asus-nb-wm causes the camera LED to turn and _stay_ on.
+ */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
+ },
+ },
+ {
+ /* The Asus T200TA has the same issue as the T100TA */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T200TA"),
+ },
+ },
+ {} /* Terminating entry */
+};
static int __init asus_nb_wmi_init(void)
{
+ if (dmi_check_system(asus_nb_wmi_blacklist))
+ return -ENODEV;
+
return asus_wmi_register_driver(&asus_nb_wmi_driver);
}
diff --git a/drivers/platform/x86/hp-wireless.c b/drivers/platform/x86/hp-wireless.c
index d6ea5e998fb8..bb95bec0b110 100644
--- a/drivers/platform/x86/hp-wireless.c
+++ b/drivers/platform/x86/hp-wireless.c
@@ -30,12 +30,14 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alex Hung");
MODULE_ALIAS("acpi*:HPQ6001:*");
MODULE_ALIAS("acpi*:WSTADEF:*");
+MODULE_ALIAS("acpi*:AMDI0051:*");
static struct input_dev *hpwl_input_dev;
static const struct acpi_device_id hpwl_ids[] = {
{"HPQ6001", 0},
{"WSTADEF", 0},
+ {"AMDI0051", 0},
{"", 0},
};
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index 06a3c1ef8eee..93fadd4abf14 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -45,6 +45,10 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C");
MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
+static int enable_tablet_mode_sw = -1;
+module_param(enable_tablet_mode_sw, int, 0444);
+MODULE_PARM_DESC(enable_tablet_mode_sw, "Enable SW_TABLET_MODE reporting (-1=auto, 0=no, 1=yes)");
+
#define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C"
#define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4"
@@ -474,8 +478,14 @@ static ssize_t postcode_show(struct device *dev, struct device_attribute *attr,
static ssize_t als_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- u32 tmp = simple_strtoul(buf, NULL, 10);
- int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, HPWMI_WRITE, &tmp,
+ u32 tmp;
+ int ret;
+
+ ret = kstrtou32(buf, 10, &tmp);
+ if (ret)
+ return ret;
+
+ ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, HPWMI_WRITE, &tmp,
sizeof(tmp), sizeof(tmp));
if (ret)
return ret < 0 ? ret : -EINVAL;
@@ -650,10 +660,12 @@ static int __init hp_wmi_input_setup(void)
}
/* Tablet mode */
- val = hp_wmi_hw_state(HPWMI_TABLET_MASK);
- if (!(val < 0)) {
- __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
- input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val);
+ if (enable_tablet_mode_sw > 0) {
+ val = hp_wmi_hw_state(HPWMI_TABLET_MASK);
+ if (val >= 0) {
+ __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
+ input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val);
+ }
}
err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL);
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c
index 7b12abe86b94..075332c6890d 100644
--- a/drivers/platform/x86/hp_accel.c
+++ b/drivers/platform/x86/hp_accel.c
@@ -101,6 +101,9 @@ MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids);
static int lis3lv02d_acpi_init(struct lis3lv02d *lis3)
{
struct acpi_device *dev = lis3->bus_priv;
+ if (!lis3->init_required)
+ return 0;
+
if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI,
NULL, NULL) != AE_OK)
return -EINVAL;
@@ -367,6 +370,7 @@ static int lis3lv02d_add(struct acpi_device *device)
}
/* call the core layer do its init */
+ lis3_dev.init_required = true;
ret = lis3lv02d_init_device(&lis3_dev);
if (ret)
return ret;
@@ -379,9 +383,11 @@ static int lis3lv02d_add(struct acpi_device *device)
INIT_WORK(&hpled_led.work, delayed_set_status_worker);
ret = led_classdev_register(NULL, &hpled_led.led_classdev);
if (ret) {
+ i8042_remove_filter(hp_accel_i8042_filter);
lis3lv02d_joystick_disable(&lis3_dev);
lis3lv02d_poweroff(&lis3_dev);
flush_work(&hpled_led.work);
+ lis3lv02d_remove_fs(&lis3_dev);
return ret;
}
@@ -414,11 +420,27 @@ static int lis3lv02d_suspend(struct device *dev)
static int lis3lv02d_resume(struct device *dev)
{
+ lis3_dev.init_required = false;
+ lis3lv02d_poweron(&lis3_dev);
+ return 0;
+}
+
+static int lis3lv02d_restore(struct device *dev)
+{
+ lis3_dev.init_required = true;
lis3lv02d_poweron(&lis3_dev);
return 0;
}
-static SIMPLE_DEV_PM_OPS(hp_accel_pm, lis3lv02d_suspend, lis3lv02d_resume);
+static const struct dev_pm_ops hp_accel_pm = {
+ .suspend = lis3lv02d_suspend,
+ .resume = lis3lv02d_resume,
+ .freeze = lis3lv02d_suspend,
+ .thaw = lis3lv02d_resume,
+ .poweroff = lis3lv02d_suspend,
+ .restore = lis3lv02d_restore,
+};
+
#define HP_ACCEL_PM (&hp_accel_pm)
#else
#define HP_ACCEL_PM NULL
diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c
index e34fd70b67af..3add7b3f9658 100644
--- a/drivers/platform/x86/intel-hid.c
+++ b/drivers/platform/x86/intel-hid.c
@@ -366,7 +366,7 @@ check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv)
return AE_OK;
if (acpi_match_device_ids(dev, ids) == 0)
- if (acpi_create_platform_device(dev, NULL))
+ if (!IS_ERR_OR_NULL(acpi_create_platform_device(dev, NULL)))
dev_info(&dev->dev,
"intel-hid: created platform device\n");
diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c
index 58c5ff36523a..d7fa2b88d27a 100644
--- a/drivers/platform/x86/intel-vbtn.c
+++ b/drivers/platform/x86/intel-vbtn.c
@@ -178,7 +178,7 @@ check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv)
return AE_OK;
if (acpi_match_device_ids(dev, ids) == 0)
- if (acpi_create_platform_device(dev, NULL))
+ if (!IS_ERR_OR_NULL(acpi_create_platform_device(dev, NULL)))
dev_info(&dev->dev,
"intel-vbtn: created platform device\n");
diff --git a/drivers/platform/x86/intel_punit_ipc.c b/drivers/platform/x86/intel_punit_ipc.c
index b7dfe06261f1..9865d11eda75 100644
--- a/drivers/platform/x86/intel_punit_ipc.c
+++ b/drivers/platform/x86/intel_punit_ipc.c
@@ -330,6 +330,7 @@ static const struct acpi_device_id punit_ipc_acpi_ids[] = {
{ "INT34D4", 0 },
{ }
};
+MODULE_DEVICE_TABLE(acpi, punit_ipc_acpi_ids);
static struct platform_driver intel_punit_ipc_driver = {
.probe = intel_punit_ipc_probe,
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index 2434ce8bead6..46d543063b6d 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -183,7 +183,7 @@ static inline int busy_loop(struct intel_scu_ipc_dev *scu)
return 0;
}
-/* Wait till ipc ioc interrupt is received or timeout in 3 HZ */
+/* Wait till ipc ioc interrupt is received or timeout in 10 HZ */
static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
{
int status;
diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
index 92205b90c25c..d1d5ec3c0f14 100644
--- a/drivers/platform/x86/pmc_atom.c
+++ b/drivers/platform/x86/pmc_atom.c
@@ -453,34 +453,10 @@ static const struct dmi_system_id critclk_systems[] = {
},
{
/* pmc_plt_clk* - are used for ethernet controllers */
- .ident = "Beckhoff CB3163",
+ .ident = "Beckhoff Baytrail",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation"),
- DMI_MATCH(DMI_BOARD_NAME, "CB3163"),
- },
- },
- {
- /* pmc_plt_clk* - are used for ethernet controllers */
- .ident = "Beckhoff CB4063",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation"),
- DMI_MATCH(DMI_BOARD_NAME, "CB4063"),
- },
- },
- {
- /* pmc_plt_clk* - are used for ethernet controllers */
- .ident = "Beckhoff CB6263",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation"),
- DMI_MATCH(DMI_BOARD_NAME, "CB6263"),
- },
- },
- {
- /* pmc_plt_clk* - are used for ethernet controllers */
- .ident = "Beckhoff CB6363",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation"),
- DMI_MATCH(DMI_BOARD_NAME, "CB6363"),
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "CBxx63"),
},
},
{
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index c3fb9d66b768..05b3e0f724fc 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -1180,15 +1180,6 @@ static int tpacpi_rfk_update_swstate(const struct tpacpi_rfk *tp_rfk)
return status;
}
-/* Query FW and update rfkill sw state for all rfkill switches */
-static void tpacpi_rfk_update_swstate_all(void)
-{
- unsigned int i;
-
- for (i = 0; i < TPACPI_RFK_SW_MAX; i++)
- tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[i]);
-}
-
/*
* Sync the HW-blocking state of all rfkill switches,
* do notice it causes the rfkill core to schedule uevents
@@ -2477,7 +2468,7 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
*/
static int hotkey_kthread(void *data)
{
- struct tp_nvram_state s[2];
+ struct tp_nvram_state s[2] = { 0 };
u32 poll_mask, event_mask;
unsigned int si, so;
unsigned long t;
@@ -3025,9 +3016,6 @@ static void tpacpi_send_radiosw_update(void)
if (wlsw == TPACPI_RFK_RADIO_OFF)
tpacpi_rfk_update_hwblock_state(true);
- /* Sync sw blocking state */
- tpacpi_rfk_update_swstate_all();
-
/* Sync hw blocking state last if it is hw-unblocked */
if (wlsw == TPACPI_RFK_RADIO_ON)
tpacpi_rfk_update_hwblock_state(false);
@@ -3964,13 +3952,19 @@ static bool hotkey_notify_6xxx(const u32 hkey,
case TP_HKEY_EV_KEY_NUMLOCK:
case TP_HKEY_EV_KEY_FN:
- case TP_HKEY_EV_KEY_FN_ESC:
/* key press events, we just ignore them as long as the EC
* is still reporting them in the normal keyboard stream */
*send_acpi_ev = false;
*ignore_acpi_ev = true;
return true;
+ case TP_HKEY_EV_KEY_FN_ESC:
+ /* Get the media key status to foce the status LED to update */
+ acpi_evalf(hkey_handle, NULL, "GMKS", "v");
+ *send_acpi_ev = false;
+ *ignore_acpi_ev = true;
+ return true;
+
case TP_HKEY_EV_TABLET_CHANGED:
tpacpi_input_send_tabletsw();
hotkey_tablet_mode_notify_change();
@@ -6156,6 +6150,7 @@ enum thermal_access_mode {
enum { /* TPACPI_THERMAL_TPEC_* */
TP_EC_THERMAL_TMP0 = 0x78, /* ACPI EC regs TMP 0..7 */
TP_EC_THERMAL_TMP8 = 0xC0, /* ACPI EC regs TMP 8..15 */
+ TP_EC_FUNCREV = 0xEF, /* ACPI EC Functional revision */
TP_EC_THERMAL_TMP_NA = -128, /* ACPI EC sensor not available */
TPACPI_THERMAL_SENSOR_NA = -128000, /* Sensor not available */
@@ -6354,7 +6349,7 @@ static const struct attribute_group thermal_temp_input8_group = {
static int __init thermal_init(struct ibm_init_struct *iibm)
{
- u8 t, ta1, ta2;
+ u8 t, ta1, ta2, ver = 0;
int i;
int acpi_tmp7;
int res;
@@ -6369,7 +6364,14 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
* 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for
* non-implemented, thermal sensors return 0x80 when
* not available
+ * The above rule is unfortunately flawed. This has been seen with
+ * 0xC2 (power supply ID) causing thermal control problems.
+ * The EC version can be determined by offset 0xEF and at least for
+ * version 3 the Lenovo firmware team confirmed that registers 0xC0-0xC7
+ * are not thermal registers.
*/
+ if (!acpi_ec_read(TP_EC_FUNCREV, &ver))
+ pr_warn("Thinkpad ACPI EC unable to access EC version\n");
ta1 = ta2 = 0;
for (i = 0; i < 8; i++) {
@@ -6379,11 +6381,13 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
ta1 = 0;
break;
}
- if (acpi_ec_read(TP_EC_THERMAL_TMP8 + i, &t)) {
- ta2 |= t;
- } else {
- ta1 = 0;
- break;
+ if (ver < 3) {
+ if (acpi_ec_read(TP_EC_THERMAL_TMP8 + i, &t)) {
+ ta2 |= t;
+ } else {
+ ta1 = 0;
+ break;
+ }
}
}
if (ta1 == 0) {
@@ -6396,9 +6400,12 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
thermal_read_mode = TPACPI_THERMAL_NONE;
}
} else {
- thermal_read_mode =
- (ta2 != 0) ?
- TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8;
+ if (ver >= 3)
+ thermal_read_mode = TPACPI_THERMAL_TPEC_8;
+ else
+ thermal_read_mode =
+ (ta2 != 0) ?
+ TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8;
}
} else if (acpi_tmp7) {
if (tpacpi_is_ibm() &&
@@ -6749,8 +6756,10 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle)
list_for_each_entry(child, &device->children, node) {
acpi_status status = acpi_evaluate_object(child->handle, "_BCL",
NULL, &buffer);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(status)) {
+ buffer.length = ACPI_ALLOCATE_BUFFER;
continue;
+ }
obj = (union acpi_object *)buffer.pointer;
if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
@@ -8957,7 +8966,7 @@ static int fan_write_cmd_level(const char *cmd, int *rc)
if (strlencmp(cmd, "level auto") == 0)
level = TP_EC_FAN_AUTO;
- else if ((strlencmp(cmd, "level disengaged") == 0) |
+ else if ((strlencmp(cmd, "level disengaged") == 0) ||
(strlencmp(cmd, "level full-speed") == 0))
level = TP_EC_FAN_FULLSPEED;
else if (sscanf(cmd, "level %d", &level) != 1)
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 8221e000c8c2..61eccbb900e0 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -1497,7 +1497,7 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf,
struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file));
char *buffer;
char *cmd;
- int lcd_out, crt_out, tv_out;
+ int lcd_out = -1, crt_out = -1, tv_out = -1;
int remain = count;
int value;
int ret;
@@ -1529,7 +1529,6 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf,
kfree(cmd);
- lcd_out = crt_out = tv_out = -1;
ret = get_video_status(dev, &video_out);
if (!ret) {
unsigned int new_video_out = video_out;
@@ -2862,6 +2861,7 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
if (!dev->info_supported && !dev->system_event_supported) {
pr_warn("No hotkey query interface found\n");
+ error = -EINVAL;
goto err_remove_filter;
}
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index a56e997816b2..07c1e0829b19 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -307,7 +307,14 @@ static acpi_status __query_block(struct wmi_block *wblock, u8 instance,
* the WQxx method failed - we should disable collection anyway.
*/
if ((block->flags & ACPI_WMI_EXPENSIVE) && ACPI_SUCCESS(wc_status)) {
- status = acpi_execute_simple_method(handle, wc_method, 0);
+ /*
+ * Ignore whether this WCxx call succeeds or not since
+ * the previously executed WQxx method call might have
+ * succeeded, and returning the failing status code
+ * of this call would throw away the result of the WQxx
+ * call, potentially leaking memory.
+ */
+ acpi_execute_simple_method(handle, wc_method, 0);
}
return status;