arch/powerpc/kernel/pci_of_scan.c

Source file repositories/reference/linux-study-clean/arch/powerpc/kernel/pci_of_scan.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/kernel/pci_of_scan.c
Extension
.c
Size
13368 bytes
Lines
455
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
		} else if (i == dev->rom_base_reg) {
			res = &dev->resource[PCI_ROM_RESOURCE];
			flags |= IORESOURCE_READONLY;
		} else {
			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
			continue;
		}
		res->flags = flags;
		if (mark_unset)
			res->flags |= IORESOURCE_UNSET;
		res->name = pci_name(dev);
		region.start = base;
		region.end = base + size - 1;
		pcibios_bus_to_resource(dev->bus, res, &region);
	}
}

/**
 * of_create_pci_dev - Given a device tree node on a pci bus, create a pci_dev
 * @node: device tree node pointer
 * @bus: bus the device is sitting on
 * @devfn: PCI function number, extracted from device tree by caller.
 */
struct pci_dev *of_create_pci_dev(struct device_node *node,
				 struct pci_bus *bus, int devfn)
{
	struct pci_dev *dev;

	dev = pci_alloc_dev(bus);
	if (!dev)
		return NULL;

	pr_debug("    create device, devfn: %x, type: %s\n", devfn,
		 of_node_get_device_type(node));

	dev->dev.of_node = of_node_get(node);
	dev->dev.parent = bus->bridge;
	dev->dev.bus = &pci_bus_type;
	dev->devfn = devfn;
	dev->multifunction = 0;		/* maybe a lie? */
	dev->needs_freset = 0;		/* pcie fundamental reset required */
	set_pcie_port_type(dev);

	pci_dev_assign_slot(dev);
	dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
	dev->device = get_int_prop(node, "device-id", 0xffff);
	dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
	dev->subsystem_device = get_int_prop(node, "subsystem-id", 0);

	dev->cfg_size = pci_cfg_space_size(dev);

	dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(bus),
		dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
	dev->class = get_int_prop(node, "class-code", 0);
	dev->revision = get_int_prop(node, "revision-id", 0);

	pr_debug("    class: 0x%x\n", dev->class);
	pr_debug("    revision: 0x%x\n", dev->revision);

	dev->current_state = PCI_UNKNOWN;	/* unknown power state */
	dev->error_state = pci_channel_io_normal;
	dev->dma_mask = 0xffffffff;

	/*
	 * Assume 64-bit addresses for MSI initially. Will be changed to 32-bit
	 * if MSI (rather than MSI-X) capability does not have
	 * PCI_MSI_FLAGS_64BIT. Can also be overridden by driver.
	 */
	dev->msi_addr_mask = DMA_BIT_MASK(64);

	/* Early fixups, before probing the BARs */
	pci_fixup_device(pci_fixup_early, dev);

	if (of_node_is_type(node, "pci") || of_node_is_type(node, "pciex")) {
		/* a PCI-PCI bridge */
		dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
		dev->rom_base_reg = PCI_ROM_ADDRESS1;
		set_pcie_hotplug_bridge(dev);
	} else if (of_node_is_type(node, "cardbus")) {
		dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
	} else {
		dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
		dev->rom_base_reg = PCI_ROM_ADDRESS;
		/* Maybe do a default OF mapping here */
		dev->irq = 0;
	}

	of_pci_parse_addrs(node, dev);

Annotation

Implementation Notes