|
@@ -38,15 +38,15 @@ static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
|
|
|
|
|
|
static void __devinit quirk_fsl_pcie_header(struct pci_dev *dev)
|
|
|
{
|
|
|
- u8 progif;
|
|
|
+ u8 hdr_type;
|
|
|
|
|
|
/* if we aren't a PCIe don't bother */
|
|
|
if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
|
|
|
return;
|
|
|
|
|
|
/* if we aren't in host mode don't bother */
|
|
|
- pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
|
|
|
- if (progif & 0x1)
|
|
|
+ pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type);
|
|
|
+ if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
|
|
|
return;
|
|
|
|
|
|
dev->class = PCI_CLASS_BRIDGE_PCI << 8;
|
|
@@ -427,7 +427,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
|
|
|
struct pci_controller *hose;
|
|
|
struct resource rsrc;
|
|
|
const int *bus_range;
|
|
|
- u8 progif;
|
|
|
+ u8 hdr_type, progif;
|
|
|
|
|
|
if (!of_device_is_available(dev)) {
|
|
|
pr_warning("%s: disabled\n", dev->full_name);
|
|
@@ -459,15 +459,17 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
|
|
|
setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
|
|
|
PPC_INDIRECT_TYPE_BIG_ENDIAN);
|
|
|
|
|
|
- early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
|
|
|
- if ((progif & 1) == 1) {
|
|
|
- /* unmap cfg_data & cfg_addr separately if not on same page */
|
|
|
- if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
|
|
|
- ((unsigned long)hose->cfg_addr & PAGE_MASK))
|
|
|
- iounmap(hose->cfg_data);
|
|
|
- iounmap(hose->cfg_addr);
|
|
|
- pcibios_free_controller(hose);
|
|
|
- return -ENODEV;
|
|
|
+ if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
|
|
|
+ /* For PCIE read HEADER_TYPE to identify controler mode */
|
|
|
+ early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type);
|
|
|
+ if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
|
|
|
+ goto no_bridge;
|
|
|
+
|
|
|
+ } else {
|
|
|
+ /* For PCI read PROG to identify controller mode */
|
|
|
+ early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
|
|
|
+ if ((progif & 1) == 1)
|
|
|
+ goto no_bridge;
|
|
|
}
|
|
|
|
|
|
setup_pci_cmd(hose);
|
|
@@ -496,6 +498,15 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
|
|
|
setup_pci_atmu(hose, &rsrc);
|
|
|
|
|
|
return 0;
|
|
|
+
|
|
|
+no_bridge:
|
|
|
+ /* unmap cfg_data & cfg_addr separately if not on same page */
|
|
|
+ if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
|
|
|
+ ((unsigned long)hose->cfg_addr & PAGE_MASK))
|
|
|
+ iounmap(hose->cfg_data);
|
|
|
+ iounmap(hose->cfg_addr);
|
|
|
+ pcibios_free_controller(hose);
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
|
|
|
|