Skip to content

Commit 0e4c2ee

Browse files
Lorenzo Pieralisibjorn-helgaas
authored andcommitted
alpha/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks
The pci_fixup_irqs() function allocates IRQs for all PCI devices present in a system; those PCI devices possibly belong to different PCI bus trees (and possibly rooted at different host bridges) and may well be enabled (ie probed and bound to a driver) by the time pci_fixup_irqs() is called when probing a given host bridge driver. Furthermore, current kernel code relying on pci_fixup_irqs() to assign legacy PCI IRQs to devices does not work at all for hotplugged devices in that the code carrying out the IRQ fixup is called at host bridge driver probe time, which just cannot take into account devices hotplugged after the system has booted. The introduction of map/swizzle function hooks in struct pci_host_bridge allows us to define per-bridge map/swizzle functions that can be used at device probe time in PCI core code to allocate IRQs for a given device (through pci_assign_irq()). Convert PCI host bridge initialization code to the pci_scan_root_bus_bridge() API (that allows to pass a struct pci_host_bridge with initialized map/swizzle pointers) and remove the pci_fixup_irqs() call from arch code. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
1 parent 20d6932 commit 0e4c2ee

File tree

2 files changed

+47
-11
lines changed

2 files changed

+47
-11
lines changed

arch/alpha/kernel/pci.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,9 @@ common_init_pci(void)
312312
{
313313
struct pci_controller *hose;
314314
struct list_head resources;
315+
struct pci_host_bridge *bridge;
315316
struct pci_bus *bus;
316-
int next_busno;
317+
int ret, next_busno;
317318
int need_domain_info = 0;
318319
u32 pci_mem_end;
319320
u32 sg_base;
@@ -336,11 +337,25 @@ common_init_pci(void)
336337
pci_add_resource_offset(&resources, hose->mem_space,
337338
hose->mem_space->start);
338339

339-
bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops,
340-
hose, &resources);
341-
if (!bus)
340+
bridge = pci_alloc_host_bridge(0);
341+
if (!bridge)
342342
continue;
343-
hose->bus = bus;
343+
344+
list_splice_init(&resources, &bridge->windows);
345+
bridge->dev.parent = NULL;
346+
bridge->sysdata = hose;
347+
bridge->busnr = next_busno;
348+
bridge->ops = alpha_mv.pci_ops;
349+
bridge->swizzle_irq = alpha_mv.pci_swizzle;
350+
bridge->map_irq = alpha_mv.pci_map_irq;
351+
352+
ret = pci_scan_root_bus_bridge(bridge);
353+
if (ret) {
354+
pci_free_host_bridge(bridge);
355+
continue;
356+
}
357+
358+
bus = hose->bus = bridge->bus;
344359
hose->need_domain_info = need_domain_info;
345360
next_busno = bus->busn_res.end + 1;
346361
/* Don't allow 8-bit bus number overflow inside the hose -
@@ -354,15 +369,13 @@ common_init_pci(void)
354369
pcibios_claim_console_setup();
355370

356371
pci_assign_unassigned_resources();
357-
pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
358372
for (hose = hose_head; hose; hose = hose->next) {
359373
bus = hose->bus;
360374
if (bus)
361375
pci_bus_add_devices(bus);
362376
}
363377
}
364378

365-
366379
struct pci_controller * __init
367380
alloc_pci_controller(void)
368381
{

arch/alpha/kernel/sys_nautilus.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,22 +194,46 @@ static struct resource irongate_mem = {
194194
.name = "Irongate PCI MEM",
195195
.flags = IORESOURCE_MEM,
196196
};
197+
static struct resource busn_resource = {
198+
.name = "PCI busn",
199+
.start = 0,
200+
.end = 255,
201+
.flags = IORESOURCE_BUS,
202+
};
197203

198204
void __init
199205
nautilus_init_pci(void)
200206
{
201207
struct pci_controller *hose = hose_head;
208+
struct pci_host_bridge *bridge;
202209
struct pci_bus *bus;
203210
struct pci_dev *irongate;
204211
unsigned long bus_align, bus_size, pci_mem;
205212
unsigned long memtop = max_low_pfn << PAGE_SHIFT;
213+
int ret;
214+
215+
bridge = pci_alloc_host_bridge(0);
216+
if (!bridge)
217+
return;
218+
219+
pci_add_resource(&bridge->windows, &ioport_resource);
220+
pci_add_resource(&bridge->windows, &iomem_resource);
221+
pci_add_resource(&bridge->windows, &busn_resource);
222+
bridge->dev.parent = NULL;
223+
bridge->sysdata = hose;
224+
bridge->busnr = 0;
225+
bridge->ops = alpha_mv.pci_ops;
226+
bridge->swizzle_irq = alpha_mv.pci_swizzle;
227+
bridge->map_irq = alpha_mv.pci_map_irq;
206228

207229
/* Scan our single hose. */
208-
bus = pci_scan_bus(0, alpha_mv.pci_ops, hose);
209-
if (!bus)
230+
ret = pci_scan_root_bus_bridge(bridge);
231+
if (ret) {
232+
pci_free_host_bridge(bridge);
210233
return;
234+
}
211235

212-
hose->bus = bus;
236+
bus = hose->bus = bridge->bus;
213237
pcibios_claim_one_bus(bus);
214238

215239
irongate = pci_get_bus_and_slot(0, 0);
@@ -254,7 +278,6 @@ nautilus_init_pci(void)
254278
/* pci_common_swizzle() relies on bus->self being NULL
255279
for the root bus, so just clear it. */
256280
bus->self = NULL;
257-
pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
258281
pci_bus_add_devices(bus);
259282
}
260283

0 commit comments

Comments
 (0)