rendered paste body#include <linux/device.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/prom.h>
#include <asm/of_device.h>
#include <asm/ppc-pci.h>
static int of_soc_create_device_name(struct device_node *node, char *name)
{
const u32 *reg;
u64 addr;
reg = get_property(node, "dcr-reg", NULL);
if (reg) {
addr = of_translate_dcr_address(node, reg);
if (addr != OF_BAD_ADDR)
goto found_dcr;
}
reg = get_property(node, "reg", NULL);
if (reg) {
addr = of_translate_address(node, reg);
if (addr != OF_BAD_ADDR)
goto found;
}
return -EINVAL;
found_dcr:
sprintf(name, "D%lx.%s", addr, node->name);
return 0;
found:
sprintf(name, "%lx.%s", addr, node->name);
return 0;
}
static int of_soc_device_create(struct device_node *node, struct device *parent)
{
char name[BUS_ID_SIZE];
int ret;
ret = of_soc_create_device_name(node, name);
if (ret)
return ret;
of_platform_device_create(node, name, parent);
return 0;
}
static int of_soc_bus_probe(struct of_device *dev,
const struct of_device_id *match)
{
struct device_node *child;
int ret = -ENODEV;
for (child = NULL; (child = of_get_next_child(dev->node, child)); ) {
if (strcmp(child->type, "soc") == 0) {
ret = of_soc_device_create(child, &dev->dev);
if (ret)
break;
}
}
return ret;
}
static struct of_device_id of_soc_ids[] = {
{ .type = "soc", },
{},
};
static struct of_platform_driver of_soc_driver = {
.name = "soc",
.match_table = of_soc_ids,
.probe = of_soc_bus_probe,
};
static int of_pci_bus_probe(struct of_device *dev,
const struct of_device_id *match)
{
struct pci_controller *phb;
phb = pcibios_alloc_controller(dev->node);
if (!phb)
return -ENODEV;
setup_phb(dev->node, phb);
pci_process_bridge_OF_ranges(phb, dev->node, 0);
pci_setup_phb_io(phb, 0);
return 0;
}
static struct of_device_id of_pci_ids[] = {
{ .type = "pci", },
{ .type = "pcie", },
{ .type = "pciex", },
{ .type = "ht", },
{ .compatible = "pci", },
{ .compatible = "pcie", },
{ .compatible = "pciex", },
{ .compatible = "ht", },
};
static struct of_platform_driver of_pci_driver = {
.name = "pci",
.match_table = of_pci_ids,
.probe = of_pci_bus_probe,
};
static int of_soc_probe(void)
{
struct device_node *root, *child;
int ret;
root = of_find_node_by_name(NULL, "/");
ret = of_register_driver(&of_soc_driver);
if (ret)
goto out;
ret = of_register_driver(&of_pci_driver);
if (ret)
goto out2;
for (child = NULL; (child = of_get_next_child(root, child)); ) {
if (strcmp(child->type, "soc") == 0) {
ret = of_soc_device_create(child, NULL);
if (ret)
goto out3;
}
}
return 0;
out3:
of_unregister_driver(&of_soc_driver);
out2:
of_unregister_driver(&of_pci_driver);
out:
return ret;
}
__initcall(of_soc_probe);