diff options
author | Myles Watson <mylesgw@gmail.com> | 2010-06-17 16:16:56 +0000 |
---|---|---|
committer | Myles Watson <mylesgw@gmail.com> | 2010-06-17 16:16:56 +0000 |
commit | 7eac4450b32f6961d5abd8dae32c5eefc1a07c11 (patch) | |
tree | 455e0181fea42d7c6bab09878ef35dc666789977 /src/devices | |
parent | e10757ed525cdd1a5263b9d79e284310c999c0f7 (diff) | |
download | coreboot-7eac4450b32f6961d5abd8dae32c5eefc1a07c11.tar.xz |
Always enable parent resources before child resources.
Always initialize parents before children.
Move s2881 code into a driver.
Signed-off-by: Myles Watson <mylesgw@gmail.com>
Acked-by: Peter Stuge <peter@stuge.se>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@5633 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/devices')
-rw-r--r-- | src/devices/cardbus_device.c | 2 | ||||
-rw-r--r-- | src/devices/device.c | 105 | ||||
-rw-r--r-- | src/devices/pci_device.c | 1 | ||||
-rw-r--r-- | src/devices/root_device.c | 37 |
4 files changed, 78 insertions, 67 deletions
diff --git a/src/devices/cardbus_device.c b/src/devices/cardbus_device.c index fab0a3afc2..ccd78eb414 100644 --- a/src/devices/cardbus_device.c +++ b/src/devices/cardbus_device.c @@ -170,8 +170,6 @@ void cardbus_enable_resources(device_t dev) pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl); pci_dev_enable_resources(dev); - - enable_childrens_resources(dev); } struct device_operations default_cardbus_ops_bus = { diff --git a/src/devices/device.c b/src/devices/device.c index 2a05a30fc1..79d22109d4 100644 --- a/src/devices/device.c +++ b/src/devices/device.c @@ -782,33 +782,34 @@ void assign_resources(struct bus *bus) } /** - * @brief Enable the resources for a specific device + * @brief Enable the resources for devices on a link * - * @param dev the device whose resources are to be enabled + * @param link the link whose devices' resources are to be enabled * * Enable resources of the device by calling the device specific * enable_resources() method. * * The parent's resources should be enabled first to avoid having enabling * order problem. This is done by calling the parent's enable_resources() - * method and let that method to call it's children's enable_resoruces() - * method via the (global) enable_childrens_resources(). + * method before its childrens' enable_resources() methods. * - * Indirect mutual recursion: - * enable_resources() -> device_operations::enable_resource() - * device_operations::enable_resource() -> enable_children_resources() - * enable_children_resources() -> enable_resources() */ -void enable_resources(struct device *dev) +static void enable_resources(struct bus *link) { - if (!dev->enabled) { - return; + struct device *dev; + struct bus *c_link; + + for (dev = link->children; dev; dev = dev->sibling) { + if (dev->enabled && dev->ops && dev->ops->enable_resources) { + dev->ops->enable_resources(dev); + } } - if (!dev->ops || !dev->ops->enable_resources) { - printk(BIOS_ERR, "%s missing enable_resources\n", dev_path(dev)); - return; + + 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); + } } - dev->ops->enable_resources(dev); } /** @@ -1036,39 +1037,77 @@ void dev_configure(void) */ void dev_enable(void) { + struct bus *link; + printk(BIOS_INFO, "Enabling resources...\n"); /* now enable everything. */ - enable_resources(&dev_root); + for (link = dev_root.link_list; link; link = link->next) + enable_resources(link); printk(BIOS_INFO, "done.\n"); } /** - * @brief Initialize all devices in the global device list. + * @brief Initialize a specific device + * + * @param dev the device to be initialized + * + * The parent should be initialized first to avoid having an ordering + * problem. This is done by calling the parent's init() + * method before its childrens' init() methods. * - * Starting at the first device on the global device link list, - * walk the list and call the device's init() method to do deivce - * specific setup. */ -void dev_initialize(void) +static void init_dev(struct device *dev) +{ + if (!dev->enabled) { + return; + } + + if (!dev->initialized && dev->ops && dev->ops->init) { + 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, "%s init\n", dev_path(dev)); + dev->initialized = 1; + dev->ops->init(dev); + } +} + +static void init_link(struct bus *link) { struct device *dev; + struct bus *c_link; - printk(BIOS_INFO, "Initializing devices...\n"); - for (dev = all_devices; dev; dev = dev->next) { - if (dev->enabled && !dev->initialized && - dev->ops && dev->ops->init) { - 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, "%s init\n", dev_path(dev)); - dev->initialized = 1; - dev->ops->init(dev); + for (dev = link->children; dev; dev = dev->sibling) { + 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); } } +} + +/** + * @brief Initialize all devices in the global device tree. + * + * Starting at the root device, call the device's init() method to do device- + * specific setup, then call each child's init() method. + */ +void dev_initialize(void) +{ + struct bus *link; + + printk(BIOS_INFO, "Initializing devices...\n"); + + /* now initialize everything. */ + for (link = dev_root.link_list; link; link = link->next) + init_link(link); + printk(BIOS_INFO, "Devices initialized\n"); show_all_devs(BIOS_SPEW, "After init."); } diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c index e6cebcaae6..4a9fa1466e 100644 --- a/src/devices/pci_device.c +++ b/src/devices/pci_device.c @@ -621,7 +621,6 @@ void pci_bus_enable_resources(struct device *dev) pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl); pci_dev_enable_resources(dev); - enable_childrens_resources(dev); } void pci_bus_reset(struct bus *bus) diff --git a/src/devices/root_device.c b/src/devices/root_device.c index a77b5c8b62..cd576a15b6 100644 --- a/src/devices/root_device.c +++ b/src/devices/root_device.c @@ -32,7 +32,7 @@ * that encompass the resources for the entire system. * @param root Pointer to the device structure for the system root device */ -void root_dev_read_resources(device_t root) +static void root_dev_read_resources(device_t root) { printk(BIOS_ERR, "%s should never be called.\n", __func__); } @@ -44,7 +44,7 @@ void root_dev_read_resources(device_t root) * and every device under it which are all of the devices. * @param root Pointer to the device structure for the system root device */ -void root_dev_set_resources(device_t root) +static void root_dev_set_resources(device_t root) { printk(BIOS_ERR, "%s should never be called.\n", __func__); } @@ -115,33 +115,8 @@ unsigned int scan_static_bus(device_t bus, unsigned int max) return max; } -/** - * @brief Enable resources for children devices - * - * @param dev the device whos children's resources are to be enabled - * - * This function is called by the global enable_resource() indirectly via the - * device_operation::enable_resources() method of devices. - * - * Indirect mutual recursion: - * enable_childrens_resources() -> enable_resources() - * enable_resources() -> device_operation::enable_resources() - * device_operation::enable_resources() -> enable_children_resources() - */ -void enable_childrens_resources(device_t dev) -{ - struct bus *link; - for(link = dev->link_list; link; link = link->next) { - device_t child; - for(child = link->children; child; child = child->sibling) { - enable_resources(child); - } - } -} - -void root_dev_enable_resources(device_t dev) +static void root_dev_enable_resources(device_t dev) { - enable_childrens_resources(dev); } /** @@ -152,16 +127,16 @@ void root_dev_enable_resources(device_t dev) * * This function is the default scan_bus() method of the root device. */ -unsigned int root_dev_scan_bus(device_t root, unsigned int max) +static unsigned int root_dev_scan_bus(device_t root, unsigned int max) { return scan_static_bus(root, max); } -void root_dev_init(device_t root) +static void root_dev_init(device_t root) { } -void root_dev_reset(struct bus *bus) +static void root_dev_reset(struct bus *bus) { printk(BIOS_INFO, "Reseting board...\n"); hard_reset(); |