summaryrefslogtreecommitdiff
path: root/src/devices
diff options
context:
space:
mode:
authorMyles Watson <mylesgw@gmail.com>2010-06-17 16:16:56 +0000
committerMyles Watson <mylesgw@gmail.com>2010-06-17 16:16:56 +0000
commit7eac4450b32f6961d5abd8dae32c5eefc1a07c11 (patch)
tree455e0181fea42d7c6bab09878ef35dc666789977 /src/devices
parente10757ed525cdd1a5263b9d79e284310c999c0f7 (diff)
downloadcoreboot-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.c2
-rw-r--r--src/devices/device.c105
-rw-r--r--src/devices/pci_device.c1
-rw-r--r--src/devices/root_device.c37
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();