aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/intel-vbtn.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/intel-vbtn.c')
-rw-r--r--drivers/platform/x86/intel-vbtn.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c
index c2035e121ac2..61f106377661 100644
--- a/drivers/platform/x86/intel-vbtn.c
+++ b/drivers/platform/x86/intel-vbtn.c
@@ -23,6 +23,7 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/input/sparse-keymap.h> 24#include <linux/input/sparse-keymap.h>
25#include <linux/acpi.h> 25#include <linux/acpi.h>
26#include <linux/suspend.h>
26#include <acpi/acpi_bus.h> 27#include <acpi/acpi_bus.h>
27 28
28MODULE_LICENSE("GPL"); 29MODULE_LICENSE("GPL");
@@ -46,6 +47,7 @@ static const struct key_entry intel_vbtn_keymap[] = {
46 47
47struct intel_vbtn_priv { 48struct intel_vbtn_priv {
48 struct input_dev *input_dev; 49 struct input_dev *input_dev;
50 bool wakeup_mode;
49}; 51};
50 52
51static int intel_vbtn_input_setup(struct platform_device *device) 53static int intel_vbtn_input_setup(struct platform_device *device)
@@ -73,9 +75,15 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
73 struct platform_device *device = context; 75 struct platform_device *device = context;
74 struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev); 76 struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
75 77
76 if (!sparse_keymap_report_event(priv->input_dev, event, 1, true)) 78 if (priv->wakeup_mode) {
77 dev_info(&device->dev, "unknown event index 0x%x\n", 79 if (sparse_keymap_entry_from_scancode(priv->input_dev, event)) {
78 event); 80 pm_wakeup_hard_event(&device->dev);
81 return;
82 }
83 } else if (sparse_keymap_report_event(priv->input_dev, event, 1, true)) {
84 return;
85 }
86 dev_info(&device->dev, "unknown event index 0x%x\n", event);
79} 87}
80 88
81static int intel_vbtn_probe(struct platform_device *device) 89static int intel_vbtn_probe(struct platform_device *device)
@@ -109,6 +117,7 @@ static int intel_vbtn_probe(struct platform_device *device)
109 if (ACPI_FAILURE(status)) 117 if (ACPI_FAILURE(status))
110 return -EBUSY; 118 return -EBUSY;
111 119
120 device_init_wakeup(&device->dev, true);
112 return 0; 121 return 0;
113} 122}
114 123
@@ -125,10 +134,34 @@ static int intel_vbtn_remove(struct platform_device *device)
125 return 0; 134 return 0;
126} 135}
127 136
137static int intel_vbtn_pm_prepare(struct device *dev)
138{
139 struct intel_vbtn_priv *priv = dev_get_drvdata(dev);
140
141 priv->wakeup_mode = true;
142 return 0;
143}
144
145static int intel_vbtn_pm_resume(struct device *dev)
146{
147 struct intel_vbtn_priv *priv = dev_get_drvdata(dev);
148
149 priv->wakeup_mode = false;
150 return 0;
151}
152
153static const struct dev_pm_ops intel_vbtn_pm_ops = {
154 .prepare = intel_vbtn_pm_prepare,
155 .resume = intel_vbtn_pm_resume,
156 .restore = intel_vbtn_pm_resume,
157 .thaw = intel_vbtn_pm_resume,
158};
159
128static struct platform_driver intel_vbtn_pl_driver = { 160static struct platform_driver intel_vbtn_pl_driver = {
129 .driver = { 161 .driver = {
130 .name = "intel-vbtn", 162 .name = "intel-vbtn",
131 .acpi_match_table = intel_vbtn_ids, 163 .acpi_match_table = intel_vbtn_ids,
164 .pm = &intel_vbtn_pm_ops,
132 }, 165 },
133 .probe = intel_vbtn_probe, 166 .probe = intel_vbtn_probe,
134 .remove = intel_vbtn_remove, 167 .remove = intel_vbtn_remove,