unsigned long pci_probe_only = 1;
int pci_assign_all_buses = 0;
+static int pci_initial_scan_done;
static void fixup_resource(struct resource *res, struct pci_dev *dev);
static void do_bus_setup(struct pci_bus *bus);
LIST_HEAD(hose_list);
-struct dma_mapping_ops *pci_dma_ops;
-EXPORT_SYMBOL(pci_dma_ops);
+static struct dma_mapping_ops *pci_dma_ops;
int global_phb_number; /* Global phb counter */
struct pci_dev *ppc64_isabridge_dev = NULL;
EXPORT_SYMBOL_GPL(ppc64_isabridge_dev);
+void set_pci_dma_ops(struct dma_mapping_ops *dma_ops)
+{
+ pci_dma_ops = dma_ops;
+}
+
+struct dma_mapping_ops *get_pci_dma_ops(void)
+{
+ return pci_dma_ops;
+}
+EXPORT_SYMBOL(get_pci_dma_ops);
+
static void fixup_broken_pcnet32(struct pci_dev* dev)
{
if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
const u32 *prop;
int len;
- prop = get_property(np, name, &len);
+ prop = of_get_property(np, name, &len);
if (prop && len >= 4)
return *prop;
return def;
u32 i;
int proplen;
- addrs = get_property(node, "assigned-addresses", &proplen);
+ addrs = of_get_property(node, "assigned-addresses", &proplen);
if (!addrs)
return;
DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs);
struct pci_dev *dev;
const char *type;
- dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
+ dev = alloc_pci_dev();
if (!dev)
return NULL;
- type = get_property(node, "device_type", NULL);
+ type = of_get_property(node, "device_type", NULL);
if (type == NULL)
type = "";
while ((child = of_get_next_child(node, child)) != NULL) {
DBG(" * %s\n", child->full_name);
- reg = get_property(child, "reg", ®len);
+ reg = of_get_property(child, "reg", ®len);
if (reg == NULL || reglen < 20)
continue;
devfn = (reg[0] >> 8) & 0xff;
DBG("of_scan_pci_bridge(%s)\n", node->full_name);
/* parse bus-range property */
- busrange = get_property(node, "bus-range", &len);
+ busrange = of_get_property(node, "bus-range", &len);
if (busrange == NULL || len != 8) {
printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
node->full_name);
return;
}
- ranges = get_property(node, "ranges", &len);
+ ranges = of_get_property(node, "ranges", &len);
if (ranges == NULL) {
printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
node->full_name);
/* map in PCI I/O space */
phbs_remap_io();
+ pci_initial_scan_done = 1;
+
printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
return 0;
unsigned int size;
int rlen = 0;
- range = get_property(isa_node, "ranges", &rlen);
+ range = of_get_property(isa_node, "ranges", &rlen);
if (range == NULL || (rlen < sizeof(struct isa_range))) {
printk(KERN_ERR "no ISA ranges or unexpected isa range size,"
"mapping 64k\n");
int rlen = 0;
int memno = 0;
struct resource *res;
- int np, na = prom_n_addr_cells(dev);
+ int np, na = of_n_addr_cells(dev);
unsigned long pci_addr, cpu_phys_addr;
np = na + 5;
* (size depending on dev->n_addr_cells)
* cells 4+5 or 5+6: the size of the range
*/
- ranges = get_property(dev, "ranges", &rlen);
+ ranges = of_get_property(dev, "ranges", &rlen);
if (ranges == NULL)
return;
hose->io_base_phys = 0;
switch ((pci_space >> 24) & 0x3) {
case 1: /* I/O space */
- hose->io_base_phys = cpu_phys_addr;
- hose->pci_io_size = size;
+ hose->io_base_phys = cpu_phys_addr - pci_addr;
+ /* handle from 0 to top of I/O window */
+ hose->pci_io_size = pci_addr + size;
res = &hose->io_resource;
res->flags = IORESOURCE_IO;
}
}
-void __init pci_setup_phb_io(struct pci_controller *hose, int primary)
+void __devinit pci_setup_phb_io(struct pci_controller *hose, int primary)
{
unsigned long size = hose->pci_io_size;
unsigned long io_virt_offset;
struct resource *res;
struct device_node *isa_dn;
+ if (size == 0)
+ return;
+
hose->io_base_virt = reserve_phb_iospace(size);
DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
hose->global_number, hose->io_base_phys,
res = &hose->io_resource;
res->start += io_virt_offset;
res->end += io_virt_offset;
+
+ /* If this is called after the initial PCI scan, then we need to
+ * proceed to IO mappings now
+ */
+ if (pci_initial_scan_done)
+ __ioremap_explicit(hose->io_base_phys,
+ (unsigned long)hose->io_base_virt,
+ hose->pci_io_size,
+ _PAGE_NO_CACHE | _PAGE_GUARDED);
}
void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose,
unsigned long io_virt_offset;
struct resource *res;
+ if (size == 0)
+ return;
+
hose->io_base_virt = __ioremap(hose->io_base_phys, size,
_PAGE_NO_CACHE | _PAGE_GUARDED);
DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
unsigned long *start_virt, unsigned long *size)
{
struct pci_controller *hose = pci_bus_to_host(bus);
- struct pci_bus_region region;
struct resource *res;
- if (bus->self) {
+ if (bus->self)
res = bus->resource[0];
- pcibios_resource_to_bus(bus->self, ®ion, res);
- *start_phys = hose->io_base_phys + region.start;
- *start_virt = (unsigned long) hose->io_base_virt +
- region.start;
- if (region.end > region.start)
- *size = region.end - region.start + 1;
- else {
- printk("%s(): unexpected region 0x%lx->0x%lx\n",
- __FUNCTION__, region.start, region.end);
- return 1;
- }
-
- } else {
+ else
/* Root Bus */
res = &hose->io_resource;
- *start_phys = hose->io_base_phys;
- *start_virt = (unsigned long) hose->io_base_virt;
- if (res->end > res->start)
- *size = res->end - res->start + 1;
- else {
- printk("%s(): unexpected region 0x%lx->0x%lx\n",
- __FUNCTION__, res->start, res->end);
- return 1;
- }
+
+ if (res->end == 0 && res->start == 0)
+ return 1;
+
+ *start_virt = pci_io_base + res->start;
+ *start_phys = *start_virt + hose->io_base_phys
+ - (unsigned long) hose->io_base_virt;
+
+ if (res->end > res->start)
+ *size = res->end - res->start + 1;
+ else {
+ printk("%s(): unexpected region 0x%lx->0x%lx\n",
+ __FUNCTION__, res->start, res->end);
+ return 1;
}
return 0;