summaryrefslogtreecommitdiffstats
path: root/target/linux/cns3xxx/patches-3.14/120-backport_pcie_topology_fix.patch
blob: 4f68e6fb14aa1f7dd9d31c3adcdcb4aff453b770 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
--- a/arch/arm/mach-cns3xxx/pcie.c
+++ b/arch/arm/mach-cns3xxx/pcie.c
@@ -71,7 +71,7 @@ static void __iomem *cns3xxx_pci_cfg_bas
 	void __iomem *base;
 
 	/* If there is no link, just show the CNS PCI bridge. */
-	if (!cnspci->linked && (busno > 0 || slot > 0))
+	if (!cnspci->linked && (busno > 0))
 		return NULL;
 
 	/*
@@ -80,15 +80,19 @@ static void __iomem *cns3xxx_pci_cfg_bas
 	 * the first device on the same bus as the CNS PCI bridge.
 	 */
 	if (busno == 0) {
-		if (slot > 1)
+		type = CNS3XXX_HOST_TYPE;
+		if (devfn)
+			return NULL;
+	} else if (busno == 1) {
+		type = CNS3XXX_CFG0_TYPE;
+		if (slot)
 			return NULL;
-		type = slot;
 	} else {
 		type = CNS3XXX_CFG1_TYPE;
 	}
 
 	base = (void __iomem *)cnspci->cfg_bases[type].virtual;
-	offset = ((busno & 0xf) << 20) | (devfn << 12) | (where & 0xffc);
+	offset = (devfn << 12) | (where & 0xffc);
 
 	return base + offset;
 }
@@ -256,7 +260,7 @@ static struct pci_ops cns3xxx_pcie_ops =
 static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 	struct cns3xxx_pcie *cnspci = pdev_to_cnspci(dev);
-	int irq = cnspci->irqs[slot+pin-1];
+	int irq = cnspci->irqs[!!dev->bus->number+pin-1];
 
 	pr_info("PCIe map irq: %04d:%02x:%02x.%02x slot %d, pin %d, irq: %d\n",
 		pci_domain_nr(dev->bus), dev->bus->number, PCI_SLOT(dev->devfn),
@@ -434,7 +438,8 @@ static void __init cns3xxx_pcie_hw_init(
 		return;
 
 	/* Set Device Max_Read_Request_Size to 128 byte */
-	devfn = PCI_DEVFN(1, 0);
+	bus.number = 1;
+	devfn = PCI_DEVFN(0, 0);
 	pos = pci_bus_find_capability(&bus, devfn, PCI_CAP_ID_EXP);
 	pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc);
 	dc &= ~(0x3 << 12);	/* Clear Device Control Register [14:12] */