diff options
-rw-r--r-- | common/battery.c | 8 | ||||
-rw-r--r-- | driver/battery/smart.c | 36 | ||||
-rw-r--r-- | include/battery.h | 11 |
3 files changed, 52 insertions, 3 deletions
diff --git a/common/battery.c b/common/battery.c index 00c9540a1f..d538ed4c43 100644 --- a/common/battery.c +++ b/common/battery.c @@ -311,10 +311,16 @@ int battery_is_cut_off(void) return (battery_cutoff_state == BATTERY_CUTOFF_STATE_CUT_OFF); } +int battery_cutoff_in_progress(void) +{ + return (battery_cutoff_state == BATTERY_CUTOFF_STATE_IN_PROGRESS); +} + static void pending_cutoff_deferred(void) { int rv; + battery_cutoff_state = BATTERY_CUTOFF_STATE_IN_PROGRESS; rv = board_cut_off_battery(); if (rv == EC_RES_SUCCESS) { @@ -350,6 +356,7 @@ static enum ec_status battery_command_cutoff(struct host_cmd_handler_args *args) } } + battery_cutoff_state = BATTERY_CUTOFF_STATE_IN_PROGRESS; rv = board_cut_off_battery(); if (rv == EC_RES_SUCCESS) { CUTOFFPRINTS("is successful."); @@ -387,6 +394,7 @@ static int command_cutoff(int argc, const char **argv) } } + battery_cutoff_state = BATTERY_CUTOFF_STATE_IN_PROGRESS; rv = board_cut_off_battery(); if (rv == EC_RES_SUCCESS) { ccprints("Battery cut off"); diff --git a/driver/battery/smart.c b/driver/battery/smart.c index 1f9512ce71..539580d201 100644 --- a/driver/battery/smart.c +++ b/driver/battery/smart.c @@ -50,6 +50,13 @@ test_mockable int sb_read(int cmd, int *param) #ifdef CONFIG_BATTERY_CUT_OFF /* + * Ship mode command need to set continuously, can't be interfered + * by another command. + */ + if (battery_cutoff_in_progress()) + return EC_ERROR_ACCESS_DENIED; + + /* * Some batteries would wake up after cut-off if we talk to it. */ if (battery_is_cut_off()) @@ -84,6 +91,13 @@ int sb_read_string(int offset, uint8_t *data, int len) #ifdef CONFIG_BATTERY_CUT_OFF /* + * Ship mode command need to set continuously, can't be interfered + * by another command. + */ + if (battery_cutoff_in_progress()) + return EC_ERROR_ACCESS_DENIED; + + /* * Some batteries would wake up after cut-off if we talk to it. */ if (battery_is_cut_off()) @@ -102,6 +116,13 @@ int sb_read_sized_block(int offset, uint8_t *data, int len) if (IS_ENABLED(CONFIG_BATTERY_CUT_OFF)) { /* + * Ship mode command need to set continuously, can't be + * interfered by another command. + */ + if (battery_cutoff_in_progress()) + return EC_ERROR_ACCESS_DENIED; + + /* * Some batteries would wake up after cut-off if we talk to it. */ if (battery_is_cut_off()) @@ -669,7 +690,10 @@ host_command_sb_read_word(struct host_cmd_handler_args *args) return EC_RES_INVALID_PARAM; rv = sb_read(p->reg, &val); if (rv) - return EC_RES_ERROR; + if (rv == EC_ERROR_ACCESS_DENIED) + return EC_RES_ACCESS_DENIED; + else + return EC_RES_ERROR; r->value = val; args->response_size = sizeof(struct ec_response_sb_rd_word); @@ -689,7 +713,10 @@ host_command_sb_write_word(struct host_cmd_handler_args *args) return EC_RES_INVALID_PARAM; rv = sb_write(p->reg, p->value); if (rv) - return EC_RES_ERROR; + if (rv == EC_ERROR_ACCESS_DENIED) + return EC_RES_ACCESS_DENIED; + else + return EC_RES_ERROR; return EC_RES_SUCCESS; } @@ -708,7 +735,10 @@ host_command_sb_read_block(struct host_cmd_handler_args *args) return EC_RES_INVALID_PARAM; rv = sb_read_string(p->reg, r->data, 32); if (rv) - return EC_RES_ERROR; + if (rv == EC_ERROR_ACCESS_DENIED) + return EC_RES_ACCESS_DENIED; + else + return EC_RES_ERROR; args->response_size = sizeof(struct ec_response_sb_rd_block); diff --git a/include/battery.h b/include/battery.h index be93b44c21..f754c9de91 100644 --- a/include/battery.h +++ b/include/battery.h @@ -76,8 +76,14 @@ FORWARD_DECLARE_ENUM(battery_present){ BP_NOT_SURE, }; +/* + * BATTERY_CUTOFF_STATE_IN_PROGRESS: Battery cutoff has begun but not completed. + * BATTERY_CUTOFF_STATE_PENDING: Battery cutoff is requested by the + * AP but hasn't started. + */ enum battery_cutoff_states { BATTERY_CUTOFF_STATE_NORMAL = 0, + BATTERY_CUTOFF_STATE_IN_PROGRESS, BATTERY_CUTOFF_STATE_CUT_OFF, BATTERY_CUTOFF_STATE_PENDING, }; @@ -439,6 +445,11 @@ int battery_imbalance_mv(void); int board_cut_off_battery(void); /** + * Return if the battery start cut off. + */ +int battery_cutoff_in_progress(void); + +/** * Return if the battery has been cut off. */ int battery_is_cut_off(void); |