aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorYuanquan Chen <Yuanquan.Chen@freescale.com>2013-04-01 21:26:54 -0400
committerMichael Ellerman <michael@ellerman.id.au>2013-04-18 01:59:57 -0400
commit37f02195bee9c25ce44e25204f40b7961a6d7c9d (patch)
tree1e89a6a728fa0a1a0ad874b96ae47cb08078ce60 /arch/powerpc/kernel
parent55671f3cc29c31681278b7782de4f6a4edb97a7e (diff)
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 <Yuanquan.Chen@freescale.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Hiroo Matsumoto <matsumoto.hiroo@jp.fujitsu.com> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/pci-common.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index fa12ae42d98c..032475851d6a 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1023,6 +1023,27 @@ void pcibios_setup_bus_self(struct pci_bus *bus)
1023 ppc_md.pci_dma_bus_setup(bus); 1023 ppc_md.pci_dma_bus_setup(bus);
1024} 1024}
1025 1025
1026void 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
1026void pcibios_setup_bus_devices(struct pci_bus *bus) 1047void pcibios_setup_bus_devices(struct pci_bus *bus)
1027{ 1048{
1028 struct pci_dev *dev; 1049 struct pci_dev *dev;
@@ -1037,23 +1058,7 @@ void pcibios_setup_bus_devices(struct pci_bus *bus)
1037 if (dev->is_added) 1058 if (dev->is_added)
1038 continue; 1059 continue;
1039 1060
1040 /* Fixup NUMA node as it may not be setup yet by the generic 1061 pcibios_setup_device(dev);
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);
1057 } 1062 }
1058} 1063}
1059 1064
@@ -1494,6 +1499,10 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
1494 if (ppc_md.pcibios_enable_device_hook(dev)) 1499 if (ppc_md.pcibios_enable_device_hook(dev))
1495 return -EINVAL; 1500 return -EINVAL;
1496 1501
1502 /* avoid pcie irq fix up impact on cardbus */
1503 if (dev->hdr_type != PCI_HEADER_TYPE_CARDBUS)
1504 pcibios_setup_device(dev);
1505
1497 return pci_enable_resources(dev, mask); 1506 return pci_enable_resources(dev, mask);
1498} 1507}
1499 1508