From 12e86f92fcfe4f0bcab0ad7fa4088a64c60d9b38 Mon Sep 17 00:00:00 2001
From: Paul Mackerras <paulus@samba.org>
Date: Thu, 8 Feb 2007 15:02:35 +1100
Subject: [PATCH] [POWERPC] Only use H_BULK_REMOVE if the firmware supports it

The previous patch changing pSeries to use H_BULK_REMOVE broke the
JS20 blade, where the firmware doesn't support H_BULK_REMOVE.  This
adds a firmware check so that on machines that don't have H_BULK_REMOVE,
we just use the H_REMOVE call as before.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 arch/powerpc/platforms/pseries/firmware.c |  1 +
 arch/powerpc/platforms/pseries/lpar.c     | 22 ++++++++++++++--------
 include/asm-powerpc/firmware.h            |  1 +
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index 1c7b2baa5f73..90522e3c9d46 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -59,6 +59,7 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
 	{FW_FEATURE_XDABR,		"hcall-xdabr"},
 	{FW_FEATURE_MULTITCE,		"hcall-multi-tce"},
 	{FW_FEATURE_SPLPAR,		"hcall-splpar"},
+	{FW_FEATURE_BULK_REMOVE,	"hcall-bulk"},
 };
 
 /* Build up the firmware features bitmask using the contents of
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 5a684fbd8f27..7496005566ef 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -516,7 +516,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
 static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
 {
 	unsigned long i, pix, rc;
-	unsigned long flags;
+	unsigned long flags = 0;
 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
 	int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
 	unsigned long param[9];
@@ -540,16 +540,22 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
 				hash = ~hash;
 			slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 			slot += hidx & _PTEIDX_GROUP_IX;
-			param[pix] = HBR_REQUEST | HBR_AVPN | slot;
-			param[pix+1] = hpte_encode_v(va, psize) & HPTE_V_AVPN;
-			pix += 2;
-			if (pix == 8) {
-				rc = plpar_hcall9(H_BULK_REMOVE, param,
+			if (!firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
+				pSeries_lpar_hpte_invalidate(slot, va, psize,
+							     local);
+			} else {
+				param[pix] = HBR_REQUEST | HBR_AVPN | slot;
+				param[pix+1] = hpte_encode_v(va, psize) &
+					HPTE_V_AVPN;
+				pix += 2;
+				if (pix == 8) {
+					rc = plpar_hcall9(H_BULK_REMOVE, param,
 						param[0], param[1], param[2],
 						param[3], param[4], param[5],
 						param[6], param[7]);
-				BUG_ON(rc != H_SUCCESS);
-				pix = 0;
+					BUG_ON(rc != H_SUCCESS);
+					pix = 0;
+				}
 			}
 		} pte_iterate_hashed_end();
 	}
diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h
index abba808cc53c..3671c128f271 100644
--- a/include/asm-powerpc/firmware.h
+++ b/include/asm-powerpc/firmware.h
@@ -44,6 +44,7 @@
 #define FW_FEATURE_LPAR		ASM_CONST(0x0000000000400000)
 #define FW_FEATURE_PS3_LV1	ASM_CONST(0x0000000000800000)
 #define FW_FEATURE_BEAT		ASM_CONST(0x0000000001000000)
+#define FW_FEATURE_BULK_REMOVE	ASM_CONST(0x0000000002000000)
 
 #ifndef __ASSEMBLY__
 
-- 
GitLab