diff options
author | Ravi Chandra Sadineni <ravisadineni@chromium.org> | 2018-05-30 15:22:04 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2018-05-30 19:42:12 -0400 |
commit | 38ba34a43dbc00c87d13d1c4b6d0719a2ac87b2e (patch) | |
tree | 5279be593f866181bfa759a135963d180cbfc6f8 /drivers | |
parent | cbd606ec9feff7c428cfec9b4a90a6b5e6744c31 (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.c | 33 | ||||
-rw-r--r-- | drivers/mfd/cros_ec.c | 19 |
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 | } |
230 | EXPORT_SYMBOL(cros_ec_suspend); | 230 | EXPORT_SYMBOL(cros_ec_suspend); |
231 | 231 | ||
232 | static void cros_ec_drain_events(struct cros_ec_device *ec_dev) | 232 | static 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 | } |