// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2021
 * Köry Maincent, Bootlin, <kory.maincent@bootlin.com>
 */

#include <bootdev.h>
#include <command.h>
#include <dm.h>
#include <malloc.h>
#include <extension_board.h>
#include <mapmem.h>
#include <linux/libfdt.h>
#include <fdt_support.h>

static LIST_HEAD(extension_list);

static int extension_apply(struct extension *extension)
{
	char *overlay_cmd;
	ulong extrasize, overlay_addr;
	struct fdt_header *blob;

	if (!working_fdt) {
		printf("No FDT memory address configured. Please configure\n"
		       "the FDT address via \"fdt addr <address>\" command.\n");
		return CMD_RET_FAILURE;
	}

	overlay_cmd = env_get("extension_overlay_cmd");
	if (!overlay_cmd) {
		printf("Environment extension_overlay_cmd is missing\n");
		return CMD_RET_FAILURE;
	}

	overlay_addr = env_get_hex("extension_overlay_addr", 0);
	if (!overlay_addr) {
		printf("Environment extension_overlay_addr is missing\n");
		return CMD_RET_FAILURE;
	}

	env_set("extension_overlay_name", extension->overlay);
	if (run_command(overlay_cmd, 0) != 0)
		return CMD_RET_FAILURE;

	extrasize = env_get_hex("filesize", 0);
	if (!extrasize)
		return CMD_RET_FAILURE;

	fdt_shrink_to_minimum(working_fdt, extrasize);

	blob = map_sysmem(overlay_addr, 0);
	if (!fdt_valid(&blob))
		return CMD_RET_FAILURE;

	/* apply method prints messages on error */
	if (fdt_overlay_apply_verbose(working_fdt, blob))
		return CMD_RET_FAILURE;

	return CMD_RET_SUCCESS;
}

static int do_extension_list(struct cmd_tbl *cmdtp, int flag,
			     int argc, char *const argv[])
{
	int i = 0;
	struct extension *extension;

	if (list_empty(&extension_list)) {
		printf("No extension registered - Please run \"extension scan\"\n");
		return CMD_RET_SUCCESS;
	}

	list_for_each_entry(extension, &extension_list, list) {
		printf("Extension %d: %s\n", i++, extension->name);
		printf("\tManufacturer: \t\t%s\n", extension->owner);
		printf("\tVersion: \t\t%s\n", extension->version);
		printf("\tDevicetree overlay: \t%s\n", extension->overlay);
		printf("\tOther information: \t%s\n", extension->other);
	}
	return CMD_RET_SUCCESS;
}

static int extension_scan(bool show)
{
	struct extension *extension, *next;
	int extension_num;

	list_for_each_entry_safe(extension, next, &extension_list, list) {
		list_del(&extension->list);
		free(extension);
	}
	extension_num = extension_board_scan(&extension_list);
	if (show && extension_num >= 0)
		printf("Found %d extension board(s).\n", extension_num);

	/* either the number of extensions, or -ve for error */
	return extension_num;
}


static int do_extension_scan(struct cmd_tbl *cmdtp, int flag,
			     int argc, char *const argv[])
{
	int extension_num;

	extension_num = extension_scan(true);
	if (extension_num < 0)
		return CMD_RET_FAILURE;

	return CMD_RET_SUCCESS;
}

static int do_extension_apply(struct cmd_tbl *cmdtp, int flag,
			      int argc, char *const argv[])
{
	struct extension *extension = NULL;
	struct list_head *entry;
	int i = 0, extension_id, ret;

	if (argc < 2)
		return CMD_RET_USAGE;

	if (strcmp(argv[1], "all") == 0) {
		ret = CMD_RET_FAILURE;
		list_for_each_entry(extension, &extension_list, list) {
			ret = extension_apply(extension);
			if (ret != CMD_RET_SUCCESS)
				break;
		}
	} else {
		extension_id = simple_strtol(argv[1], NULL, 10);
		list_for_each(entry, &extension_list) {
			if (i == extension_id) {
				extension = list_entry(entry, struct extension,  list);
				break;
			}
			i++;
		}

		if (!extension) {
			printf("Wrong extension number\n");
			return CMD_RET_FAILURE;
		}

		ret = extension_apply(extension);
	}

	return ret;
}

static struct cmd_tbl cmd_extension[] = {
	U_BOOT_CMD_MKENT(scan, 1, 1, do_extension_scan, "", ""),
	U_BOOT_CMD_MKENT(list, 1, 0, do_extension_list, "", ""),
	U_BOOT_CMD_MKENT(apply, 2, 0, do_extension_apply, "", ""),
};

static int do_extensionops(struct cmd_tbl *cmdtp, int flag, int argc,
			   char *const argv[])
{
	struct cmd_tbl *cp;

	/* Drop the extension command */
	argc--;
	argv++;

	cp = find_cmd_tbl(argv[0], cmd_extension, ARRAY_SIZE(cmd_extension));
	if (cp)
		return cp->cmd(cmdtp, flag, argc, argv);

	return CMD_RET_USAGE;
}

U_BOOT_CMD(extension, 3, 1, do_extensionops,
	"Extension board management sub system",
	"scan - scan plugged extension(s) board(s)\n"
	"extension list - lists available extension(s) board(s)\n"
	"extension apply <extension number|all> - applies DT overlays corresponding to extension boards\n"
);

static int extension_bootdev_hunt(struct bootdev_hunter *info, bool show)
{
	int ret;

	ret = env_set_hex("extension_overlay_addr",
			  env_get_hex("fdtoverlay_addr_r", 0));
	if (ret)
		return log_msg_ret("env", ret);

	ret = extension_scan(show);
	if (ret < 0)
		return log_msg_ret("ext", ret);

	return 0;
}

/* extensions should have a uclass - for now we use UCLASS_SIMPLE_BUS uclass */
BOOTDEV_HUNTER(extension_bootdev_hunter) = {
	.prio		= BOOTDEVP_1_PRE_SCAN,
	.uclass		= UCLASS_SIMPLE_BUS,
	.hunt		= extension_bootdev_hunt,
};
