diff options
author | Rojhalat Ibrahim <imr@rtschenk.de> | 2013-06-17 10:02:41 -0400 |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2013-06-24 17:54:09 -0400 |
commit | b37e161388ac3980d5dfb73050e85874b84253eb (patch) | |
tree | 49216c3a8c311009d5d85db41c7844a69d6548e6 | |
parent | 17858ca65eef148d335ffd4cfc09228a1c1cbfb5 (diff) |
powerpc/pci: Fix boot panic on mpc83xx (regression)
The following commit caused a fatal oops when booting on mpc83xx with
a non-express PCI bus (regardless of whether a PCI device is present):
commit 50d8f87d2b39313dae9d0a2d9b23d377328f2f7b
Author: Rojhalat Ibrahim <imr@rtschenk.de>
Date: Mon Apr 8 10:15:28 2013 +0200
powerpc/fsl-pci Make PCIe hotplug work with Freescale PCIe controllers
Up to now the PCIe link status on Freescale PCIe controllers was only
checked once at boot time. So hotplug did not work. With this patch the
link status is checked on every config read. PCIe devices not present at
boot time are found after doing 'echo 1 >/sys/bus/pci/rescan'.
Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
This patch fixes the issue by calling setup_indirect_pci for all device types.
fsl_indirect_read_config is now only used for booke/86xx PCIe controllers.
Reported-by: Michael Guntsche <mike@it-loops.com>
Cc: Scott Wood <scottwood@freescale.com>
Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de>
Signed-off-by: Scott Wood <scottwood@freescale.com>
-rw-r--r-- | arch/powerpc/sysdev/fsl_pci.c | 24 |
1 files changed, 9 insertions, 15 deletions
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 028ac1f71b51..46ac1ddea683 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
@@ -97,22 +97,14 @@ static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn, | |||
97 | return indirect_read_config(bus, devfn, offset, len, val); | 97 | return indirect_read_config(bus, devfn, offset, len, val); |
98 | } | 98 | } |
99 | 99 | ||
100 | static struct pci_ops fsl_indirect_pci_ops = | 100 | #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx) |
101 | |||
102 | static struct pci_ops fsl_indirect_pcie_ops = | ||
101 | { | 103 | { |
102 | .read = fsl_indirect_read_config, | 104 | .read = fsl_indirect_read_config, |
103 | .write = indirect_write_config, | 105 | .write = indirect_write_config, |
104 | }; | 106 | }; |
105 | 107 | ||
106 | static void __init fsl_setup_indirect_pci(struct pci_controller* hose, | ||
107 | resource_size_t cfg_addr, | ||
108 | resource_size_t cfg_data, u32 flags) | ||
109 | { | ||
110 | setup_indirect_pci(hose, cfg_addr, cfg_data, flags); | ||
111 | hose->ops = &fsl_indirect_pci_ops; | ||
112 | } | ||
113 | |||
114 | #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx) | ||
115 | |||
116 | #define MAX_PHYS_ADDR_BITS 40 | 108 | #define MAX_PHYS_ADDR_BITS 40 |
117 | static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS; | 109 | static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS; |
118 | 110 | ||
@@ -504,13 +496,15 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary) | |||
504 | if (!hose->private_data) | 496 | if (!hose->private_data) |
505 | goto no_bridge; | 497 | goto no_bridge; |
506 | 498 | ||
507 | fsl_setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, | 499 | setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, |
508 | PPC_INDIRECT_TYPE_BIG_ENDIAN); | 500 | PPC_INDIRECT_TYPE_BIG_ENDIAN); |
509 | 501 | ||
510 | if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0) | 502 | if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0) |
511 | hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK; | 503 | hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK; |
512 | 504 | ||
513 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { | 505 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { |
506 | /* use fsl_indirect_read_config for PCIe */ | ||
507 | hose->ops = &fsl_indirect_pcie_ops; | ||
514 | /* For PCIE read HEADER_TYPE to identify controler mode */ | 508 | /* For PCIE read HEADER_TYPE to identify controler mode */ |
515 | early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type); | 509 | early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type); |
516 | if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) | 510 | if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) |
@@ -814,8 +808,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev) | |||
814 | if (ret) | 808 | if (ret) |
815 | goto err0; | 809 | goto err0; |
816 | } else { | 810 | } else { |
817 | fsl_setup_indirect_pci(hose, rsrc_cfg.start, | 811 | setup_indirect_pci(hose, rsrc_cfg.start, |
818 | rsrc_cfg.start + 4, 0); | 812 | rsrc_cfg.start + 4, 0); |
819 | } | 813 | } |
820 | 814 | ||
821 | printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. " | 815 | printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. " |