/* 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 domain for the given device */
const struct device *dev_get_domain(const struct device *dev)
{
	/* Walk up the tree up to the domain */
	while (dev && dev->upstream && !is_root_device(dev)) {
		if (dev->path.type == DEVICE_PATH_DOMAIN)
			return dev;
		dev = dev->upstream->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;
}

bool is_pci_bridge(const struct device *pci)
{
	return is_pci(pci) && ((pci->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE);
}
