diff options
Diffstat (limited to 'arch/powerpc/sysdev/indirect_pci.c')
-rw-r--r-- | arch/powerpc/sysdev/indirect_pci.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/arch/powerpc/sysdev/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c index e71488469704..c7e6e859b393 100644 --- a/arch/powerpc/sysdev/indirect_pci.c +++ b/arch/powerpc/sysdev/indirect_pci.c | |||
@@ -33,18 +33,27 @@ indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | |||
33 | struct pci_controller *hose = bus->sysdata; | 33 | struct pci_controller *hose = bus->sysdata; |
34 | volatile void __iomem *cfg_data; | 34 | volatile void __iomem *cfg_data; |
35 | u8 cfg_type = 0; | 35 | u8 cfg_type = 0; |
36 | u32 bus_no, reg; | ||
36 | 37 | ||
37 | if (ppc_md.pci_exclude_device) | 38 | if (ppc_md.pci_exclude_device) |
38 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | 39 | if (ppc_md.pci_exclude_device(hose, bus->number, devfn)) |
39 | return PCIBIOS_DEVICE_NOT_FOUND; | 40 | return PCIBIOS_DEVICE_NOT_FOUND; |
40 | 41 | ||
41 | if (hose->set_cfg_type) | 42 | if (hose->indirect_type & PPC_INDIRECT_TYPE_SET_CFG_TYPE) |
42 | if (bus->number != hose->first_busno) | 43 | if (bus->number != hose->first_busno) |
43 | cfg_type = 1; | 44 | cfg_type = 1; |
44 | 45 | ||
45 | PCI_CFG_OUT(hose->cfg_addr, | 46 | bus_no = (bus->number == hose->first_busno) ? |
46 | (0x80000000 | ((bus->number - hose->bus_offset) << 16) | 47 | hose->self_busno : bus->number; |
47 | | (devfn << 8) | ((offset & 0xfc) | cfg_type))); | 48 | |
49 | if (hose->indirect_type & PPC_INDIRECT_TYPE_EXT_REG) | ||
50 | reg = ((offset & 0xf00) << 16) | (offset & 0xfc); | ||
51 | else | ||
52 | reg = offset & 0xfc; | ||
53 | |||
54 | PCI_CFG_OUT(hose->cfg_addr, | ||
55 | (0x80000000 | (bus_no << 16) | ||
56 | | (devfn << 8) | reg | cfg_type)); | ||
48 | 57 | ||
49 | /* | 58 | /* |
50 | * Note: the caller has already checked that offset is | 59 | * Note: the caller has already checked that offset is |
@@ -72,18 +81,33 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset, | |||
72 | struct pci_controller *hose = bus->sysdata; | 81 | struct pci_controller *hose = bus->sysdata; |
73 | volatile void __iomem *cfg_data; | 82 | volatile void __iomem *cfg_data; |
74 | u8 cfg_type = 0; | 83 | u8 cfg_type = 0; |
84 | u32 bus_no, reg; | ||
75 | 85 | ||
76 | if (ppc_md.pci_exclude_device) | 86 | if (ppc_md.pci_exclude_device) |
77 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | 87 | if (ppc_md.pci_exclude_device(hose, bus->number, devfn)) |
78 | return PCIBIOS_DEVICE_NOT_FOUND; | 88 | return PCIBIOS_DEVICE_NOT_FOUND; |
79 | 89 | ||
80 | if (hose->set_cfg_type) | 90 | if (hose->indirect_type & PPC_INDIRECT_TYPE_SET_CFG_TYPE) |
81 | if (bus->number != hose->first_busno) | 91 | if (bus->number != hose->first_busno) |
82 | cfg_type = 1; | 92 | cfg_type = 1; |
83 | 93 | ||
84 | PCI_CFG_OUT(hose->cfg_addr, | 94 | bus_no = (bus->number == hose->first_busno) ? |
85 | (0x80000000 | ((bus->number - hose->bus_offset) << 16) | 95 | hose->self_busno : bus->number; |
86 | | (devfn << 8) | ((offset & 0xfc) | cfg_type))); | 96 | |
97 | if (hose->indirect_type & PPC_INDIRECT_TYPE_EXT_REG) | ||
98 | reg = ((offset & 0xf00) << 16) | (offset & 0xfc); | ||
99 | else | ||
100 | reg = offset & 0xfc; | ||
101 | |||
102 | PCI_CFG_OUT(hose->cfg_addr, | ||
103 | (0x80000000 | (bus_no << 16) | ||
104 | | (devfn << 8) | reg | cfg_type)); | ||
105 | |||
106 | /* surpress setting of PCI_PRIMARY_BUS */ | ||
107 | if (hose->indirect_type & PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS) | ||
108 | if ((offset == PCI_PRIMARY_BUS) && | ||
109 | (bus->number == hose->first_busno)) | ||
110 | val &= 0xffffff00; | ||
87 | 111 | ||
88 | /* | 112 | /* |
89 | * Note: the caller has already checked that offset is | 113 | * Note: the caller has already checked that offset is |