/*
 * Copyright (c) 2013 Google, Inc
 *
 * (C) Copyright 2012
 * Marek Vasut <marex@denx.de>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <errno.h>
#include <dm/device.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/platdata.h>
#include <dm/uclass.h>
#include <dm/util.h>
#include <fdtdec.h>
#include <linux/compiler.h>

struct driver *lists_driver_lookup_name(const char *name)
{
	struct driver *drv =
		ll_entry_start(struct driver, driver);
	const int n_ents = ll_entry_count(struct driver, driver);
	struct driver *entry;

	for (entry = drv; entry != drv + n_ents; entry++) {
		if (!strcmp(name, entry->name))
			return entry;
	}

	/* Not found */
	return NULL;
}

struct uclass_driver *lists_uclass_lookup(enum uclass_id id)
{
	struct uclass_driver *uclass =
		ll_entry_start(struct uclass_driver, uclass);
	const int n_ents = ll_entry_count(struct uclass_driver, uclass);
	struct uclass_driver *entry;

	for (entry = uclass; entry != uclass + n_ents; entry++) {
		if (entry->id == id)
			return entry;
	}

	return NULL;
}

int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
{
	struct driver_info *info =
		ll_entry_start(struct driver_info, driver_info);
	const int n_ents = ll_entry_count(struct driver_info, driver_info);
	struct driver_info *entry;
	struct udevice *dev;
	int result = 0;
	int ret;

	for (entry = info; entry != info + n_ents; entry++) {
		ret = device_bind_by_name(parent, pre_reloc_only, entry, &dev);
		if (ret && ret != -EPERM) {
			dm_warn("No match for driver '%s'\n", entry->name);
			if (!result || ret != -ENOENT)
				result = ret;
		}
	}

	return result;
}

int device_bind_driver(struct udevice *parent, const char *drv_name,
		       const char *dev_name, struct udevice **devp)
{
	struct driver *drv;
	int ret;

	drv = lists_driver_lookup_name(drv_name);
	if (!drv) {
		printf("Cannot find driver '%s'\n", drv_name);
		return -ENOENT;
	}
	ret = device_bind(parent, drv, dev_name, NULL, -1, devp);
	if (ret) {
		printf("Cannot create device named '%s' (err=%d)\n",
		       dev_name, ret);
		return ret;
	}

	return 0;
}

#ifdef CONFIG_OF_CONTROL
/**
 * driver_check_compatible() - Check if a driver is compatible with this node
 *
 * @param blob:		Device tree pointer
 * @param offset:	Offset of node in device tree
 * @param of_match:	List of compatible strings to match
 * @param of_idp:	Returns the match that was found
 * @return 0 if there is a match, -ENOENT if no match, -ENODEV if the node
 * does not have a compatible string, other error <0 if there is a device
 * tree error
 */
static int driver_check_compatible(const void *blob, int offset,
				   const struct udevice_id *of_match,
				   const struct udevice_id **of_idp)
{
	int ret;

	*of_idp = NULL;
	if (!of_match)
		return -ENOENT;

	while (of_match->compatible) {
		ret = fdt_node_check_compatible(blob, offset,
						of_match->compatible);
		if (!ret) {
			*of_idp = of_match;
			return 0;
		} else if (ret == -FDT_ERR_NOTFOUND) {
			return -ENODEV;
		} else if (ret < 0) {
			return -EINVAL;
		}
		of_match++;
	}

	return -ENOENT;
}

int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
		   struct udevice **devp)
{
	struct driver *driver = ll_entry_start(struct driver, driver);
	const int n_ents = ll_entry_count(struct driver, driver);
	const struct udevice_id *id;
	struct driver *entry;
	struct udevice *dev;
	bool found = false;
	const char *name;
	int result = 0;
	int ret = 0;

	dm_dbg("bind node %s\n", fdt_get_name(blob, offset, NULL));
	if (devp)
		*devp = NULL;
	for (entry = driver; entry != driver + n_ents; entry++) {
		ret = driver_check_compatible(blob, offset, entry->of_match,
					      &id);
		name = fdt_get_name(blob, offset, NULL);
		if (ret == -ENOENT) {
			continue;
		} else if (ret == -ENODEV) {
			dm_dbg("Device '%s' has no compatible string\n", name);
			break;
		} else if (ret) {
			dm_warn("Device tree error at offset %d\n", offset);
			result = ret;
			break;
		}

		dm_dbg("   - found match at '%s'\n", entry->name);
		ret = device_bind(parent, entry, name, NULL, offset, &dev);
		if (ret) {
			dm_warn("Error binding driver '%s'\n", entry->name);
			return ret;
		} else {
			dev->of_id = id;
			found = true;
			if (devp)
				*devp = dev;
		}
		break;
	}

	if (!found && !result && ret != -ENODEV) {
		dm_dbg("No match for node '%s'\n",
		       fdt_get_name(blob, offset, NULL));
	}

	return result;
}
#endif
