From 061d7bbd58cd4baacadd55bb71a3b263bcb07871 Mon Sep 17 00:00:00 2001 From: Daisuke Nojiri Date: Mon, 1 Feb 2021 10:06:15 -0800 Subject: pchg: Notify host of only device detection in suspend Currently, pchg sends a host event for any event including charging update. This will prevent the host from staying in S3 while charging a peripheral device. This patch makes pchg notify the host only a device attach or detach event when the system is in S3/S0ix. Tested resume on detach as follows: 1. Verify system can suspend with a stylus attached. 2. Detach a stylus. 3. Verify system resumes. Tested resume on attach as follows: 1. Suspend with a stylus detached. 2. Attach a stylus. 3. Verify system resumes. BUG=b:177664326,b:173235954 BRANCH=trogdor TEST=CoachZ. See above. Signed-off-by: Daisuke Nojiri Change-Id: Icf7c6c46f94f27f1f24eb2ac9634d317bc14f4d9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2665407 Reviewed-by: Vincent Palatin --- common/peripheral_charger.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/common/peripheral_charger.c b/common/peripheral_charger.c index 326b0bb495..131d660d40 100644 --- a/common/peripheral_charger.c +++ b/common/peripheral_charger.c @@ -268,7 +268,6 @@ static int pchg_run(struct pchg *ctx) rv = ctx->cfg->drv->get_event(ctx); if (rv) { CPRINTS("ERR: get_event (%d)", rv); - ctx->event = PCHG_EVENT_NONE; return 0; } CPRINTS("IRQ:EVENT_%s", _text_event(ctx->event)); @@ -298,9 +297,19 @@ static int pchg_run(struct pchg *ctx) if (previous_state != ctx->state) CPRINTS("->STATE_%s", _text_state(ctx->state)); - ctx->event = PCHG_EVENT_NONE; + /* + * Notify the host of + * - [S0] any event + * - [S3/S0IX] device attach or detach (for wake-up) + * - [S5/G3] no events. + */ + if (chipset_in_state(CHIPSET_STATE_ON)) + return ctx->event != PCHG_EVENT_NONE; + else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) + return (ctx->event == PCHG_EVENT_DEVICE_DETECTED) + || (ctx->event == PCHG_EVENT_DEVICE_LOST); - return 1; + return 0; } void pchg_irq(enum gpio_signal signal) @@ -356,7 +365,6 @@ void pchg_task(void *u) { struct pchg *ctx; int p; - int rv; /* In case we arrive here after power-on (for late sysjump) */ if (chipset_in_state(CHIPSET_STATE_ON)) @@ -364,7 +372,8 @@ void pchg_task(void *u) while (true) { /* Process pending events for all ports. */ - rv = 0; + int rv = 0; + for (p = 0; p < pchg_count; p++) { ctx = &pchgs[p]; do { @@ -373,13 +382,11 @@ void pchg_task(void *u) rv |= pchg_run(ctx); } while (queue_count(&ctx->events)); } - /* - * Send one host event for all ports. Currently PCHG supports - * only WLC but in the future other types (e.g. WPC Qi) should - * send different device events. - */ + + /* Send one host event for all ports. */ if (rv) device_set_single_event(EC_DEVICE_EVENT_WLC); + task_wait_event(-1); } } @@ -432,7 +439,7 @@ static int cc_pchg(int argc, char **argv) ctx = &pchgs[port]; if (argc == 2) { - ccprintf("P%d %s %s\n", port, + ccprintf("P%d STATE_%s EVENT_%s\n", port, _text_state(ctx->state), _text_event(ctx->event)); return EC_SUCCESS; } -- cgit v1.2.1