2 * $Id: pci.c,v 1.60 1999/09/08 03:04:07 cort Exp $
3 * Common pmac/prep/chrp pci routines. -- Cort
6 #include <linux/kernel.h>
8 #include <linux/delay.h>
9 #include <linux/string.h>
10 #include <linux/init.h>
11 #include <linux/config.h>
12 #include <linux/openpic.h>
14 #include <asm/processor.h>
17 #include <asm/pci-bridge.h>
18 #include <asm/residual.h>
19 #include <asm/byteorder.h>
25 static void __init
pcibios_claim_resources(struct pci_bus
*);
27 unsigned long isa_io_base
= 0;
28 unsigned long isa_mem_base
= 0;
29 unsigned long pci_dram_offset
= 0;
31 struct pci_fixup pcibios_fixups
[] = {
35 int generic_pcibios_read_byte(struct pci_dev
*dev
, int where
, u8
*val
)
37 return ppc_md
.pcibios_read_config_byte(dev
->bus
->number
,dev
->devfn
,where
,val
);
39 int generic_pcibios_read_word(struct pci_dev
*dev
, int where
, u16
*val
)
41 return ppc_md
.pcibios_read_config_word(dev
->bus
->number
,dev
->devfn
,where
,val
);
43 int generic_pcibios_read_dword(struct pci_dev
*dev
, int where
, u32
*val
)
45 return ppc_md
.pcibios_read_config_dword(dev
->bus
->number
,dev
->devfn
,where
,val
);
47 int generic_pcibios_write_byte(struct pci_dev
*dev
, int where
, u8 val
)
49 return ppc_md
.pcibios_write_config_byte(dev
->bus
->number
,dev
->devfn
,where
,val
);
51 int generic_pcibios_write_word(struct pci_dev
*dev
, int where
, u16 val
)
53 return ppc_md
.pcibios_write_config_word(dev
->bus
->number
,dev
->devfn
,where
,val
);
55 int generic_pcibios_write_dword(struct pci_dev
*dev
, int where
, u32 val
)
57 return ppc_md
.pcibios_write_config_dword(dev
->bus
->number
,dev
->devfn
,where
,val
);
60 struct pci_ops generic_pci_ops
=
62 generic_pcibios_read_byte
,
63 generic_pcibios_read_word
,
64 generic_pcibios_read_dword
,
65 generic_pcibios_write_byte
,
66 generic_pcibios_write_word
,
67 generic_pcibios_write_dword
70 void __init
pcibios_init(void)
72 printk("PCI: Probing PCI hardware\n");
73 ioport_resource
.end
= ~0L;
74 pci_scan_bus(0, &generic_pci_ops
, NULL
);
75 pcibios_claim_resources(pci_root
);
76 if ( ppc_md
.pcibios_fixup
)
77 ppc_md
.pcibios_fixup();
80 static void __init
pcibios_claim_resources(struct pci_bus
*bus
)
87 for (dev
=bus
->devices
; dev
; dev
=dev
->sibling
)
89 for (idx
= 0; idx
< PCI_NUM_RESOURCES
; idx
++)
91 struct resource
*r
= &dev
->resource
[idx
];
95 pr
= pci_find_parent_resource(dev
, r
);
96 if (!pr
|| request_resource(pr
, r
) < 0)
98 printk(KERN_ERR
"PCI: Address space collision on region %d of device %s\n", idx
, dev
->name
);
99 /* We probably should disable the region, shouldn't we? */
104 pcibios_claim_resources(bus
->children
);
109 void __init
pcibios_fixup_bus(struct pci_bus
*bus
)
111 if ( ppc_md
.pcibios_fixup_bus
)
112 ppc_md
.pcibios_fixup_bus(bus
);
115 char __init
*pcibios_setup(char *str
)
121 /* Recursively searches any node that is of type PCI-PCI bridge. Without
122 * this, the old code would miss children of P2P bridges and hence not
123 * fix IRQ's for cards located behind P2P bridges.
124 * - Ranjit Deshpande, 01/20/99
126 void __init
fix_intr(struct device_node
*node
, struct pci_dev
*dev
)
128 unsigned int *reg
, *class_code
;
130 for (; node
!= 0;node
= node
->sibling
) {
131 class_code
= (unsigned int *) get_property(node
, "class-code", 0);
132 if((*class_code
>> 8) == PCI_CLASS_BRIDGE_PCI
)
133 fix_intr(node
->child
, dev
);
134 reg
= (unsigned int *) get_property(node
, "reg", 0);
135 if (reg
== 0 || ((reg
[0] >> 8) & 0xff) != dev
->devfn
)
137 /* this is the node, see if it has interrupts */
138 if (node
->n_intrs
> 0)
139 dev
->irq
= node
->intrs
[0].line
;
145 int pcibios_assign_resource(struct pci_dev
*pdev
, int resource
)