From: Philippe Bergheaud <felix@linux.vnet.ibm.com>
Subject: powerpc/pseries: fix regression on PCI link speed
Git-commit: b020cc6c03a37c3526fcb1dff274f649257949e0
Patch-mainline: v3.14-rc5
References: bnc#863310, fate#315275, LTC#92305
X-Patchwork-Id: 312070

Summary:     ## powerpc: add little-endian support
Description: ## Add little-endian support for POWER8.

Upstream-Description:

    Commit 5091f0c (powerpc/pseries: Fix PCIE link speed endian issue)
    introduced a regression on the PCI link speed detection using the
    device-tree property. The ibm,pcie-link-speed-stats property is composed
    of two 32-bit integers, the first one being the maxinum link speed and
    the second the current link speed. The changes introduced by the
    aforementioned commit are considering just the first integer.
    
    Fix this issue by changing how the property is accessed, using the
    helper functions to properly access the array of values. The explicit
    byte swapping is not needed anymore here, since it's done by the helper
    functions.
    
    Signed-off-by: Kleber Sacilotto de Souza <klebers@linux.vnet.ibm.com>

Signed-off-by: Philippe Bergheaud <felix@linux.vnet.ibm.com>
Acked-by: Torsten Duwe <duwe@suse.de>
---
arch/powerpc/platforms/pseries/pci.c |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index 70670a2..a6f7a14 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -113,7 +113,8 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge)
 {
 	struct device_node *dn, *pdn;
 	struct pci_bus *bus;
-	const __be32 *pcie_link_speed_stats;
+	u32 pcie_link_speed_stats[2];
+	int rc;
 
 	bus = bridge->bus;
 
@@ -122,20 +123,21 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge)
 		return 0;
 
 	for (pdn = dn; pdn != NULL; pdn = of_get_next_parent(pdn)) {
-		pcie_link_speed_stats = of_get_property(pdn,
-			"ibm,pcie-link-speed-stats", NULL);
-		if (pcie_link_speed_stats)
+		rc = of_property_read_u32_array(pdn,
+				"ibm,pcie-link-speed-stats",
+				&pcie_link_speed_stats[0], 2);
+		if (!rc)
 			break;
 	}
 
 	of_node_put(pdn);
 
-	if (!pcie_link_speed_stats) {
+	if (rc) {
 		pr_err("no ibm,pcie-link-speed-stats property\n");
 		return 0;
 	}
 
-	switch (be32_to_cpup(pcie_link_speed_stats)) {
+	switch (pcie_link_speed_stats[0]) {
 	case 0x01:
 		bus->max_bus_speed = PCIE_SPEED_2_5GT;
 		break;
@@ -147,7 +149,7 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge)
 		break;
 	}
 
-	switch (be32_to_cpup(pcie_link_speed_stats)) {
+	switch (pcie_link_speed_stats[1]) {
 	case 0x01:
 		bus->cur_bus_speed = PCIE_SPEED_2_5GT;
 		break;
