diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-05-09 05:35:27 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-05-09 05:35:27 -0400 |
commit | ca3dd88e411648c76e1911a729440e3763ba5049 (patch) | |
tree | e874ed0c1e91269aa514a443358d4f3738bcb244 /arch/sparc64/kernel/pci_psycho.c | |
parent | de372ecd80a42c4fb485c7232475301a18d05184 (diff) |
[SPARC64] PCI: Consolidate PCI access code into pci_common.c
All the sun4u controllers do the same thing to compute the physical
I/O address to poke, and we can move the sun4v code into this common
location too.
This one needs a bit of testing, in particular the Sabre code had some
funny stuff that would break up u16 and/or u32 accesses into pieces
and I didn't think that was needed any more. If it is we need to find
out why and add back code to do it again.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci_psycho.c')
-rw-r--r-- | arch/sparc64/kernel/pci_psycho.c | 119 |
1 files changed, 2 insertions, 117 deletions
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 2edcb1dd13c3..598393a2df16 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c | |||
@@ -94,122 +94,6 @@ static void *psycho_pci_config_mkaddr(struct pci_pbm_info *pbm, | |||
94 | PSYCHO_CONFIG_ENCODE(bus, devfn, where)); | 94 | PSYCHO_CONFIG_ENCODE(bus, devfn, where)); |
95 | } | 95 | } |
96 | 96 | ||
97 | static int psycho_out_of_range(struct pci_pbm_info *pbm, | ||
98 | unsigned char bus, | ||
99 | unsigned char devfn) | ||
100 | { | ||
101 | return ((bus == pbm->pci_first_busno) && | ||
102 | PCI_SLOT(devfn) > 8); | ||
103 | } | ||
104 | |||
105 | /* PSYCHO PCI configuration space accessors. */ | ||
106 | |||
107 | static int psycho_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
108 | int where, int size, u32 *value) | ||
109 | { | ||
110 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
111 | unsigned char bus = bus_dev->number; | ||
112 | u32 *addr; | ||
113 | u16 tmp16; | ||
114 | u8 tmp8; | ||
115 | |||
116 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
117 | return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, | ||
118 | size, value); | ||
119 | |||
120 | switch (size) { | ||
121 | case 1: | ||
122 | *value = 0xff; | ||
123 | break; | ||
124 | case 2: | ||
125 | *value = 0xffff; | ||
126 | break; | ||
127 | case 4: | ||
128 | *value = 0xffffffff; | ||
129 | break; | ||
130 | } | ||
131 | |||
132 | addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where); | ||
133 | if (!addr) | ||
134 | return PCIBIOS_SUCCESSFUL; | ||
135 | |||
136 | if (psycho_out_of_range(pbm, bus, devfn)) | ||
137 | return PCIBIOS_SUCCESSFUL; | ||
138 | switch (size) { | ||
139 | case 1: | ||
140 | pci_config_read8((u8 *)addr, &tmp8); | ||
141 | *value = (u32) tmp8; | ||
142 | break; | ||
143 | |||
144 | case 2: | ||
145 | if (where & 0x01) { | ||
146 | printk("pci_read_config_word: misaligned reg [%x]\n", | ||
147 | where); | ||
148 | return PCIBIOS_SUCCESSFUL; | ||
149 | } | ||
150 | pci_config_read16((u16 *)addr, &tmp16); | ||
151 | *value = (u32) tmp16; | ||
152 | break; | ||
153 | |||
154 | case 4: | ||
155 | if (where & 0x03) { | ||
156 | printk("pci_read_config_dword: misaligned reg [%x]\n", | ||
157 | where); | ||
158 | return PCIBIOS_SUCCESSFUL; | ||
159 | } | ||
160 | pci_config_read32(addr, value); | ||
161 | break; | ||
162 | } | ||
163 | return PCIBIOS_SUCCESSFUL; | ||
164 | } | ||
165 | |||
166 | static int psycho_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | ||
167 | int where, int size, u32 value) | ||
168 | { | ||
169 | struct pci_pbm_info *pbm = bus_dev->sysdata; | ||
170 | unsigned char bus = bus_dev->number; | ||
171 | u32 *addr; | ||
172 | |||
173 | if (bus_dev == pbm->pci_bus && devfn == 0x00) | ||
174 | return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, | ||
175 | size, value); | ||
176 | addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where); | ||
177 | if (!addr) | ||
178 | return PCIBIOS_SUCCESSFUL; | ||
179 | |||
180 | if (psycho_out_of_range(pbm, bus, devfn)) | ||
181 | return PCIBIOS_SUCCESSFUL; | ||
182 | |||
183 | switch (size) { | ||
184 | case 1: | ||
185 | pci_config_write8((u8 *)addr, value); | ||
186 | break; | ||
187 | |||
188 | case 2: | ||
189 | if (where & 0x01) { | ||
190 | printk("pci_write_config_word: misaligned reg [%x]\n", | ||
191 | where); | ||
192 | return PCIBIOS_SUCCESSFUL; | ||
193 | } | ||
194 | pci_config_write16((u16 *)addr, value); | ||
195 | break; | ||
196 | |||
197 | case 4: | ||
198 | if (where & 0x03) { | ||
199 | printk("pci_write_config_dword: misaligned reg [%x]\n", | ||
200 | where); | ||
201 | return PCIBIOS_SUCCESSFUL; | ||
202 | } | ||
203 | pci_config_write32(addr, value); | ||
204 | } | ||
205 | return PCIBIOS_SUCCESSFUL; | ||
206 | } | ||
207 | |||
208 | static struct pci_ops psycho_ops = { | ||
209 | .read = psycho_read_pci_cfg, | ||
210 | .write = psycho_write_pci_cfg, | ||
211 | }; | ||
212 | |||
213 | /* PSYCHO error handling support. */ | 97 | /* PSYCHO error handling support. */ |
214 | enum psycho_error_type { | 98 | enum psycho_error_type { |
215 | UE_ERR, CE_ERR, PCI_ERR | 99 | UE_ERR, CE_ERR, PCI_ERR |
@@ -1089,7 +973,8 @@ static void psycho_pbm_init(struct pci_controller_info *p, | |||
1089 | pci_pbm_root = pbm; | 973 | pci_pbm_root = pbm; |
1090 | 974 | ||
1091 | pbm->scan_bus = psycho_scan_bus; | 975 | pbm->scan_bus = psycho_scan_bus; |
1092 | pbm->pci_ops = &psycho_ops; | 976 | pbm->pci_ops = &sun4u_pci_ops; |
977 | pbm->config_space_reg_bits = 8; | ||
1093 | 978 | ||
1094 | pbm->index = pci_num_pbms++; | 979 | pbm->index = pci_num_pbms++; |
1095 | 980 | ||