device/device.h: Drop multiple links

Multiple links are unused throughout the tree and make the code more
confusing as an iteration over all busses is needed to get downstream
devices. This also not done consistently e.g. the allocator does not
care about multiple links on busses. A better way of dealing multiple
links below a device is to feature dummy devices with each their
respective bus.

This drops the sconfig capability to declare the same device multiple
times which was previously used to declare multiple links.

Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Change-Id: Iab6fe269faef46ae77ed1ea425440cf5c7dbd49b
Reviewed-on: https://review.coreboot.org/c/coreboot/+/78328
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Jincheng Li <jincheng.li@intel.com>
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
diff --git a/src/arch/x86/mpspec.c b/src/arch/x86/mpspec.c
index 7744f68..3ddee2f 100644
--- a/src/arch/x86/mpspec.c
+++ b/src/arch/x86/mpspec.c
@@ -282,48 +282,46 @@
 	int srcbus;
 	int slot;
 
-	struct bus *link;
 	unsigned char dstirq_x[4];
 
-	for (link = dev->link_list; link; link = link->next) {
+	if (!dev->link_list)
+		return;
 
-		child = link->children;
-		srcbus = link->secondary;
+	child = dev->link_list->children;
+	srcbus = dev->link_list->secondary;
 
-		while (child) {
-			if (child->path.type != DEVICE_PATH_PCI)
-				goto next;
+	while (child) {
+		if (child->path.type != DEVICE_PATH_PCI)
+			goto next;
 
-			slot = (child->path.pci.devfn >> 3);
-			/* round pins */
+		slot = (child->path.pci.devfn >> 3);
+		/* round pins */
+		for (i = 0; i < 4; i++)
+			dstirq_x[i] = dstirq[(i + slot) % 4];
+
+		if ((child->class >> 16) != PCI_BASE_CLASS_BRIDGE) {
+			/* pci device */
+			printk(BIOS_DEBUG, "route irq: %s\n",
+			       dev_path(child));
 			for (i = 0; i < 4; i++)
-				dstirq_x[i] = dstirq[(i + slot) % 4];
-
-			if ((child->class >> 16) != PCI_BASE_CLASS_BRIDGE) {
-				/* pci device */
-				printk(BIOS_DEBUG, "route irq: %s\n",
-					dev_path(child));
-				for (i = 0; i < 4; i++)
-					smp_write_intsrc(mc, irqtype, irqflag,
-						srcbus, (slot<<2)|i, dstapic,
-						dstirq_x[i]);
-				goto next;
-			}
-
-			switch (child->class>>8) {
-			case PCI_CLASS_BRIDGE_PCI:
-			case PCI_CLASS_BRIDGE_PCMCIA:
-			case PCI_CLASS_BRIDGE_CARDBUS:
-				printk(BIOS_DEBUG, "route irq bridge: %s\n",
-					dev_path(child));
-				smp_write_intsrc_pci_bridge(mc, irqtype,
-					irqflag, child, dstapic, dstirq_x);
-			}
-
-next:
-			child = child->sibling;
+				smp_write_intsrc(mc, irqtype, irqflag,
+						 srcbus, (slot<<2)|i, dstapic,
+						 dstirq_x[i]);
+			goto next;
 		}
 
+		switch (child->class>>8) {
+		case PCI_CLASS_BRIDGE_PCI:
+		case PCI_CLASS_BRIDGE_PCMCIA:
+		case PCI_CLASS_BRIDGE_CARDBUS:
+			printk(BIOS_DEBUG, "route irq bridge: %s\n",
+			       dev_path(child));
+			smp_write_intsrc_pci_bridge(mc, irqtype,
+						    irqflag, child, dstapic, dstirq_x);
+		}
+
+next:
+		child = child->sibling;
 	}
 }
 
@@ -478,17 +476,16 @@
 	memset(buses, 0, sizeof(buses));
 
 	for (dev = all_devices; dev; dev = dev->next) {
-		struct bus *bus;
-		for (bus = dev->link_list; bus; bus = bus->next) {
-			if (bus->secondary > 255) {
-				printk(BIOS_ERR,
-					"A bus claims to have a bus ID > 255?!? Aborting");
-				return;
-			}
-			buses[bus->secondary] = 1;
-			if (highest < bus->secondary)
-				highest = bus->secondary;
+		struct bus *bus = dev->link_list;
+		if (!bus)
+			continue;
+		if (bus->secondary > 255) {
+			printk(BIOS_ERR, "A bus claims to have a bus ID > 255?!? Aborting\n");
+			return;
 		}
+		buses[bus->secondary] = 1;
+		if (highest < bus->secondary)
+			highest = bus->secondary;
 	}
 	for (i = 0; i <= highest; i++) {
 		if (buses[i]) {
diff --git a/src/device/device.c b/src/device/device.c
index d877e14..743a3af 100644
--- a/src/device/device.c
+++ b/src/device/device.c
@@ -187,13 +187,11 @@
 {
 	struct device *curdev;
 
-	printk(BIOS_SPEW, "%s %s segment group %d bus %d link: %d\n", dev_path(bus->dev),
-	       __func__, bus->segment_group, bus->secondary, bus->link_num);
+	printk(BIOS_SPEW, "%s %s segment group %d bus %d\n", dev_path(bus->dev),
+	       __func__, bus->segment_group, bus->secondary);
 
 	/* Walk through all devices and find which resources they need. */
 	for (curdev = bus->children; curdev; curdev = curdev->sibling) {
-		struct bus *link;
-
 		if (!curdev->enabled)
 			continue;
 
@@ -207,12 +205,12 @@
 		curdev->ops->read_resources(curdev);
 
 		/* Read in the resources behind the current device's links. */
-		for (link = curdev->link_list; link; link = link->next)
-			read_resources(link);
+		if (curdev->link_list)
+			read_resources(curdev->link_list);
 	}
 	post_log_clear();
-	printk(BIOS_SPEW, "%s %s segment group %d bus %d link: %d done\n",
-	       dev_path(bus->dev), __func__, bus->segment_group, bus->secondary, bus->link_num);
+	printk(BIOS_SPEW, "%s %s segment group %d bus %d done\n",
+	       dev_path(bus->dev), __func__, bus->segment_group, bus->secondary);
 }
 
 struct device *vga_pri = NULL;
@@ -301,8 +299,8 @@
 {
 	struct device *curdev;
 
-	printk(BIOS_SPEW, "%s %s, segment group %d bus %d link: %d\n",
-	       dev_path(bus->dev), __func__, bus->segment_group, bus->secondary, bus->link_num);
+	printk(BIOS_SPEW, "%s %s, segment group %d bus %d\n",
+	       dev_path(bus->dev), __func__, bus->segment_group, bus->secondary);
 
 	for (curdev = bus->children; curdev; curdev = curdev->sibling) {
 		if (!curdev->enabled || !curdev->resource_list)
@@ -317,8 +315,8 @@
 		curdev->ops->set_resources(curdev);
 	}
 	post_log_clear();
-	printk(BIOS_SPEW, "%s %s, segment group %d bus %d link: %d done\n",
-	       dev_path(bus->dev), __func__, bus->segment_group, bus->secondary, bus->link_num);
+	printk(BIOS_SPEW, "%s %s, segment group %d bus %d done\n",
+	       dev_path(bus->dev), __func__, bus->segment_group, bus->secondary);
 }
 
 /**
@@ -336,7 +334,6 @@
 static void enable_resources(struct bus *link)
 {
 	struct device *dev;
-	struct bus *c_link;
 
 	for (dev = link->children; dev; dev = dev->sibling) {
 		if (dev->enabled && dev->ops && dev->ops->enable_resources) {
@@ -346,8 +343,8 @@
 	}
 
 	for (dev = link->children; dev; dev = dev->sibling) {
-		for (c_link = dev->link_list; c_link; c_link = c_link->next)
-			enable_resources(c_link);
+		if (dev->link_list)
+			enable_resources(dev->link_list);
 	}
 	post_log_clear();
 }
@@ -394,17 +391,15 @@
 
 	do_scan_bus = 1;
 	while (do_scan_bus) {
-		struct bus *link;
+		struct bus *link = busdev->link_list;
 		busdev->ops->scan_bus(busdev);
 		do_scan_bus = 0;
-		for (link = busdev->link_list; link; link = link->next) {
-			if (link->reset_needed) {
-				if (reset_bus(link))
-					do_scan_bus = 1;
-				else
-					busdev->bus->reset_needed = 1;
-			}
-		}
+		if (!link || !link->reset_needed)
+			continue;
+		if (reset_bus(link))
+			do_scan_bus = 1;
+		else
+			busdev->bus->reset_needed = 1;
 	}
 
 	scan_time = stopwatch_duration_msecs(&sw);
@@ -523,13 +518,11 @@
  */
 void dev_enable(void)
 {
-	struct bus *link;
-
 	printk(BIOS_INFO, "Enabling resources...\n");
 
 	/* Now enable everything. */
-	for (link = dev_root.link_list; link; link = link->next)
-		enable_resources(link);
+	if (dev_root.link_list)
+		enable_resources(dev_root.link_list);
 
 	printk(BIOS_INFO, "done.\n");
 }
@@ -553,8 +546,7 @@
 		long init_time;
 
 		if (dev->path.type == DEVICE_PATH_I2C) {
-			printk(BIOS_DEBUG, "smbus: %s[%d]->",
-			       dev_path(dev->bus->dev), dev->bus->link_num);
+			printk(BIOS_DEBUG, "smbus: %s->", dev_path(dev->bus->dev));
 		}
 
 		printk(BIOS_DEBUG, "%s init\n", dev_path(dev));
@@ -572,7 +564,6 @@
 static void init_link(struct bus *link)
 {
 	struct device *dev;
-	struct bus *c_link;
 
 	for (dev = link->children; dev; dev = dev->sibling) {
 		post_code(POSTCODE_BS_DEV_INIT);
@@ -580,10 +571,9 @@
 		init_dev(dev);
 	}
 
-	for (dev = link->children; dev; dev = dev->sibling) {
-		for (c_link = dev->link_list; c_link; c_link = c_link->next)
-			init_link(c_link);
-	}
+	for (dev = link->children; dev; dev = dev->sibling)
+		if (dev->link_list)
+			init_link(dev->link_list);
 }
 
 /**
@@ -594,16 +584,14 @@
  */
 void dev_initialize(void)
 {
-	struct bus *link;
-
 	printk(BIOS_INFO, "Initializing devices...\n");
 
 	/* First call the mainboard init. */
 	init_dev(&dev_root);
 
 	/* Now initialize everything. */
-	for (link = dev_root.link_list; link; link = link->next)
-		init_link(link);
+	if (dev_root.link_list)
+		init_link(dev_root.link_list);
 	post_log_clear();
 
 	printk(BIOS_INFO, "Devices initialized\n");
@@ -633,15 +621,13 @@
 static void final_link(struct bus *link)
 {
 	struct device *dev;
-	struct bus *c_link;
 
 	for (dev = link->children; dev; dev = dev->sibling)
 		final_dev(dev);
 
-	for (dev = link->children; dev; dev = dev->sibling) {
-		for (c_link = dev->link_list; c_link; c_link = c_link->next)
-			final_link(c_link);
-	}
+	for (dev = link->children; dev; dev = dev->sibling)
+		if (dev->link_list)
+			final_link(dev->link_list);
 }
 /**
  * Finalize all devices in the global device tree.
@@ -651,16 +637,13 @@
  */
 void dev_finalize(void)
 {
-	struct bus *link;
-
 	printk(BIOS_INFO, "Finalize devices...\n");
 
 	/* First call the mainboard finalize. */
 	final_dev(&dev_root);
 
 	/* Now finalize everything. */
-	for (link = dev_root.link_list; link; link = link->next)
-		final_link(link);
+	final_link(dev_root.link_list);
 
 	printk(BIOS_INFO, "Devices finalized\n");
 }
diff --git a/src/device/device_util.c b/src/device/device_util.c
index 260c9b4..ea4ef27 100644
--- a/src/device/device_util.c
+++ b/src/device/device_util.c
@@ -560,16 +560,9 @@
 
 			/* If it is a subtractive resource recurse. */
 			if (res->flags & IORESOURCE_SUBTRACTIVE) {
-				struct bus *subbus;
-				for (subbus = curdev->link_list; subbus;
-				     subbus = subbus->next)
-					if (subbus->link_num
-					== IOINDEX_SUBTRACTIVE_LINK(res->index))
-						break;
-				if (!subbus) /* Why can subbus be NULL?  */
-					break;
-				search_bus_resources(subbus, type_mask, type,
-						     search, gp);
+				if (curdev->link_list)
+					search_bus_resources(curdev->link_list, type_mask, type,
+							     search, gp);
 				continue;
 			}
 			search(gp, curdev, res);
@@ -624,9 +617,8 @@
 	struct device *child;
 
 	for (child = bus->children; child; child = child->sibling) {
-		struct bus *link;
-		for (link = child->link_list; link; link = link->next)
-			disable_children(link);
+		if (child->link_list)
+			disable_children(child->link_list);
 		dev_set_enabled(child, 0);
 	}
 }
@@ -637,7 +629,6 @@
  */
 bool dev_is_active_bridge(struct device *dev)
 {
-	struct bus *link;
 	struct device *child;
 
 	if (!dev || !dev->enabled)
@@ -646,71 +637,20 @@
 	if (!dev->link_list || !dev->link_list->children)
 		return 0;
 
-	for (link = dev->link_list; link; link = link->next) {
-		for (child = link->children; child; child = child->sibling) {
-			if (child->path.type == DEVICE_PATH_NONE)
-				continue;
-
-			if (child->enabled)
-				return 1;
-		}
+	for (child = dev->link_list->children; child; child = child->sibling) {
+		if (child->path.type == DEVICE_PATH_NONE)
+			continue;
+		if (child->enabled)
+			return 1;
 	}
 
 	return 0;
 }
 
-/**
- * Ensure the device has a minimum number of bus links.
- *
- * @param dev The device to add links to.
- * @param total_links The minimum number of links to have.
- */
-void add_more_links(struct device *dev, unsigned int total_links)
-{
-	struct bus *link, *last = NULL;
-	int link_num = -1;
-
-	for (link = dev->link_list; link; link = link->next) {
-		if (link_num < link->link_num)
-			link_num = link->link_num;
-		last = link;
-	}
-
-	if (last) {
-		int links = total_links - (link_num + 1);
-		if (links > 0) {
-			link = malloc(links * sizeof(*link));
-			if (!link)
-				die("Couldn't allocate more links!\n");
-			memset(link, 0, links * sizeof(*link));
-			last->next = link;
-		} else {
-			/* No more links to add */
-			return;
-		}
-	} else {
-		link = malloc(total_links * sizeof(*link));
-		if (!link)
-			die("Couldn't allocate more links!\n");
-		memset(link, 0, total_links * sizeof(*link));
-		dev->link_list = link;
-	}
-
-	for (link_num = link_num + 1; link_num < total_links; link_num++) {
-		link->link_num = link_num;
-		link->dev = dev;
-		link->next = link + 1;
-		last = link;
-		link = link->next;
-	}
-	last->next = NULL;
-}
-
 static void resource_tree(const struct device *root, int debug_level, int depth)
 {
 	int i = 0;
 	struct device *child;
-	struct bus *link;
 	struct resource *res;
 	char indent[30];	/* If your tree has more levels, it's wrong. */
 
@@ -732,10 +672,11 @@
 			  res->index);
 	}
 
-	for (link = root->link_list; link; link = link->next) {
-		for (child = link->children; child; child = child->sibling)
-			resource_tree(child, debug_level, depth + 1);
-	}
+	if (!root->link_list)
+		return;
+
+	for (child = root->link_list->children; child; child = child->sibling)
+		resource_tree(child, debug_level, depth + 1);
 }
 
 void print_resource_tree(const struct device *root, int debug_level,
@@ -760,7 +701,6 @@
 	char depth_str[20];
 	int i;
 	struct device *sibling;
-	struct bus *link;
 
 	for (i = 0; i < depth; i++)
 		depth_str[i] = ' ';
@@ -769,11 +709,11 @@
 	printk(debug_level, "%s%s: enabled %d\n",
 		  depth_str, dev_path(dev), dev->enabled);
 
-	for (link = dev->link_list; link; link = link->next) {
-		for (sibling = link->children; sibling;
-		     sibling = sibling->sibling)
-			show_devs_tree(sibling, debug_level, depth + 1);
-	}
+	if (!dev->link_list)
+		return;
+
+	for (sibling = dev->link_list->children; sibling; sibling = sibling->sibling)
+		show_devs_tree(sibling, debug_level, depth + 1);
 }
 
 void show_all_devs_tree(int debug_level, const char *msg)
diff --git a/src/device/pci_device.c b/src/device/pci_device.c
index acdad42..24b9523 100644
--- a/src/device/pci_device.c
+++ b/src/device/pci_device.c
@@ -713,16 +713,13 @@
 void pci_dev_set_resources(struct device *dev)
 {
 	struct resource *res;
-	struct bus *bus;
 	u8 line;
 
 	for (res = dev->resource_list; res; res = res->next)
 		pci_set_resource(dev, res);
 
-	for (bus = dev->link_list; bus; bus = bus->next) {
-		if (bus->children)
-			assign_resources(bus);
-	}
+	if (dev->link_list && dev->link_list->children)
+		assign_resources(dev->link_list);
 
 	/* Set a default latency timer. */
 	pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
diff --git a/src/device/root_device.c b/src/device/root_device.c
index d8edbd5..54e82ea 100644
--- a/src/device/root_device.c
+++ b/src/device/root_device.c
@@ -38,31 +38,27 @@
 void enable_static_devices(struct device *bus)
 {
 	struct device *child;
-	struct bus *link;
 
-	for (link = bus->link_list; link; link = link->next) {
-		for (child = link->children; child; child = child->sibling) {
-			enable_static_device(child);
-		}
-	}
+	if (!bus->link_list)
+		return;
+
+	for (child = bus->link_list->children; child; child = child->sibling)
+		enable_static_device(child);
 }
 
 void scan_generic_bus(struct device *bus)
 {
 	struct device *child;
-	struct bus *link;
 	static int bus_max = 0;
 
 	printk(BIOS_SPEW, "%s for %s\n", __func__, dev_path(bus));
 
-	for (link = bus->link_list; link; link = link->next) {
+	if (bus->link_list) {
+		bus->link_list->secondary = ++bus_max;
 
-		link->secondary = ++bus_max;
-
-		for (child = link->children; child; child = child->sibling) {
+		for (child = bus->link_list->children; child; child = child->sibling) {
 			enable_static_device(child);
-			printk(BIOS_DEBUG, "bus: %s[%d]->", dev_path(child->bus->dev),
-			       child->bus->link_num);
+			printk(BIOS_DEBUG, "bus: %s->", dev_path(child->bus->dev));
 		}
 	}
 
@@ -86,14 +82,12 @@
  */
 void scan_static_bus(struct device *bus)
 {
-	struct bus *link;
-
 	printk(BIOS_SPEW, "%s for %s\n", __func__, dev_path(bus));
 
 	enable_static_devices(bus);
 
-	for (link = bus->link_list; link; link = link->next)
-		scan_bridges(link);
+	if (bus->link_list)
+		scan_bridges(bus->link_list);
 
 	printk(BIOS_SPEW, "%s for %s done\n", __func__, dev_path(bus));
 }
diff --git a/src/include/device/device.h b/src/include/device/device.h
index 13bc8dc..b7917e3 100644
--- a/src/include/device/device.h
+++ b/src/include/device/device.h
@@ -4,11 +4,13 @@
 
 #define DEVICE_H
 
-#include <device/resource.h>
+#include <console/console.h>
 #include <device/path.h>
 #include <device/pci_type.h>
+#include <device/resource.h>
 #include <smbios.h>
 #include <static.h>
+#include <stdlib.h>
 #include <types.h>
 
 struct fw_config;
@@ -78,10 +80,8 @@
 struct bus {
 	DEVTREE_CONST struct device *dev;	/* This bridge device */
 	DEVTREE_CONST struct device *children;	/* devices behind this bridge */
-	DEVTREE_CONST struct bus *next;		/* The next bridge on this device */
 	unsigned int	bridge_ctrl;		/* Bridge control register */
 	uint16_t	bridge_cmd;		/* Bridge command register */
-	unsigned char	link_num;		/* The index of this link */
 	uint16_t	secondary;		/* secondary bus number */
 	uint16_t	subordinate;		/* subordinate bus number */
 	uint16_t	max_subordinate;	/* max subordinate bus number */
@@ -193,7 +193,6 @@
 void dev_set_enabled(struct device *dev, int enable);
 void disable_children(struct bus *bus);
 bool dev_is_active_bridge(struct device *dev);
-void add_more_links(struct device *dev, unsigned int total_links);
 bool is_dev_enabled(const struct device *const dev);
 bool is_devfn_enabled(unsigned int devfn);
 bool is_cpu(const struct device *cpu);
diff --git a/src/northbridge/amd/pi/00730F01/northbridge.c b/src/northbridge/amd/pi/00730F01/northbridge.c
index a4409fb..5e82ccd 100644
--- a/src/northbridge/amd/pi/00730F01/northbridge.c
+++ b/src/northbridge/amd/pi/00730F01/northbridge.c
@@ -235,7 +235,6 @@
 				    unsigned long *current, uint16_t *ivhd_length)
 {
 	struct device *sibling;
-	struct bus *link;
 
 	if (!root_level) {
 		root_level = malloc(sizeof(int8_t));
@@ -254,11 +253,11 @@
 		}
 	}
 
-	for (link = dev->link_list; link; link = link->next)
-		for (sibling = link->children; sibling; sibling =
-		     sibling->sibling)
+	if (dev->link_list) {
+		for (sibling = dev->link_list->children; sibling; sibling = sibling->sibling)
 			add_ivhd_device_entries(dev, sibling, depth + 1, depth, root_level,
 						current, ivhd_length);
+	}
 
 	free(root_level);
 }
diff --git a/src/soc/amd/common/block/acpi/ivrs.c b/src/soc/amd/common/block/acpi/ivrs.c
index 9d0ece1..57b5974 100644
--- a/src/soc/amd/common/block/acpi/ivrs.c
+++ b/src/soc/amd/common/block/acpi/ivrs.c
@@ -140,7 +140,6 @@
 				    unsigned long *current, uint16_t nb_bus)
 {
 	struct device *sibling;
-	struct bus *link;
 
 	if (!root_level)
 		return;
@@ -155,11 +154,11 @@
 				ivrs_add_device_or_bridge(parent, dev, current);
 	}
 
-	for (link = dev->link_list; link; link = link->next)
-		for (sibling = link->children; sibling; sibling =
-		     sibling->sibling)
-			add_ivhd_device_entries(dev, sibling, depth + 1, depth, root_level,
-						current, nb_bus);
+	if (!dev->link_list)
+		return;
+	for (sibling = dev->link_list->children; sibling; sibling = sibling->sibling)
+		add_ivhd_device_entries(dev, sibling, depth + 1, depth, root_level, current,
+					nb_bus);
 }
 
 static unsigned long acpi_ivhd_misc(unsigned long current, struct device *dev)
diff --git a/src/soc/amd/common/block/lpc/lpc.c b/src/soc/amd/common/block/lpc/lpc.c
index 4e81316..c076361 100644
--- a/src/soc/amd/common/block/lpc/lpc.c
+++ b/src/soc/amd/common/block/lpc/lpc.c
@@ -278,20 +278,20 @@
 
 static void lpc_enable_children_resources(struct device *dev)
 {
-	struct bus *link;
 	struct device *child;
 
-	for (link = dev->link_list; link; link = link->next) {
-		for (child = link->children; child; child = child->sibling) {
-			if (!child->enabled)
-				continue;
-			if (child->path.type != DEVICE_PATH_PNP)
-				continue;
-			if (CONFIG(SOC_AMD_COMMON_BLOCK_USE_ESPI))
-				configure_child_espi_windows(child);
-			else
-				configure_child_lpc_windows(dev, child);
-		}
+	if (!dev->link_list)
+		return;
+
+	for (child = dev->link_list->children; child; child = child->sibling) {
+		if (!child->enabled)
+			continue;
+		if (child->path.type != DEVICE_PATH_PNP)
+			continue;
+		if (CONFIG(SOC_AMD_COMMON_BLOCK_USE_ESPI))
+			configure_child_espi_windows(child);
+		else
+			configure_child_lpc_windows(dev, child);
 	}
 }
 
diff --git a/src/soc/amd/stoneyridge/northbridge.c b/src/soc/amd/stoneyridge/northbridge.c
index deebfb3..b95c4cd 100644
--- a/src/soc/amd/stoneyridge/northbridge.c
+++ b/src/soc/amd/stoneyridge/northbridge.c
@@ -52,16 +52,9 @@
 
 static void create_vga_resource(struct device *dev)
 {
-	struct bus *link;
-
-	/* find out which link the VGA card is connected,
-	 * we only deal with the 'first' vga card */
-	for (link = dev->link_list ; link ; link = link->next)
-		if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA)
-			break;
-
-	/* no VGA card installed */
-	if (link == NULL)
+	if (!dev->link_list)
+		return;
+	if (!(dev->link_list->bridge_ctrl & PCI_BRIDGE_CTL_VGA))
 		return;
 
 	printk(BIOS_DEBUG, "VGA: %s has VGA device\n",	dev_path(dev));
@@ -71,14 +64,11 @@
 
 static void set_resources(struct device *dev)
 {
-	struct bus *bus;
-
 	/* do we need this? */
 	create_vga_resource(dev);
 
-	for (bus = dev->link_list ; bus ; bus = bus->next)
-		if (bus->children)
-			assign_resources(bus);
+	if (dev->link_list && dev->link_list->children)
+		assign_resources(dev->link_list);
 }
 
 static void northbridge_init(struct device *dev)
diff --git a/src/soc/intel/common/block/lpc/lpc.c b/src/soc/intel/common/block/lpc/lpc.c
index 6d3b90f..994ef9b 100644
--- a/src/soc/intel/common/block/lpc/lpc.c
+++ b/src/soc/intel/common/block/lpc/lpc.c
@@ -100,13 +100,13 @@
  */
 static void pch_lpc_set_child_resources(struct device *dev)
 {
-	struct bus *link;
 	struct device *child;
 
-	for (link = dev->link_list; link; link = link->next) {
-		for (child = link->children; child; child = child->sibling)
-			pch_lpc_loop_resources(child);
-	}
+	if (!dev->link_list)
+		return;
+
+	for (child = dev->link_list->children; child; child = child->sibling)
+		pch_lpc_loop_resources(child);
 }
 
 static void pch_lpc_set_resources(struct device *dev)
diff --git a/src/southbridge/amd/pi/hudson/lpc.c b/src/southbridge/amd/pi/hudson/lpc.c
index 0a4e038..266d75c 100644
--- a/src/southbridge/amd/pi/hudson/lpc.c
+++ b/src/southbridge/amd/pi/hudson/lpc.c
@@ -134,7 +134,6 @@
  */
 static void hudson_lpc_enable_childrens_resources(struct device *dev)
 {
-	struct bus *link;
 	u32 reg, reg_x;
 	int var_num = 0;
 	u16 reg_var[3];
@@ -171,12 +170,10 @@
 	reg_var[1] = pci_read_config16(dev, 0x66);
 	reg_var[0] = pci_read_config16(dev, 0x64);
 
-	for (link = dev->link_list; link; link = link->next) {
-		struct device *child;
-		for (child = link->children; child;
-		     child = child->sibling) {
-			if (child->enabled
-			    && (child->path.type == DEVICE_PATH_PNP)) {
+	struct device *child;
+	if (dev->link_list) {
+		for (child = dev->link_list->children; child; child = child->sibling) {
+			if (child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
 				struct resource *res;
 				for (res = child->resource_list; res; res = res->next) {
 					u32 base, end;	/*  don't need long long */