On 2014-11-13, 12:19 PM, Daniel Dragomir wrote:
From: John Jacques <[email protected]>

Signed-off-by: John Jacques <[email protected]>
---
  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);

When using raw_* locks, we should have an explanation of why the standard
spinlock variants won't work.

Bruce

        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;
                }


--
_______________________________________________
linux-yocto mailing list
[email protected]
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to