Commit 922842a3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'dmaengine-fix-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine

Pull dmaengine fixes from Vinod Koul:

 - A bunch of dw driver changes to fix the src/dst addr width config

 - Omap driver fix for sglen initialization

 - stm32-dma3 driver lli_size init fix

 - dw edma driver fixes for watermark interrupts and unmasking STOP and
   ABORT interrupts

* tag 'dmaengine-fix-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine:
  dmaengine: dw-edma: Do not enable watermark interrupts for HDMA
  dmaengine: dw-edma: Fix unmasking STOP and ABORT interrupts for HDMA
  dmaengine: stm32-dma3: Set lli_size after allocation
  dmaengine: ti: omap-dma: Initialize sglen after allocation
  dmaengine: dw: Unify ret-val local variables naming
  dmaengine: dw: Simplify max-burst calculation procedure
  dmaengine: dw: Define encode_maxburst() above prepare_ctllo() callbacks
  dmaengine: dw: Simplify prepare CTL_LO methods
  dmaengine: dw: Add memory bus width verification
  dmaengine: dw: Add peripheral bus width verification
parents 32fafaf2 9f646ff2
...@@ -17,8 +17,8 @@ enum dw_hdma_control { ...@@ -17,8 +17,8 @@ enum dw_hdma_control {
DW_HDMA_V0_CB = BIT(0), DW_HDMA_V0_CB = BIT(0),
DW_HDMA_V0_TCB = BIT(1), DW_HDMA_V0_TCB = BIT(1),
DW_HDMA_V0_LLP = BIT(2), DW_HDMA_V0_LLP = BIT(2),
DW_HDMA_V0_LIE = BIT(3), DW_HDMA_V0_LWIE = BIT(3),
DW_HDMA_V0_RIE = BIT(4), DW_HDMA_V0_RWIE = BIT(4),
DW_HDMA_V0_CCS = BIT(8), DW_HDMA_V0_CCS = BIT(8),
DW_HDMA_V0_LLE = BIT(9), DW_HDMA_V0_LLE = BIT(9),
}; };
...@@ -195,25 +195,14 @@ static void dw_hdma_v0_write_ll_link(struct dw_edma_chunk *chunk, ...@@ -195,25 +195,14 @@ static void dw_hdma_v0_write_ll_link(struct dw_edma_chunk *chunk,
static void dw_hdma_v0_core_write_chunk(struct dw_edma_chunk *chunk) static void dw_hdma_v0_core_write_chunk(struct dw_edma_chunk *chunk)
{ {
struct dw_edma_burst *child; struct dw_edma_burst *child;
struct dw_edma_chan *chan = chunk->chan;
u32 control = 0, i = 0; u32 control = 0, i = 0;
int j;
if (chunk->cb) if (chunk->cb)
control = DW_HDMA_V0_CB; control = DW_HDMA_V0_CB;
j = chunk->bursts_alloc; list_for_each_entry(child, &chunk->burst->list, list)
list_for_each_entry(child, &chunk->burst->list, list) {
j--;
if (!j) {
control |= DW_HDMA_V0_LIE;
if (!(chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL))
control |= DW_HDMA_V0_RIE;
}
dw_hdma_v0_write_ll_data(chunk, i++, control, child->sz, dw_hdma_v0_write_ll_data(chunk, i++, control, child->sz,
child->sar, child->dar); child->sar, child->dar);
}
control = DW_HDMA_V0_LLP | DW_HDMA_V0_TCB; control = DW_HDMA_V0_LLP | DW_HDMA_V0_TCB;
if (!chunk->cb) if (!chunk->cb)
...@@ -247,10 +236,11 @@ static void dw_hdma_v0_core_start(struct dw_edma_chunk *chunk, bool first) ...@@ -247,10 +236,11 @@ static void dw_hdma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
if (first) { if (first) {
/* Enable engine */ /* Enable engine */
SET_CH_32(dw, chan->dir, chan->id, ch_en, BIT(0)); SET_CH_32(dw, chan->dir, chan->id, ch_en, BIT(0));
/* Interrupt enable&unmask - done, abort */ /* Interrupt unmask - stop, abort */
tmp = GET_CH_32(dw, chan->dir, chan->id, int_setup) | tmp = GET_CH_32(dw, chan->dir, chan->id, int_setup);
HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK | tmp &= ~(HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK);
HDMA_V0_LOCAL_STOP_INT_EN | HDMA_V0_LOCAL_ABORT_INT_EN; /* Interrupt enable - stop, abort */
tmp |= HDMA_V0_LOCAL_STOP_INT_EN | HDMA_V0_LOCAL_ABORT_INT_EN;
if (!(dw->chip->flags & DW_EDMA_CHIP_LOCAL)) if (!(dw->chip->flags & DW_EDMA_CHIP_LOCAL))
tmp |= HDMA_V0_REMOTE_STOP_INT_EN | HDMA_V0_REMOTE_ABORT_INT_EN; tmp |= HDMA_V0_REMOTE_STOP_INT_EN | HDMA_V0_REMOTE_ABORT_INT_EN;
SET_CH_32(dw, chan->dir, chan->id, int_setup, tmp); SET_CH_32(dw, chan->dir, chan->id, int_setup, tmp);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/log2.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -621,12 +622,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ...@@ -621,12 +622,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
struct dw_desc *prev; struct dw_desc *prev;
struct dw_desc *first; struct dw_desc *first;
u32 ctllo, ctlhi; u32 ctllo, ctlhi;
u8 m_master = dwc->dws.m_master; u8 lms = DWC_LLP_LMS(dwc->dws.m_master);
u8 lms = DWC_LLP_LMS(m_master);
dma_addr_t reg; dma_addr_t reg;
unsigned int reg_width; unsigned int reg_width;
unsigned int mem_width; unsigned int mem_width;
unsigned int data_width = dw->pdata->data_width[m_master];
unsigned int i; unsigned int i;
struct scatterlist *sg; struct scatterlist *sg;
size_t total_len = 0; size_t total_len = 0;
...@@ -660,7 +659,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ...@@ -660,7 +659,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
mem = sg_dma_address(sg); mem = sg_dma_address(sg);
len = sg_dma_len(sg); len = sg_dma_len(sg);
mem_width = __ffs(data_width | mem | len); mem_width = __ffs(sconfig->src_addr_width | mem | len);
slave_sg_todev_fill_desc: slave_sg_todev_fill_desc:
desc = dwc_desc_get(dwc); desc = dwc_desc_get(dwc);
...@@ -720,7 +719,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ...@@ -720,7 +719,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
lli_write(desc, sar, reg); lli_write(desc, sar, reg);
lli_write(desc, dar, mem); lli_write(desc, dar, mem);
lli_write(desc, ctlhi, ctlhi); lli_write(desc, ctlhi, ctlhi);
mem_width = __ffs(data_width | mem); mem_width = __ffs(sconfig->dst_addr_width | mem);
lli_write(desc, ctllo, ctllo | DWC_CTLL_DST_WIDTH(mem_width)); lli_write(desc, ctllo, ctllo | DWC_CTLL_DST_WIDTH(mem_width));
desc->len = dlen; desc->len = dlen;
...@@ -780,20 +779,108 @@ bool dw_dma_filter(struct dma_chan *chan, void *param) ...@@ -780,20 +779,108 @@ bool dw_dma_filter(struct dma_chan *chan, void *param)
} }
EXPORT_SYMBOL_GPL(dw_dma_filter); EXPORT_SYMBOL_GPL(dw_dma_filter);
static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig) static int dwc_verify_maxburst(struct dma_chan *chan)
{ {
struct dw_dma_chan *dwc = to_dw_dma_chan(chan); struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
struct dw_dma *dw = to_dw_dma(chan->device);
memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig)); dwc->dma_sconfig.src_maxburst =
clamp(dwc->dma_sconfig.src_maxburst, 1U, dwc->max_burst);
dwc->dma_sconfig.dst_maxburst =
clamp(dwc->dma_sconfig.dst_maxburst, 1U, dwc->max_burst);
dwc->dma_sconfig.src_maxburst = dwc->dma_sconfig.src_maxburst =
clamp(dwc->dma_sconfig.src_maxburst, 0U, dwc->max_burst); rounddown_pow_of_two(dwc->dma_sconfig.src_maxburst);
dwc->dma_sconfig.dst_maxburst = dwc->dma_sconfig.dst_maxburst =
clamp(dwc->dma_sconfig.dst_maxburst, 0U, dwc->max_burst); rounddown_pow_of_two(dwc->dma_sconfig.dst_maxburst);
dw->encode_maxburst(dwc, &dwc->dma_sconfig.src_maxburst); return 0;
dw->encode_maxburst(dwc, &dwc->dma_sconfig.dst_maxburst); }
static int dwc_verify_p_buswidth(struct dma_chan *chan)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
struct dw_dma *dw = to_dw_dma(chan->device);
u32 reg_width, max_width;
if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
reg_width = dwc->dma_sconfig.dst_addr_width;
else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM)
reg_width = dwc->dma_sconfig.src_addr_width;
else /* DMA_MEM_TO_MEM */
return 0;
max_width = dw->pdata->data_width[dwc->dws.p_master];
/* Fall-back to 1-byte transfer width if undefined */
if (reg_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
reg_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
else if (!is_power_of_2(reg_width) || reg_width > max_width)
return -EINVAL;
else /* bus width is valid */
return 0;
/* Update undefined addr width value */
if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
dwc->dma_sconfig.dst_addr_width = reg_width;
else /* DMA_DEV_TO_MEM */
dwc->dma_sconfig.src_addr_width = reg_width;
return 0;
}
static int dwc_verify_m_buswidth(struct dma_chan *chan)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
struct dw_dma *dw = to_dw_dma(chan->device);
u32 reg_width, reg_burst, mem_width;
mem_width = dw->pdata->data_width[dwc->dws.m_master];
/*
* It's possible to have a data portion locked in the DMA FIFO in case
* of the channel suspension. Subsequent channel disabling will cause
* that data silent loss. In order to prevent that maintain the src and
* dst transfer widths coherency by means of the relation:
* (CTLx.SRC_TR_WIDTH * CTLx.SRC_MSIZE >= CTLx.DST_TR_WIDTH)
* Look for the details in the commit message that brings this change.
*
* Note the DMA configs utilized in the calculations below must have
* been verified to have correct values by this method call.
*/
if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV) {
reg_width = dwc->dma_sconfig.dst_addr_width;
if (mem_width < reg_width)
return -EINVAL;
dwc->dma_sconfig.src_addr_width = mem_width;
} else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM) {
reg_width = dwc->dma_sconfig.src_addr_width;
reg_burst = dwc->dma_sconfig.src_maxburst;
dwc->dma_sconfig.dst_addr_width = min(mem_width, reg_width * reg_burst);
}
return 0;
}
static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
int ret;
memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
ret = dwc_verify_maxburst(chan);
if (ret)
return ret;
ret = dwc_verify_p_buswidth(chan);
if (ret)
return ret;
ret = dwc_verify_m_buswidth(chan);
if (ret)
return ret;
return 0; return 0;
} }
...@@ -1068,7 +1155,7 @@ int do_dma_probe(struct dw_dma_chip *chip) ...@@ -1068,7 +1155,7 @@ int do_dma_probe(struct dw_dma_chip *chip)
bool autocfg = false; bool autocfg = false;
unsigned int dw_params; unsigned int dw_params;
unsigned int i; unsigned int i;
int err; int ret;
dw->pdata = devm_kzalloc(chip->dev, sizeof(*dw->pdata), GFP_KERNEL); dw->pdata = devm_kzalloc(chip->dev, sizeof(*dw->pdata), GFP_KERNEL);
if (!dw->pdata) if (!dw->pdata)
...@@ -1084,7 +1171,7 @@ int do_dma_probe(struct dw_dma_chip *chip) ...@@ -1084,7 +1171,7 @@ int do_dma_probe(struct dw_dma_chip *chip)
autocfg = dw_params >> DW_PARAMS_EN & 1; autocfg = dw_params >> DW_PARAMS_EN & 1;
if (!autocfg) { if (!autocfg) {
err = -EINVAL; ret = -EINVAL;
goto err_pdata; goto err_pdata;
} }
...@@ -1104,7 +1191,7 @@ int do_dma_probe(struct dw_dma_chip *chip) ...@@ -1104,7 +1191,7 @@ int do_dma_probe(struct dw_dma_chip *chip)
pdata->chan_allocation_order = CHAN_ALLOCATION_ASCENDING; pdata->chan_allocation_order = CHAN_ALLOCATION_ASCENDING;
pdata->chan_priority = CHAN_PRIORITY_ASCENDING; pdata->chan_priority = CHAN_PRIORITY_ASCENDING;
} else if (chip->pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS) { } else if (chip->pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS) {
err = -EINVAL; ret = -EINVAL;
goto err_pdata; goto err_pdata;
} else { } else {
memcpy(dw->pdata, chip->pdata, sizeof(*dw->pdata)); memcpy(dw->pdata, chip->pdata, sizeof(*dw->pdata));
...@@ -1116,7 +1203,7 @@ int do_dma_probe(struct dw_dma_chip *chip) ...@@ -1116,7 +1203,7 @@ int do_dma_probe(struct dw_dma_chip *chip)
dw->chan = devm_kcalloc(chip->dev, pdata->nr_channels, sizeof(*dw->chan), dw->chan = devm_kcalloc(chip->dev, pdata->nr_channels, sizeof(*dw->chan),
GFP_KERNEL); GFP_KERNEL);
if (!dw->chan) { if (!dw->chan) {
err = -ENOMEM; ret = -ENOMEM;
goto err_pdata; goto err_pdata;
} }
...@@ -1134,15 +1221,15 @@ int do_dma_probe(struct dw_dma_chip *chip) ...@@ -1134,15 +1221,15 @@ int do_dma_probe(struct dw_dma_chip *chip)
sizeof(struct dw_desc), 4, 0); sizeof(struct dw_desc), 4, 0);
if (!dw->desc_pool) { if (!dw->desc_pool) {
dev_err(chip->dev, "No memory for descriptors dma pool\n"); dev_err(chip->dev, "No memory for descriptors dma pool\n");
err = -ENOMEM; ret = -ENOMEM;
goto err_pdata; goto err_pdata;
} }
tasklet_setup(&dw->tasklet, dw_dma_tasklet); tasklet_setup(&dw->tasklet, dw_dma_tasklet);
err = request_irq(chip->irq, dw_dma_interrupt, IRQF_SHARED, ret = request_irq(chip->irq, dw_dma_interrupt, IRQF_SHARED,
dw->name, dw); dw->name, dw);
if (err) if (ret)
goto err_pdata; goto err_pdata;
INIT_LIST_HEAD(&dw->dma.channels); INIT_LIST_HEAD(&dw->dma.channels);
...@@ -1254,8 +1341,8 @@ int do_dma_probe(struct dw_dma_chip *chip) ...@@ -1254,8 +1341,8 @@ int do_dma_probe(struct dw_dma_chip *chip)
*/ */
dma_set_max_seg_size(dw->dma.dev, dw->chan[0].block_size); dma_set_max_seg_size(dw->dma.dev, dw->chan[0].block_size);
err = dma_async_device_register(&dw->dma); ret = dma_async_device_register(&dw->dma);
if (err) if (ret)
goto err_dma_register; goto err_dma_register;
dev_info(chip->dev, "DesignWare DMA Controller, %d channels\n", dev_info(chip->dev, "DesignWare DMA Controller, %d channels\n",
...@@ -1269,7 +1356,7 @@ int do_dma_probe(struct dw_dma_chip *chip) ...@@ -1269,7 +1356,7 @@ int do_dma_probe(struct dw_dma_chip *chip)
free_irq(chip->irq, dw); free_irq(chip->irq, dw);
err_pdata: err_pdata:
pm_runtime_put_sync_suspend(chip->dev); pm_runtime_put_sync_suspend(chip->dev);
return err; return ret;
} }
int do_dma_remove(struct dw_dma_chip *chip) int do_dma_remove(struct dw_dma_chip *chip)
......
...@@ -64,30 +64,39 @@ static size_t dw_dma_block2bytes(struct dw_dma_chan *dwc, u32 block, u32 width) ...@@ -64,30 +64,39 @@ static size_t dw_dma_block2bytes(struct dw_dma_chan *dwc, u32 block, u32 width)
return DWC_CTLH_BLOCK_TS(block) << width; return DWC_CTLH_BLOCK_TS(block) << width;
} }
static inline u8 dw_dma_encode_maxburst(u32 maxburst)
{
/*
* Fix burst size according to dw_dmac. We need to convert them as:
* 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
*/
return maxburst > 1 ? fls(maxburst) - 2 : 0;
}
static u32 dw_dma_prepare_ctllo(struct dw_dma_chan *dwc) static u32 dw_dma_prepare_ctllo(struct dw_dma_chan *dwc)
{ {
struct dma_slave_config *sconfig = &dwc->dma_sconfig; struct dma_slave_config *sconfig = &dwc->dma_sconfig;
u8 smsize = (dwc->direction == DMA_DEV_TO_MEM) ? sconfig->src_maxburst : 0; u8 smsize = 0, dmsize = 0;
u8 dmsize = (dwc->direction == DMA_MEM_TO_DEV) ? sconfig->dst_maxburst : 0; u8 sms, dms;
u8 p_master = dwc->dws.p_master;
u8 m_master = dwc->dws.m_master; if (dwc->direction == DMA_MEM_TO_DEV) {
u8 dms = (dwc->direction == DMA_MEM_TO_DEV) ? p_master : m_master; sms = dwc->dws.m_master;
u8 sms = (dwc->direction == DMA_DEV_TO_MEM) ? p_master : m_master; dms = dwc->dws.p_master;
dmsize = dw_dma_encode_maxburst(sconfig->dst_maxburst);
} else if (dwc->direction == DMA_DEV_TO_MEM) {
sms = dwc->dws.p_master;
dms = dwc->dws.m_master;
smsize = dw_dma_encode_maxburst(sconfig->src_maxburst);
} else /* DMA_MEM_TO_MEM */ {
sms = dwc->dws.m_master;
dms = dwc->dws.m_master;
}
return DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN | return DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN |
DWC_CTLL_DST_MSIZE(dmsize) | DWC_CTLL_SRC_MSIZE(smsize) | DWC_CTLL_DST_MSIZE(dmsize) | DWC_CTLL_SRC_MSIZE(smsize) |
DWC_CTLL_DMS(dms) | DWC_CTLL_SMS(sms); DWC_CTLL_DMS(dms) | DWC_CTLL_SMS(sms);
} }
static void dw_dma_encode_maxburst(struct dw_dma_chan *dwc, u32 *maxburst)
{
/*
* Fix burst size according to dw_dmac. We need to convert them as:
* 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
*/
*maxburst = *maxburst > 1 ? fls(*maxburst) - 2 : 0;
}
static void dw_dma_set_device_name(struct dw_dma *dw, int id) static void dw_dma_set_device_name(struct dw_dma *dw, int id)
{ {
snprintf(dw->name, sizeof(dw->name), "dw:dmac%d", id); snprintf(dw->name, sizeof(dw->name), "dw:dmac%d", id);
...@@ -116,7 +125,6 @@ int dw_dma_probe(struct dw_dma_chip *chip) ...@@ -116,7 +125,6 @@ int dw_dma_probe(struct dw_dma_chip *chip)
dw->suspend_chan = dw_dma_suspend_chan; dw->suspend_chan = dw_dma_suspend_chan;
dw->resume_chan = dw_dma_resume_chan; dw->resume_chan = dw_dma_resume_chan;
dw->prepare_ctllo = dw_dma_prepare_ctllo; dw->prepare_ctllo = dw_dma_prepare_ctllo;
dw->encode_maxburst = dw_dma_encode_maxburst;
dw->bytes2block = dw_dma_bytes2block; dw->bytes2block = dw_dma_bytes2block;
dw->block2bytes = dw_dma_block2bytes; dw->block2bytes = dw_dma_block2bytes;
......
...@@ -199,21 +199,25 @@ static size_t idma32_block2bytes(struct dw_dma_chan *dwc, u32 block, u32 width) ...@@ -199,21 +199,25 @@ static size_t idma32_block2bytes(struct dw_dma_chan *dwc, u32 block, u32 width)
return IDMA32C_CTLH_BLOCK_TS(block); return IDMA32C_CTLH_BLOCK_TS(block);
} }
static inline u8 idma32_encode_maxburst(u32 maxburst)
{
return maxburst > 1 ? fls(maxburst) - 1 : 0;
}
static u32 idma32_prepare_ctllo(struct dw_dma_chan *dwc) static u32 idma32_prepare_ctllo(struct dw_dma_chan *dwc)
{ {
struct dma_slave_config *sconfig = &dwc->dma_sconfig; struct dma_slave_config *sconfig = &dwc->dma_sconfig;
u8 smsize = (dwc->direction == DMA_DEV_TO_MEM) ? sconfig->src_maxburst : 0; u8 smsize = 0, dmsize = 0;
u8 dmsize = (dwc->direction == DMA_MEM_TO_DEV) ? sconfig->dst_maxburst : 0;
if (dwc->direction == DMA_MEM_TO_DEV)
dmsize = idma32_encode_maxburst(sconfig->dst_maxburst);
else if (dwc->direction == DMA_DEV_TO_MEM)
smsize = idma32_encode_maxburst(sconfig->src_maxburst);
return DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN | return DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN |
DWC_CTLL_DST_MSIZE(dmsize) | DWC_CTLL_SRC_MSIZE(smsize); DWC_CTLL_DST_MSIZE(dmsize) | DWC_CTLL_SRC_MSIZE(smsize);
} }
static void idma32_encode_maxburst(struct dw_dma_chan *dwc, u32 *maxburst)
{
*maxburst = *maxburst > 1 ? fls(*maxburst) - 1 : 0;
}
static void idma32_set_device_name(struct dw_dma *dw, int id) static void idma32_set_device_name(struct dw_dma *dw, int id)
{ {
snprintf(dw->name, sizeof(dw->name), "idma32:dmac%d", id); snprintf(dw->name, sizeof(dw->name), "idma32:dmac%d", id);
...@@ -270,7 +274,6 @@ int idma32_dma_probe(struct dw_dma_chip *chip) ...@@ -270,7 +274,6 @@ int idma32_dma_probe(struct dw_dma_chip *chip)
dw->suspend_chan = idma32_suspend_chan; dw->suspend_chan = idma32_suspend_chan;
dw->resume_chan = idma32_resume_chan; dw->resume_chan = idma32_resume_chan;
dw->prepare_ctllo = idma32_prepare_ctllo; dw->prepare_ctllo = idma32_prepare_ctllo;
dw->encode_maxburst = idma32_encode_maxburst;
dw->bytes2block = idma32_bytes2block; dw->bytes2block = idma32_bytes2block;
dw->block2bytes = idma32_block2bytes; dw->block2bytes = idma32_block2bytes;
......
...@@ -29,7 +29,7 @@ static int dw_probe(struct platform_device *pdev) ...@@ -29,7 +29,7 @@ static int dw_probe(struct platform_device *pdev)
struct dw_dma_chip_pdata *data; struct dw_dma_chip_pdata *data;
struct dw_dma_chip *chip; struct dw_dma_chip *chip;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
int err; int ret;
match = device_get_match_data(dev); match = device_get_match_data(dev);
if (!match) if (!match)
...@@ -51,9 +51,9 @@ static int dw_probe(struct platform_device *pdev) ...@@ -51,9 +51,9 @@ static int dw_probe(struct platform_device *pdev)
if (IS_ERR(chip->regs)) if (IS_ERR(chip->regs))
return PTR_ERR(chip->regs); return PTR_ERR(chip->regs);
err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (err) if (ret)
return err; return ret;
if (!data->pdata) if (!data->pdata)
data->pdata = dev_get_platdata(dev); data->pdata = dev_get_platdata(dev);
...@@ -69,14 +69,14 @@ static int dw_probe(struct platform_device *pdev) ...@@ -69,14 +69,14 @@ static int dw_probe(struct platform_device *pdev)
chip->clk = devm_clk_get_optional(chip->dev, "hclk"); chip->clk = devm_clk_get_optional(chip->dev, "hclk");
if (IS_ERR(chip->clk)) if (IS_ERR(chip->clk))
return PTR_ERR(chip->clk); return PTR_ERR(chip->clk);
err = clk_prepare_enable(chip->clk); ret = clk_prepare_enable(chip->clk);
if (err) if (ret)
return err; return ret;
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
err = data->probe(chip); ret = data->probe(chip);
if (err) if (ret)
goto err_dw_dma_probe; goto err_dw_dma_probe;
platform_set_drvdata(pdev, data); platform_set_drvdata(pdev, data);
...@@ -90,7 +90,7 @@ static int dw_probe(struct platform_device *pdev) ...@@ -90,7 +90,7 @@ static int dw_probe(struct platform_device *pdev)
err_dw_dma_probe: err_dw_dma_probe:
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
clk_disable_unprepare(chip->clk); clk_disable_unprepare(chip->clk);
return err; return ret;
} }
static void dw_remove(struct platform_device *pdev) static void dw_remove(struct platform_device *pdev)
......
...@@ -327,7 +327,6 @@ struct dw_dma { ...@@ -327,7 +327,6 @@ struct dw_dma {
void (*suspend_chan)(struct dw_dma_chan *dwc, bool drain); void (*suspend_chan)(struct dw_dma_chan *dwc, bool drain);
void (*resume_chan)(struct dw_dma_chan *dwc, bool drain); void (*resume_chan)(struct dw_dma_chan *dwc, bool drain);
u32 (*prepare_ctllo)(struct dw_dma_chan *dwc); u32 (*prepare_ctllo)(struct dw_dma_chan *dwc);
void (*encode_maxburst)(struct dw_dma_chan *dwc, u32 *maxburst);
u32 (*bytes2block)(struct dw_dma_chan *dwc, size_t bytes, u32 (*bytes2block)(struct dw_dma_chan *dwc, size_t bytes,
unsigned int width, size_t *len); unsigned int width, size_t *len);
size_t (*block2bytes)(struct dw_dma_chan *dwc, u32 block, u32 width); size_t (*block2bytes)(struct dw_dma_chan *dwc, u32 block, u32 width);
......
...@@ -403,6 +403,7 @@ static struct stm32_dma3_swdesc *stm32_dma3_chan_desc_alloc(struct stm32_dma3_ch ...@@ -403,6 +403,7 @@ static struct stm32_dma3_swdesc *stm32_dma3_chan_desc_alloc(struct stm32_dma3_ch
swdesc = kzalloc(struct_size(swdesc, lli, count), GFP_NOWAIT); swdesc = kzalloc(struct_size(swdesc, lli, count), GFP_NOWAIT);
if (!swdesc) if (!swdesc)
return NULL; return NULL;
swdesc->lli_size = count;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
swdesc->lli[i].hwdesc = dma_pool_zalloc(chan->lli_pool, GFP_NOWAIT, swdesc->lli[i].hwdesc = dma_pool_zalloc(chan->lli_pool, GFP_NOWAIT,
...@@ -410,7 +411,6 @@ static struct stm32_dma3_swdesc *stm32_dma3_chan_desc_alloc(struct stm32_dma3_ch ...@@ -410,7 +411,6 @@ static struct stm32_dma3_swdesc *stm32_dma3_chan_desc_alloc(struct stm32_dma3_ch
if (!swdesc->lli[i].hwdesc) if (!swdesc->lli[i].hwdesc)
goto err_pool_free; goto err_pool_free;
} }
swdesc->lli_size = count;
swdesc->ccr = 0; swdesc->ccr = 0;
/* Set LL base address */ /* Set LL base address */
......
...@@ -1186,10 +1186,10 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic( ...@@ -1186,10 +1186,10 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
d->dev_addr = dev_addr; d->dev_addr = dev_addr;
d->fi = burst; d->fi = burst;
d->es = es; d->es = es;
d->sglen = 1;
d->sg[0].addr = buf_addr; d->sg[0].addr = buf_addr;
d->sg[0].en = period_len / es_bytes[es]; d->sg[0].en = period_len / es_bytes[es];
d->sg[0].fn = buf_len / period_len; d->sg[0].fn = buf_len / period_len;
d->sglen = 1;
d->ccr = c->ccr; d->ccr = c->ccr;
if (dir == DMA_DEV_TO_MEM) if (dir == DMA_DEV_TO_MEM)
...@@ -1258,10 +1258,10 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_memcpy( ...@@ -1258,10 +1258,10 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_memcpy(
d->dev_addr = src; d->dev_addr = src;
d->fi = 0; d->fi = 0;
d->es = data_type; d->es = data_type;
d->sglen = 1;
d->sg[0].en = len / BIT(data_type); d->sg[0].en = len / BIT(data_type);
d->sg[0].fn = 1; d->sg[0].fn = 1;
d->sg[0].addr = dest; d->sg[0].addr = dest;
d->sglen = 1;
d->ccr = c->ccr; d->ccr = c->ccr;
d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_POSTINC; d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_POSTINC;
...@@ -1309,6 +1309,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_interleaved( ...@@ -1309,6 +1309,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_interleaved(
if (data_type > CSDP_DATA_TYPE_32) if (data_type > CSDP_DATA_TYPE_32)
data_type = CSDP_DATA_TYPE_32; data_type = CSDP_DATA_TYPE_32;
d->sglen = 1;
sg = &d->sg[0]; sg = &d->sg[0];
d->dir = DMA_MEM_TO_MEM; d->dir = DMA_MEM_TO_MEM;
d->dev_addr = xt->src_start; d->dev_addr = xt->src_start;
...@@ -1316,7 +1317,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_interleaved( ...@@ -1316,7 +1317,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_interleaved(
sg->en = xt->sgl[0].size / BIT(data_type); sg->en = xt->sgl[0].size / BIT(data_type);
sg->fn = xt->numf; sg->fn = xt->numf;
sg->addr = xt->dst_start; sg->addr = xt->dst_start;
d->sglen = 1;
d->ccr = c->ccr; d->ccr = c->ccr;
src_icg = dmaengine_get_src_icg(xt, &xt->sgl[0]); src_icg = dmaengine_get_src_icg(xt, &xt->sgl[0]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment