* [v2,2/2] dmaengine: stm32-mdma: Fix incomplete Hw descriptors allocator
@ 2018-04-13 10:09 Vinod Koul
0 siblings, 0 replies; 6+ messages in thread
From: Vinod Koul @ 2018-04-13 10:09 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Pierre-Yves MORDRET, Alexandre Torgue, Linux Kernel Mailing List,
dmaengine, Maxime Coquelin, M'boumba Cedric Madianga,
Dan Williams, Linux ARM
On Fri, Apr 13, 2018 at 10:39:48AM +0200, Geert Uytterhoeven wrote:
> Hi Vinod,
>
> On Fri, Apr 13, 2018 at 6:02 AM, Vinod Koul <vinod.koul@intel.com> wrote:
> > On Wed, Apr 11, 2018 at 04:44:39PM +0200, Pierre-Yves MORDRET wrote:
> >
> >> struct stm32_mdma_desc {
> >> struct virt_dma_desc vdesc;
> >> u32 ccr;
> >> - struct stm32_mdma_hwdesc *hwdesc;
> >> - dma_addr_t hwdesc_phys;
> >> bool cyclic;
> >> u32 count;
> >> + struct stm32_mdma_desc_node node[];
> >
> > some ppl use node[0] for this but i think either is fine..
>
> node[] is the correct one, node[0] may hide future bugs, cfr. commit
> a158531f3c92467d ("gpio: 74x164: Fix crash during .remove()")
Yeah but it this case it is the last element. But yes it helps to avoid such
mistakes in future..
^ permalink raw reply [flat|nested] 6+ messages in thread* [v2,2/2] dmaengine: stm32-mdma: Fix incomplete Hw descriptors allocator
@ 2018-04-13 11:48 Robin Murphy
0 siblings, 0 replies; 6+ messages in thread
From: Robin Murphy @ 2018-04-13 11:48 UTC (permalink / raw)
To: Pierre-Yves MORDRET, Vinod Koul, Maxime Coquelin,
Alexandre Torgue, Dan Williams, M'boumba Cedric Madianga,
dmaengine, linux-arm-kernel, linux-kernel
On 11/04/18 15:44, Pierre-Yves MORDRET wrote:
> Only 1 Hw Descriptor is allocated. Loop over required Hw descriptor for
> proper allocation.
>
> Signed-off-by: Pierre-Yves MORDRET <pierre-yves.mordret@st.com>
> ---
> Version history:
> v1:
> * Initial
> v2:
> * Fix kbuild warning format: /0x%08x/%pad/
> ---
> ---
> drivers/dma/stm32-mdma.c | 90 ++++++++++++++++++++++++++++++------------------
> 1 file changed, 56 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c
> index fbcffa2..3a477bc 100644
> --- a/drivers/dma/stm32-mdma.c
> +++ b/drivers/dma/stm32-mdma.c
> @@ -252,13 +252,17 @@ struct stm32_mdma_hwdesc {
> u32 cmdr;
> } __aligned(64);
>
> +struct stm32_mdma_desc_node {
> + struct stm32_mdma_hwdesc *hwdesc;
> + dma_addr_t hwdesc_phys;
> +};
> +
> struct stm32_mdma_desc {
> struct virt_dma_desc vdesc;
> u32 ccr;
> - struct stm32_mdma_hwdesc *hwdesc;
> - dma_addr_t hwdesc_phys;
> bool cyclic;
> u32 count;
> + struct stm32_mdma_desc_node node[];
> };
>
> struct stm32_mdma_chan {
> @@ -344,30 +348,43 @@ static struct stm32_mdma_desc *stm32_mdma_alloc_desc(
> struct stm32_mdma_chan *chan, u32 count)
> {
> struct stm32_mdma_desc *desc;
> + int i;
>
> - desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
> + desc = kzalloc(sizeof(*desc) +
> + sizeof(struct stm32_mdma_desc_node) * count, GFP_NOWAIT);
You could use "offsetof(typeof(*desc), node[count])" instead of the
explicit calculation here.
Robin.
> if (!desc)
> return NULL;
>
> - desc->hwdesc = dma_pool_alloc(chan->desc_pool, GFP_NOWAIT,
> - &desc->hwdesc_phys);
> - if (!desc->hwdesc) {
> - dev_err(chan2dev(chan), "Failed to allocate descriptor\n");
> - kfree(desc);
> - return NULL;
> + for (i = 0; i < count; i++) {
> + desc->node[i].hwdesc =
> + dma_pool_alloc(chan->desc_pool, GFP_NOWAIT,
> + &desc->node[i].hwdesc_phys);
> + if (!desc->node[i].hwdesc)
> + goto err;
> }
>
> desc->count = count;
>
> return desc;
> +
> +err:
> + dev_err(chan2dev(chan), "Failed to allocate descriptor\n");
> + while (--i >= 0)
> + dma_pool_free(chan->desc_pool, desc->node[i].hwdesc,
> + desc->node[i].hwdesc_phys);
> + kfree(desc);
> + return NULL;
> }
>
> static void stm32_mdma_desc_free(struct virt_dma_desc *vdesc)
> {
> struct stm32_mdma_desc *desc = to_stm32_mdma_desc(vdesc);
> struct stm32_mdma_chan *chan = to_stm32_mdma_chan(vdesc->tx.chan);
> + int i;
>
> - dma_pool_free(chan->desc_pool, desc->hwdesc, desc->hwdesc_phys);
> + for (i = 0; i < desc->count; i++)
> + dma_pool_free(chan->desc_pool, desc->node[i].hwdesc,
> + desc->node[i].hwdesc_phys);
> kfree(desc);
> }
>
> @@ -669,18 +686,18 @@ static int stm32_mdma_set_xfer_param(struct stm32_mdma_chan *chan,
> }
>
> static void stm32_mdma_dump_hwdesc(struct stm32_mdma_chan *chan,
> - struct stm32_mdma_hwdesc *hwdesc)
> + struct stm32_mdma_desc_node *node)
> {
> - dev_dbg(chan2dev(chan), "hwdesc: 0x%p\n", hwdesc);
> - dev_dbg(chan2dev(chan), "CTCR: 0x%08x\n", hwdesc->ctcr);
> - dev_dbg(chan2dev(chan), "CBNDTR: 0x%08x\n", hwdesc->cbndtr);
> - dev_dbg(chan2dev(chan), "CSAR: 0x%08x\n", hwdesc->csar);
> - dev_dbg(chan2dev(chan), "CDAR: 0x%08x\n", hwdesc->cdar);
> - dev_dbg(chan2dev(chan), "CBRUR: 0x%08x\n", hwdesc->cbrur);
> - dev_dbg(chan2dev(chan), "CLAR: 0x%08x\n", hwdesc->clar);
> - dev_dbg(chan2dev(chan), "CTBR: 0x%08x\n", hwdesc->ctbr);
> - dev_dbg(chan2dev(chan), "CMAR: 0x%08x\n", hwdesc->cmar);
> - dev_dbg(chan2dev(chan), "CMDR: 0x%08x\n\n", hwdesc->cmdr);
> + dev_dbg(chan2dev(chan), "hwdesc: %pad\n", &node->hwdesc_phys);
> + dev_dbg(chan2dev(chan), "CTCR: 0x%08x\n", node->hwdesc->ctcr);
> + dev_dbg(chan2dev(chan), "CBNDTR: 0x%08x\n", node->hwdesc->cbndtr);
> + dev_dbg(chan2dev(chan), "CSAR: 0x%08x\n", node->hwdesc->csar);
> + dev_dbg(chan2dev(chan), "CDAR: 0x%08x\n", node->hwdesc->cdar);
> + dev_dbg(chan2dev(chan), "CBRUR: 0x%08x\n", node->hwdesc->cbrur);
> + dev_dbg(chan2dev(chan), "CLAR: 0x%08x\n", node->hwdesc->clar);
> + dev_dbg(chan2dev(chan), "CTBR: 0x%08x\n", node->hwdesc->ctbr);
> + dev_dbg(chan2dev(chan), "CMAR: 0x%08x\n", node->hwdesc->cmar);
> + dev_dbg(chan2dev(chan), "CMDR: 0x%08x\n\n", node->hwdesc->cmdr);
> }
>
> static void stm32_mdma_setup_hwdesc(struct stm32_mdma_chan *chan,
> @@ -694,7 +711,7 @@ static void stm32_mdma_setup_hwdesc(struct stm32_mdma_chan *chan,
> struct stm32_mdma_hwdesc *hwdesc;
> u32 next = count + 1;
>
> - hwdesc = &desc->hwdesc[count];
> + hwdesc = desc->node[count].hwdesc;
> hwdesc->ctcr = ctcr;
> hwdesc->cbndtr &= ~(STM32_MDMA_CBNDTR_BRC_MK |
> STM32_MDMA_CBNDTR_BRDUM |
> @@ -704,19 +721,20 @@ static void stm32_mdma_setup_hwdesc(struct stm32_mdma_chan *chan,
> hwdesc->csar = src_addr;
> hwdesc->cdar = dst_addr;
> hwdesc->cbrur = 0;
> - hwdesc->clar = desc->hwdesc_phys + next * sizeof(*hwdesc);
> hwdesc->ctbr = ctbr;
> hwdesc->cmar = config->mask_addr;
> hwdesc->cmdr = config->mask_data;
>
> if (is_last) {
> if (is_cyclic)
> - hwdesc->clar = desc->hwdesc_phys;
> + hwdesc->clar = desc->node[0].hwdesc_phys;
> else
> hwdesc->clar = 0;
> + } else {
> + hwdesc->clar = desc->node[next].hwdesc_phys;
> }
>
> - stm32_mdma_dump_hwdesc(chan, hwdesc);
> + stm32_mdma_dump_hwdesc(chan, &desc->node[count]);
> }
>
> static int stm32_mdma_setup_xfer(struct stm32_mdma_chan *chan,
> @@ -780,7 +798,7 @@ stm32_mdma_prep_slave_sg(struct dma_chan *c, struct scatterlist *sgl,
> {
> struct stm32_mdma_chan *chan = to_stm32_mdma_chan(c);
> struct stm32_mdma_desc *desc;
> - int ret;
> + int i, ret;
>
> /*
> * Once DMA is in setup cyclic mode the channel we cannot assign this
> @@ -806,7 +824,9 @@ stm32_mdma_prep_slave_sg(struct dma_chan *c, struct scatterlist *sgl,
> return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
>
> xfer_setup_err:
> - dma_pool_free(chan->desc_pool, &desc->hwdesc, desc->hwdesc_phys);
> + for (i = 0; i < desc->count; i++)
> + dma_pool_free(chan->desc_pool, desc->node[i].hwdesc,
> + desc->node[i].hwdesc_phys);
> kfree(desc);
> return NULL;
> }
> @@ -895,7 +915,9 @@ stm32_mdma_prep_dma_cyclic(struct dma_chan *c, dma_addr_t buf_addr,
> return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
>
> xfer_setup_err:
> - dma_pool_free(chan->desc_pool, &desc->hwdesc, desc->hwdesc_phys);
> + for (i = 0; i < desc->count; i++)
> + dma_pool_free(chan->desc_pool, desc->node[i].hwdesc,
> + desc->node[i].hwdesc_phys);
> kfree(desc);
> return NULL;
> }
> @@ -1009,7 +1031,7 @@ stm32_mdma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dest, dma_addr_t src,
> ctcr |= STM32_MDMA_CTCR_PKE;
>
> /* Prepare hardware descriptor */
> - hwdesc = desc->hwdesc;
> + hwdesc = desc->node[0].hwdesc;
> hwdesc->ctcr = ctcr;
> hwdesc->cbndtr = cbndtr;
> hwdesc->csar = src;
> @@ -1020,7 +1042,7 @@ stm32_mdma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dest, dma_addr_t src,
> hwdesc->cmar = 0;
> hwdesc->cmdr = 0;
>
> - stm32_mdma_dump_hwdesc(chan, hwdesc);
> + stm32_mdma_dump_hwdesc(chan, &desc->node[0]);
> } else {
> /* Setup a LLI transfer */
> ctcr |= STM32_MDMA_CTCR_TRGM(STM32_MDMA_LINKED_LIST) |
> @@ -1120,7 +1142,7 @@ static void stm32_mdma_start_transfer(struct stm32_mdma_chan *chan)
> }
>
> chan->desc = to_stm32_mdma_desc(vdesc);
> - hwdesc = chan->desc->hwdesc;
> + hwdesc = chan->desc->node[0].hwdesc;
> chan->curr_hwdesc = 0;
>
> stm32_mdma_write(dmadev, STM32_MDMA_CCR(id), chan->desc->ccr);
> @@ -1198,7 +1220,7 @@ static int stm32_mdma_resume(struct dma_chan *c)
> unsigned long flags;
> u32 status, reg;
>
> - hwdesc = &chan->desc->hwdesc[chan->curr_hwdesc];
> + hwdesc = chan->desc->node[chan->curr_hwdesc].hwdesc;
>
> spin_lock_irqsave(&chan->vchan.lock, flags);
>
> @@ -1268,13 +1290,13 @@ static size_t stm32_mdma_desc_residue(struct stm32_mdma_chan *chan,
> u32 curr_hwdesc)
> {
> struct stm32_mdma_device *dmadev = stm32_mdma_get_dev(chan);
> + struct stm32_mdma_hwdesc *hwdesc = desc->node[0].hwdesc;
> u32 cbndtr, residue, modulo, burst_size;
> int i;
>
> residue = 0;
> for (i = curr_hwdesc + 1; i < desc->count; i++) {
> - struct stm32_mdma_hwdesc *hwdesc = &desc->hwdesc[i];
> -
> + hwdesc = desc->node[i].hwdesc;
> residue += STM32_MDMA_CBNDTR_BNDT(hwdesc->cbndtr);
> }
> cbndtr = stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id));
>
---
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 6+ messages in thread* [v2,2/2] dmaengine: stm32-mdma: Fix incomplete Hw descriptors allocator
@ 2018-04-13 10:40 Geert Uytterhoeven
0 siblings, 0 replies; 6+ messages in thread
From: Geert Uytterhoeven @ 2018-04-13 10:40 UTC (permalink / raw)
To: Vinod Koul
Cc: Pierre-Yves MORDRET, Alexandre Torgue, Linux Kernel Mailing List,
dmaengine, Maxime Coquelin, M'boumba Cedric Madianga,
Dan Williams, Linux ARM
Hi Vinod,
On Fri, Apr 13, 2018 at 12:09 PM, Vinod Koul <vinod.koul@intel.com> wrote:
> On Fri, Apr 13, 2018 at 10:39:48AM +0200, Geert Uytterhoeven wrote:
>> On Fri, Apr 13, 2018 at 6:02 AM, Vinod Koul <vinod.koul@intel.com> wrote:
>> > On Wed, Apr 11, 2018 at 04:44:39PM +0200, Pierre-Yves MORDRET wrote:
>> >
>> >> struct stm32_mdma_desc {
>> >> struct virt_dma_desc vdesc;
>> >> u32 ccr;
>> >> - struct stm32_mdma_hwdesc *hwdesc;
>> >> - dma_addr_t hwdesc_phys;
>> >> bool cyclic;
>> >> u32 count;
>> >> + struct stm32_mdma_desc_node node[];
>> >
>> > some ppl use node[0] for this but i think either is fine..
>>
>> node[] is the correct one, node[0] may hide future bugs, cfr. commit
>> a158531f3c92467d ("gpio: 74x164: Fix crash during .remove()")
>
> Yeah but it this case it is the last element. But yes it helps to avoid such
> mistakes in future..
It was the last element in 74x164, too. Unless someone changed that.
Gr{oetje,eeting}s,
Geert
^ permalink raw reply [flat|nested] 6+ messages in thread* [v2,2/2] dmaengine: stm32-mdma: Fix incomplete Hw descriptors allocator
@ 2018-04-13 8:39 Geert Uytterhoeven
0 siblings, 0 replies; 6+ messages in thread
From: Geert Uytterhoeven @ 2018-04-13 8:39 UTC (permalink / raw)
To: Vinod Koul
Cc: Pierre-Yves MORDRET, Alexandre Torgue, Linux Kernel Mailing List,
dmaengine, Maxime Coquelin, M'boumba Cedric Madianga,
Dan Williams, Linux ARM
Hi Vinod,
On Fri, Apr 13, 2018 at 6:02 AM, Vinod Koul <vinod.koul@intel.com> wrote:
> On Wed, Apr 11, 2018 at 04:44:39PM +0200, Pierre-Yves MORDRET wrote:
>
>> struct stm32_mdma_desc {
>> struct virt_dma_desc vdesc;
>> u32 ccr;
>> - struct stm32_mdma_hwdesc *hwdesc;
>> - dma_addr_t hwdesc_phys;
>> bool cyclic;
>> u32 count;
>> + struct stm32_mdma_desc_node node[];
>
> some ppl use node[0] for this but i think either is fine..
node[] is the correct one, node[0] may hide future bugs, cfr. commit
a158531f3c92467d ("gpio: 74x164: Fix crash during .remove()")
Gr{oetje,eeting}s,
Geert
^ permalink raw reply [flat|nested] 6+ messages in thread* [v2,2/2] dmaengine: stm32-mdma: Fix incomplete Hw descriptors allocator
@ 2018-04-13 4:02 Vinod Koul
0 siblings, 0 replies; 6+ messages in thread
From: Vinod Koul @ 2018-04-13 4:02 UTC (permalink / raw)
To: Pierre-Yves MORDRET
Cc: Maxime Coquelin, Alexandre Torgue, Dan Williams,
M'boumba Cedric Madianga, dmaengine, linux-arm-kernel,
linux-kernel
On Wed, Apr 11, 2018 at 04:44:39PM +0200, Pierre-Yves MORDRET wrote:
> struct stm32_mdma_desc {
> struct virt_dma_desc vdesc;
> u32 ccr;
> - struct stm32_mdma_hwdesc *hwdesc;
> - dma_addr_t hwdesc_phys;
> bool cyclic;
> u32 count;
> + struct stm32_mdma_desc_node node[];
some ppl use node[0] for this but i think either is fine..
> static void stm32_mdma_dump_hwdesc(struct stm32_mdma_chan *chan,
> - struct stm32_mdma_hwdesc *hwdesc)
> + struct stm32_mdma_desc_node *node)
> {
> - dev_dbg(chan2dev(chan), "CTCR: 0x%08x\n", hwdesc->ctcr);
> + dev_dbg(chan2dev(chan), "CTCR: 0x%08x\n", node->hwdesc->ctcr);
this is noise for this patch and IIUC you should be able to pass
node->hwdesc and keep fn same?
^ permalink raw reply [flat|nested] 6+ messages in thread* [v2,2/2] dmaengine: stm32-mdma: Fix incomplete Hw descriptors allocator
@ 2018-04-11 14:44 Pierre Yves MORDRET
0 siblings, 0 replies; 6+ messages in thread
From: Pierre Yves MORDRET @ 2018-04-11 14:44 UTC (permalink / raw)
To: Vinod Koul, Maxime Coquelin, Alexandre Torgue, Dan Williams,
M'boumba Cedric Madianga, dmaengine, linux-arm-kernel,
linux-kernel
Cc: Pierre-Yves MORDRET
Only 1 Hw Descriptor is allocated. Loop over required Hw descriptor for
proper allocation.
Signed-off-by: Pierre-Yves MORDRET <pierre-yves.mordret@st.com>
---
Version history:
v1:
* Initial
v2:
* Fix kbuild warning format: /0x%08x/%pad/
---
---
drivers/dma/stm32-mdma.c | 90 ++++++++++++++++++++++++++++++------------------
1 file changed, 56 insertions(+), 34 deletions(-)
diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c
index fbcffa2..3a477bc 100644
--- a/drivers/dma/stm32-mdma.c
+++ b/drivers/dma/stm32-mdma.c
@@ -252,13 +252,17 @@ struct stm32_mdma_hwdesc {
u32 cmdr;
} __aligned(64);
+struct stm32_mdma_desc_node {
+ struct stm32_mdma_hwdesc *hwdesc;
+ dma_addr_t hwdesc_phys;
+};
+
struct stm32_mdma_desc {
struct virt_dma_desc vdesc;
u32 ccr;
- struct stm32_mdma_hwdesc *hwdesc;
- dma_addr_t hwdesc_phys;
bool cyclic;
u32 count;
+ struct stm32_mdma_desc_node node[];
};
struct stm32_mdma_chan {
@@ -344,30 +348,43 @@ static struct stm32_mdma_desc *stm32_mdma_alloc_desc(
struct stm32_mdma_chan *chan, u32 count)
{
struct stm32_mdma_desc *desc;
+ int i;
- desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
+ desc = kzalloc(sizeof(*desc) +
+ sizeof(struct stm32_mdma_desc_node) * count, GFP_NOWAIT);
if (!desc)
return NULL;
- desc->hwdesc = dma_pool_alloc(chan->desc_pool, GFP_NOWAIT,
- &desc->hwdesc_phys);
- if (!desc->hwdesc) {
- dev_err(chan2dev(chan), "Failed to allocate descriptor\n");
- kfree(desc);
- return NULL;
+ for (i = 0; i < count; i++) {
+ desc->node[i].hwdesc =
+ dma_pool_alloc(chan->desc_pool, GFP_NOWAIT,
+ &desc->node[i].hwdesc_phys);
+ if (!desc->node[i].hwdesc)
+ goto err;
}
desc->count = count;
return desc;
+
+err:
+ dev_err(chan2dev(chan), "Failed to allocate descriptor\n");
+ while (--i >= 0)
+ dma_pool_free(chan->desc_pool, desc->node[i].hwdesc,
+ desc->node[i].hwdesc_phys);
+ kfree(desc);
+ return NULL;
}
static void stm32_mdma_desc_free(struct virt_dma_desc *vdesc)
{
struct stm32_mdma_desc *desc = to_stm32_mdma_desc(vdesc);
struct stm32_mdma_chan *chan = to_stm32_mdma_chan(vdesc->tx.chan);
+ int i;
- dma_pool_free(chan->desc_pool, desc->hwdesc, desc->hwdesc_phys);
+ for (i = 0; i < desc->count; i++)
+ dma_pool_free(chan->desc_pool, desc->node[i].hwdesc,
+ desc->node[i].hwdesc_phys);
kfree(desc);
}
@@ -669,18 +686,18 @@ static int stm32_mdma_set_xfer_param(struct stm32_mdma_chan *chan,
}
static void stm32_mdma_dump_hwdesc(struct stm32_mdma_chan *chan,
- struct stm32_mdma_hwdesc *hwdesc)
+ struct stm32_mdma_desc_node *node)
{
- dev_dbg(chan2dev(chan), "hwdesc: 0x%p\n", hwdesc);
- dev_dbg(chan2dev(chan), "CTCR: 0x%08x\n", hwdesc->ctcr);
- dev_dbg(chan2dev(chan), "CBNDTR: 0x%08x\n", hwdesc->cbndtr);
- dev_dbg(chan2dev(chan), "CSAR: 0x%08x\n", hwdesc->csar);
- dev_dbg(chan2dev(chan), "CDAR: 0x%08x\n", hwdesc->cdar);
- dev_dbg(chan2dev(chan), "CBRUR: 0x%08x\n", hwdesc->cbrur);
- dev_dbg(chan2dev(chan), "CLAR: 0x%08x\n", hwdesc->clar);
- dev_dbg(chan2dev(chan), "CTBR: 0x%08x\n", hwdesc->ctbr);
- dev_dbg(chan2dev(chan), "CMAR: 0x%08x\n", hwdesc->cmar);
- dev_dbg(chan2dev(chan), "CMDR: 0x%08x\n\n", hwdesc->cmdr);
+ dev_dbg(chan2dev(chan), "hwdesc: %pad\n", &node->hwdesc_phys);
+ dev_dbg(chan2dev(chan), "CTCR: 0x%08x\n", node->hwdesc->ctcr);
+ dev_dbg(chan2dev(chan), "CBNDTR: 0x%08x\n", node->hwdesc->cbndtr);
+ dev_dbg(chan2dev(chan), "CSAR: 0x%08x\n", node->hwdesc->csar);
+ dev_dbg(chan2dev(chan), "CDAR: 0x%08x\n", node->hwdesc->cdar);
+ dev_dbg(chan2dev(chan), "CBRUR: 0x%08x\n", node->hwdesc->cbrur);
+ dev_dbg(chan2dev(chan), "CLAR: 0x%08x\n", node->hwdesc->clar);
+ dev_dbg(chan2dev(chan), "CTBR: 0x%08x\n", node->hwdesc->ctbr);
+ dev_dbg(chan2dev(chan), "CMAR: 0x%08x\n", node->hwdesc->cmar);
+ dev_dbg(chan2dev(chan), "CMDR: 0x%08x\n\n", node->hwdesc->cmdr);
}
static void stm32_mdma_setup_hwdesc(struct stm32_mdma_chan *chan,
@@ -694,7 +711,7 @@ static void stm32_mdma_setup_hwdesc(struct stm32_mdma_chan *chan,
struct stm32_mdma_hwdesc *hwdesc;
u32 next = count + 1;
- hwdesc = &desc->hwdesc[count];
+ hwdesc = desc->node[count].hwdesc;
hwdesc->ctcr = ctcr;
hwdesc->cbndtr &= ~(STM32_MDMA_CBNDTR_BRC_MK |
STM32_MDMA_CBNDTR_BRDUM |
@@ -704,19 +721,20 @@ static void stm32_mdma_setup_hwdesc(struct stm32_mdma_chan *chan,
hwdesc->csar = src_addr;
hwdesc->cdar = dst_addr;
hwdesc->cbrur = 0;
- hwdesc->clar = desc->hwdesc_phys + next * sizeof(*hwdesc);
hwdesc->ctbr = ctbr;
hwdesc->cmar = config->mask_addr;
hwdesc->cmdr = config->mask_data;
if (is_last) {
if (is_cyclic)
- hwdesc->clar = desc->hwdesc_phys;
+ hwdesc->clar = desc->node[0].hwdesc_phys;
else
hwdesc->clar = 0;
+ } else {
+ hwdesc->clar = desc->node[next].hwdesc_phys;
}
- stm32_mdma_dump_hwdesc(chan, hwdesc);
+ stm32_mdma_dump_hwdesc(chan, &desc->node[count]);
}
static int stm32_mdma_setup_xfer(struct stm32_mdma_chan *chan,
@@ -780,7 +798,7 @@ stm32_mdma_prep_slave_sg(struct dma_chan *c, struct scatterlist *sgl,
{
struct stm32_mdma_chan *chan = to_stm32_mdma_chan(c);
struct stm32_mdma_desc *desc;
- int ret;
+ int i, ret;
/*
* Once DMA is in setup cyclic mode the channel we cannot assign this
@@ -806,7 +824,9 @@ stm32_mdma_prep_slave_sg(struct dma_chan *c, struct scatterlist *sgl,
return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
xfer_setup_err:
- dma_pool_free(chan->desc_pool, &desc->hwdesc, desc->hwdesc_phys);
+ for (i = 0; i < desc->count; i++)
+ dma_pool_free(chan->desc_pool, desc->node[i].hwdesc,
+ desc->node[i].hwdesc_phys);
kfree(desc);
return NULL;
}
@@ -895,7 +915,9 @@ stm32_mdma_prep_dma_cyclic(struct dma_chan *c, dma_addr_t buf_addr,
return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
xfer_setup_err:
- dma_pool_free(chan->desc_pool, &desc->hwdesc, desc->hwdesc_phys);
+ for (i = 0; i < desc->count; i++)
+ dma_pool_free(chan->desc_pool, desc->node[i].hwdesc,
+ desc->node[i].hwdesc_phys);
kfree(desc);
return NULL;
}
@@ -1009,7 +1031,7 @@ stm32_mdma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dest, dma_addr_t src,
ctcr |= STM32_MDMA_CTCR_PKE;
/* Prepare hardware descriptor */
- hwdesc = desc->hwdesc;
+ hwdesc = desc->node[0].hwdesc;
hwdesc->ctcr = ctcr;
hwdesc->cbndtr = cbndtr;
hwdesc->csar = src;
@@ -1020,7 +1042,7 @@ stm32_mdma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dest, dma_addr_t src,
hwdesc->cmar = 0;
hwdesc->cmdr = 0;
- stm32_mdma_dump_hwdesc(chan, hwdesc);
+ stm32_mdma_dump_hwdesc(chan, &desc->node[0]);
} else {
/* Setup a LLI transfer */
ctcr |= STM32_MDMA_CTCR_TRGM(STM32_MDMA_LINKED_LIST) |
@@ -1120,7 +1142,7 @@ static void stm32_mdma_start_transfer(struct stm32_mdma_chan *chan)
}
chan->desc = to_stm32_mdma_desc(vdesc);
- hwdesc = chan->desc->hwdesc;
+ hwdesc = chan->desc->node[0].hwdesc;
chan->curr_hwdesc = 0;
stm32_mdma_write(dmadev, STM32_MDMA_CCR(id), chan->desc->ccr);
@@ -1198,7 +1220,7 @@ static int stm32_mdma_resume(struct dma_chan *c)
unsigned long flags;
u32 status, reg;
- hwdesc = &chan->desc->hwdesc[chan->curr_hwdesc];
+ hwdesc = chan->desc->node[chan->curr_hwdesc].hwdesc;
spin_lock_irqsave(&chan->vchan.lock, flags);
@@ -1268,13 +1290,13 @@ static size_t stm32_mdma_desc_residue(struct stm32_mdma_chan *chan,
u32 curr_hwdesc)
{
struct stm32_mdma_device *dmadev = stm32_mdma_get_dev(chan);
+ struct stm32_mdma_hwdesc *hwdesc = desc->node[0].hwdesc;
u32 cbndtr, residue, modulo, burst_size;
int i;
residue = 0;
for (i = curr_hwdesc + 1; i < desc->count; i++) {
- struct stm32_mdma_hwdesc *hwdesc = &desc->hwdesc[i];
-
+ hwdesc = desc->node[i].hwdesc;
residue += STM32_MDMA_CBNDTR_BNDT(hwdesc->cbndtr);
}
cbndtr = stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id));
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-04-13 11:48 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-04-13 10:09 [v2,2/2] dmaengine: stm32-mdma: Fix incomplete Hw descriptors allocator Vinod Koul
-- strict thread matches above, loose matches on Subject: below --
2018-04-13 11:48 Robin Murphy
2018-04-13 10:40 Geert Uytterhoeven
2018-04-13 8:39 Geert Uytterhoeven
2018-04-13 4:02 Vinod Koul
2018-04-11 14:44 Pierre Yves MORDRET
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).