From 4a1ecb67f9ff1745422aecdd5cc70a9f630d7dc8 Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Thu, 24 Oct 2013 14:36:10 -0700 Subject: [PATCH] pit: Fix battery cutoff command to use deferred function call Rather than hackily sending a host response before sending the battery cutoff command, just put the cutoff command in a deferred function call and respond normally to the host command. BUG=chrome-os-partner:23568 BRANCH=none TEST=On battery power, 'ectool batterycutoff' prints success, then the system loses power due to battery cutoff. Change-Id: Ic42d08ef94a10f89d093290cda63da01fca985a5 Signed-off-by: Randall Spangler Reviewed-on: https://chromium-review.googlesource.com/174573 Reviewed-by: Bill Richardson --- driver/battery/bq20z453.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/driver/battery/bq20z453.c b/driver/battery/bq20z453.c index cda3a7cbdb..d15496b6d5 100644 --- a/driver/battery/bq20z453.c +++ b/driver/battery/bq20z453.c @@ -6,32 +6,30 @@ */ #include "battery_smart.h" +#include "hooks.h" #include "host_command.h" #define PARAM_CUT_OFF 0x0010 +static void cutoff(void) +{ + /* Claim i2c and send cutoff command to battery. */ + sb_write(SB_MANUFACTURER_ACCESS, PARAM_CUT_OFF); +} +DECLARE_DEFERRED(cutoff); + int battery_command_cut_off(struct host_cmd_handler_args *args) { /* - * TODO: Since this is a host command, the i2c bus is claimed by host. - * Thus, we would send back the response in advanced so that - * the host can release the bus and then EC can send command to - * battery. - * - * Refactoring this via task is a way. However, it is wasteful. - * Need a light-weight solution. + * Queue battery cutoff. This must be deferred so we can send the + * response to the host first. Some platforms (snow) share an I2C bus + * between the EC, AP, and battery, so we need the host to complete the + * transaction and release the I2C bus before we'll be abl eto send the + * cutoff command. */ - args->result = EC_RES_SUCCESS; - host_send_response(args); - - /* This function would try to claim i2c and then send to battery. */ - sb_write(SB_MANUFACTURER_ACCESS, PARAM_CUT_OFF); + hook_call_deferred(cutoff, 1000); return EC_RES_SUCCESS; - /* - * Not sure if there is a side-effect since this could send result - * back to host TWICE. - */ } DECLARE_HOST_COMMAND(EC_CMD_BATTERY_CUT_OFF, battery_command_cut_off, EC_VER_MASK(0));