diff mbox

[2/4] dmaengine: qcom_bam_dma: clear BAM interrupt only if it is rised

Message ID 1448961299-15161-3-git-send-email-stanimir.varbanov@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Stanimir Varbanov Dec. 1, 2015, 9:14 a.m. UTC
Currently we write BAM_IRQ_CLR register with zero even when no
BAM_IRQ occured. This write has some bad side effects when the
BAM instance is for the crypto engine. In case of crypto engine
some of the BAM registers are xPU protected and they cannot be
controlled by the driver.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
 drivers/dma/qcom_bam_dma.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

Comments

Arnd Bergmann Dec. 1, 2015, 10:29 a.m. UTC | #1
On Tuesday 01 December 2015 11:14:57 Stanimir Varbanov wrote:
> +       if (srcs & BAM_IRQ) {
>                 clr_mask = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_STTS));
>  
> -       /* don't allow reorder of the various accesses to the BAM registers */
> -       mb();
> +               /*
> +                * don't allow reorder of the various accesses to the BAM
> +                * registers
> +                */
> +               mb();
>  
> -       writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
> +               writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
> +       }
> 

I think the comment here should be moved: change the writel_relaxed()
to writel(), which already includes the appropriate barriers, and
add a comment at the readl_relaxed() to explain why it doesn't need
a barrier.

	Arnd
Andy Gross Dec. 1, 2015, 5:28 p.m. UTC | #2
On Tue, Dec 01, 2015 at 11:14:57AM +0200, Stanimir Varbanov wrote:
> Currently we write BAM_IRQ_CLR register with zero even when no
> BAM_IRQ occured. This write has some bad side effects when the
> BAM instance is for the crypto engine. In case of crypto engine
> some of the BAM registers are xPU protected and they cannot be
> controlled by the driver.
> 
> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
> ---
>  drivers/dma/qcom_bam_dma.c |   12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c
> index dc9da477eb69..0f06f3b7a72b 100644
> --- a/drivers/dma/qcom_bam_dma.c
> +++ b/drivers/dma/qcom_bam_dma.c
> @@ -800,13 +800,17 @@ static irqreturn_t bam_dma_irq(int irq, void *data)
>  	if (srcs & P_IRQ)
>  		tasklet_schedule(&bdev->task);
>  
> -	if (srcs & BAM_IRQ)
> +	if (srcs & BAM_IRQ) {
>  		clr_mask = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_STTS));
>  
> -	/* don't allow reorder of the various accesses to the BAM registers */
> -	mb();
> +		/*
> +		 * don't allow reorder of the various accesses to the BAM
> +		 * registers
> +		 */
> +		mb();
>  
> -	writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
> +		writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
> +	}

Looks good.  We shouldn't be accessing this unless there is actually an irq
shown in the srcs.


Thanks for catching this.


Reviewed-by: Andy Gross <agross@codeaurora.org>
Stanimir Varbanov Dec. 2, 2015, 12:56 p.m. UTC | #3
On 12/01/2015 12:29 PM, Arnd Bergmann wrote:
> On Tuesday 01 December 2015 11:14:57 Stanimir Varbanov wrote:
>> +       if (srcs & BAM_IRQ) {
>>                 clr_mask = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_STTS));
>>  
>> -       /* don't allow reorder of the various accesses to the BAM registers */
>> -       mb();
>> +               /*
>> +                * don't allow reorder of the various accesses to the BAM
>> +                * registers
>> +                */
>> +               mb();
>>  
>> -       writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
>> +               writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
>> +       }
>>
> 
> I think the comment here should be moved: change the writel_relaxed()
> to writel(), which already includes the appropriate barriers, and

If we agree with such a change it should be subject to another patch.

> add a comment at the readl_relaxed() to explain why it doesn't need
> a barrier.

Infact I'm not sure that readl_relaxed(BAM_IRQ_STTS) does not need
barrier. If I read the code above correctly the mb() should guarantee
that all load and store operations before it are happened before the
write to BAM_IRQ_CLR register, and on the other hand if we replace
writel_relaxed with writel, the writel has wmb() which guarantees only
store operations. Did I miss something?
Arnd Bergmann Dec. 2, 2015, 1:05 p.m. UTC | #4
On Wednesday 02 December 2015 14:56:57 Stanimir Varbanov wrote:
> On 12/01/2015 12:29 PM, Arnd Bergmann wrote:
> > On Tuesday 01 December 2015 11:14:57 Stanimir Varbanov wrote:
> >> +       if (srcs & BAM_IRQ) {
> >>                 clr_mask = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_STTS));
> >>  
> >> -       /* don't allow reorder of the various accesses to the BAM registers */
> >> -       mb();
> >> +               /*
> >> +                * don't allow reorder of the various accesses to the BAM
> >> +                * registers
> >> +                */
> >> +               mb();
> >>  
> >> -       writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
> >> +               writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
> >> +       }
> >>
> > 
> > I think the comment here should be moved: change the writel_relaxed()
> > to writel(), which already includes the appropriate barriers, and
> 
> If we agree with such a change it should be subject to another patch.

Correct.

> > add a comment at the readl_relaxed() to explain why it doesn't need
> > a barrier.
> 
> Infact I'm not sure that readl_relaxed(BAM_IRQ_STTS) does not need
> barrier. If I read the code above correctly the mb() should guarantee
> that all load and store operations before it are happened before the
> write to BAM_IRQ_CLR register, and on the other hand if we replace
> writel_relaxed with writel, the writel has wmb() which guarantees only
> store operations. Did I miss something?

You are right, we only guarantee that stores to memory are complete
before we writel() an MMIO register.

What do you gain from synchronizing reads before an MMIO write?

	Arnd
Stanimir Varbanov Dec. 2, 2015, 4:47 p.m. UTC | #5
On 12/02/2015 03:05 PM, Arnd Bergmann wrote:
> On Wednesday 02 December 2015 14:56:57 Stanimir Varbanov wrote:
>> On 12/01/2015 12:29 PM, Arnd Bergmann wrote:
>>> On Tuesday 01 December 2015 11:14:57 Stanimir Varbanov wrote:
>>>> +       if (srcs & BAM_IRQ) {
>>>>                 clr_mask = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_STTS));
>>>>  
>>>> -       /* don't allow reorder of the various accesses to the BAM registers */
>>>> -       mb();
>>>> +               /*
>>>> +                * don't allow reorder of the various accesses to the BAM
>>>> +                * registers
>>>> +                */
>>>> +               mb();
>>>>  
>>>> -       writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
>>>> +               writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
>>>> +       }
>>>>
>>>
>>> I think the comment here should be moved: change the writel_relaxed()
>>> to writel(), which already includes the appropriate barriers, and
>>
>> If we agree with such a change it should be subject to another patch.
> 
> Correct.
> 
>>> add a comment at the readl_relaxed() to explain why it doesn't need
>>> a barrier.
>>
>> Infact I'm not sure that readl_relaxed(BAM_IRQ_STTS) does not need
>> barrier. If I read the code above correctly the mb() should guarantee
>> that all load and store operations before it are happened before the
>> write to BAM_IRQ_CLR register, and on the other hand if we replace
>> writel_relaxed with writel, the writel has wmb() which guarantees only
>> store operations. Did I miss something?
> 
> You are right, we only guarantee that stores to memory are complete
> before we writel() an MMIO register.
> 
> What do you gain from synchronizing reads before an MMIO write?

I don't know just tried to understand the meaning of mb() above.
diff mbox

Patch

diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c
index dc9da477eb69..0f06f3b7a72b 100644
--- a/drivers/dma/qcom_bam_dma.c
+++ b/drivers/dma/qcom_bam_dma.c
@@ -800,13 +800,17 @@  static irqreturn_t bam_dma_irq(int irq, void *data)
 	if (srcs & P_IRQ)
 		tasklet_schedule(&bdev->task);
 
-	if (srcs & BAM_IRQ)
+	if (srcs & BAM_IRQ) {
 		clr_mask = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_STTS));
 
-	/* don't allow reorder of the various accesses to the BAM registers */
-	mb();
+		/*
+		 * don't allow reorder of the various accesses to the BAM
+		 * registers
+		 */
+		mb();
 
-	writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
+		writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
+	}
 
 	return IRQ_HANDLED;
 }