Skip to content

Commit 37f0219

Browse files
Yuanquan Chenmpe
authored andcommitted
powerpc/pci: fix PCI-e devices rescan issue on powerpc platform
Powerpc initializes the DMA and IRQ information in pci_scan_child_bus()-> pcibios_fixup_bus()->pcibios_setup_bus_devices(). But for the devices which are hotpluged, bus->is added has been set for the first scan of the PCI-e bus, so the initialization code won't be called. Then the hotpluged devices' driver will fail to load. For example : The PCI-e device 0001:03:00.0 is the Intel PCI-e e1000e network card, remove it from the system: # echo 1 > /sys/bus/pci/devices/0001\:03\:00.0/remove # e1000e 0001:03:00.0 eth0: removed PHC Rescan it from it's bus: # echo 1 > /sys/bus/pci/devices/0001\:02\:00.0/rescan ... e1000e 0001:03:00.0: Disabling ASPM L0s L1 e1000e 0001:03:00.0: No usable DMA configuration, aborting e1000e: probe of 0001:03:00.0 failed with error -5 So we move the DMA & IRQ initialization code from pcibios_setup_devices() and construct a new function pcibios_enable_device. We call this function in pcibios_enable_device, which will be called by PCI-e rescan code. At the meanwhile, we avoid the the impact on cardbus. I also validate this patch with silicon's PCIe-sata which encounters the IRQ issue. Signed-off-by: Yuanquan Chen <[email protected]> Cc: Benjamin Herrenschmidt <[email protected]> Cc: Hiroo Matsumoto <[email protected]> Signed-off-by: Michael Ellerman <[email protected]>
1 parent 55671f3 commit 37f0219

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

arch/powerpc/kernel/pci-common.c

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,27 @@ void pcibios_setup_bus_self(struct pci_bus *bus)
10231023
ppc_md.pci_dma_bus_setup(bus);
10241024
}
10251025

1026+
void pcibios_setup_device(struct pci_dev *dev)
1027+
{
1028+
/* Fixup NUMA node as it may not be setup yet by the generic
1029+
* code and is needed by the DMA init
1030+
*/
1031+
set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
1032+
1033+
/* Hook up default DMA ops */
1034+
set_dma_ops(&dev->dev, pci_dma_ops);
1035+
set_dma_offset(&dev->dev, PCI_DRAM_OFFSET);
1036+
1037+
/* Additional platform DMA/iommu setup */
1038+
if (ppc_md.pci_dma_dev_setup)
1039+
ppc_md.pci_dma_dev_setup(dev);
1040+
1041+
/* Read default IRQs and fixup if necessary */
1042+
pci_read_irq_line(dev);
1043+
if (ppc_md.pci_irq_fixup)
1044+
ppc_md.pci_irq_fixup(dev);
1045+
}
1046+
10261047
void pcibios_setup_bus_devices(struct pci_bus *bus)
10271048
{
10281049
struct pci_dev *dev;
@@ -1037,23 +1058,7 @@ void pcibios_setup_bus_devices(struct pci_bus *bus)
10371058
if (dev->is_added)
10381059
continue;
10391060

1040-
/* Fixup NUMA node as it may not be setup yet by the generic
1041-
* code and is needed by the DMA init
1042-
*/
1043-
set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
1044-
1045-
/* Hook up default DMA ops */
1046-
set_dma_ops(&dev->dev, pci_dma_ops);
1047-
set_dma_offset(&dev->dev, PCI_DRAM_OFFSET);
1048-
1049-
/* Additional platform DMA/iommu setup */
1050-
if (ppc_md.pci_dma_dev_setup)
1051-
ppc_md.pci_dma_dev_setup(dev);
1052-
1053-
/* Read default IRQs and fixup if necessary */
1054-
pci_read_irq_line(dev);
1055-
if (ppc_md.pci_irq_fixup)
1056-
ppc_md.pci_irq_fixup(dev);
1061+
pcibios_setup_device(dev);
10571062
}
10581063
}
10591064

@@ -1494,6 +1499,10 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
14941499
if (ppc_md.pcibios_enable_device_hook(dev))
14951500
return -EINVAL;
14961501

1502+
/* avoid pcie irq fix up impact on cardbus */
1503+
if (dev->hdr_type != PCI_HEADER_TYPE_CARDBUS)
1504+
pcibios_setup_device(dev);
1505+
14971506
return pci_enable_resources(dev, mask);
14981507
}
14991508

0 commit comments

Comments
 (0)