[linux-yocto] [PATCH 14/35] arch/arm/mach-axxia: Check Status and Add Locks to NCR Accesses

Daniel Dragomir daniel.dragomir at windriver.com
Thu Nov 13 09:19:41 PST 2014


From: John Jacques <john.jacques at lsi.com>

Signed-off-by: John Jacques <john.jacques at lsi.com>
---
 arch/arm/mach-axxia/ncr.c | 73 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 64 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-axxia/ncr.c b/arch/arm/mach-axxia/ncr.c
index 51fcf66..995e8a0 100644
--- a/arch/arm/mach-axxia/ncr.c
+++ b/arch/arm/mach-axxia/ncr.c
@@ -40,6 +40,9 @@ static void __iomem *apb2ser0_address;
 
 #define WFC_TIMEOUT (400000)
 
+static DEFINE_RAW_SPINLOCK(ncr_spin_lock);
+static unsigned long flags;
+
 #define LOCK_DOMAIN 0
 
 typedef union {
@@ -170,15 +173,48 @@ ncr_lock(int domain)
 	unsigned long offset;
 	unsigned long value;
 	int loops = 10000;
+	command_data_register_0_t cdr0;
 
+	raw_spin_lock_irqsave(&ncr_spin_lock, flags);
 	offset = (0xff80 + (domain * 4));
 
 	do {
 		value = ncr_register_read((unsigned *)(nca_address + offset));
 	} while ((0 != value) && (0 < --loops));
 
-	if (0 == loops)
+	if (0 == loops) {
+		raw_spin_unlock_irqrestore(&ncr_spin_lock, flags);
+		printk(KERN_ERR "ncr_lock() Timeout!\n");
+		BUG();
+
+		return -1;
+	}
+
+	/*
+	  Make sure any previous commands completed, and check for errors.
+	*/
+
+	loops = 10000;
+
+	do {
+		--loops;
+		cdr0.raw =
+			ncr_register_read((unsigned *)(nca_address + 0xf0));
+	} while ((0x1 == cdr0.bits.status) &&
+		 (0 < loops));
+
+	if (0 == loops) {
+		raw_spin_unlock_irqrestore(&ncr_spin_lock, flags);
+		printk(KERN_ERR
+		       "ncr_lock() Previous command didn't complete!\n");
+		BUG();
+
 		return -1;
+	}
+
+	if (0x2 == cdr0.bits.status) {
+		printk(KERN_ERR "Previous ncr access failed!\n");
+	}
 
 	return 0;
 }
@@ -195,6 +231,7 @@ ncr_unlock(int domain)
 
 	offset = (0xff80 + (domain * 4));
 	ncr_register_write(0, (unsigned *)(nca_address + offset));
+	raw_spin_unlock_irqrestore(&ncr_spin_lock, flags);
 
 	return;
 }
@@ -264,12 +301,24 @@ ncr_read(unsigned long region, unsigned long address, int number,
 
 		do {
 			--wfc_timeout;
-		} while ((0x80000000UL ==
-				ncr_register_read((unsigned *)(nca_address + 0xf0))) &&
-				0 < wfc_timeout);
+			cdr0.raw =
+				ncr_register_read((unsigned *)
+						  (nca_address + 0xf0));
+		} while (1 == cdr0.bits.start_done && 0 < wfc_timeout);
 
 		if (0 == wfc_timeout) {
 			ncr_unlock(LOCK_DOMAIN);
+			printk(KERN_ERR "ncr_read() Timeout!\n");
+			BUG();
+
+			return -1;
+		}
+
+		if (0x3 != cdr0.bits.status) {
+			ncr_unlock(LOCK_DOMAIN);
+			printk(KERN_ERR "ncr_write() failed: 0x%x\n",
+			       cdr0.bits.status);
+
 			return -1;
 		}
 
@@ -459,12 +508,16 @@ ncr_write(unsigned long region, unsigned long address, int number,
 
 		do {
 			--wfc_timeout;
-		} while ((0x80000000UL ==
-				ncr_register_read((unsigned *)(nca_address + 0xf0))) &&
-				0 < wfc_timeout);
+			cdr0.raw =
+				ncr_register_read((unsigned *)
+						  (nca_address + 0xf0));
+		} while (1 == cdr0.bits.start_done && 0 < wfc_timeout);
 
 		if (0 == wfc_timeout) {
 			ncr_unlock(LOCK_DOMAIN);
+			printk(KERN_ERR "ncr_write() Timeout!\n");
+			BUG();
+
 			return -1;
 		}
 
@@ -472,13 +525,15 @@ ncr_write(unsigned long region, unsigned long address, int number,
 		Check status.
 		*/
 
-		if (0x3 != ((ncr_register_read((unsigned *) (nca_address + 0xf0)) &
-						0x00c00000) >> 22)) {
+		if ((0x3 != cdr0.bits.status) && (0x00c00000) >> 22) {
 			unsigned long status;
 
 			status = ncr_register_read((unsigned *)(nca_address +
 								0xe4));
 			ncr_unlock(LOCK_DOMAIN);
+			printk(KERN_ERR
+			       "ncr_write() Error: 0x%x 0x%lx\n",
+			       cdr0.bits.status, status);
 
 			return status;
 		}
-- 
1.8.1.4



More information about the linux-yocto mailing list