Skip to content

Commit 306a63b

Browse files
committed
Merge tag 'dmaengine-fix-4.6-rc4' of git://git.infradead.org/users/vkoul/slave-dma
Pull dmaengine fixes from Vinod Koul: "This time we have some odd fixes in hsu, edma, omap and xilinx. Usual fixes and nothing special" * tag 'dmaengine-fix-4.6-rc4' of git://git.infradead.org/users/vkoul/slave-dma: dmaengine: dw: fix master selection dmaengine: edma: special case slot limit workaround dmaengine: edma: Remove dynamic TPTC power management feature dmaengine: vdma: don't crash when bad channel is requested dmaengine: omap-dma: Do not suppress interrupts for memcpy dmaengine: omap-dma: Fix polled channel completion detection and handling dmaengine: hsu: correct use of channel status register dmaengine: hsu: correct residue calculation of active descriptor dmaengine: hsu: set HSU_CH_MTSR to memory width
2 parents ac82a57 + 956e6c8 commit 306a63b

File tree

6 files changed

+73
-68
lines changed

6 files changed

+73
-68
lines changed

drivers/dma/dw/core.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -130,26 +130,14 @@ static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc)
130130
static void dwc_initialize(struct dw_dma_chan *dwc)
131131
{
132132
struct dw_dma *dw = to_dw_dma(dwc->chan.device);
133-
struct dw_dma_slave *dws = dwc->chan.private;
134133
u32 cfghi = DWC_CFGH_FIFO_MODE;
135134
u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority);
136135

137136
if (dwc->initialized == true)
138137
return;
139138

140-
if (dws) {
141-
/*
142-
* We need controller-specific data to set up slave
143-
* transfers.
144-
*/
145-
BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev);
146-
147-
cfghi |= DWC_CFGH_DST_PER(dws->dst_id);
148-
cfghi |= DWC_CFGH_SRC_PER(dws->src_id);
149-
} else {
150-
cfghi |= DWC_CFGH_DST_PER(dwc->dst_id);
151-
cfghi |= DWC_CFGH_SRC_PER(dwc->src_id);
152-
}
139+
cfghi |= DWC_CFGH_DST_PER(dwc->dst_id);
140+
cfghi |= DWC_CFGH_SRC_PER(dwc->src_id);
153141

154142
channel_writel(dwc, CFG_LO, cfglo);
155143
channel_writel(dwc, CFG_HI, cfghi);
@@ -941,7 +929,7 @@ bool dw_dma_filter(struct dma_chan *chan, void *param)
941929
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
942930
struct dw_dma_slave *dws = param;
943931

944-
if (!dws || dws->dma_dev != chan->device->dev)
932+
if (dws->dma_dev != chan->device->dev)
945933
return false;
946934

947935
/* We have to copy data since dws can be temporary storage */
@@ -1165,6 +1153,14 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
11651153
* doesn't mean what you think it means), and status writeback.
11661154
*/
11671155

1156+
/*
1157+
* We need controller-specific data to set up slave transfers.
1158+
*/
1159+
if (chan->private && !dw_dma_filter(chan, chan->private)) {
1160+
dev_warn(chan2dev(chan), "Wrong controller-specific data\n");
1161+
return -EINVAL;
1162+
}
1163+
11681164
/* Enable controller here if needed */
11691165
if (!dw->in_use)
11701166
dw_dma_on(dw);
@@ -1226,6 +1222,14 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
12261222
spin_lock_irqsave(&dwc->lock, flags);
12271223
list_splice_init(&dwc->free_list, &list);
12281224
dwc->descs_allocated = 0;
1225+
1226+
/* Clear custom channel configuration */
1227+
dwc->src_id = 0;
1228+
dwc->dst_id = 0;
1229+
1230+
dwc->src_master = 0;
1231+
dwc->dst_master = 0;
1232+
12291233
dwc->initialized = false;
12301234

12311235
/* Disable interrupts */

drivers/dma/edma.c

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
12381238
struct edma_desc *edesc;
12391239
dma_addr_t src_addr, dst_addr;
12401240
enum dma_slave_buswidth dev_width;
1241+
bool use_intermediate = false;
12411242
u32 burst;
12421243
int i, ret, nslots;
12431244

@@ -1279,8 +1280,21 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
12791280
* but the synchronization is difficult to achieve with Cyclic and
12801281
* cannot be guaranteed, so we error out early.
12811282
*/
1282-
if (nslots > MAX_NR_SG)
1283-
return NULL;
1283+
if (nslots > MAX_NR_SG) {
1284+
/*
1285+
* If the burst and period sizes are the same, we can put
1286+
* the full buffer into a single period and activate
1287+
* intermediate interrupts. This will produce interrupts
1288+
* after each burst, which is also after each desired period.
1289+
*/
1290+
if (burst == period_len) {
1291+
period_len = buf_len;
1292+
nslots = 2;
1293+
use_intermediate = true;
1294+
} else {
1295+
return NULL;
1296+
}
1297+
}
12841298

12851299
edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]),
12861300
GFP_ATOMIC);
@@ -1358,8 +1372,13 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
13581372
/*
13591373
* Enable period interrupt only if it is requested
13601374
*/
1361-
if (tx_flags & DMA_PREP_INTERRUPT)
1375+
if (tx_flags & DMA_PREP_INTERRUPT) {
13621376
edesc->pset[i].param.opt |= TCINTEN;
1377+
1378+
/* Also enable intermediate interrupts if necessary */
1379+
if (use_intermediate)
1380+
edesc->pset[i].param.opt |= ITCINTEN;
1381+
}
13631382
}
13641383

13651384
/* Place the cyclic channel to highest priority queue */
@@ -1570,32 +1589,6 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data)
15701589
return IRQ_HANDLED;
15711590
}
15721591

1573-
static void edma_tc_set_pm_state(struct edma_tc *tc, bool enable)
1574-
{
1575-
struct platform_device *tc_pdev;
1576-
int ret;
1577-
1578-
if (!IS_ENABLED(CONFIG_OF) || !tc)
1579-
return;
1580-
1581-
tc_pdev = of_find_device_by_node(tc->node);
1582-
if (!tc_pdev) {
1583-
pr_err("%s: TPTC device is not found\n", __func__);
1584-
return;
1585-
}
1586-
if (!pm_runtime_enabled(&tc_pdev->dev))
1587-
pm_runtime_enable(&tc_pdev->dev);
1588-
1589-
if (enable)
1590-
ret = pm_runtime_get_sync(&tc_pdev->dev);
1591-
else
1592-
ret = pm_runtime_put_sync(&tc_pdev->dev);
1593-
1594-
if (ret < 0)
1595-
pr_err("%s: pm_runtime_%s_sync() failed for %s\n", __func__,
1596-
enable ? "get" : "put", dev_name(&tc_pdev->dev));
1597-
}
1598-
15991592
/* Alloc channel resources */
16001593
static int edma_alloc_chan_resources(struct dma_chan *chan)
16011594
{
@@ -1632,8 +1625,6 @@ static int edma_alloc_chan_resources(struct dma_chan *chan)
16321625
EDMA_CHAN_SLOT(echan->ch_num), chan->chan_id,
16331626
echan->hw_triggered ? "HW" : "SW");
16341627

1635-
edma_tc_set_pm_state(echan->tc, true);
1636-
16371628
return 0;
16381629

16391630
err_slot:
@@ -1670,7 +1661,6 @@ static void edma_free_chan_resources(struct dma_chan *chan)
16701661
echan->alloced = false;
16711662
}
16721663

1673-
edma_tc_set_pm_state(echan->tc, false);
16741664
echan->tc = NULL;
16751665
echan->hw_triggered = false;
16761666

@@ -2417,10 +2407,8 @@ static int edma_pm_suspend(struct device *dev)
24172407
int i;
24182408

24192409
for (i = 0; i < ecc->num_channels; i++) {
2420-
if (echan[i].alloced) {
2410+
if (echan[i].alloced)
24212411
edma_setup_interrupt(&echan[i], false);
2422-
edma_tc_set_pm_state(echan[i].tc, false);
2423-
}
24242412
}
24252413

24262414
return 0;
@@ -2450,8 +2438,6 @@ static int edma_pm_resume(struct device *dev)
24502438

24512439
/* Set up channel -> slot mapping for the entry slot */
24522440
edma_set_chmap(&echan[i], echan[i].slot[0]);
2453-
2454-
edma_tc_set_pm_state(echan[i].tc, true);
24552441
}
24562442
}
24572443

@@ -2475,7 +2461,8 @@ static struct platform_driver edma_driver = {
24752461

24762462
static int edma_tptc_probe(struct platform_device *pdev)
24772463
{
2478-
return 0;
2464+
pm_runtime_enable(&pdev->dev);
2465+
return pm_runtime_get_sync(&pdev->dev);
24792466
}
24802467

24812468
static struct platform_driver edma_tptc_driver = {

drivers/dma/hsu/hsu.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ static void hsu_dma_chan_start(struct hsu_dma_chan *hsuc)
6464

6565
if (hsuc->direction == DMA_MEM_TO_DEV) {
6666
bsr = config->dst_maxburst;
67-
mtsr = config->dst_addr_width;
67+
mtsr = config->src_addr_width;
6868
} else if (hsuc->direction == DMA_DEV_TO_MEM) {
6969
bsr = config->src_maxburst;
70-
mtsr = config->src_addr_width;
70+
mtsr = config->dst_addr_width;
7171
}
7272

7373
hsu_chan_disable(hsuc);
@@ -135,7 +135,7 @@ static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc)
135135
sr = hsu_chan_readl(hsuc, HSU_CH_SR);
136136
spin_unlock_irqrestore(&hsuc->vchan.lock, flags);
137137

138-
return sr;
138+
return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
139139
}
140140

141141
irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr)
@@ -254,10 +254,13 @@ static void hsu_dma_issue_pending(struct dma_chan *chan)
254254
static size_t hsu_dma_active_desc_size(struct hsu_dma_chan *hsuc)
255255
{
256256
struct hsu_dma_desc *desc = hsuc->desc;
257-
size_t bytes = desc->length;
257+
size_t bytes = 0;
258258
int i;
259259

260-
i = desc->active % HSU_DMA_CHAN_NR_DESC;
260+
for (i = desc->active; i < desc->nents; i++)
261+
bytes += desc->sg[i].len;
262+
263+
i = HSU_DMA_CHAN_NR_DESC - 1;
261264
do {
262265
bytes += hsu_chan_readl(hsuc, HSU_CH_DxTSR(i));
263266
} while (--i >= 0);

drivers/dma/hsu/hsu.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
#define HSU_CH_SR_DESCTO(x) BIT(8 + (x))
4242
#define HSU_CH_SR_DESCTO_ANY (BIT(11) | BIT(10) | BIT(9) | BIT(8))
4343
#define HSU_CH_SR_CHE BIT(15)
44+
#define HSU_CH_SR_DESCE(x) BIT(16 + (x))
45+
#define HSU_CH_SR_DESCE_ANY (BIT(19) | BIT(18) | BIT(17) | BIT(16))
46+
#define HSU_CH_SR_CDESC_ANY (BIT(31) | BIT(30))
4447

4548
/* Bits in HSU_CH_CR */
4649
#define HSU_CH_CR_CHA BIT(0)

drivers/dma/omap-dma.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ struct omap_chan {
4848
unsigned dma_sig;
4949
bool cyclic;
5050
bool paused;
51+
bool running;
5152

5253
int dma_ch;
5354
struct omap_desc *desc;
@@ -294,6 +295,8 @@ static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
294295

295296
/* Enable channel */
296297
omap_dma_chan_write(c, CCR, d->ccr | CCR_ENABLE);
298+
299+
c->running = true;
297300
}
298301

299302
static void omap_dma_stop(struct omap_chan *c)
@@ -355,6 +358,8 @@ static void omap_dma_stop(struct omap_chan *c)
355358

356359
omap_dma_chan_write(c, CLNK_CTRL, val);
357360
}
361+
362+
c->running = false;
358363
}
359364

360365
static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
@@ -673,15 +678,20 @@ static enum dma_status omap_dma_tx_status(struct dma_chan *chan,
673678
struct omap_chan *c = to_omap_dma_chan(chan);
674679
struct virt_dma_desc *vd;
675680
enum dma_status ret;
676-
uint32_t ccr;
677681
unsigned long flags;
678682

679-
ccr = omap_dma_chan_read(c, CCR);
680-
/* The channel is no longer active, handle the completion right away */
681-
if (!(ccr & CCR_ENABLE))
682-
omap_dma_callback(c->dma_ch, 0, c);
683-
684683
ret = dma_cookie_status(chan, cookie, txstate);
684+
685+
if (!c->paused && c->running) {
686+
uint32_t ccr = omap_dma_chan_read(c, CCR);
687+
/*
688+
* The channel is no longer active, set the return value
689+
* accordingly
690+
*/
691+
if (!(ccr & CCR_ENABLE))
692+
ret = DMA_COMPLETE;
693+
}
694+
685695
if (ret == DMA_COMPLETE || !txstate)
686696
return ret;
687697

@@ -945,9 +955,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_memcpy(
945955
d->ccr = c->ccr;
946956
d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_POSTINC;
947957

948-
d->cicr = CICR_DROP_IE;
949-
if (tx_flags & DMA_PREP_INTERRUPT)
950-
d->cicr |= CICR_FRAME_IE;
958+
d->cicr = CICR_DROP_IE | CICR_FRAME_IE;
951959

952960
d->csdp = data_type;
953961

drivers/dma/xilinx/xilinx_vdma.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
12361236
struct xilinx_vdma_device *xdev = ofdma->of_dma_data;
12371237
int chan_id = dma_spec->args[0];
12381238

1239-
if (chan_id >= XILINX_VDMA_MAX_CHANS_PER_DEVICE)
1239+
if (chan_id >= XILINX_VDMA_MAX_CHANS_PER_DEVICE || !xdev->chan[chan_id])
12401240
return NULL;
12411241

12421242
return dma_get_slave_channel(&xdev->chan[chan_id]->common);

0 commit comments

Comments
 (0)