summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2021-01-21 10:16:46 -0800
committerCommit Bot <commit-bot@chromium.org>2021-01-25 21:38:51 +0000
commitb1d414b7799cddd11f7d02fdd7c23325e5d18ac1 (patch)
tree52659dce690e7ed79d00565991f46a303872c87d
parent3c5f55ace377e1c939be2397c4fe73a3b2ee4fb4 (diff)
downloadchrome-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.c85
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);