// SPDX-License-Identifier: GPL-2.0+
/*
 * Uclass implementation for standard boot
 *
 * Copyright 2021 Google LLC
 * Written by Simon Glass <sjg@chromium.org>
 */

#include <common.h>
#include <bootflow.h>
#include <bootstd.h>
#include <dm.h>
#include <log.h>
#include <malloc.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/read.h>
#include <dm/uclass-internal.h>

DECLARE_GLOBAL_DATA_PTR;

/* These are used if filename-prefixes is not present */
const char *const default_prefixes[] = {"/", "/boot/", NULL};

static int bootstd_of_to_plat(struct udevice *dev)
{
	struct bootstd_priv *priv = dev_get_priv(dev);
	int ret;

	if (IS_ENABLED(CONFIG_BOOTSTD_FULL)) {
		/* Don't check errors since livetree and flattree are different */
		ret = dev_read_string_list(dev, "filename-prefixes",
					   &priv->prefixes);
		dev_read_string_list(dev, "bootdev-order",
				     &priv->bootdev_order);
	}

	return 0;
}

static void bootstd_clear_glob_(struct bootstd_priv *priv)
{
	while (!list_empty(&priv->glob_head)) {
		struct bootflow *bflow;

		bflow = list_first_entry(&priv->glob_head, struct bootflow,
					 glob_node);
		bootflow_remove(bflow);
	}
}

void bootstd_clear_glob(void)
{
	struct bootstd_priv *std;

	if (bootstd_get_priv(&std))
		return;

	bootstd_clear_glob_(std);
}

static int bootstd_remove(struct udevice *dev)
{
	struct bootstd_priv *priv = dev_get_priv(dev);

	free(priv->prefixes);
	free(priv->bootdev_order);
	bootstd_clear_glob_(priv);

	return 0;
}

const char *const *const bootstd_get_bootdev_order(struct udevice *dev)
{
	struct bootstd_priv *std = dev_get_priv(dev);

	return std->bootdev_order;
}

const char *const *const bootstd_get_prefixes(struct udevice *dev)
{
	struct bootstd_priv *std = dev_get_priv(dev);

	return std->prefixes ? std->prefixes : default_prefixes;
}

int bootstd_get_priv(struct bootstd_priv **stdp)
{
	struct udevice *dev;
	int ret;

	ret = uclass_first_device_err(UCLASS_BOOTSTD, &dev);
	if (ret)
		return ret;
	*stdp = dev_get_priv(dev);

	return 0;
}

static int bootstd_probe(struct udevice *dev)
{
	struct bootstd_priv *std = dev_get_priv(dev);

	INIT_LIST_HEAD(&std->glob_head);

	return 0;
}

/* For now, bind the boormethod device if none are found in the devicetree */
int dm_scan_other(bool pre_reloc_only)
{
	struct driver *drv = ll_entry_start(struct driver, driver);
	const int n_ents = ll_entry_count(struct driver, driver);
	struct udevice *dev, *bootstd;
	int i, ret;

	/* These are not needed before relocation */
	if (!(gd->flags & GD_FLG_RELOC))
		return 0;

	/* Create a bootstd device if needed */
	uclass_find_first_device(UCLASS_BOOTSTD, &bootstd);
	if (!bootstd) {
		ret = device_bind_driver(gd->dm_root, "bootstd_drv", "bootstd",
					 &bootstd);
		if (ret)
			return log_msg_ret("bootstd", ret);
	}

	/* If there are no bootmeth devices, create them */
	uclass_find_first_device(UCLASS_BOOTMETH, &dev);
	if (dev)
		return 0;

	for (i = 0; i < n_ents; i++, drv++) {
		if (drv->id == UCLASS_BOOTMETH) {
			const char *name = drv->name;

			if (!strncmp("bootmeth_", name, 9))
				name += 9;
			ret = device_bind(bootstd, drv, name, 0, ofnode_null(),
					  &dev);
			if (ret)
				return log_msg_ret("meth", ret);
		}
	}

	return 0;
}

static const struct udevice_id bootstd_ids[] = {
	{ .compatible = "u-boot,boot-std" },
	{ }
};

U_BOOT_DRIVER(bootstd_drv) = {
	.id		= UCLASS_BOOTSTD,
	.name		= "bootstd_drv",
	.of_to_plat	= bootstd_of_to_plat,
	.probe		= bootstd_probe,
	.remove		= bootstd_remove,
	.of_match	= bootstd_ids,
	.priv_auto	= sizeof(struct bootstd_priv),
};

UCLASS_DRIVER(bootstd) = {
	.id		= UCLASS_BOOTSTD,
	.name		= "bootstd",
#if CONFIG_IS_ENABLED(OF_REAL)
	.post_bind	= dm_scan_fdt_dev,
#endif
};
