summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2016-11-01 15:22:02 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2016-11-04 15:34:48 +0000
commitaa2f01566314604404e104d7975c6c755c22a601 (patch)
tree4c85e2678b963044cac7de1e7b0115eb312934d0
parent6f6bf59278f24047c94806dfd1f7d3230cf08e97 (diff)
downloadchrome-ec-aa2f01566314604404e104d7975c6c755c22a601.tar.gz
mkbp_event: Properly queue events during host sleep
Don't queue non-wake events, and ensure wake events (and all subsequent events) always get queued. BUG=chrome-os-partner:59248, chrome-os-partner:59336 BRANCH=gru TEST=Manual on kevin, go to suspend, press volume keys dozens of times, press 'shift', verify device wakes. Place cursor on URL bar, go to suspend, type "google" quickly, verify device wakes and "google" appears on URL bar. Go to suspend, press 'VolUp' key 5 times, press keyboard, verify device wakes and no volume meter is seen on display. Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Change-Id: Ibe761187fbcefd686776a512786550970a6fc067 Reviewed-on: https://chromium-review.googlesource.com/405717 Commit-Queue: Douglas Anderson <dianders@chromium.org> Tested-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Douglas Anderson <dianders@chromium.org>
-rw-r--r--common/keyboard_mkbp.c20
-rw-r--r--common/mkbp_event.c16
-rw-r--r--include/mkbp_event.h3
3 files changed, 19 insertions, 20 deletions
diff --git a/common/keyboard_mkbp.c b/common/keyboard_mkbp.c
index 08ec9d8c80..85e9a7b106 100644
--- a/common/keyboard_mkbp.c
+++ b/common/keyboard_mkbp.c
@@ -161,7 +161,6 @@ test_mockable int keyboard_fifo_add(const uint8_t *buffp)
test_mockable int mkbp_fifo_add(uint8_t event_type, const uint8_t *buffp)
{
- int ret = EC_SUCCESS;
uint8_t size;
/*
@@ -175,8 +174,8 @@ test_mockable int mkbp_fifo_add(uint8_t event_type, const uint8_t *buffp)
if (fifo_entries >= config.fifo_max_depth) {
CPRINTS("MKBP common FIFO depth %d reached",
config.fifo_max_depth);
- ret = EC_ERROR_OVERFLOW;
- goto fifo_push_done;
+
+ return EC_ERROR_OVERFLOW;
}
size = get_data_size(event_type);
@@ -185,14 +184,17 @@ test_mockable int mkbp_fifo_add(uint8_t event_type, const uint8_t *buffp)
memcpy(&fifo[fifo_end].data, buffp, size);
fifo_end = (fifo_end + 1) % FIFO_DEPTH;
atomic_add(&fifo_entries, 1);
- mutex_unlock(&fifo_mutex);
-fifo_push_done:
-
- if (ret == EC_SUCCESS)
- mkbp_send_event(event_type);
+ /*
+ * If our event didn't generate an interrupt then the host is still
+ * asleep. In this case, we don't want to queue our event, except if
+ * another event just woke the host (and wake is already in progress).
+ */
+ if (!mkbp_send_event(event_type) && fifo_entries == 1)
+ mkbp_clear_fifo();
- return ret;
+ mutex_unlock(&fifo_mutex);
+ return EC_SUCCESS;
}
void mkbp_update_switches(uint32_t sw, int state)
diff --git a/common/mkbp_event.c b/common/mkbp_event.c
index ec8aad35aa..6848bd2813 100644
--- a/common/mkbp_event.c
+++ b/common/mkbp_event.c
@@ -60,26 +60,22 @@ static inline int host_is_sleeping(void)
return is_sleeping;
}
-void mkbp_send_event(uint8_t event_type)
+int mkbp_send_event(uint8_t event_type)
{
set_event(event_type);
#ifdef CONFIG_MKBP_WAKEUP_MASK
/* Only assert interrupt for wake events if host is sleeping */
if (host_is_sleeping()) {
- /*
- * interrupt the AP if it is a wakeup event
- * which is defined in the white list.
- */
- if ((host_get_events() & CONFIG_MKBP_WAKEUP_MASK) ||
- (event_type == EC_MKBP_EVENT_KEY_MATRIX))
- set_host_interrupt(1);
-
- return;
+ /* Skip host wake if this isn't a wake event */
+ if (!(host_get_events() & CONFIG_MKBP_WAKEUP_MASK) &&
+ event_type != EC_MKBP_EVENT_KEY_MATRIX)
+ return 0;
}
#endif
set_host_interrupt(1);
+ return 1;
}
static int mkbp_get_next_event(struct host_cmd_handler_args *args)
diff --git a/include/mkbp_event.h b/include/mkbp_event.h
index 6e97c2e973..cad43444b5 100644
--- a/include/mkbp_event.h
+++ b/include/mkbp_event.h
@@ -15,8 +15,9 @@
* when the AP queries the event, an error is returned and the event is lost.
*
* @param event_type One of EC_MKBP_EVENT_*.
+ * @return True if event succeeded to generate host interrupt.
*/
-void mkbp_send_event(uint8_t event_type);
+int mkbp_send_event(uint8_t event_type);
/*
* The struct to store the event source definition. The get_data routine is