diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 14:15:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 14:15:26 -0400 |
commit | 37577505ec6e67d550aa5fb452c7b45a093cc7f3 (patch) | |
tree | 44f22364883679308c51cae6ebb8d164ad3aa5d1 /arch/ia64/sn/kernel | |
parent | 04bbc8e1f68cf4c1aac8024d6aea1a24757e8a5a (diff) | |
parent | c4cbf6b96100bbcd5da6e38b3334901b2eaa25bf (diff) |
Merge tag 'please-pull-root_bus_hotplug' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux
Pull ia64 IOH hotplug fixes from Tony Luck:
"Series to fix IOH hotplug in ia64"
* tag 'please-pull-root_bus_hotplug' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux:
PCI: Replace printks with appropriate pr_*()
PCI/IA64: introduce probe_pci_root_info() to manage _CRS resource
PCI/IA64: Add host bridge resource release for _CRS path
PCI/IA64: fix memleak for create pci root bus fail
PCI/IA64: Allocate pci_root_info instead of using stack
PCI/IA64: embed pci hostbridge resources into pci_root_info
PCI/IA64: SN: use normal resource instead of pci_window
PCI/IA64: SN: remove sn_pci_window_fixup()
Diffstat (limited to 'arch/ia64/sn/kernel')
-rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 109 |
1 files changed, 26 insertions, 83 deletions
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 238e2c511d94..2b00adedc45e 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -118,76 +118,26 @@ static void __init sn_fixup_ionodes(void) | |||
118 | } | 118 | } |
119 | 119 | ||
120 | /* | 120 | /* |
121 | * sn_pci_legacy_window_fixup - Create PCI controller windows for | 121 | * sn_pci_legacy_window_fixup - Setup PCI resources for |
122 | * legacy IO and MEM space. This needs to | 122 | * legacy IO and MEM space. This needs to |
123 | * be done here, as the PROM does not have | 123 | * be done here, as the PROM does not have |
124 | * ACPI support defining the root buses | 124 | * ACPI support defining the root buses |
125 | * and their resources (_CRS), | 125 | * and their resources (_CRS), |
126 | */ | 126 | */ |
127 | static void | 127 | static void |
128 | sn_legacy_pci_window_fixup(struct pci_controller *controller, | 128 | sn_legacy_pci_window_fixup(struct resource *res, |
129 | u64 legacy_io, u64 legacy_mem) | 129 | u64 legacy_io, u64 legacy_mem) |
130 | { | 130 | { |
131 | controller->window = kcalloc(2, sizeof(struct pci_window), | 131 | res[0].name = "legacy_io"; |
132 | GFP_KERNEL); | 132 | res[0].flags = IORESOURCE_IO; |
133 | BUG_ON(controller->window == NULL); | 133 | res[0].start = legacy_io; |
134 | controller->window[0].offset = legacy_io; | 134 | res[0].end = res[0].start + 0xffff; |
135 | controller->window[0].resource.name = "legacy_io"; | 135 | res[0].parent = &ioport_resource; |
136 | controller->window[0].resource.flags = IORESOURCE_IO; | 136 | res[1].name = "legacy_mem"; |
137 | controller->window[0].resource.start = legacy_io; | 137 | res[1].flags = IORESOURCE_MEM; |
138 | controller->window[0].resource.end = | 138 | res[1].start = legacy_mem; |
139 | controller->window[0].resource.start + 0xffff; | 139 | res[1].end = res[1].start + (1024 * 1024) - 1; |
140 | controller->window[0].resource.parent = &ioport_resource; | 140 | res[1].parent = &iomem_resource; |
141 | controller->window[1].offset = legacy_mem; | ||
142 | controller->window[1].resource.name = "legacy_mem"; | ||
143 | controller->window[1].resource.flags = IORESOURCE_MEM; | ||
144 | controller->window[1].resource.start = legacy_mem; | ||
145 | controller->window[1].resource.end = | ||
146 | controller->window[1].resource.start + (1024 * 1024) - 1; | ||
147 | controller->window[1].resource.parent = &iomem_resource; | ||
148 | controller->windows = 2; | ||
149 | } | ||
150 | |||
151 | /* | ||
152 | * sn_pci_window_fixup() - Create a pci_window for each device resource. | ||
153 | * It will setup pci_windows for use by | ||
154 | * pcibios_bus_to_resource(), pcibios_resource_to_bus(), | ||
155 | * etc. | ||
156 | */ | ||
157 | static void | ||
158 | sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, | ||
159 | s64 * pci_addrs) | ||
160 | { | ||
161 | struct pci_controller *controller = PCI_CONTROLLER(dev->bus); | ||
162 | unsigned int i; | ||
163 | unsigned int idx; | ||
164 | unsigned int new_count; | ||
165 | struct pci_window *new_window; | ||
166 | |||
167 | if (count == 0) | ||
168 | return; | ||
169 | idx = controller->windows; | ||
170 | new_count = controller->windows + count; | ||
171 | new_window = kcalloc(new_count, sizeof(struct pci_window), GFP_KERNEL); | ||
172 | BUG_ON(new_window == NULL); | ||
173 | if (controller->window) { | ||
174 | memcpy(new_window, controller->window, | ||
175 | sizeof(struct pci_window) * controller->windows); | ||
176 | kfree(controller->window); | ||
177 | } | ||
178 | |||
179 | /* Setup a pci_window for each device resource. */ | ||
180 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
181 | if (pci_addrs[i] == -1) | ||
182 | continue; | ||
183 | |||
184 | new_window[idx].offset = dev->resource[i].start - pci_addrs[i]; | ||
185 | new_window[idx].resource = dev->resource[i]; | ||
186 | idx++; | ||
187 | } | ||
188 | |||
189 | controller->windows = new_count; | ||
190 | controller->window = new_window; | ||
191 | } | 141 | } |
192 | 142 | ||
193 | /* | 143 | /* |
@@ -199,9 +149,7 @@ sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, | |||
199 | void | 149 | void |
200 | sn_io_slot_fixup(struct pci_dev *dev) | 150 | sn_io_slot_fixup(struct pci_dev *dev) |
201 | { | 151 | { |
202 | unsigned int count = 0; | ||
203 | int idx; | 152 | int idx; |
204 | s64 pci_addrs[PCI_ROM_RESOURCE + 1]; | ||
205 | unsigned long addr, end, size, start; | 153 | unsigned long addr, end, size, start; |
206 | struct pcidev_info *pcidev_info; | 154 | struct pcidev_info *pcidev_info; |
207 | struct sn_irq_info *sn_irq_info; | 155 | struct sn_irq_info *sn_irq_info; |
@@ -229,7 +177,6 @@ sn_io_slot_fixup(struct pci_dev *dev) | |||
229 | for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { | 177 | for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { |
230 | 178 | ||
231 | if (!pcidev_info->pdi_pio_mapped_addr[idx]) { | 179 | if (!pcidev_info->pdi_pio_mapped_addr[idx]) { |
232 | pci_addrs[idx] = -1; | ||
233 | continue; | 180 | continue; |
234 | } | 181 | } |
235 | 182 | ||
@@ -237,11 +184,8 @@ sn_io_slot_fixup(struct pci_dev *dev) | |||
237 | end = dev->resource[idx].end; | 184 | end = dev->resource[idx].end; |
238 | size = end - start; | 185 | size = end - start; |
239 | if (size == 0) { | 186 | if (size == 0) { |
240 | pci_addrs[idx] = -1; | ||
241 | continue; | 187 | continue; |
242 | } | 188 | } |
243 | pci_addrs[idx] = start; | ||
244 | count++; | ||
245 | addr = pcidev_info->pdi_pio_mapped_addr[idx]; | 189 | addr = pcidev_info->pdi_pio_mapped_addr[idx]; |
246 | addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET; | 190 | addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET; |
247 | dev->resource[idx].start = addr; | 191 | dev->resource[idx].start = addr; |
@@ -276,11 +220,6 @@ sn_io_slot_fixup(struct pci_dev *dev) | |||
276 | IORESOURCE_ROM_BIOS_COPY; | 220 | IORESOURCE_ROM_BIOS_COPY; |
277 | } | 221 | } |
278 | } | 222 | } |
279 | /* Create a pci_window in the pci_controller struct for | ||
280 | * each device resource. | ||
281 | */ | ||
282 | if (count > 0) | ||
283 | sn_pci_window_fixup(dev, count, pci_addrs); | ||
284 | 223 | ||
285 | sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); | 224 | sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); |
286 | } | 225 | } |
@@ -297,8 +236,8 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
297 | s64 status = 0; | 236 | s64 status = 0; |
298 | struct pci_controller *controller; | 237 | struct pci_controller *controller; |
299 | struct pcibus_bussoft *prom_bussoft_ptr; | 238 | struct pcibus_bussoft *prom_bussoft_ptr; |
239 | struct resource *res; | ||
300 | LIST_HEAD(resources); | 240 | LIST_HEAD(resources); |
301 | int i; | ||
302 | 241 | ||
303 | status = sal_get_pcibus_info((u64) segment, (u64) busnum, | 242 | status = sal_get_pcibus_info((u64) segment, (u64) busnum, |
304 | (u64) ia64_tpa(&prom_bussoft_ptr)); | 243 | (u64) ia64_tpa(&prom_bussoft_ptr)); |
@@ -310,19 +249,23 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
310 | BUG_ON(!controller); | 249 | BUG_ON(!controller); |
311 | controller->segment = segment; | 250 | controller->segment = segment; |
312 | 251 | ||
252 | res = kcalloc(2, sizeof(struct resource), GFP_KERNEL); | ||
253 | BUG_ON(!res); | ||
254 | |||
313 | /* | 255 | /* |
314 | * Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup(). | 256 | * Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup(). |
315 | * (platform_data will be overwritten later in sn_common_bus_fixup()) | 257 | * (platform_data will be overwritten later in sn_common_bus_fixup()) |
316 | */ | 258 | */ |
317 | controller->platform_data = prom_bussoft_ptr; | 259 | controller->platform_data = prom_bussoft_ptr; |
318 | 260 | ||
319 | sn_legacy_pci_window_fixup(controller, | 261 | sn_legacy_pci_window_fixup(res, |
320 | prom_bussoft_ptr->bs_legacy_io, | 262 | prom_bussoft_ptr->bs_legacy_io, |
321 | prom_bussoft_ptr->bs_legacy_mem); | 263 | prom_bussoft_ptr->bs_legacy_mem); |
322 | for (i = 0; i < controller->windows; i++) | 264 | pci_add_resource_offset(&resources, &res[0], |
323 | pci_add_resource_offset(&resources, | 265 | prom_bussoft_ptr->bs_legacy_io); |
324 | &controller->window[i].resource, | 266 | pci_add_resource_offset(&resources, &res[1], |
325 | controller->window[i].offset); | 267 | prom_bussoft_ptr->bs_legacy_mem); |
268 | |||
326 | bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller, | 269 | bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller, |
327 | &resources); | 270 | &resources); |
328 | if (bus == NULL) | 271 | if (bus == NULL) |
@@ -333,7 +276,7 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
333 | return; | 276 | return; |
334 | 277 | ||
335 | error_return: | 278 | error_return: |
336 | 279 | kfree(res); | |
337 | kfree(controller); | 280 | kfree(controller); |
338 | return; | 281 | return; |
339 | } | 282 | } |