summaryrefslogtreecommitdiff
path: root/drivers/platform/x86/xiaomi-wmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/xiaomi-wmi.c')
-rw-r--r--drivers/platform/x86/xiaomi-wmi.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/platform/x86/xiaomi-wmi.c b/drivers/platform/x86/xiaomi-wmi.c
index 54a2546bb93b..cbed29ca502a 100644
--- a/drivers/platform/x86/xiaomi-wmi.c
+++ b/drivers/platform/x86/xiaomi-wmi.c
@@ -2,8 +2,10 @@
/* WMI driver for Xiaomi Laptops */
#include <linux/acpi.h>
+#include <linux/device.h>
#include <linux/input.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/wmi.h>
#include <uapi/linux/input-event-codes.h>
@@ -20,14 +22,23 @@
struct xiaomi_wmi {
struct input_dev *input_dev;
+ struct mutex key_lock; /* Protects the key event sequence */
unsigned int key_code;
};
+static void xiaomi_mutex_destroy(void *data)
+{
+ struct mutex *lock = data;
+
+ mutex_destroy(lock);
+}
+
static int xiaomi_wmi_probe(struct wmi_device *wdev, const void *context)
{
struct xiaomi_wmi *data;
+ int ret;
- if (wdev == NULL || context == NULL)
+ if (!context)
return -EINVAL;
data = devm_kzalloc(&wdev->dev, sizeof(struct xiaomi_wmi), GFP_KERNEL);
@@ -35,6 +46,11 @@ static int xiaomi_wmi_probe(struct wmi_device *wdev, const void *context)
return -ENOMEM;
dev_set_drvdata(&wdev->dev, data);
+ mutex_init(&data->key_lock);
+ ret = devm_add_action_or_reset(&wdev->dev, xiaomi_mutex_destroy, &data->key_lock);
+ if (ret < 0)
+ return ret;
+
data->input_dev = devm_input_allocate_device(&wdev->dev);
if (data->input_dev == NULL)
return -ENOMEM;
@@ -50,19 +66,14 @@ static int xiaomi_wmi_probe(struct wmi_device *wdev, const void *context)
static void xiaomi_wmi_notify(struct wmi_device *wdev, union acpi_object *dummy)
{
- struct xiaomi_wmi *data;
-
- if (wdev == NULL)
- return;
-
- data = dev_get_drvdata(&wdev->dev);
- if (data == NULL)
- return;
+ struct xiaomi_wmi *data = dev_get_drvdata(&wdev->dev);
+ mutex_lock(&data->key_lock);
input_report_key(data->input_dev, data->key_code, 1);
input_sync(data->input_dev);
input_report_key(data->input_dev, data->key_code, 0);
input_sync(data->input_dev);
+ mutex_unlock(&data->key_lock);
}
static const struct wmi_device_id xiaomi_wmi_id_table[] = {
@@ -83,6 +94,7 @@ static struct wmi_driver xiaomi_wmi_driver = {
.id_table = xiaomi_wmi_id_table,
.probe = xiaomi_wmi_probe,
.notify = xiaomi_wmi_notify,
+ .no_singleton = true,
};
module_wmi_driver(xiaomi_wmi_driver);