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>
This commit is contained in:
committed by
Felix Held
parent
27ce0ec2b6
commit
80c79a5dc3
@@ -187,13 +187,11 @@ static void read_resources(struct bus *bus)
|
||||
{
|
||||
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 @@ static void read_resources(struct bus *bus)
|
||||
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 @@ void assign_resources(struct bus *bus)
|
||||
{
|
||||
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 @@ void assign_resources(struct bus *bus)
|
||||
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 @@ void assign_resources(struct bus *bus)
|
||||
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 @@ static void enable_resources(struct bus *link)
|
||||
}
|
||||
|
||||
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 @@ static void scan_bus(struct device *busdev)
|
||||
|
||||
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_configure(void)
|
||||
*/
|
||||
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 @@ static void init_dev(struct device *dev)
|
||||
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_dev(struct device *dev)
|
||||
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 @@ static void init_link(struct bus *link)
|
||||
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 @@ static void init_link(struct bus *link)
|
||||
*/
|
||||
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_dev(struct device *dev)
|
||||
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 @@ static void final_link(struct bus *link)
|
||||
*/
|
||||
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");
|
||||
}
|
||||
|
@@ -560,16 +560,9 @@ void search_bus_resources(struct bus *bus, unsigned long type_mask,
|
||||
|
||||
/* 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 @@ void disable_children(struct bus *bus)
|
||||
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 @@ void disable_children(struct bus *bus)
|
||||
*/
|
||||
bool dev_is_active_bridge(struct device *dev)
|
||||
{
|
||||
struct bus *link;
|
||||
struct device *child;
|
||||
|
||||
if (!dev || !dev->enabled)
|
||||
@@ -646,71 +637,20 @@ bool dev_is_active_bridge(struct device *dev)
|
||||
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 @@ static void resource_tree(const struct device *root, int debug_level, int depth)
|
||||
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 @@ void show_devs_tree(const struct device *dev, int debug_level, int depth)
|
||||
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 @@ void show_devs_tree(const struct device *dev, int debug_level, int depth)
|
||||
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)
|
||||
|
@@ -713,16 +713,13 @@ static void pci_set_resource(struct device *dev, struct resource *resource)
|
||||
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);
|
||||
|
@@ -38,31 +38,27 @@ void enable_static_device(struct device *dev)
|
||||
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_smbus(struct device *bus)
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
Reference in New Issue
Block a user