Message ID | 1448961299-15161-3-git-send-email-stanimir.varbanov@linaro.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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
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>
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?
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
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 --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; }
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(-)