All pastes #182257 Raw Edit

Anonymous

public text v1 · immutable
#182257 ·published 2006-09-25 21:30 UTC
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);