aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRavi Chandra Sadineni <ravisadineni@chromium.org>2018-05-30 15:22:04 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2018-05-30 19:42:12 -0400
commit38ba34a43dbc00c87d13d1c4b6d0719a2ac87b2e (patch)
tree5279be593f866181bfa759a135963d180cbfc6f8 /drivers
parentcbd606ec9feff7c428cfec9b4a90a6b5e6744c31 (diff)
Input: cros_ec_keyb - mark cros_ec_keyb driver as wake enabled device.
Mark cros_ec_keyb has wake enabled by default. If we see a MKBP event related to keyboard, call pm_wakeup_event() to make sure wakeup triggers are accounted to keyb during suspend resume path. Signed-off-by: Ravi Chandra Sadineni <ravisadineni@chromium.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/keyboard/cros_ec_keyb.c33
-rw-r--r--drivers/mfd/cros_ec.c19
2 files changed, 28 insertions, 24 deletions
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c
index 79eb29550c34..489ddd37bd4e 100644
--- a/drivers/input/keyboard/cros_ec_keyb.c
+++ b/drivers/input/keyboard/cros_ec_keyb.c
@@ -244,24 +244,35 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
244 244
245 switch (ckdev->ec->event_data.event_type) { 245 switch (ckdev->ec->event_data.event_type) {
246 case EC_MKBP_EVENT_KEY_MATRIX: 246 case EC_MKBP_EVENT_KEY_MATRIX:
247 /* 247 if (device_may_wakeup(ckdev->dev)) {
248 * If EC is not the wake source, discard key state changes 248 pm_wakeup_event(ckdev->dev, 0);
249 * during suspend. 249 } else {
250 */ 250 /*
251 if (queued_during_suspend) 251 * If keyboard is not wake enabled, discard key state
252 return NOTIFY_OK; 252 * changes during suspend. Switches will be re-checked
253 * in cros_ec_keyb_resume() to be sure nothing is lost.
254 */
255 if (queued_during_suspend)
256 return NOTIFY_OK;
257 }
253 258
254 if (ckdev->ec->event_size != ckdev->cols) { 259 if (ckdev->ec->event_size != ckdev->cols) {
255 dev_err(ckdev->dev, 260 dev_err(ckdev->dev,
256 "Discarded incomplete key matrix event.\n"); 261 "Discarded incomplete key matrix event.\n");
257 return NOTIFY_OK; 262 return NOTIFY_OK;
258 } 263 }
264
259 cros_ec_keyb_process(ckdev, 265 cros_ec_keyb_process(ckdev,
260 ckdev->ec->event_data.data.key_matrix, 266 ckdev->ec->event_data.data.key_matrix,
261 ckdev->ec->event_size); 267 ckdev->ec->event_size);
262 break; 268 break;
263 269
264 case EC_MKBP_EVENT_SYSRQ: 270 case EC_MKBP_EVENT_SYSRQ:
271 if (device_may_wakeup(ckdev->dev))
272 pm_wakeup_event(ckdev->dev, 0);
273 else if (queued_during_suspend)
274 return NOTIFY_OK;
275
265 val = get_unaligned_le32(&ckdev->ec->event_data.data.sysrq); 276 val = get_unaligned_le32(&ckdev->ec->event_data.data.sysrq);
266 dev_dbg(ckdev->dev, "sysrq code from EC: %#x\n", val); 277 dev_dbg(ckdev->dev, "sysrq code from EC: %#x\n", val);
267 handle_sysrq(val); 278 handle_sysrq(val);
@@ -269,12 +280,9 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
269 280
270 case EC_MKBP_EVENT_BUTTON: 281 case EC_MKBP_EVENT_BUTTON:
271 case EC_MKBP_EVENT_SWITCH: 282 case EC_MKBP_EVENT_SWITCH:
272 /* 283 if (device_may_wakeup(ckdev->dev))
273 * If EC is not the wake source, discard key state 284 pm_wakeup_event(ckdev->dev, 0);
274 * changes during suspend. Switches will be re-checked in 285 else if (queued_during_suspend)
275 * cros_ec_keyb_resume() to be sure nothing is lost.
276 */
277 if (queued_during_suspend)
278 return NOTIFY_OK; 286 return NOTIFY_OK;
279 287
280 if (ckdev->ec->event_data.event_type == EC_MKBP_EVENT_BUTTON) { 288 if (ckdev->ec->event_data.event_type == EC_MKBP_EVENT_BUTTON) {
@@ -639,6 +647,7 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
639 return err; 647 return err;
640 } 648 }
641 649
650 device_init_wakeup(ckdev->dev, true);
642 return 0; 651 return 0;
643} 652}
644 653
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c
index d61024141e2b..36156a41499c 100644
--- a/drivers/mfd/cros_ec.c
+++ b/drivers/mfd/cros_ec.c
@@ -229,7 +229,7 @@ int cros_ec_suspend(struct cros_ec_device *ec_dev)
229} 229}
230EXPORT_SYMBOL(cros_ec_suspend); 230EXPORT_SYMBOL(cros_ec_suspend);
231 231
232static void cros_ec_drain_events(struct cros_ec_device *ec_dev) 232static void cros_ec_report_events_during_suspend(struct cros_ec_device *ec_dev)
233{ 233{
234 while (cros_ec_get_next_event(ec_dev, NULL) > 0) 234 while (cros_ec_get_next_event(ec_dev, NULL) > 0)
235 blocking_notifier_call_chain(&ec_dev->event_notifier, 235 blocking_notifier_call_chain(&ec_dev->event_notifier,
@@ -253,21 +253,16 @@ int cros_ec_resume(struct cros_ec_device *ec_dev)
253 dev_dbg(ec_dev->dev, "Error %d sending resume event to ec", 253 dev_dbg(ec_dev->dev, "Error %d sending resume event to ec",
254 ret); 254 ret);
255 255
256 /*
257 * In some cases, we need to distinguish between events that occur
258 * during suspend if the EC is not a wake source. For example,
259 * keypresses during suspend should be discarded if it does not wake
260 * the system.
261 *
262 * If the EC is not a wake source, drain the event queue and mark them
263 * as "queued during suspend".
264 */
265 if (ec_dev->wake_enabled) { 256 if (ec_dev->wake_enabled) {
266 disable_irq_wake(ec_dev->irq); 257 disable_irq_wake(ec_dev->irq);
267 ec_dev->wake_enabled = 0; 258 ec_dev->wake_enabled = 0;
268 } else {
269 cros_ec_drain_events(ec_dev);
270 } 259 }
260 /*
261 * Let the mfd devices know about events that occur during
262 * suspend. This way the clients know what to do with them.
263 */
264 cros_ec_report_events_during_suspend(ec_dev);
265
271 266
272 return 0; 267 return 0;
273} 268}