diff options
author | Yuanquan Chen <Yuanquan.Chen@freescale.com> | 2013-04-01 21:26:54 -0400 |
---|---|---|
committer | Michael Ellerman <michael@ellerman.id.au> | 2013-04-18 01:59:57 -0400 |
commit | 37f02195bee9c25ce44e25204f40b7961a6d7c9d (patch) | |
tree | 1e89a6a728fa0a1a0ad874b96ae47cb08078ce60 /arch/powerpc/kernel | |
parent | 55671f3cc29c31681278b7782de4f6a4edb97a7e (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.c | 43 |
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 | ||
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 | |||
1026 | void pcibios_setup_bus_devices(struct pci_bus *bus) | 1047 | void 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 | ||