diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2021-01-21 10:16:46 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-01-25 21:38:51 +0000 |
commit | b1d414b7799cddd11f7d02fdd7c23325e5d18ac1 (patch) | |
tree | 52659dce690e7ed79d00565991f46a303872c87d | |
parent | 3c5f55ace377e1c939be2397c4fe73a3b2ee4fb4 (diff) | |
download | chrome-ec-b1d414b7799cddd11f7d02fdd7c23325e5d18ac1.tar.gz |
pchg: Initialize pchg chips on startup
This patch makes pchg task disable the interrupt on shutdown and
initialize pchg chips on start-up.
Tested as follows:
1. Run dut-control power_state:on -> off -> on.
2. Run dut-control power_state:reset.
Do 1 and 2 with and without a stylus attached and verify pchg task
remains under control.
BUG=b:176725734, b:173235954
BRANCH=trogdor
TEST=CoachZ
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Change-Id: I0b1b5501975ad6c8a89041639d3fa90a71b4e9b5
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2643586
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | common/peripheral_charger.c | 85 |
1 files changed, 69 insertions, 16 deletions
diff --git a/common/peripheral_charger.c b/common/peripheral_charger.c index 8e714e99c9..e907257452 100644 --- a/common/peripheral_charger.c +++ b/common/peripheral_charger.c @@ -4,6 +4,7 @@ */ #include "atomic.h" +#include "chipset.h" #include "common.h" #include "device_event.h" #include "hooks.h" @@ -69,20 +70,29 @@ static const char *_text_event(enum pchg_event event) return event_names[event]; } +static enum pchg_state pchg_initialize(struct pchg *ctx, enum pchg_state state) +{ + int rv = ctx->cfg->drv->init(ctx); + + if (rv == EC_SUCCESS) { + pchg_queue_event(ctx, PCHG_EVENT_ENABLE); + state = PCHG_STATE_INITIALIZED; + } else if (rv == EC_SUCCESS_IN_PROGRESS) { + state = PCHG_STATE_RESET; + } else { + CPRINTS("ERR: Failed to initialize"); + } + + return state; +} + static enum pchg_state pchg_state_reset(struct pchg *ctx) { enum pchg_state state = PCHG_STATE_RESET; - int rv; switch (ctx->event) { case PCHG_EVENT_INITIALIZE: - rv = ctx->cfg->drv->init(ctx); - if (rv == EC_SUCCESS) { - pchg_queue_event(ctx, PCHG_EVENT_ENABLE); - state = PCHG_STATE_INITIALIZED; - } else if (rv != EC_SUCCESS_IN_PROGRESS) { - CPRINTS("ERR: Failed to initialize"); - } + state = pchg_initialize(ctx, state); break; case PCHG_EVENT_INITIALIZED: pchg_queue_event(ctx, PCHG_EVENT_ENABLE); @@ -108,6 +118,9 @@ static enum pchg_state pchg_state_initialized(struct pchg *ctx) return state; switch (ctx->event) { + case PCHG_EVENT_INITIALIZE: + state = pchg_initialize(ctx, state); + break; case PCHG_EVENT_ENABLE: rv = ctx->cfg->drv->enable(ctx, true); if (rv == EC_SUCCESS) @@ -131,6 +144,9 @@ static enum pchg_state pchg_state_enabled(struct pchg *ctx) int rv; switch (ctx->event) { + case PCHG_EVENT_INITIALIZE: + state = pchg_initialize(ctx, state); + break; case PCHG_EVENT_DISABLE: ctx->error |= PCHG_ERROR_HOST; rv = ctx->cfg->drv->enable(ctx, false); @@ -161,6 +177,9 @@ static enum pchg_state pchg_state_detected(struct pchg *ctx) int rv; switch (ctx->event) { + case PCHG_EVENT_INITIALIZE: + state = pchg_initialize(ctx, state); + break; case PCHG_EVENT_DISABLE: ctx->error |= PCHG_ERROR_HOST; rv = ctx->cfg->drv->enable(ctx, false); @@ -194,6 +213,9 @@ static enum pchg_state pchg_state_charging(struct pchg *ctx) int rv; switch (ctx->event) { + case PCHG_EVENT_INITIALIZE: + state = pchg_initialize(ctx, state); + break; case PCHG_EVENT_DISABLE: ctx->error |= PCHG_ERROR_HOST; rv = ctx->cfg->drv->enable(ctx, false); @@ -277,7 +299,6 @@ static int pchg_run(struct pchg *ctx) CPRINTS("->%s", _text_state(ctx->state)); ctx->event = PCHG_EVENT_NONE; - CPRINTS("Done"); return 1; } @@ -297,23 +318,56 @@ void pchg_irq(enum gpio_signal signal) } } -void pchg_task(void *u) +static void pchg_startup(void) { struct pchg *ctx; int p; - int rv; - /* TODO: i2c is wedged for a while after reset. investigate. */ - msleep(500); + CPRINTS("%s", __func__); for (p = 0; p < pchg_count; p++) { ctx = &pchgs[p]; - ctx->state = PCHG_STATE_RESET; - queue_init(&ctx->events); pchg_queue_event(ctx, PCHG_EVENT_INITIALIZE); gpio_enable_interrupt(ctx->cfg->irq_pin); } + task_wake(TASK_ID_PCHG); +} +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, pchg_startup, HOOK_PRIO_DEFAULT); + +static void pchg_shutdown(void) +{ + struct pchg *ctx; + int p; + + CPRINTS("%s", __func__); + + for (p = 0; p < pchg_count; p++) { + ctx = &pchgs[0]; + gpio_disable_interrupt(ctx->cfg->irq_pin); + mutex_lock(&ctx->mtx); + queue_init(&ctx->events); + mutex_unlock(&ctx->mtx); + } +} +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, pchg_shutdown, HOOK_PRIO_DEFAULT); + +void pchg_task(void *u) +{ + struct pchg *ctx; + int p; + int rv; + + /* + * Without delay, after servo flash, ctn730 in RW always fails to write + * ENABLE_CMD (b:176824601). + */ + msleep(50); + + /* In case we arrive here after power-on (for late sysjump) */ + if (chipset_in_state(CHIPSET_STATE_ON)) + pchg_startup(); + while (true) { /* Process pending events for all ports. */ rv = 0; @@ -390,7 +444,6 @@ static int cc_pchg(int argc, char **argv) } if (!strcasecmp(argv[2], "init")) { - ctx->state = PCHG_STATE_RESET; pchg_queue_event(ctx, PCHG_EVENT_INITIALIZE); } else if (!strcasecmp(argv[2], "enable")) { pchg_queue_event(ctx, PCHG_EVENT_ENABLE); |