static int ziirave_firm_upload()

in ziirave_wdt.c [337:417]


static int ziirave_firm_upload(struct watchdog_device *wdd,
			       const struct firmware *fw)
{
	struct i2c_client *client = to_i2c_client(wdd->parent);
	const struct ihex_binrec *rec;
	int ret;

	ret = i2c_smbus_write_byte_data(client,
					ZIIRAVE_CMD_JUMP_TO_BOOTLOADER,
					ZIIRAVE_CMD_JUMP_TO_BOOTLOADER_MAGIC);
	if (ret) {
		dev_err(&client->dev, "Failed to jump to bootloader\n");
		return ret;
	}

	msleep(500);

	ret = i2c_smbus_write_byte(client, ZIIRAVE_CMD_DOWNLOAD_START);
	if (ret) {
		dev_err(&client->dev, "Failed to start download\n");
		return ret;
	}

	ret = ziirave_firm_read_ack(wdd);
	if (ret) {
		dev_err(&client->dev, "No ACK for start download\n");
		return ret;
	}

	msleep(500);

	for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
		ret = ziirave_firm_write_pkt(wdd, be32_to_cpu(rec->addr),
					     rec->data, be16_to_cpu(rec->len));
		if (ret)
			return ret;
	}

	/*
	 * Finish firmware download process by sending a zero length
	 * payload
	 */
	ret = ziirave_firm_write_pkt(wdd, 0, NULL, 0);
	if (ret) {
		dev_err(&client->dev, "Failed to send EMPTY packet: %d\n", ret);
		return ret;
	}

	/* This sleep seems to be required */
	msleep(20);

	/* Start firmware verification */
	ret = ziirave_firm_verify(wdd, fw);
	if (ret) {
		dev_err(&client->dev,
			"Failed to verify firmware: %d\n", ret);
		return ret;
	}

	/* End download operation */
	ret = i2c_smbus_write_byte(client, ZIIRAVE_CMD_DOWNLOAD_END);
	if (ret) {
		dev_err(&client->dev,
			"Failed to end firmware download: %d\n", ret);
		return ret;
	}

	/* Reset the processor */
	ret = i2c_smbus_write_byte_data(client,
					ZIIRAVE_CMD_RESET_PROCESSOR,
					ZIIRAVE_CMD_RESET_PROCESSOR_MAGIC);
	if (ret) {
		dev_err(&client->dev,
			"Failed to reset the watchdog: %d\n", ret);
		return ret;
	}

	msleep(500);

	return 0;
}