/* SPDX-License-Identifier: GPL-2.0-only */

#include <commonlib/bsd/helpers.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci_def.h>
#include <stdlib.h>
#include <string.h>
#include <types.h>

/**
 * Given a Local APIC ID, find the device structure.
 *
 * @param apic_id The Local APIC ID number.
 * @return Pointer to the device structure (if found), 0 otherwise.
 */
struct device *dev_find_lapic(unsigned int apic_id)
{
	struct device *dev;
	struct device *result = NULL;

	for (dev = all_devices; dev; dev = dev->next) {
		if (dev->path.type == DEVICE_PATH_APIC &&
		    dev->path.apic.apic_id == apic_id) {
			result = dev;
			break;
		}
	}
	return result;
}

/**
 * Find a device of a given vendor and type.
 *
 * @param vendor A PCI vendor ID (e.g. 0x8086 for Intel).
 * @param device A PCI device ID.
 * @param from Pointer to the device structure, used as a starting point in
 *             the linked list of all_devices, which can be 0 to start at the
 *             head of the list (i.e. all_devices).
 * @return Pointer to the device struct.
 */
struct device *dev_find_device(u16 vendor, u16 device, struct device *from)
{
	if (!from)
		from = all_devices;
	else
		from = from->next;

	while (from && (from->vendor != vendor || from->device != device))
		from = from->next;

	return from;
}

/**
 * Find a device of a given class.
 *
 * @param class Class of the device.
 * @param from Pointer to the device structure, used as a starting point in
 *             the linked list of all_devices, which can be 0 to start at the
 *             head of the list (i.e. all_devices).
 * @return Pointer to the device struct.
 */
struct device *dev_find_class(unsigned int class, struct device *from)
{
	if (!from)
		from = all_devices;
	else
		from = from->next;

	while (from && (from->class & 0xffffff00) != class)
		from = from->next;

	return from;
}

/**
 * Encode the device path into 3 bytes for logging to CMOS.
 *
 * @param dev The device path to encode.
 * @return Device path encoded into lower 3 bytes of dword.
 */
u32 dev_path_encode(const struct device *dev)
{
	u32 ret;

	if (!dev)
		return 0;

	/* Store the device type in 3rd byte. */
	ret = dev->path.type << 16;

	/* Encode the device specific path in the low word. */
	switch (dev->path.type) {
	case DEVICE_PATH_ROOT:
		break;
	case DEVICE_PATH_PCI:
		ret |= dev->upstream->segment_group << 16 | dev->upstream->secondary << 8 | dev->path.pci.devfn;
		break;
	case DEVICE_PATH_PNP:
		ret |= dev->path.pnp.port << 8 | dev->path.pnp.device;
		break;
	case DEVICE_PATH_I2C:
		ret |= dev->path.i2c.mode_10bit << 8 | dev->path.i2c.device;
		break;
	case DEVICE_PATH_APIC:
		ret |= dev->path.apic.apic_id;
		break;
	case DEVICE_PATH_DOMAIN:
		ret |= dev->path.domain.domain;
		break;
	case DEVICE_PATH_CPU_CLUSTER:
		ret |= dev->path.cpu_cluster.cluster;
		break;
	case DEVICE_PATH_CPU:
		ret |= dev->path.cpu.id;
		break;
	case DEVICE_PATH_CPU_BUS:
		ret |= dev->path.cpu_bus.id;
		break;
	case DEVICE_PATH_IOAPIC:
		ret |= dev->path.ioapic.ioapic_id;
		break;
	case DEVICE_PATH_GENERIC:
		ret |= dev->path.generic.subid << 8 | dev->path.generic.id;
		break;
	case DEVICE_PATH_SPI:
		ret |= dev->path.spi.cs;
		break;
	case DEVICE_PATH_USB:
		ret |= dev->path.usb.port_type << 8 | dev->path.usb.port_id;
		break;
	case DEVICE_PATH_GPIO:
		ret |= dev->path.gpio.id;
		break;
	case DEVICE_PATH_MDIO:
		ret |= dev->path.mdio.addr;
		break;
	case DEVICE_PATH_NONE:
	case DEVICE_PATH_MMIO:  /* don't care */
	default:
		break;
	}

	return ret;
}

/*
 * Warning: This function uses a static buffer. Don't call it more than once
 * from the same print statement!
 */
const char *dev_path(const struct device *dev)
{
	static char buffer[DEVICE_PATH_MAX];

	buffer[0] = '\0';
	if (!dev) {
		strcpy(buffer, "<null>");
	} else {
		switch (dev->path.type) {
		case DEVICE_PATH_NONE:
			strcpy(buffer, "NONE");
			break;
		case DEVICE_PATH_ROOT:
			strcpy(buffer, "Root Device");
			break;
		case DEVICE_PATH_PCI:
			snprintf(buffer, sizeof(buffer),
				 "PCI: %02x:%02x:%02x.%01x",
				 dev->upstream->segment_group,
				 dev->upstream->secondary,
				 PCI_SLOT(dev->path.pci.devfn),
				 PCI_FUNC(dev->path.pci.devfn));
			break;
		case DEVICE_PATH_PNP:
			snprintf(buffer, sizeof(buffer), "PNP: %04x.%01x",
				 dev->path.pnp.port, dev->path.pnp.device);
			break;
		case DEVICE_PATH_I2C:
			snprintf(buffer, sizeof(buffer), "I2C: %02x:%02x",
				 dev->upstream->secondary,
				 dev->path.i2c.device);
			break;
		case DEVICE_PATH_APIC:
			snprintf(buffer, sizeof(buffer), "APIC: %02x",
				 dev->path.apic.apic_id);
			break;
		case DEVICE_PATH_IOAPIC:
			snprintf(buffer, sizeof(buffer), "IOAPIC: %02x",
				 dev->path.ioapic.ioapic_id);
			break;
		case DEVICE_PATH_DOMAIN:
			snprintf(buffer, sizeof(buffer), "DOMAIN: %08x",
				dev->path.domain.domain);
			break;
		case DEVICE_PATH_CPU_CLUSTER:
			snprintf(buffer, sizeof(buffer), "CPU_CLUSTER: %01x",
				dev->path.cpu_cluster.cluster);
			break;
		case DEVICE_PATH_CPU:
			snprintf(buffer, sizeof(buffer),
				 "CPU: %02x", dev->path.cpu.id);
			break;
		case DEVICE_PATH_CPU_BUS:
			snprintf(buffer, sizeof(buffer),
				 "CPU_BUS: %02x", dev->path.cpu_bus.id);
			break;
		case DEVICE_PATH_GENERIC:
			snprintf(buffer, sizeof(buffer),
				 "GENERIC: %d.%d", dev->path.generic.id,
				 dev->path.generic.subid);
			break;
		case DEVICE_PATH_SPI:
			snprintf(buffer, sizeof(buffer), "SPI: %02x",
				 dev->path.spi.cs);
			break;
		case DEVICE_PATH_USB:
			snprintf(buffer, sizeof(buffer), "USB%u port %u",
				 dev->path.usb.port_type, dev->path.usb.port_id);
			break;
		case DEVICE_PATH_MMIO:
			snprintf(buffer, sizeof(buffer), "MMIO: %08lx",
				 dev->path.mmio.addr);
			break;
		case DEVICE_PATH_GPIO:
			snprintf(buffer, sizeof(buffer), "GPIO: %d", dev->path.gpio.id);
			break;
		case DEVICE_PATH_MDIO:
			snprintf(buffer, sizeof(buffer), "MDIO: %02x", dev->path.mdio.addr);
			break;
		default:
			printk(BIOS_ERR, "Unknown device path type: %d\n",
			       dev->path.type);
			break;
		}
	}
	return buffer;
}

const char *dev_name(const struct device *dev)
{
	if (dev->name)
		return dev->name;
	else if (dev->chip_ops && dev->chip_ops->name)
		return dev->chip_ops->name;
	else
		return "unknown";
}

/* Returns the PCI domain for the given PCI device */
struct device *dev_get_pci_domain(struct device *dev)
{
	/* Walk up the tree up to the PCI domain */
	while (dev && dev->upstream && !is_root_device(dev)) {
		dev = dev->upstream->dev;
		if (dev->path.type == DEVICE_PATH_DOMAIN)
			return dev;
	}

	return NULL;
}

/**
 * Allocate 64 more resources to the free list.
 *
 * @return TODO.
 */
static int allocate_more_resources(void)
{
	int i;
	struct resource *new_res_list;

	new_res_list = malloc(64 * sizeof(*new_res_list));

	if (new_res_list == NULL)
		return 0;

	memset(new_res_list, 0, 64 * sizeof(*new_res_list));

	for (i = 0; i < 64 - 1; i++)
		new_res_list[i].next = &new_res_list[i+1];

	free_resources = new_res_list;
	return 1;
}

/**
 * Remove resource res from the device's list and add it to the free list.
 *
 * @param dev TODO
 * @param res TODO
 * @param prev TODO
 * @return TODO.
 */
static void free_resource(struct device *dev, struct resource *res,
			  struct resource *prev)
{
	if (prev)
		prev->next = res->next;
	else
		dev->resource_list = res->next;

	res->next = free_resources;
	free_resources = res;
}

/**
 * See if we have unused but allocated resource structures.
 *
 * If so remove the allocation.
 *
 * @param dev The device to find the resource on.
 */
void compact_resources(struct device *dev)
{
	struct resource *res, *next, *prev = NULL;

	/* Move all of the free resources to the end */
	for (res = dev->resource_list; res; res = next) {
		next = res->next;
		if (!res->flags)
			free_resource(dev, res, prev);
		else
			prev = res;
	}
}

/**
 * See if a resource structure already exists for a given index.
 *
 * @param dev The device to find the resource on.
 * @param index The index of the resource on the device.
 * @return The resource, if it already exists.
 */
struct resource *probe_resource(const struct device *dev, unsigned int index)
{
	struct resource *res;

	/* See if there is a resource with the appropriate index */
	for (res = dev->resource_list; res; res = res->next) {
		if (res->index == index)
			break;
	}

	return res;
}

/**
 * See if a resource structure already exists for a given index and if not
 * allocate one.
 *
 * Then initialize the resource to default values.
 *
 * @param dev The device to find the resource on.
 * @param index The index of the resource on the device.
 * @return TODO.
 */
struct resource *new_resource(struct device *dev, unsigned int index)
{
	struct resource *resource, *tail;

	/* First move all of the free resources to the end. */
	compact_resources(dev);

	/* See if there is a resource with the appropriate index. */
	resource = probe_resource(dev, index);
	if (!resource) {
		if (free_resources == NULL && !allocate_more_resources())
			die("Couldn't allocate more resources.");

		resource = free_resources;
		free_resources = free_resources->next;
		memset(resource, 0, sizeof(*resource));
		resource->next = NULL;
		tail = dev->resource_list;
		if (tail) {
			while (tail->next)
				tail = tail->next;
			tail->next = resource;
		} else {
			dev->resource_list = resource;
		}
	}

	/* Initialize the resource values. */
	if (!(resource->flags & IORESOURCE_FIXED)) {
		resource->flags = 0;
		resource->base = 0;
	}
	resource->size  = 0;
	resource->limit = 0;
	resource->index = index;
	resource->align = 0;
	resource->gran  = 0;

	return resource;
}

/**
 * Return an existing resource structure for a given index.
 *
 * @param dev The device to find the resource on.
 * @param index The index of the resource on the device.
 * return TODO.
 */
struct resource *find_resource(const struct device *dev, unsigned int index)
{
	struct resource *resource;

	/* See if there is a resource with the appropriate index. */
	resource = probe_resource(dev, index);
	if (!resource)
		die("%s missing resource: %02x\n", dev_path(dev), index);
	return resource;
}

/**
 * Round a number up to the next multiple of gran.
 *
 * @param val The starting value.
 * @param gran Granularity we are aligning the number to.
 * @return The aligned value.
 */
static resource_t align_up(resource_t val, unsigned long gran)
{
	resource_t mask;
	mask = (1ULL << gran) - 1ULL;
	val += mask;
	val &= ~mask;
	return val;
}

/**
 * Round a number up to the previous multiple of gran.
 *
 * @param val The starting value.
 * @param gran Granularity we are aligning the number to.
 * @return The aligned value.
 */
static resource_t align_down(resource_t val, unsigned long gran)
{
	resource_t mask;
	mask = (1ULL << gran) - 1ULL;
	val &= ~mask;
	return val;
}

/**
 * Compute the maximum address that is part of a resource.
 *
 * @param resource The resource whose limit is desired.
 * @return The end.
 */
resource_t resource_end(const struct resource *resource)
{
	resource_t base, end;

	/* Get the base address. */
	base = resource->base;

	/*
	 * For a non bridge resource granularity and alignment are the same.
	 * For a bridge resource align is the largest needed alignment below
	 * the bridge. While the granularity is simply how many low bits of
	 * the address cannot be set.
	 */

	/* Get the end (rounded up). */
	end = base + align_up(resource->size, resource->gran) - 1;

	return end;
}

/**
 * Compute the maximum legal value for resource->base.
 *
 * @param resource The resource whose maximum is desired.
 * @return The maximum.
 */
resource_t resource_max(const struct resource *resource)
{
	resource_t max;

	max = align_down(resource->limit - resource->size + 1, resource->align);

	return max;
}

/**
 * Return the resource type of a resource.
 *
 * @param resource The resource type to decode.
 * @return TODO.
 */
const char *resource_type(const struct resource *resource)
{
	static char buffer[RESOURCE_TYPE_MAX];
	snprintf(buffer, sizeof(buffer), "%s%s%s%s",
		 ((resource->flags & IORESOURCE_READONLY) ? "ro" : ""),
		 ((resource->flags & IORESOURCE_PREFETCH) ? "pref" : ""),
		 ((resource->flags == 0) ? "unused" :
		  (resource->flags & IORESOURCE_IO) ? "io" :
		  (resource->flags & IORESOURCE_DRQ) ? "drq" :
		  (resource->flags & IORESOURCE_IRQ) ? "irq" :
		  (resource->flags & IORESOURCE_MEM) ? "mem" : "??????"),
		 ((resource->flags & IORESOURCE_PCI64) ? "64" : ""));
	return buffer;
}

/**
 * Print the resource that was just stored.
 *
 * @param dev The device the stored resource lives on.
 * @param resource The resource that was just stored.
 * @param comment TODO
 */
void report_resource_stored(struct device *dev, const struct resource *resource,
			    const char *comment)
{
	char buf[10];
	unsigned long long base, end;

	if (!(resource->flags & IORESOURCE_STORED))
		return;

	base = resource->base;
	end = resource_end(resource);
	buf[0] = '\0';

	if (dev->downstream && (resource->flags & IORESOURCE_PCI_BRIDGE)) {
		snprintf(buf, sizeof(buf),
			 "seg %02x bus %02x ", dev->downstream->segment_group,
			 dev->downstream->secondary);
	}
	printk(BIOS_DEBUG, "%s %02lx <- [0x%016llx - 0x%016llx] size 0x%08llx "
	       "gran 0x%02x %s%s%s\n", dev_path(dev), resource->index,
		base, end, resource->size, resource->gran, buf,
		resource_type(resource), comment);
}

void search_bus_resources(struct bus *bus, unsigned long type_mask,
			  unsigned long type, resource_search_t search,
			  void *gp)
{
	struct device *curdev;

	for (curdev = bus->children; curdev; curdev = curdev->sibling) {
		struct resource *res;

		/* Ignore disabled devices. */
		if (!curdev->enabled)
			continue;

		for (res = curdev->resource_list; res; res = res->next) {
			/* If it isn't the right kind of resource ignore it. */
			if ((res->flags & type_mask) != type)
				continue;

			/* If it is a subtractive resource recurse. */
			if (res->flags & IORESOURCE_SUBTRACTIVE) {
				if (curdev->downstream)
					search_bus_resources(curdev->downstream, type_mask, type,
							     search, gp);
				continue;
			}
			search(gp, curdev, res);
		}
	}
}

void search_global_resources(unsigned long type_mask, unsigned long type,
			     resource_search_t search, void *gp)
{
	struct device *curdev;

	for (curdev = all_devices; curdev; curdev = curdev->next) {
		struct resource *res;

		/* Ignore disabled devices. */
		if (!curdev->enabled)
			continue;

		for (res = curdev->resource_list; res; res = res->next) {
			/* If it isn't the right kind of resource ignore it. */
			if ((res->flags & type_mask) != type)
				continue;

			/* If it is a subtractive resource ignore it. */
			if (res->flags & IORESOURCE_SUBTRACTIVE)
				continue;

			/* If the resource is not assigned ignore it. */
			if (!(res->flags & IORESOURCE_ASSIGNED))
				continue;

			search(gp, curdev, res);
		}
	}
}

void dev_set_enabled(struct device *dev, int enable)
{
	if (dev->enabled == enable)
		return;

	dev->enabled = enable;
	if (dev->ops && dev->ops->enable)
		dev->ops->enable(dev);
	else if (dev->chip_ops && dev->chip_ops->enable_dev)
		dev->chip_ops->enable_dev(dev);
}

void disable_children(struct bus *bus)
{
	struct device *child;

	for (child = bus->children; child; child = child->sibling) {
		if (child->downstream)
			disable_children(child->downstream);
		dev_set_enabled(child, 0);
	}
}

/*
 * Returns true if the device is an enabled bridge that has at least
 * one enabled device on its secondary bus that is not of type NONE.
 */
bool dev_is_active_bridge(struct device *dev)
{
	struct device *child;

	if (!dev || !dev->enabled)
		return 0;

	if (!dev->downstream || !dev->downstream->children)
		return 0;

	for (child = dev->downstream->children; child; child = child->sibling) {
		if (child->path.type == DEVICE_PATH_NONE)
			continue;
		if (child->enabled)
			return 1;
	}

	return 0;
}

static void resource_tree(const struct device *root, int debug_level, int depth)
{
	int i = 0;
	struct device *child;
	struct resource *res;
	char indent[30];	/* If your tree has more levels, it's wrong. */

	for (i = 0; i < depth + 1 && i < 29; i++)
		indent[i] = ' ';
	indent[i] = '\0';

	printk(BIOS_DEBUG, "%s%s", indent, dev_path(root));
	if (root->downstream && root->downstream->children)
		printk(BIOS_DEBUG, " child on link 0 %s",
			  dev_path(root->downstream->children));
	printk(BIOS_DEBUG, "\n");

	for (res = root->resource_list; res; res = res->next) {
		printk(debug_level, "%s%s resource base %llx size %llx "
			  "align %d gran %d limit %llx flags %lx index %lx\n",
			  indent, dev_path(root), res->base, res->size,
			  res->align, res->gran, res->limit, res->flags,
			  res->index);
	}

	if (!root->downstream)
		return;

	for (child = root->downstream->children; child; child = child->sibling)
		resource_tree(child, debug_level, depth + 1);
}

void print_resource_tree(const struct device *root, int debug_level,
			 const char *msg)
{
	/* Bail if root is null. */
	if (!root) {
		printk(debug_level, "%s passed NULL for root!\n", __func__);
		return;
	}

	/* Bail if not printing to screen. */
	if (!printk(debug_level, "Show resources in subtree (%s)...%s\n",
		       dev_path(root), msg))
		return;

	resource_tree(root, debug_level, 0);
}

void show_devs_tree(const struct device *dev, int debug_level, int depth)
{
	char depth_str[20];
	int i;
	struct device *sibling;

	for (i = 0; i < depth; i++)
		depth_str[i] = ' ';
	depth_str[i] = '\0';

	printk(debug_level, "%s%s: enabled %d\n",
		  depth_str, dev_path(dev), dev->enabled);

	if (!dev->downstream)
		return;

	for (sibling = dev->downstream->children; sibling; sibling = sibling->sibling)
		show_devs_tree(sibling, debug_level, depth + 1);
}

void show_all_devs_tree(int debug_level, const char *msg)
{
	/* Bail if not printing to screen. */
	if (!printk(debug_level, "Show all devs in tree form... %s\n", msg))
		return;
	show_devs_tree(all_devices, debug_level, 0);
}

void show_devs_subtree(struct device *root, int debug_level, const char *msg)
{
	/* Bail if not printing to screen. */
	if (!printk(debug_level, "Show all devs in subtree %s... %s\n",
		       dev_path(root), msg))
		return;
	printk(debug_level, "%s\n", msg);
	show_devs_tree(root, debug_level, 0);
}

void show_all_devs(int debug_level, const char *msg)
{
	struct device *dev;

	/* Bail if not printing to screen. */
	if (!printk(debug_level, "Show all devs... %s\n", msg))
		return;
	for (dev = all_devices; dev; dev = dev->next) {
		printk(debug_level, "%s: enabled %d\n",
			  dev_path(dev), dev->enabled);
	}
}

void show_one_resource(int debug_level, struct device *dev,
		       struct resource *resource, const char *comment)
{
	char buf[10];
	unsigned long long base, end;
	base = resource->base;
	end = resource_end(resource);
	buf[0] = '\0';

	printk(debug_level, "%s %02lx <- [0x%016llx - 0x%016llx] "
		  "size 0x%08llx gran 0x%02x %s%s%s\n", dev_path(dev),
		  resource->index, base, end, resource->size, resource->gran,
		  buf, resource_type(resource), comment);
}

void show_all_devs_resources(int debug_level, const char *msg)
{
	struct device *dev;

	if (!printk(debug_level, "Show all devs with resources... %s\n", msg))
		return;

	for (dev = all_devices; dev; dev = dev->next) {
		struct resource *res;
		printk(debug_level, "%s: enabled %d\n",
			  dev_path(dev), dev->enabled);
		for (res = dev->resource_list; res; res = res->next)
			show_one_resource(debug_level, dev, res, "");
	}
}

const struct resource *fixed_resource_range_idx(struct device *dev, unsigned long index,
				uint64_t base, uint64_t size, unsigned long flags)
{
	struct resource *resource;
	if (!size)
		return NULL;

	resource = new_resource(dev, index);
	resource->base = base;
	resource->size = size;
	resource->flags = IORESOURCE_FIXED | IORESOURCE_ASSIGNED;
	resource->flags |= flags;

	printk(BIOS_SPEW, "dev: %s, index: 0x%lx, base: 0x%llx, size: 0x%llx\n",
	       dev_path(dev), resource->index, resource->base, resource->size);

	return resource;
}

const struct resource *lower_ram_end(struct device *dev, unsigned long index, uint64_t end)
{
	return ram_from_to(dev, index, 0, end);
}

const struct resource *upper_ram_end(struct device *dev, unsigned long index, uint64_t end)
{
	if (end <= 4ull * GiB)
		return NULL;

	printk(BIOS_INFO, "Available memory above 4GB: %lluM\n", (end - 4ull * GiB) / MiB);

	return ram_from_to(dev, index, 4ull * GiB, end);
}

void mmconf_resource(struct device *dev, unsigned long index)
{
	struct resource *resource = new_resource(dev, index);
	resource->base = CONFIG_ECAM_MMCONF_BASE_ADDRESS;
	resource->size = CONFIG_ECAM_MMCONF_LENGTH;
	resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
		IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;

	printk(BIOS_DEBUG, "Adding PCIe enhanced config space BAR 0x%08lx-0x%08lx.\n",
			(unsigned long)(resource->base),
			(unsigned long)(resource->base + resource->size));
}

void tolm_test(void *gp, struct device *dev, struct resource *new)
{
	struct resource **best_p = gp;
	struct resource *best;

	best = *best_p;

	/*
	 * If resource is not allocated any space i.e. size is zero,
	 * then do not consider this resource in tolm calculations.
	 */
	if (new->size == 0)
		return;

	if (!best || (best->base > new->base))
		best = new;

	*best_p = best;
}

u32 find_pci_tolm(struct bus *bus)
{
	struct resource *min = NULL;
	u32 tolm;
	unsigned long mask_match = IORESOURCE_MEM | IORESOURCE_ASSIGNED;

	search_bus_resources(bus, mask_match, mask_match, tolm_test, &min);

	tolm = 0xffffffffUL;

	if (min && tolm > min->base)
		tolm = min->base;

	return tolm;
}

/* Count of enabled CPUs */
int dev_count_cpu(void)
{
	struct device *cpu;
	int count = 0;

	for (cpu = all_devices; cpu; cpu = cpu->next) {
		if (!is_enabled_cpu(cpu))
			continue;
		count++;
	}

	return count;
}

/* Get device path name */
const char *dev_path_name(enum device_path_type type)
{
	static const char *const type_names[] = DEVICE_PATH_NAMES;
	const char *type_name = "Unknown";

	/* Translate the type value into a string */
	if (type < ARRAY_SIZE(type_names))
		type_name = type_names[type];
	return type_name;
}

bool dev_path_hotplug(const struct device *dev)
{
	for (dev = dev->upstream->dev; dev != dev->upstream->dev; dev = dev->upstream->dev) {
		if (dev->hotplug_port)
			return true;
	}
	return false;
}

void log_resource(const char *type, const struct device *dev, const struct resource *res,
			const char *srcfile, const int line)
{
	printk(BIOS_SPEW, "%s:%d res: %s, dev: %s, index: 0x%lx, base: 0x%llx, "
			  "end: 0x%llx, size_kb: 0x%llx\n",
			  srcfile, line, type, dev_path(dev), res->index, res->base,
			  resource_end(res), res->size / KiB);
}

bool is_cpu(const struct device *cpu)
{
	return cpu->path.type == DEVICE_PATH_APIC &&
	       cpu->upstream->dev->path.type == DEVICE_PATH_CPU_CLUSTER;
}

bool is_enabled_cpu(const struct device *cpu)
{
	return is_cpu(cpu) && cpu->enabled;
}

bool is_pci(const struct device *pci)
{
	return pci->path.type == DEVICE_PATH_PCI;
}

bool is_enabled_pci(const struct device *pci)
{
	return is_pci(pci) && pci->enabled;
}

bool is_pci_dev_on_bus(const struct device *pci, unsigned int bus)
{
	return is_pci(pci) && pci->upstream->segment_group == 0
		&& pci->upstream->secondary == bus;
}
