[PATCH V2] MIPS/PCI: Let Loongson-3 pci_ops access extended config space

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Original Loongson-3 pci_ops can only access standard pci config space,
this patch let it be able to access extended pci config space.

Signed-off-by: Huacai Chen <chenhc@xxxxxxxxxx>
---
 arch/mips/pci/ops-loongson3.c | 34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/arch/mips/pci/ops-loongson3.c b/arch/mips/pci/ops-loongson3.c
index 9e11843..9588769 100644
--- a/arch/mips/pci/ops-loongson3.c
+++ b/arch/mips/pci/ops-loongson3.c
@@ -17,24 +17,36 @@ static int loongson3_pci_config_access(unsigned char access_type,
 		struct pci_bus *bus, unsigned int devfn,
 		int where, u32 *data)
 {
-	unsigned char busnum = bus->number;
-	u_int64_t addr, type;
+	u_int64_t addr;
 	void *addrp;
+	unsigned char busnum = bus->number;
 	int device = PCI_SLOT(devfn);
 	int function = PCI_FUNC(devfn);
 	int reg = where & ~3;
 
-	addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
-	if (busnum == 0) {
-		if (device > 31)
+	if (where < PCI_CFG_SPACE_SIZE) { /* standard config */
+		addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
+		if (busnum == 0) {
+			if (device > 31)
+				return PCIBIOS_DEVICE_NOT_FOUND;
+			addrp = (void *)TO_UNCAC(HT1LO_PCICFG_BASE | addr);
+		} else {
+			addrp = (void *)TO_UNCAC(HT1LO_PCICFG_BASE_TP1 | addr);
+		}
+	} else if (where < PCI_CFG_SPACE_EXP_SIZE) {  /* extended config */
+		struct pci_dev *rootdev;
+
+		rootdev = pci_get_domain_bus_and_slot(0, 0, 0);
+		if (!rootdev)
 			return PCIBIOS_DEVICE_NOT_FOUND;
-		addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE) | (addr & 0xffff));
-		type = 0;
 
-	} else {
-		addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE_TP1) | (addr));
-		type = 0x10000;
-	}
+		addr = pci_resource_start(rootdev, 3);
+		if (!addr)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+		addrp = (void *)TO_UNCAC(addr | busnum << 20 | device << 15 | function << 12 | reg);
+	} else
+		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	if (access_type == PCI_ACCESS_WRITE)
 		writel(*data, addrp);
-- 
2.7.0



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux