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

Bruce Ashfield bruce.ashfield at windriver.com
Sun Nov 16 20:43:55 PST 2014


On 2014-11-13, 12:19 PM, Daniel Dragomir wrote:
> 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);

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



More information about the linux-yocto mailing list