/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2023, Google Inc
 *
 * MAX77779 firmware updater
 */

#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/regmap.h>
#include <linux/debugfs.h>

#include "google_bms.h"
#include "max77779_regs.h"
#include "max77779.h"
#include "maxfg_common.h"
#include "max77779_charger.h"

#define MAX77779_FIRMWARE_BINARY_PREFIX "batt_fw_adi_79"
#define MAX77779_REASON_FIRMWARE        "FW_UPDATE"

#define FW_UPDATE_RETRY_CPU_RESET             100
#define FW_UPDATE_RETRY_FW_UPDATE             1000
#define FW_UPDATE_RETRY_RISCV_REBOOT          20
#define FW_UPDATE_RETRY_ONCE                  1
#define FW_UPDATE_WAIT_INTERVAL_MS            50
#define FW_UPDATE_WAIT_LOAD_BIN_MS            50
#define FW_UPDATE_TIMER_CHECK_INTERVAL_MS     1000
#define FW_UPDATE_CONDITION_CHECK_INTERVAL_MS (60 * 1000)

#define FW_UPDATE_MAXIMUM_PAGE_SIZE            (PAGE_SIZE*10)

/* b/308445917: adding device tree for voltage threshold in micro volts */
#define MAX77779_FW_UPDATE_MIN_VOLTAGE 4000000

#define MAX77779_FW_IMG_SZ_HEADER 8
#define MAX77779_FW_IMG_SZ_PACKET 42
#define MAX77779_FW_IMG_SZ_FRAME (MAX77779_FW_IMG_SZ_PACKET * 20)


#define MAX77779_FG_SECUPDATE_STATUS_REG 0x6F
#define MAX77779_FG_SECUPDATE_STATUS_SUCCESS 0x03

/* PMIC.0x62 can be set 0xFF if previous firmware update fails */
#define MAX77779_FW_INVALID_FW_VER 0xFF

#define MAX77779_REV_PASS_1_5 0x1
#define MAX77779_REV_PASS_2_0 0x2

#define MAX77779_REV_PASS_1_5_FIRMWARE 2
#define MAX77779_REV_PASS_2_0_FIRMWARE 3

/* vimon's memory mapped to 0x80 */
#define MAX77779_VIMON_MEM_BASE_ADDR 0x80
#define MAX77779_VIMON_PG_SIZE 256
#define MAX77779_VIMON_PG3_SIZE (MAX77779_VIMON_PG_SIZE - 32)

#define MAX77779_OFFSET_VER_MAJOR 7
#define MAX77779_OFFSET_VER_MINOR 6

#define MAX77779_FW_UPDATE_STRING_MAX 32

#define MAX77779_FW_UPDATE_RETRY_MAX 10

#define MAX77779_GET_DATA_FRAME_SIZE(filelen) \
	(filelen - MAX77779_FW_IMG_SZ_HEADER - 3*MAX77779_FW_IMG_SZ_PACKET)

#define MAX77779_ABORT_ON_ERROR(result, name, err_op) { \
	if (result) { \
		dev_err(fwu->dev, "[%s] failed: %s (%d)\n", name, err_op, result); \
		return result; \
	} \
}

#define MARK_IN_PROGRESS() do {} while (0);

#define MAX77779_FW_HIST_OFFSET_TAG 16
#define MAX77779_FW_HIST_VER_MASK   0xFFFF


enum max77779_fwupdate_fg_lock {
	FG_ST_LOCK_ALL_SECTION = 0x0e,
	FG_ST_UNLOCK_ALL_SECTION = 0x00,
};

enum max77779_fg_operation_status {
	FGST_NOT_CACHED = 0x01,
	FGST_FWUPDATE = 0x02,
	FGST_BASEFW = 0x03,
	FGST_ERR_READTAG = 0x10,
	FGST_NORMAL = 0xff,
};

enum max77779_fwupdate_intr {
	MAX77779_INTR_CLEAR = 0x00,
	MAX77779_INTR_SESSION_START = 0x70,
	MAX77779_INTR_TRANSFER_FRAMES = 0x72,
	MAX77779_INTR_APP_VALID = 0x77,
	MAX77779_INTR_SESSION_END = 0x74,
};

enum max77779_fwupdate_rsp_code {
	MAX77779_RSP_CODE_OK = 0x00,
	MAX77779_RSP_CODE_UNEXPECTED = 0xF0,
	MAX77779_RSP_CODE_CMD_SEC_FAIL = 0xF1,
	MAX77779_RSP_CODE_INVALID_PARAM = 0xF4,
	MAX77779_RSP_CODE_NOT_READY = 0xFF,
};

enum max77779_fwupdate_cmd {
	MAX77779_CMD_CLEAR_ALL = 0x00,
        MAX77779_CMD_REBOOT_FG = 0x0F,
	MAX77779_CMD_REBOOT_RISCV = 0x080F,
};

enum max77779_fwupdate_status {
	MAX77779_FWU_OK = 0x0,
	MAX77779_FWU_RUNNING_UPDATE,
	MAX77779_FWU_REG_ACCESS_ERR,
	MAX77779_FWU_UPDATE_FAIL,
	MAX77779_FWU_BOOT_ERR,
	MAX77779_FWU_TIMER_ERR,
};

enum max77779_fwupdate_err_code {
	MAX77779_FWU_ERR_NONE = 0,
	MAX77779_FWU_ERR_PREPARE,
	MAX77779_FWU_ERR_DATA_TRANSFER,
	MAX77779_FWU_ERR_POST_STATUS_CHECK,
};

struct max77779_version_info {
	u8 major;
	u8 minor;
};

/* saved as GBMS_TAG_FWSF */
struct max77779_fwupdate_stats {
	s16 count;
	s8  success;
	s8  fail;
}__attribute__((packed));

struct max77779_fwupdate_custom_data {
	ssize_t size;
	char*  data;
};

struct max77779_fwupdate_info {
	int new_tag;
	int retry_cnt;
	bool force_update;
	bool reboot_on_failure;
};

struct max77779_fwupdate {
	struct device *dev;
	struct dentry *de;

	struct delayed_work update_work;

	struct device *pmic;
	struct device *fg;
	struct device *vimon;
	struct device *chg;

	struct platform_device *batt;

	bool can_update;
	bool running_update;
	struct max77779_fwupdate_info update_info;

	struct max77779_version_info v_cur;
	struct max77779_version_info v_new;

	char fw_name[MAX77779_FW_UPDATE_STRING_MAX];

	size_t data_frame_size;
	u32 crc_val;

	u8 op_st;

	u8* scratch_buffer;
	u8* zero_filled_buffer;

	int minimum_voltage;

	struct max77779_version_info minimum;

	struct max77779_fwupdate_custom_data debug_image;

	struct wakeup_source *fwupdate_wake_lock;
	struct mutex status_lock;

	struct max77779_fwupdate_stats stats;

	struct logbuffer *lb;

	struct gvotable_election *mode_votable;
};

/* Defined at max77779_fg.c */
int max77779_external_fg_reg_write_nolock(struct device *, uint16_t, uint16_t);

static int get_firmware_update_tag(const struct max77779_fwupdate *fwu)
{
	int ret, ver_tag = 0;
	uint32_t fw_tag = 0, cur_ver;

	ret = gbms_storage_read(GBMS_TAG_FWHI, &fw_tag, sizeof(fw_tag));
	if (ret < 0)
		gbms_logbuffer_prlog(fwu->lb, LOGLEVEL_WARNING, 0, LOGLEVEL_INFO,
				     "failed to read GBMS_TAG_FWHI (%d)\n", ret);

	cur_ver = (fwu->v_cur.major << 8) | fwu->v_cur.minor;

	if ((fw_tag & MAX77779_FW_HIST_VER_MASK) == cur_ver)
		ver_tag = (fw_tag >> MAX77779_FW_HIST_OFFSET_TAG);

	return ver_tag;
}

static void set_firmware_update_tag(const struct max77779_fwupdate *fwu, int tag)
{
	int ret;
	uint32_t fw_tag;

	fw_tag = (tag << MAX77779_FW_HIST_OFFSET_TAG);
	fw_tag |= (fwu->v_cur.major << 8) | fwu->v_cur.minor;

	ret= gbms_storage_write(GBMS_TAG_FWHI, &fw_tag, sizeof(fw_tag));
	if (ret < 0)
		gbms_logbuffer_prlog(fwu->lb, LOGLEVEL_WARNING, 0, LOGLEVEL_INFO,
				     "failed to write GBMS_TAG_FWHI (%d)\n", ret);
}

static inline void read_fwupdate_stats(struct max77779_fwupdate *fwu)
{
	int ret;

	ret = gbms_storage_read(GBMS_TAG_FWSF, &fwu->stats, sizeof(fwu->stats));
	if (ret < 0)
		gbms_logbuffer_prlog(fwu->lb, LOGLEVEL_WARNING, 0, LOGLEVEL_INFO,
				     "failed to read GBMS_TAG_FWSF (%d)\n", ret);

	if (ret < 0 || fwu->stats.count < 0 || fwu->stats.success < 0 || fwu->stats.fail < 0
	    || fwu->stats.count != fwu->stats.success + fwu->stats.fail) {
		/* invalid stats values. reset all counter to 0 */
		fwu->stats.count = 0;
		fwu->stats.success = 0;
		fwu->stats.fail = 0;
	}
}

static inline void update_fwupdate_stats(struct max77779_fwupdate *fwu,
					 struct max77779_fwupdate_stats* stats)
{
	int ret;

	ret = gbms_storage_write(GBMS_TAG_FWSF, stats, sizeof(*stats));
	if (ret < 0)
		gbms_logbuffer_prlog(fwu->lb, LOGLEVEL_WARNING, 0, LOGLEVEL_INFO,
				     "failed to write GBMS_TAG_FWSF (%d)\n", ret);
}

/* TODO: b/326472325 it needs to handle counter reaches MAX77779_FW_UPDATE_RETRY_MAX */
static inline int max77779_schedule_update(struct max77779_fwupdate* fwu)
{
	int ret = -1;

	mutex_lock(&fwu->status_lock);

	if (fwu->update_info.retry_cnt < MAX77779_FW_UPDATE_RETRY_MAX) {
		fwu->update_info.retry_cnt++;
		ret = 0;
	}

	mutex_unlock(&fwu->status_lock);

	if (ret == 0) {
		dev_info(fwu->dev, "will schedule firmware update for [%s]\n", fwu->fw_name);
		schedule_delayed_work(&fwu->update_work,
				      msecs_to_jiffies(FW_UPDATE_CONDITION_CHECK_INTERVAL_MS));
	}

	return ret;
}

static int max77779_fwupdate_init(struct max77779_fwupdate *fwu)
{
	struct device* dev = fwu->dev;
	struct device_node *dn;
	int val = 0;

	if (!dev)
		return -EINVAL;

	fwu->update_info.force_update = false;
	fwu->running_update = false;
	fwu->minimum_voltage = MAX77779_FW_UPDATE_MIN_VOLTAGE;

	fwu->debug_image.data = NULL;
	fwu->debug_image.size = 0;

	mutex_init(&fwu->status_lock);

	fwu->pmic = max77779_get_dev(fwu->dev, MAX77779_PMIC_OF_NAME);
	if (!fwu->pmic) {
		dev_err(dev, "Error finding pmic\n");
		return -EPROBE_DEFER;
	}

	fwu->fg = max77779_get_dev(fwu->dev, "max77779,fg");
	if (!fwu->fg) {
		dev_err(dev, "Error finding fg\n");
		return -EPROBE_DEFER;
	}

	fwu->vimon = max77779_get_dev(fwu->dev, "max77779,vimon");
	if (!fwu->vimon) {
		dev_err(dev, "Error finding vimon\n");
		return -EPROBE_DEFER;
	}

	fwu->chg = max77779_get_dev(fwu->dev, "max77779,chg");
	if (!fwu->chg) {
		dev_err(dev, "Error finding chg\n");
		return -EPROBE_DEFER;
	}

	if (!fwu->batt) {
		dn = of_parse_phandle(dev->of_node, "google,battery", 0);
		if (!dn)
			return -ENXIO;

		fwu->batt = of_find_device_by_node(dn);
		if (!fwu->batt)
			return -EPROBE_DEFER;
	}

	val = gbms_storage_read(GBMS_TAG_FGST, &fwu->op_st, sizeof(fwu->op_st));
	if (val < 0)
		gbms_logbuffer_prlog(fwu->lb, LOGLEVEL_WARNING, 0, LOGLEVEL_INFO,
				     "failed to read FGST tag (%d)\n", val);

	if (of_property_read_u32(dev->of_node, "fwu,enabled", &val) == 0)
		fwu->can_update = val;

	if (of_property_read_u32(dev->of_node, "minimum-voltage", &val) == 0)
		fwu->minimum_voltage = val;

	if (of_property_read_u32(dev->of_node, "version-major", &val) == 0)
		fwu->minimum.major = (u8)val;

	if (of_property_read_u32(dev->of_node, "version-minor", &val) == 0)
		fwu->minimum.minor = (u8)val;

	fwu->lb = logbuffer_register("max77779_fwupdate");
	if (IS_ERR(fwu->lb)) {
		val = PTR_ERR(fwu->lb);
		dev_err(dev, "failed to obtain logbuffer, ret=%d\n", val);
		fwu->lb = NULL;
		return val;
	}

	read_fwupdate_stats(fwu);

	return 0;
}

static int max77779_wait_cpu_reset(struct max77779_fwupdate *fwu)
{
	int ret;
	int cnt = 0;
	uint8_t val;

	dev_info(fwu->dev, "waiting for cpu reset\n");

	while (cnt < FW_UPDATE_RETRY_CPU_RESET) {
		msleep(FW_UPDATE_WAIT_INTERVAL_MS);
		ret = max77779_external_pmic_reg_read(fwu->pmic, MAX77779_PMIC_RISCV_AP_DATAIN0, &val);
		if (ret == 0) {
			if (val != MAX77779_RSP_CODE_UNEXPECTED) {
				MARK_IN_PROGRESS();
			} else {
				dev_info(fwu->dev, "cpu reset completed\n");
				return 0;
			}
		}
		cnt++;
	}

	dev_err(fwu->dev, "timeout for max77779_wait_cpu_reset\n");
	return -ETIMEDOUT;
}

static int max77779_wait_fw_update(struct max77779_fwupdate *fwu)
{
	int ret;
	int cnt = 0;
	uint8_t val;

	dev_info(fwu->dev, "waiting for firmware update\n");

	do {
		msleep(FW_UPDATE_WAIT_INTERVAL_MS);
		cnt++;

		ret = max77779_external_pmic_reg_read(fwu->pmic, MAX77779_PMIC_RISCV_AP_DATAIN0, &val);
		if (ret != 0 || val == MAX77779_RSP_CODE_NOT_READY) {
			MARK_IN_PROGRESS();
			continue;
		} else if (val == MAX77779_RSP_CODE_UNEXPECTED) {
			dev_err(fwu->dev, "failed to firmware update rsp %02x\n", val);
			return -EBADFD;
		}

		dev_info(fwu->dev, "firmware update completed: rsp %02x\n", val);
		return 0;

	} while (cnt < FW_UPDATE_RETRY_FW_UPDATE);

	dev_err(fwu->dev, "timeout for max77779_wait_fw_update\n");
	return -ETIMEDOUT;
}

static int max77779_wait_riscv_reboot(struct max77779_fwupdate *fwu)
{
	int ret;
	int cnt = 0;
	uint16_t val;

	dev_info(fwu->dev, "waiting for riscv reboot\n");

	while (cnt < FW_UPDATE_RETRY_RISCV_REBOOT) {
		msleep(FW_UPDATE_WAIT_INTERVAL_MS);
		ret = max77779_external_fg_reg_read(fwu->fg, MAX77779_FG_FG_INT_STS, &val);
		if (!ret && (val & MAX77779_FG_FG_INT_MASK_POR_m_MASK)) {
			dev_info(fwu->dev, "wait_risc_reboot POR interrupt received\n");
			return 0;
		}

		cnt++;
	}

	dev_err(fwu->dev, "timeout for POR interrupt\n");
	return -ETIMEDOUT;
}

/* b/328083603: Even POR triggered, RISC-V may not be ready */
static int check_boot_completed(struct max77779_fwupdate *fwu, int max_retry)
{
	int ret, retry;
	uint16_t val;

	for (retry = 0; retry < max_retry; retry++) {
		ret = max77779_external_fg_reg_read(fwu->fg, MAX77779_FG_BOOT_CHECK_REG, &val);
		if (ret) {
			dev_err(fwu->dev, "failed to read %02x (%d) in check boot completed\n",
				MAX77779_FG_BOOT_CHECK_REG, ret);
			return ret;
		}

		/* b/323382370 */
		if ((val & MAX77779_FG_BOOT_CHECK_SUCCESS) == MAX77779_FG_BOOT_CHECK_SUCCESS)
			break;

		msleep(FW_UPDATE_WAIT_INTERVAL_MS);
	}

	if (retry == max_retry) {
		dev_err(fwu->dev, "Boot NOT completed successfully: %04x\n", val);
		return -EIO;
	}

	dev_info(fwu->dev, "Boot completed successfully\n");
	return 0;
}

static int max77779_check_timer_refresh(struct max77779_fwupdate *fwu)
{
	int ret;
	uint16_t val0, val1;

	dev_info(fwu->dev, "check for timer refresh\n");

	ret = max77779_external_fg_reg_read(fwu->fg, MAX77779_FG_Timer, &val0);
	if (ret)
		goto check_timer_error;

	msleep(FW_UPDATE_TIMER_CHECK_INTERVAL_MS);

	ret = max77779_external_fg_reg_read(fwu->fg, MAX77779_FG_Timer, &val1);
	if (ret)
		goto check_timer_error;

	if (val1 <= val0) {
		dev_err(fwu->dev, "Timer NOT updating correctly\n");
		return -EIO;
	}

	dev_info(fwu->dev, "Timer updating correctly\n");
	return 0;

check_timer_error:
	dev_err(fwu->dev, "failed to read %02x (%d) in max77779_check_timer_refresh\n",
		MAX77779_FG_Timer, ret);
	return ret;
}

static int max77779_send_command(struct max77779_fwupdate *fwu,
				 enum max77779_fwupdate_cmd cmd)
{
	int ret;

	ret = max77779_external_fg_reg_write_nolock(fwu->fg, MAX77779_FG_Command_fw, cmd);
	if (ret)
		dev_err(fwu->dev, "failed to write fg reg %02x (%d) in max77779_send_command\n",
			MAX77779_FG_Command_fw, ret);

	return ret;
}

static int max77779_trigger_interrupt(struct max77779_fwupdate *fwu,
				      enum max77779_fwupdate_intr intr)
{
	int ret;

	ret = max77779_external_pmic_reg_write(fwu->pmic, MAX77779_PMIC_RISCV_AP_DATAOUT_OPCODE,
					       intr);
	if (ret)
		dev_err(fwu->dev, "failed to write pmic reg %02x (%d) in trigger_interrupt\n",
			MAX77779_PMIC_RISCV_AP_DATAOUT_OPCODE, ret);

	return ret;
}

static int max77779_get_firmware_version(struct max77779_fwupdate *fwu,
					 struct max77779_version_info *ver)
{
	int ret;
	uint8_t major, minor;

	ret = max77779_external_pmic_reg_read(fwu->pmic, MAX77779_PMIC_RISCV_FW_REV, &major);
	if (ret) {
		dev_err(fwu->dev, "failed to read pmic reg %02x (%d) in read firmware version\n",
			MAX77779_PMIC_RISCV_FW_REV, ret);
		goto max77779_get_firmware_version_done;
	}

	ret = max77779_external_pmic_reg_read(fwu->pmic, MAX77779_PMIC_RISCV_FW_SUB_REV, &minor);
	if (ret)
		dev_err(fwu->dev, "failed to read pmic reg %02x (%d) in read firmware version\n",
			MAX77779_PMIC_RISCV_FW_SUB_REV, ret);

	ver->major = major;
	ver->minor = minor;

max77779_get_firmware_version_done:
	return ret;
}


static int max77779_change_fg_lock(struct max77779_fwupdate *fwu,
				   const enum max77779_fwupdate_fg_lock st)
{
	int ret;

	/*
	 * change FG's lock status
	 * - write status_value 2 times to MAX77779_FG_USR
	 */
	ret = max77779_external_fg_reg_write_nolock(fwu->fg, MAX77779_FG_USR, st);
	if (ret == 0)
		ret = max77779_external_fg_reg_write_nolock(fwu->fg, MAX77779_FG_USR, st);

	if (ret)
		dev_err(fwu->dev, "failed to write fg reg %02x (%d) in change lock status\n",
			MAX77779_FG_USR, ret);

	return ret;
}

static int max77779_copy_to_vimon_mem(struct max77779_fwupdate *fwu,
				      const u16 page, const u8* data,
				      const size_t data_len)
{
	int ret;

	ret = max77779_external_vimon_reg_write(fwu->vimon, MAX77779_BVIM_PAGE_CTRL,
						(u8*)&page, 2);
	if (ret) {
		dev_err(fwu->dev, "failed to set page %x (%d)\n", page, ret);
		goto max77779_copy_to_vimon_mem_done;
	}

	ret = max77779_external_vimon_reg_write(fwu->vimon, MAX77779_VIMON_MEM_BASE_ADDR,
						data, data_len);
	if (ret) {
		dev_err(fwu->dev,
			"failed to write data to vimon's memory page %x (%d)\n",
			page, ret);
		goto max77779_copy_to_vimon_mem_done;
	}

max77779_copy_to_vimon_mem_done:
	return ret;
}

static int max77779_load_fw_binary(struct max77779_fwupdate *fwu,
				   const u8* data, const size_t data_len)
{
	u16 page;
	int ret;
	size_t cp_len;
	ssize_t remains = (ssize_t)data_len;

	/* copy firmware binary to vimon's memory */
	for (page = 0; (page < 4) && remains > 0; page++) {
		if (remains > MAX77779_VIMON_PG_SIZE)
			cp_len = MAX77779_VIMON_PG_SIZE;
		else
			cp_len = remains;

		ret = max77779_copy_to_vimon_mem(fwu, page, data, cp_len);
		if (ret) {
			dev_err(fwu->dev, "failed load binary in copy data in page %d\n",
				(int)page);
			goto max77779_load_fw_binary_done;
		}

		data += MAX77779_VIMON_PG_SIZE;
		remains -= MAX77779_VIMON_PG_SIZE;
	}

max77779_load_fw_binary_done:
	return ret;
}

static inline int max77779_clear_state_for_update(struct max77779_fwupdate *fwu)
{
	int ret;
	uint16_t val;

	/* clear POR bits*/
	ret = max77779_external_fg_reg_read(fwu->fg, MAX77779_FG_FG_INT_STS, &val);
	if (ret) {
		dev_err(fwu->dev,
			"failed to read reg %02x (%d) in max77779_clear_state_for_update\n",
			MAX77779_FG_FG_INT_STS, ret);
		return ret;
	}

	ret = max77779_external_fg_reg_write_nolock(fwu->fg, MAX77779_FG_FG_INT_STS, val);
	if (ret) {
		dev_err(fwu->dev,
			"failed to write reg %02x (%d) in max77779_clear_state_for_update\n",
			MAX77779_FG_FG_INT_STS, ret);
		return ret;
	}

	/* clear commands */
	max77779_send_command(fwu, MAX77779_CMD_CLEAR_ALL);

	/* corner case, handles commands still present in AP_REQUEST_OPCODE */
	ret = max77779_trigger_interrupt(fwu, MAX77779_INTR_CLEAR);
	return ret;
}

static inline int max77779_session_start(struct max77779_fwupdate *fwu,
					 const u8* fw_binary_data,
					 const char* name)
{
	int ret;

	dev_info(fwu->dev, "[%s] begins\n", name);

	ret = max77779_trigger_interrupt(fwu, MAX77779_INTR_SESSION_START);
	MAX77779_ABORT_ON_ERROR(ret, name, "interrupt trigger");

	max77779_wait_cpu_reset(fwu);

	ret = max77779_load_fw_binary(fwu, fw_binary_data, MAX77779_FW_IMG_SZ_PACKET);
	MAX77779_ABORT_ON_ERROR(ret, name, "load_binary");

	ret = max77779_wait_fw_update(fwu);
	MAX77779_ABORT_ON_ERROR(ret, name, "max77779_wait_fw_update");

	dev_info(fwu->dev, "[%s] ends\n", name);

	return ret;
}

static int max77779_transfer_binary_data(struct max77779_fwupdate *fwu,
					 const u8* fw_binary_data,
					 const size_t data_size,
					 enum max77779_fwupdate_intr intr,
					 const char* name)
{
	int ret;
	ssize_t frame_len;
	ssize_t remains = (ssize_t)data_size;

	dev_info(fwu->dev, "[%s] begins\n", name);

	while (remains > 0) {
		frame_len = (remains > MAX77779_FW_IMG_SZ_FRAME)?
			    MAX77779_FW_IMG_SZ_FRAME : remains;

		ret = max77779_load_fw_binary(fwu, fw_binary_data, frame_len);
		MAX77779_ABORT_ON_ERROR(ret, name, "load_binary");

		msleep(FW_UPDATE_WAIT_LOAD_BIN_MS);

		ret = max77779_trigger_interrupt(fwu, intr);
		MAX77779_ABORT_ON_ERROR(ret, name, "max77779_trigger_interrupt");

		ret = max77779_wait_fw_update(fwu);
		MAX77779_ABORT_ON_ERROR(ret, name, "max77779_wait_fw_update");

		fw_binary_data += frame_len;
		remains -= frame_len;

		dev_info(fwu->dev, "transferred data (%zu/%zu)\n", (data_size - remains),
			 data_size);
	}

	dev_info(fwu->dev, "[%s] ends\n", name);

	return ret;
}

/* TODO: b/303731272 condtion check */
static int max77779_can_update(struct max77779_fwupdate *fwu, struct max77779_version_info* target)
{
	/* compatibility check: major version should match */
	if (target->major != fwu->v_cur.major)
		return -EINVAL;

	/* Is this device ellgabie to update firmware? */
	if (!fwu->can_update)
		return -EACCES;

	/* check version */
	if (target->minor <= fwu->v_cur.minor && !fwu->update_info.force_update)
		return -EINVAL;

	return 0;
}

static inline int max77779_set_firmwarename(struct max77779_fwupdate *fwu)
{
	uint8_t val;
	int ret, fw_ver;

	fw_ver = fwu->v_cur.major;

	/* b/322967969 version value can be 0xFF */
	if (fw_ver == MAX77779_FW_INVALID_FW_VER) {
		ret = max77779_external_pmic_reg_read(fwu->pmic, MAX77779_PMIC_REVISION, &val);
		if (ret) {
			dev_err(fwu->dev, "faild to read pmic reg %02x (%d)\n",
				MAX77779_PMIC_REVISION, ret);
			return ret;
		}

		if (val == MAX77779_REV_PASS_1_5)
			fw_ver = MAX77779_REV_PASS_1_5_FIRMWARE;
		else if (val == MAX77779_REV_PASS_2_0)
			fw_ver = MAX77779_REV_PASS_2_0_FIRMWARE;
		else
			return -EINVAL;
	}

	scnprintf(fwu->fw_name, MAX77779_FW_UPDATE_STRING_MAX, "%s_%d.bin",
		  MAX77779_FIRMWARE_BINARY_PREFIX, fw_ver);

	return 0;
}

static inline int max77779_fwupdate_chip_reset(struct max77779_fwupdate *fwu)
{
	int ret;

	/* non zero opcode may distrub chip reset */
	ret = max77779_external_pmic_reg_write(fwu->pmic, MAX77779_PMIC_RISCV_AP_DATAOUT_OPCODE,
					       0x0);
	if (ret)
		dev_err(fwu->dev, "failed to clear opcode (%d)\n", ret);

	ret = max77779_external_pmic_reg_write(fwu->pmic, MAX77779_PMIC_RISCV_COMMAND_HW,
					       MAX77779_CMD_REBOOT_FG);
	if (ret)
		dev_err(fwu->dev, "failed to reset chip (%d)\n", ret);

	return ret;
}

static int max77779_fwl_prepare(struct max77779_fwupdate *fwu,
				const u8 *data, u32 size)
{
	int ret;
	size_t data_frame_size;
	struct gvotable_election *mode_votable;

	fwu->zero_filled_buffer = kzalloc(MAX77779_VIMON_PG_SIZE, GFP_KERNEL);
	fwu->scratch_buffer = kmalloc(MAX77779_VIMON_PG_SIZE, GFP_KERNEL);
	if (!fwu->zero_filled_buffer || !fwu->scratch_buffer) {
		dev_err(fwu->dev, "failed to allocate temporay work buffer\n");
		return -ENOMEM;
	}

	dev_info(fwu->dev, "prepare firmware update (image size: %d)\n", size);

	data_frame_size = MAX77779_GET_DATA_FRAME_SIZE(size);
	if (data_frame_size % MAX77779_FW_IMG_SZ_PACKET) {
		dev_err(fwu->dev, "incorrect image size (data section size: %zu)\n",
			data_frame_size);
		return -EINVAL;
	}

	ret = max77779_get_firmware_version(fwu, &fwu->v_cur);
	MAX77779_ABORT_ON_ERROR(ret, __func__, "failed to read version information\n");

	fwu->data_frame_size = data_frame_size;
	fwu->op_st = (u8)FGST_FWUPDATE;

	ret = gbms_storage_write(GBMS_TAG_FGST, &fwu->op_st, sizeof(fwu->op_st));
	if (ret != sizeof(fwu->op_st)) {
		fwu->op_st = (u8)FGST_ERR_READTAG;
		gbms_logbuffer_prlog(fwu->lb, LOGLEVEL_WARNING, 0, LOGLEVEL_INFO,
				     "failed to update eeprom:GBMS_TAG_FGST (%d)\n", ret);
	}

	if (!fwu->mode_votable) {
		mode_votable = gvotable_election_get_handle(GBMS_MODE_VOTABLE);
		if (!mode_votable) {
			dev_err(fwu->dev, "failed to get %s(%ld)\n", GBMS_MODE_VOTABLE,
				PTR_ERR(mode_votable));
			return -ENODEV;
		}

		fwu->mode_votable = mode_votable;
	}

	ret = gvotable_cast_long_vote(fwu->mode_votable, MAX77779_REASON_FIRMWARE,
				      GBMS_CHGR_MODE_FWUPDATE_BOOST_ON, true);
	MAX77779_ABORT_ON_ERROR(ret, __func__, "failed to set mode BOOST_ON");

	ret = max77779_fg_enable_firmware_update(fwu->fg, true);
	MAX77779_ABORT_ON_ERROR(ret, __func__, "failed to set fg_enable_firmware_update");

	dev_info(fwu->dev, "the current installed firmware version %u.%u\n",
		 (unsigned int)fwu->v_cur.major,
		 (unsigned int)fwu->v_cur.minor);

	ret = max77779_change_fg_lock(fwu, FG_ST_UNLOCK_ALL_SECTION);
	MAX77779_ABORT_ON_ERROR(ret, __func__, "failed unlock FG");

	ret = max77779_clear_state_for_update(fwu);
	MAX77779_ABORT_ON_ERROR(ret, __func__, "failed clear command / POR  interrupt");

	ret = max77779_send_command(fwu, MAX77779_CMD_REBOOT_RISCV);
	MAX77779_ABORT_ON_ERROR(ret, __func__, "failed send command CMD_REBOOT_RISCV");

	/* wait_riscv_reboot might timeout but subsequent updates will be ok */
	max77779_wait_riscv_reboot(fwu);

	return ret;
}

/* TODO: b/303132973 - consider: "offset" */
static int max77779_fwl_write(struct max77779_fwupdate *fwu, const u8 *fw_binary_data, u32 offset,
			      u32 size, u32 *written)
{
	int ret;
	uint8_t val;

	dev_info(fwu->dev, "perform firmware update\n");

	/* skip header*/
	fw_binary_data += MAX77779_FW_IMG_SZ_HEADER;
	*written += MAX77779_FW_IMG_SZ_HEADER;

	/* Session Start */
	ret = max77779_session_start(fwu, fw_binary_data, "Session Start");
	MAX77779_ABORT_ON_ERROR(ret, __func__, "Session Start");

	fw_binary_data += MAX77779_FW_IMG_SZ_PACKET;
	*written += MAX77779_FW_IMG_SZ_PACKET;

	/* Transfer Frame */
	ret = max77779_transfer_binary_data(fwu, fw_binary_data, fwu->data_frame_size,
					    MAX77779_INTR_TRANSFER_FRAMES, "Transfer Frame");
	MAX77779_ABORT_ON_ERROR(ret, __func__, "Transfer Frame");

	fw_binary_data += fwu->data_frame_size;
	*written += fwu->data_frame_size;

	/* App Valid: CRC check */
	ret = max77779_transfer_binary_data(fwu, fw_binary_data, MAX77779_FW_IMG_SZ_PACKET,
					    MAX77779_INTR_APP_VALID, "App Valid");
	MAX77779_ABORT_ON_ERROR(ret, __func__, "App Valid");

	fw_binary_data += MAX77779_FW_IMG_SZ_PACKET;
	*written += MAX77779_FW_IMG_SZ_PACKET;

	fwu->crc_val = 0;
	ret = max77779_external_pmic_reg_read(fwu->pmic, MAX77779_PMIC_RISCV_AP_DATAIN0, &val);
	MAX77779_ABORT_ON_ERROR(ret, __func__, "failed to read crc information");
	dev_info(fwu->dev, "RISCV lock status: %x\n", val);

	ret = max77779_external_pmic_reg_read(fwu->pmic, MAX77779_PMIC_RISCV_AP_DATAIN2, &val);
	MAX77779_ABORT_ON_ERROR(ret, __func__, "failed to read crc information");
	fwu->crc_val = val;

	ret = max77779_external_pmic_reg_read(fwu->pmic, MAX77779_PMIC_RISCV_AP_DATAIN3, &val);
	MAX77779_ABORT_ON_ERROR(ret, __func__, "failed to read crc information");
	fwu->crc_val |= (val << 8);


	/* Session End */
	ret = max77779_transfer_binary_data(fwu, fw_binary_data, MAX77779_FW_IMG_SZ_PACKET,
					    MAX77779_INTR_SESSION_END, "Session End");
	MAX77779_ABORT_ON_ERROR(ret, __func__, "Session End");

	*written += MAX77779_FW_IMG_SZ_PACKET;

	return ret;
}

static int max77779_fwl_poll_complete(struct max77779_fwupdate *fwu)
{
	int ret;
	uint16_t val;

	dev_info(fwu->dev, "max77779_fwl_poll_complete\n");

	/* check firmware update status */
	dev_info(fwu->dev, "firmware update CRC: %x\n", fwu->crc_val);
	if (fwu->crc_val == 0) {
		dev_info(fwu->dev, "bad CRC value returns");
		return -EIO;
	}

	ret = max77779_external_fg_reg_read(fwu->fg, MAX77779_FG_SECUPDATE_STATUS_REG, &val);
	MAX77779_ABORT_ON_ERROR(ret, __func__, "failed to read MAX77779_FG_SECUPDATE_STATUS_REG");
	if (val != MAX77779_FG_SECUPDATE_STATUS_SUCCESS) {
		dev_err(fwu->dev, "firmware update fail: MAX77779_FG_SECUPDATE_STATUS_REG:%02x\n",
			val);
		return -EAGAIN;
	}

	/* b/310710147: risc-v is not operational state. requires reboot */
	max77779_fwupdate_chip_reset(fwu);
	max77779_wait_riscv_reboot(fwu);

	ret = check_boot_completed(fwu, FW_UPDATE_RETRY_CPU_RESET);
	MAX77779_ABORT_ON_ERROR(ret, __func__, "failed on check_boot_completed\n");

	ret = max77779_get_firmware_version(fwu, &fwu->v_new);
	MAX77779_ABORT_ON_ERROR(ret, __func__, "failed to get firmware version\n");
	dev_info(fwu->dev, "updated firmware version: %u.%u\n",
		 fwu->v_new.major, fwu->v_new.minor);

	ret = max77779_check_timer_refresh(fwu);
	MAX77779_ABORT_ON_ERROR(ret, __func__, "failed on max77779_check_timer_refresh\n");

	mutex_lock(&fwu->status_lock);

	fwu->op_st = FGST_NORMAL;
	fwu->stats.count++;
	fwu->stats.success++;

	update_fwupdate_stats(fwu, &fwu->stats);

	mutex_unlock(&fwu->status_lock);

	if (fwu->v_cur.major != fwu->v_new.major || fwu->v_cur.minor != fwu->v_new.minor)
		fwu->v_cur = fwu->v_new;

	set_firmware_update_tag(fwu, fwu->update_info.new_tag);

	fwu->update_info.force_update = false;
	fwu->update_info.retry_cnt = 0;

	return ret;
}

static void max77779_fwl_cleanup(struct max77779_fwupdate *fwu)
{
	int ret;

	dev_info(fwu->dev, "max77779_fwl_cleanup\n");

	if (fwu->zero_filled_buffer)
		kfree(fwu->zero_filled_buffer);
	if (fwu->scratch_buffer)
		kfree(fwu->scratch_buffer);

	ret = max77779_fg_enable_firmware_update(fwu->fg, false);
	if (ret)
		dev_err(fwu->dev, "failed to restore FG from update mode (%d)\n", ret);

	if (!fwu->mode_votable)
		return;

	ret = gvotable_cast_long_vote(fwu->mode_votable, MAX77779_REASON_FIRMWARE,
				      GBMS_CHGR_MODE_FWUPDATE_BOOST_ON, false);
	if (ret)
		dev_err(fwu->dev, "failed to restore CHG from update mode (%d)\n", ret);
}

static inline int update_running_state(struct max77779_fwupdate *fwu, bool running)
{
	bool ret = false;

	mutex_lock(&fwu->status_lock);

	if (fwu->running_update != running) {
		fwu->running_update = running;
		ret = true;
	}

	mutex_unlock(&fwu->status_lock);

	return ret;
}

static inline int perform_firmware_update(struct max77779_fwupdate *fwu, const char* data,
					  const size_t count)
{
	u32 written = 0;
	enum max77779_fwupdate_err_code err_code = MAX77779_FWU_ERR_NONE;
	int ret, ret_st;
	struct max77779_fwupdate_stats stats_backup;

	/* if previous update is not completed yet, stop at here */
	if (!update_running_state(fwu, true))
		return -EBUSY;

	__pm_stay_awake(fwu->fwupdate_wake_lock);

	logbuffer_log(fwu->lb, "perform_firmware_update: %s", fwu->fw_name);

	/*
	 * increase failure count upfront
	 *  - update can be distrubed without cleanup
	 *  - store with new value inside of max77779_fwl_poll_complete when everything is OK
	 */
	mutex_lock(&fwu->status_lock);

	stats_backup.count = fwu->stats.count + 1;
	stats_backup.success = fwu->stats.success;
	stats_backup.fail = fwu->stats.fail + 1;

	update_fwupdate_stats(fwu, &stats_backup);

	mutex_unlock(&fwu->status_lock);

	ret = max77779_fwl_prepare(fwu, data, count);
	if (ret) {
		err_code = MAX77779_FWU_ERR_PREPARE;
		goto perform_firmware_update_cleanup;
	}

	ret = max77779_fwl_write(fwu, data, 0, count, &written);
	if (ret || written != count) {
		err_code = MAX77779_FWU_ERR_DATA_TRANSFER;
		goto perform_firmware_update_cleanup;
	}

	if (max77779_fwl_poll_complete(fwu) != 0)
		err_code = MAX77779_FWU_ERR_POST_STATUS_CHECK;

perform_firmware_update_cleanup:
	max77779_fwl_cleanup(fwu);

	/* force reboot RISC-V for the case of update failure*/
	if (ret || written != count) {
		max77779_fwupdate_chip_reset(fwu);

		mutex_lock(&fwu->status_lock);

		fwu->op_st = FGST_BASEFW;
		fwu->stats.count++;
		fwu->stats.fail++;

		mutex_unlock(&fwu->status_lock);
	}

	ret_st = gbms_storage_write(GBMS_TAG_FGST, &fwu->op_st, sizeof(fwu->op_st));
	if (ret_st != sizeof(fwu->op_st))
		gbms_logbuffer_prlog(fwu->lb, LOGLEVEL_WARNING, 0, LOGLEVEL_INFO,
				     "failed to update eeprom:GBMS_TAG_FGST (%d)\n", ret_st);

	gbms_logbuffer_prlog(fwu->lb, LOGLEVEL_INFO, 0, LOGLEVEL_INFO,
			     "complete_firmware_update: %d %d %d (%d)", fwu->stats.count,
			     fwu->stats.success, fwu->stats.fail, (int)err_code);

	__pm_relax(fwu->fwupdate_wake_lock);
	update_running_state(fwu, false);

	kobject_uevent(&fwu->fg->kobj, KOBJ_CHANGE);

	return ret;
}

static void firmware_update_work(struct work_struct* work)
{
	int ret;
	struct max77779_version_info target_version;
	const struct firmware* fw_data;
	struct max77779_fwupdate *fwu = NULL;

	fwu = container_of(work, struct max77779_fwupdate, update_work.work);
	if (!fwu)
		return;

	ret = request_firmware(&fw_data, fwu->fw_name, fwu->dev);
	if (ret) {
		dev_warn(fwu->dev, "fails on request_firmware %d\n", ret);
		goto firmware_update_work_cleanup;
	}

	target_version.major = fw_data->data[MAX77779_OFFSET_VER_MAJOR];
	target_version.minor = fw_data->data[MAX77779_OFFSET_VER_MINOR];

	ret = max77779_can_update(fwu, &target_version);
	if (ret) {
		dev_info(fwu->dev, "can not update firmware %d\n", ret);
		goto firmware_update_work_cleanup;
	}

	ret = perform_firmware_update(fwu, fw_data->data, fw_data->size);
	if (ret)
		dev_err(fwu->dev, "firmware update failed (retry:%d) %d\n",
			fwu->update_info.retry_cnt, ret);

firmware_update_work_cleanup:
	release_firmware(fw_data);

	if (ret)
		max77779_schedule_update(fwu);
}

static inline bool max77779_can_charge(struct device* chg)
{
	struct max77779_chgr_data *data = dev_get_drvdata(chg);
	int ret;
	uint8_t chg_detail;

	ret = max77779_external_chg_reg_read(chg, MAX77779_CHG_DETAILS_00, &chg_detail);
	if (ret)
		return false;

	/* check usb: 0x0 or 0x1 means VBUS is invalid */
	if (_max77779_chg_details_00_chgin_dtls_get(chg_detail) >= 2 && !data->chgin_input_suspend)
		return true;

	/* check wireless: 0x0 or 0x1 means VWCIN is invalid */
	if ((_max77779_chg_details_00_wcin_dtls_get(chg_detail) >= 2 && !data->wcin_input_suspend)
	    || data->wlc_spoof)
		return true;

	return false;
}

/*
 * trigger firmware update with override version tag
 *  - echo xxx > update_firmware
 */
static ssize_t trigger_update_firmware(struct device *dev,
				       struct device_attribute *attr,
				       const char *options, size_t count)
{
	int ret, current_ver, read_cnt, target_ver;
	int bypass_check = 0, override_ver = 0;
	uint16_t voltage;
	struct max77779_fwupdate *fwu = dev_get_drvdata(dev);

	if (!fwu)
		return -EAGAIN;

	if (!fwu->can_update) {
		dev_err(fwu->dev, "not allowed to update firmware\n");
		return -EACCES;
	}

	read_cnt = sscanf(options, "%d %d %d", &target_ver, &override_ver, &bypass_check);
	if (read_cnt < 1) {
		dev_err(fwu->dev, "incorrect input: expects override_tag(number) and reset_tag"
			"(optional)\n");
		return -EINVAL;
	}

	if (!bypass_check) {
		/* check chgin/wcin */
		if (!max77779_can_charge(fwu->chg)) {
			dev_err(fwu->dev, "charger is not plugged. connect charger required\n");
			return -EBUSY;
		}

		/* check current voltage */
		ret = max77779_external_fg_reg_read(fwu->fg, MAX77779_FG_AvgVCell, &voltage);
		if (ret || reg_to_micro_volt(voltage) < fwu->minimum_voltage) {
			dev_err(fwu->dev, "low voltage for update\n");
			return -ERANGE;
		}
	}

	current_ver = get_firmware_update_tag(fwu);
	if (!override_ver && (target_ver <= current_ver)) {
		dev_info(fwu->dev, "ver %d already installed: update request will be skipped",
			target_ver);
		return count;
	}

	if (max77779_set_firmwarename(fwu) < 0) {
		dev_err(fwu->dev, "can't set proper firmware file\n");
		return -EINVAL;
	}

	mutex_lock(&fwu->status_lock);

	fwu->update_info.new_tag = target_ver;
	fwu->update_info.force_update = true;
	fwu->update_info.reboot_on_failure = true;
	fwu->update_info.retry_cnt = 0;

	mutex_unlock(&fwu->status_lock);

	schedule_delayed_work(&fwu->update_work,
			      msecs_to_jiffies(FW_UPDATE_TIMER_CHECK_INTERVAL_MS));

	return count;
}

static DEVICE_ATTR(update_firmware, 0220, NULL, trigger_update_firmware);


static ssize_t enable_update_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct max77779_fwupdate *fwu = dev_get_drvdata(dev);
	if (!fwu)
		return -EAGAIN;

	return scnprintf(buf, PAGE_SIZE, "%d\n", fwu->can_update);
}

static ssize_t enable_update_store(struct device *dev, struct device_attribute *attr,
				   const char *buf, size_t count)
{
	struct max77779_fwupdate *fwu = dev_get_drvdata(dev);
	if (!fwu)
		return -EAGAIN;

	if (kstrtobool(buf, &fwu->can_update))
		return -EINVAL;

	return count;
}

static DEVICE_ATTR_RW(enable_update);

static ssize_t update_status_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	int ret;
	uint16_t val;
	enum max77779_fwupdate_status st = MAX77779_FWU_OK;
	struct max77779_fwupdate *fwu = dev_get_drvdata(dev);

	if (!fwu)
		return -EAGAIN;

	mutex_lock(&fwu->status_lock);
	if (fwu->running_update) {
		st = MAX77779_FWU_RUNNING_UPDATE;
		goto update_status_show_exit;
	}

	ret = max77779_external_fg_reg_read(fwu->fg, MAX77779_FG_SECUPDATE_STATUS_REG, &val);
	if (ret < 0){
		st = MAX77779_FWU_REG_ACCESS_ERR;
		goto update_status_show_exit;
	}

	if (val != MAX77779_FG_SECUPDATE_STATUS_SUCCESS) {
		dev_err(fwu->dev, "firmware update fail: %X:%02x\n",
			MAX77779_FG_SECUPDATE_STATUS_REG, val);
		st = MAX77779_FWU_UPDATE_FAIL;
		goto update_status_show_exit;
	}

	ret = check_boot_completed(fwu, FW_UPDATE_RETRY_ONCE);
	if (ret < 0) {
		st = MAX77779_FWU_BOOT_ERR;
		goto update_status_show_exit;
	}

	ret = max77779_check_timer_refresh(fwu);
	if (ret < 0)
		st = MAX77779_FWU_TIMER_ERR;

update_status_show_exit:
	mutex_unlock(&fwu->status_lock);
	return scnprintf(buf, PAGE_SIZE, "%d\n", st);
}

static const DEVICE_ATTR_RO(update_status);

static ssize_t chip_reset_store(struct device *dev, struct device_attribute *attr,
				   const char *buf, size_t count)
{
	bool trigger;
	int rt = -EBUSY;
	struct max77779_fwupdate *fwu = dev_get_drvdata(dev);

	if (!fwu)
		return -EAGAIN;

	if (kstrtobool(buf, &trigger) && !trigger)
		return -EINVAL;

	mutex_lock(&fwu->status_lock);
	/* if there is no on-going fwupdate, trigger reset */
	if (!fwu->running_update && max77779_fwupdate_chip_reset(fwu) == 0)
		rt = count;

	mutex_unlock(&fwu->status_lock);

	return rt;
}

static DEVICE_ATTR_WO(chip_reset);

static ssize_t update_stats_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	ssize_t ret;
	struct max77779_fwupdate *fwu = dev_get_drvdata(dev);
	if (!fwu)
		return -EAGAIN;

	mutex_lock(&fwu->status_lock);

	ret = scnprintf(buf, PAGE_SIZE, "%d %d %d\n", fwu->stats.count, fwu->stats.success,
			fwu->stats.fail);

	mutex_unlock(&fwu->status_lock);

	return ret;
}

static ssize_t update_stats_store(struct device *dev, struct device_attribute *attr,
				  const char *buf, size_t count)
{
	struct max77779_fwupdate *fwu = dev_get_drvdata(dev);
	int value, ret;

	if (!fwu)
		return -EAGAIN;

	ret = kstrtoint(buf, 0, &value);
	if (ret < 0)
		return ret;

	mutex_lock(&fwu->status_lock);

	if (value == 0 && !fwu->running_update) {
		fwu->stats.count = 0;
		fwu->stats.success = 0;
		fwu->stats.fail = 0;

		update_fwupdate_stats(fwu, &fwu->stats);

		ret = count;
	} else {
		ret = -EBUSY;
	}

	mutex_unlock(&fwu->status_lock);

	return ret;
}

static DEVICE_ATTR_RW(update_stats);

/*
 * Using the same pattern as FW_LOADER
 *  echo 1 > loading
 *  cat FW_IMG > data
 *  echo 0 > loading
 */
static int debug_update_firmware_loading(void *data, u64 val)
{
	struct max77779_fwupdate *fwu = data;
	int ret = 0;

	if (!fwu)
		return -EAGAIN;

	if (val) {
		if (!fwu->debug_image.data)
			fwu->debug_image.data = kzalloc(FW_UPDATE_MAXIMUM_PAGE_SIZE, GFP_KERNEL);

		if (!fwu->debug_image.data)
			return -ENOMEM;

		fwu->debug_image.size = 0;
	} else {
		if (fwu->debug_image.size > 0)
			ret = perform_firmware_update(fwu, fwu->debug_image.data, fwu->debug_image.size);

		if (fwu->debug_image.data) {
			kfree(fwu->debug_image.data);
			fwu->debug_image.data = NULL;
			fwu->debug_image.size = 0;
		}
	}

	fwu->can_update = (val != 0);

	return ret;
}

DEFINE_SIMPLE_ATTRIBUTE(debug_update_firmware_loading_fops, NULL, debug_update_firmware_loading,
			"%llu\n");


static ssize_t debug_update_firmware_data(struct file *filp, const char __user *user_buf,
					  size_t count, loff_t *ppos)
{
	struct max77779_fwupdate *fwu;
	ssize_t ret;

	fwu = (struct max77779_fwupdate *)filp->private_data;
	if (!fwu)
		return -EAGAIN;

	if (!fwu->debug_image.data)
		return -EINVAL;

	if ((FW_UPDATE_MAXIMUM_PAGE_SIZE - fwu->debug_image.size) < count)
		return -EFBIG;

	ret = simple_write_to_buffer(fwu->debug_image.data, FW_UPDATE_MAXIMUM_PAGE_SIZE, ppos,
				     user_buf, count);

	if (ret >= 0)
		fwu->debug_image.size += ret;
	else
		fwu->debug_image.size = -EINVAL;

	return ret;
}

BATTERY_DEBUG_ATTRIBUTE(debug_update_firmware_data_fops, NULL, debug_update_firmware_data);


static int max77779_fwupdate_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct dentry *de;
	struct max77779_fwupdate *fwu;

	fwu = devm_kzalloc(&pdev->dev, sizeof(*fwu), GFP_KERNEL);
	if (!fwu)
		return -ENOMEM;

	fwu->dev = &pdev->dev;
	platform_set_drvdata(pdev, fwu);

	ret = max77779_fwupdate_init(fwu);
	if (ret) {
		dev_err(fwu->dev, "error to set max77779_fwupdate\n");
		return ret;
	}

	ret = max77779_get_firmware_version(fwu, &fwu->v_cur);
	if (ret)
		dev_err(fwu->dev, "failed to read version information\n");

	ret = max77779_set_firmwarename(fwu);
	if (ret)
		dev_err(fwu->dev, "failed to set proper firmware file\n");

	INIT_DELAYED_WORK(&fwu->update_work, firmware_update_work);

	ret = device_create_file(fwu->dev, &dev_attr_update_firmware);
	if (ret != 0) {
		pr_err("Failed to create update_firmware files, ret=%d\n", ret);
		return ret;
	}

	ret = device_create_file(fwu->dev, &dev_attr_enable_update);
	if (ret != 0) {
		pr_err("Failed to create enable_update files, ret=%d\n", ret);
		return ret;
	}

	ret = device_create_file(fwu->dev, &dev_attr_update_status);
	if (ret != 0) {
		pr_err("Failed to create update_status files, ret=%d\n", ret);
		return ret;
	}

	ret = device_create_file(fwu->dev, &dev_attr_chip_reset);
	if (ret != 0) {
		pr_err("Failed to create chip_reset files, ret=%d\n", ret);
		return ret;
	}

	ret = device_create_file(fwu->dev, &dev_attr_update_stats);
	if (ret != 0) {
		pr_err("Failed to create update_stats files, ret=%d\n", ret);
		return ret;
	}

	fwu->fwupdate_wake_lock = wakeup_source_register(NULL, "max77779-fwupdate");
	if (!fwu->fwupdate_wake_lock) {
		dev_err(fwu->dev, "failed to register wakeup source\n");
		return -ENODEV;
	}

	de = debugfs_create_dir("max77779_fwupdate", 0);
	if (!de)
		return 0;

	debugfs_create_file("loading", 0400, de, fwu, &debug_update_firmware_loading_fops);
	debugfs_create_file("data", 0444, de, fwu, &debug_update_firmware_data_fops);

	fwu->de = de;

	/* the chip is running with base firmware: need to be updated */
	if (fwu->op_st == FGST_BASEFW) {
		fwu->update_info.retry_cnt = 0;
		fwu->update_info.force_update = true;
		fwu->update_info.reboot_on_failure = false;
		max77779_schedule_update(fwu);
	}

	return ret;
}

static int max77779_fwupdate_remove(struct platform_device *pdev)
{
	struct max77779_fwupdate *fwu = platform_get_drvdata(pdev);
	if (!fwu)
		return 0;

	if (fwu->lb) {
		logbuffer_unregister(fwu->lb);
		fwu->lb = NULL;
	}

	mutex_destroy(&fwu->status_lock);

	if (fwu->debug_image.data)
		kfree(fwu->debug_image.data);

	if (fwu->fwupdate_wake_lock)
		wakeup_source_unregister(fwu->fwupdate_wake_lock);

	if (fwu->de)
		debugfs_remove(fwu->de);

	return 0;
}

static const struct of_device_id max77779_fwupdate_of_match[] = {
	{.compatible = "maxim,max77779fwu"},
	{},
};
MODULE_DEVICE_TABLE(of, max77779_fwupdate_of_match);


static const struct platform_device_id max77779_fwupdate_id[] = {
	{"max77779_fwupdate", 0},
	{}
};
MODULE_DEVICE_TABLE(platform, max77779_fwupdate_id);

static struct platform_driver max77779_fwupdate_driver = {
	.driver = {
		.name = "max77779_fwupdate",
		.owner = THIS_MODULE,
		.of_match_table = max77779_fwupdate_of_match,
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
		},
	.id_table = max77779_fwupdate_id,
	.probe = max77779_fwupdate_probe,
	.remove = max77779_fwupdate_remove,
};

module_platform_driver(max77779_fwupdate_driver);

MODULE_DESCRIPTION("MAX77779 Firmware Update Driver");
MODULE_AUTHOR("Chungro Lee <chungro@google.com>");
MODULE_LICENSE("GPL");
