Moving the setup of PCI devices to within a new-device...finish-device sequence as part of the conversion further enables us to move the PCI host bridge configuration logic from ob_pci_init() to ob_configure_pci_device() where it belongs.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/pci.c | 87 ++++++++++++++++++++++----------------------------- 1 file changed, 37 insertions(+), 50 deletions(-)
diff --git a/drivers/pci.c b/drivers/pci.c index 60e3948..0b74ff8 100644 --- a/drivers/pci.c +++ b/drivers/pci.c @@ -528,7 +528,9 @@ static void pci_set_bus_range(const pci_config_t *config) set_property(dev, "bus-range", (char *)props, 2 * sizeof(props[0])); }
-static void pci_host_set_reg(phandle_t phandle) +static void ob_pci_reload_device_path(phandle_t phandle, pci_config_t *config); + +static void pci_host_set_reg(phandle_t phandle, pci_config_t *config) { phandle_t dev = phandle;
@@ -544,6 +546,8 @@ static void pci_host_set_reg(phandle_t phandle)
set_property(dev, "reg", (char *)props, ncells * sizeof(props[0]));
+ ob_pci_reload_device_path(dev, config); + #if defined(CONFIG_DEBUG_PCI) dump_reg_property("pci_host_set_reg", 4, props); #endif @@ -579,8 +583,6 @@ static void pci_host_set_ranges(const pci_config_t *config)
int host_config_cb(const pci_config_t *config) { - //XXX this overrides "reg" property - pci_host_set_reg(get_cur_dev()); pci_host_set_ranges(config);
return 0; @@ -1276,17 +1278,13 @@ static void ob_pci_add_properties(phandle_t phandle, /**/ if (pci_dev->name) { push_str(pci_dev->name); - fword("encode-string"); - push_str("name"); - fword("property"); + fword("device-name"); } else { char path[256]; snprintf(path, sizeof(path), "pci%x,%x", vendor_id, device_id); push_str(path); - fword("encode-string"); - push_str("name"); - fword("property"); + fword("device-name"); } } else { PCI_DPRINTF("*** missing pci_dev\n"); @@ -1335,15 +1333,11 @@ static void ob_pci_add_properties(phandle_t phandle, if (pci_dev) { if (pci_dev->type) { push_str(pci_dev->type); - fword("encode-string"); - push_str("device_type"); - fword("property"); + fword("device-type"); } if (pci_dev->model) { push_str(pci_dev->model); - fword("encode-string"); - push_str("model"); - fword("property"); + fword("model"); } if (pci_dev->compat) set_property(dev, "compatible", @@ -1765,7 +1759,7 @@ static phandle_t ob_configure_pci_device(const char* parent_path, uint8_t class, subclass, iface; int num_bars, rom_bar;
- phandle_t phandle = 0; + phandle_t phandle = 0, t; int is_host_bridge = 0;
if (!ob_pci_read_identification(bus, devnum, fn, &vid, &did, &class, &subclass)) { @@ -1789,54 +1783,52 @@ static phandle_t ob_configure_pci_device(const char* parent_path, } }
- /* stop adding host bridge accessible from it's primary bus - PCI host bridge is to be added by host code - */ if (class == PCI_BASE_CLASS_BRIDGE && subclass == PCI_SUBCLASS_BRIDGE_HOST) { is_host_bridge = 1; }
+ /* stop adding host bridge accessible from it's primary bus + PCI host bridge is to be added by host code + */ if (is_host_bridge) { /* reuse device tree node */ PCI_DPRINTF("host bridge found - "); - snprintf(config.path, sizeof(config.path), - "%s", parent_path); + + t = find_dev(parent_path); + if (get_property(t, "vendor-id", NULL)) { + PCI_DPRINTF("host bridge already configured\n"); + return 0; + } } else if (pci_dev == NULL || pci_dev->name == NULL) { snprintf(config.path, sizeof(config.path), "%s/pci%x,%x", parent_path, vid, did); - } - else { + } else { snprintf(config.path, sizeof(config.path), "%s/%s", parent_path, pci_dev->name); }
+ fword("new-device"); + PCI_DPRINTF("%s - ", config.path);
config.dev = addr & 0x00FFFFFF;
+ phandle = get_cur_dev(); + switch (class) { case PCI_BASE_CLASS_BRIDGE: if (subclass != PCI_SUBCLASS_BRIDGE_HOST) { - REGISTER_NAMED_NODE_PHANDLE(ob_pci_bridge_node, config.path, phandle); + BIND_NODE_METHODS(phandle, ob_pci_bridge_node); + } else { + BIND_NODE_METHODS(phandle, ob_pci_bus_node); } break; default: - REGISTER_NAMED_NODE_PHANDLE(ob_pci_empty_node, config.path, phandle); + BIND_NODE_METHODS(phandle, ob_pci_empty_node); break; }
- if (is_host_bridge) { - phandle = find_dev(config.path); - - if (get_property(phandle, "vendor-id", NULL)) { - PCI_DPRINTF("host bridge already configured\n"); - return 0; - } - } - - activate_dev(phandle); - if (htype & PCI_HEADER_TYPE_BRIDGE) { num_bars = 2; rom_bar = PCI_ROM_ADDRESS1; @@ -1852,6 +1844,8 @@ static phandle_t ob_configure_pci_device(const char* parent_path,
if (!is_host_bridge) { pci_set_reg(phandle, &config, num_bars); + } else { + pci_host_set_reg(phandle, &config); }
/* call device-specific configuration callback */ @@ -1862,12 +1856,9 @@ static phandle_t ob_configure_pci_device(const char* parent_path,
/* if devices haven't supplied open/close words then supply them with simple defaults */ if (!find_package_method("open", phandle) && !find_package_method("close", phandle)) { - REGISTER_NODE_METHODS(ob_pci_simple_node, config.path); + BIND_NODE_METHODS(phandle, ob_pci_simple_node); }
- /* device is configured so we may move it out of scope */ - device_end(); - /* scan bus behind bridge device */ //if (htype & PCI_HEADER_TYPE_BRIDGE && class == PCI_BASE_CLASS_BRIDGE) { if ( class == PCI_BASE_CLASS_BRIDGE && @@ -1882,6 +1873,8 @@ static phandle_t ob_configure_pci_device(const char* parent_path, ob_configure_pci_bridge(addr, bus_num, mem_base, io_base, bus, &config); }
+ fword("finish-device"); + return phandle; }
@@ -2103,7 +2096,8 @@ int ob_pci_init(void)
PCI_DPRINTF("Initializing PCI host bridge...\n");
- activate_device("/"); + push_str("/"); + fword("find-device");
/* Find all PCI bridges */
@@ -2130,16 +2124,9 @@ int ob_pci_init(void) /* create root node for host PCI bridge */
/* configure */ - snprintf(config.path, sizeof(config.path), "/pci"); - - REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle_host); - - pci_host_set_reg(phandle_host); - - /* update device path after changing "reg" property */ - ob_pci_reload_device_path(phandle_host, &config); + strncpy(config.path, "", sizeof(config.path));
- ob_configure_pci_device(config.path, &bus, &mem_base, &io_base, + phandle_host = ob_configure_pci_device(config.path, &bus, &mem_base, &io_base, bus, devnum, fn, 0);
/* we expect single host PCI bridge