#include <linux/bootmem.h>
#include <linux/irq.h>
#include <linux/list.h>
+#include <linux/of.h>
#include <asm/processor.h>
#include <asm/io.h>
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CPC710_PCI64, fixup_cpc710_pci64);
-
-void __init
-update_bridge_resource(struct pci_dev *dev, struct resource *res)
-{
- u8 io_base_lo, io_limit_lo;
- u16 mem_base, mem_limit;
- u16 cmd;
- resource_size_t start, end, off;
- struct pci_controller *hose = dev->sysdata;
-
- if (!hose) {
- printk("update_bridge_base: no hose?\n");
- return;
- }
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- pci_write_config_word(dev, PCI_COMMAND,
- cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
- if (res->flags & IORESOURCE_IO) {
- off = (unsigned long) hose->io_base_virt - isa_io_base;
- start = res->start - off;
- end = res->end - off;
- io_base_lo = (start >> 8) & PCI_IO_RANGE_MASK;
- io_limit_lo = (end >> 8) & PCI_IO_RANGE_MASK;
- if (end > 0xffff)
- io_base_lo |= PCI_IO_RANGE_TYPE_32;
- else
- io_base_lo |= PCI_IO_RANGE_TYPE_16;
- pci_write_config_word(dev, PCI_IO_BASE_UPPER16,
- start >> 16);
- pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16,
- end >> 16);
- pci_write_config_byte(dev, PCI_IO_BASE, io_base_lo);
- pci_write_config_byte(dev, PCI_IO_LIMIT, io_limit_lo);
-
- } else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH))
- == IORESOURCE_MEM) {
- off = hose->pci_mem_offset;
- mem_base = ((res->start - off) >> 16) & PCI_MEMORY_RANGE_MASK;
- mem_limit = ((res->end - off) >> 16) & PCI_MEMORY_RANGE_MASK;
- pci_write_config_word(dev, PCI_MEMORY_BASE, mem_base);
- pci_write_config_word(dev, PCI_MEMORY_LIMIT, mem_limit);
-
- } else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH))
- == (IORESOURCE_MEM | IORESOURCE_PREFETCH)) {
- off = hose->pci_mem_offset;
- mem_base = ((res->start - off) >> 16) & PCI_PREF_RANGE_MASK;
- mem_limit = ((res->end - off) >> 16) & PCI_PREF_RANGE_MASK;
- pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, mem_base);
- pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, mem_limit);
-
- } else {
- DBG(KERN_ERR "PCI: ugh, bridge %s res has flags=%lx\n",
- pci_name(dev), res->flags);
- }
- pci_write_config_word(dev, PCI_COMMAND, cmd);
-}
-
-
#ifdef CONFIG_PPC_OF
/*
* Functions below are used on OpenFirmware machines.
} else
pci_to_OF_bus_map[pci_bus] = bus_range[0];
- for (node=node->child; node != 0;node = node->sibling) {
+ for_each_child_of_node(node, node) {
struct pci_dev* dev;
const unsigned int *class_code, *reg;
typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data);
static struct device_node*
-scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data)
+scan_OF_pci_childs(struct device_node *parent, pci_OF_scan_iterator filter, void* data)
{
+ struct device_node *node;
struct device_node* sub_node;
- for (; node != 0;node = node->sibling) {
+ for_each_child_of_node(parent, node) {
const unsigned int *class_code;
- if (filter(node, data))
+ if (filter(node, data)) {
+ of_node_put(node);
return node;
+ }
/* For PCI<->PCI bridges or CardBus bridges, we go down
* Note: some OFs create a parent node "multifunc-device" as
(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
strcmp(node->name, "multifunc-device"))
continue;
- sub_node = scan_OF_pci_childs(node->child, filter, data);
- if (sub_node)
+ sub_node = scan_OF_pci_childs(node, filter, data);
+ if (sub_node) {
+ of_node_put(node);
return sub_node;
+ }
}
return NULL;
}
static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,
unsigned int devfn)
{
- struct device_node *np = NULL;
+ struct device_node *np;
const u32 *reg;
unsigned int psize;
- while ((np = of_get_next_child(parent, np)) != NULL) {
+ for_each_child_of_node(parent, np) {
reg = of_get_property(np, "reg", &psize);
if (reg == NULL || psize < 4)
continue;
hose = pci_find_hose_for_OF_device(node);
if (!hose || !hose->dn)
return -ENODEV;
- if (!scan_OF_pci_childs(hose->dn->child,
+ if (!scan_OF_pci_childs(hose->dn,
find_OF_pci_device_filter, (void *)node))
return -ENODEV;
reg = of_get_property(node, "reg", NULL);
hose->last_busno = 0xff;
bus = pci_scan_bus_parented(hose->parent, hose->first_busno,
hose->ops, hose);
- if (bus)
+ if (bus) {
pci_bus_add_devices(bus);
- hose->last_busno = bus->subordinate;
+ hose->last_busno = bus->subordinate;
+ }
if (pci_assign_all_buses || next_busno <= hose->last_busno)
next_busno = hose->last_busno + pcibios_assign_bus_offset;
}
/* XXX FIXME - update OF device tree node interrupt property */
}
-int pcibios_enable_device(struct pci_dev *dev, int mask)
-{
- u16 cmd, old_cmd;
- int idx;
- struct resource *r;
-
- if (ppc_md.pcibios_enable_device_hook)
- if (ppc_md.pcibios_enable_device_hook(dev, 0))
- return -EINVAL;
-
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- old_cmd = cmd;
- for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
- /* Only set up the requested stuff */
- if (!(mask & (1 << idx)))
- continue;
- r = &dev->resource[idx];
- if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
- continue;
- if (r->flags & IORESOURCE_UNSET) {
- printk(KERN_ERR "PCI: Device %s not available because"
- " of resource collisions\n", pci_name(dev));
- return -EINVAL;
- }
- if (r->flags & IORESOURCE_IO)
- cmd |= PCI_COMMAND_IO;
- if (r->flags & IORESOURCE_MEM)
- cmd |= PCI_COMMAND_MEMORY;
- }
- if (cmd != old_cmd) {
- printk("PCI: Enabling device %s (%04x -> %04x)\n",
- pci_name(dev), old_cmd, cmd);
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- }
- return 0;
-}
-
static struct pci_controller*
pci_bus_to_hose(int bus)
{