Skip to content

Commit 0665a4e

Browse files
committed
Merge tag 'dmaengine-fix-5.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine into master
Pull dmaengine fixes from Vinod Koul: - update dmaengine tree location to kernel.org - dmatest fix for completing threads - driver fixes for k3dma, fsl-dma, idxd, ,tegra, and few other drivers * tag 'dmaengine-fix-5.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine: (21 commits) dmaengine: ioat setting ioat timeout as module parameter dmaengine: fsl-edma: fix wrong tcd endianness for big-endian cpu dmaengine: dmatest: stop completed threads when running without set channel dmaengine: fsl-edma-common: correct DSIZE_32BYTE dmaengine: dw: Initialize channel before each transfer dmaengine: idxd: fix misc interrupt handler thread unmasking dmaengine: idxd: cleanup workqueue config after disabling dmaengine: tegra210-adma: Fix runtime PM imbalance on error dmaengine: mcf-edma: Fix NULL pointer exception in mcf_edma_tx_handler dmaengine: fsl-edma: Fix NULL pointer exception in fsl_edma_tx_handler dmaengine: fsl-edma: Add lockdep assert for exported function dmaengine: idxd: fix hw descriptor fields for delta record dmaengine: ti: k3-udma: add missing put_device() call in of_xudma_dev_get() dmaengine: sh: usb-dmac: set tx_result parameters dmaengine: ti: k3-udma: Fix delayed_work usage for tx drain workaround dmaengine: idxd: fix cdev locking for open and release dmaengine: imx-sdma: Fix: Remove 'always true' comparison MAINTAINERS: switch dmaengine tree to kernel.org dmaengine: ti: k3-udma: Fix the running channel handling in alloc_chan_resources dmaengine: ti: k3-udma: Fix cleanup code for alloc_chan_resources ...
2 parents 6cbba1f + 87730cc commit 0665a4e

File tree

20 files changed

+128
-60
lines changed

20 files changed

+128
-60
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5112,7 +5112,7 @@ M: Vinod Koul <[email protected]>
51125112
51135113
S: Maintained
51145114
Q: https://patchwork.kernel.org/project/linux-dmaengine/list/
5115-
T: git git://git.infradead.org/users/vkoul/slave-dma.git
5115+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git
51165116
F: Documentation/devicetree/bindings/dma/
51175117
F: Documentation/driver-api/dmaengine/
51185118
F: drivers/dma/

drivers/dma/dmatest.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,8 @@ static int dmatest_run_set(const char *val, const struct kernel_param *kp)
11761176
} else if (dmatest_run) {
11771177
if (!is_threaded_test_pending(info)) {
11781178
pr_info("No channels configured, continue with any\n");
1179+
if (!is_threaded_test_run(info))
1180+
stop_threaded_test(info);
11791181
add_threaded_test(info);
11801182
}
11811183
start_threaded_tests(info);

drivers/dma/dw/core.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,11 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
118118
{
119119
struct dw_dma *dw = to_dw_dma(dwc->chan.device);
120120

121-
if (test_bit(DW_DMA_IS_INITIALIZED, &dwc->flags))
122-
return;
123-
124121
dw->initialize_chan(dwc);
125122

126123
/* Enable interrupts */
127124
channel_set_bit(dw, MASK.XFER, dwc->mask);
128125
channel_set_bit(dw, MASK.ERROR, dwc->mask);
129-
130-
set_bit(DW_DMA_IS_INITIALIZED, &dwc->flags);
131126
}
132127

133128
/*----------------------------------------------------------------------*/
@@ -954,8 +949,6 @@ static void dwc_issue_pending(struct dma_chan *chan)
954949

955950
void do_dw_dma_off(struct dw_dma *dw)
956951
{
957-
unsigned int i;
958-
959952
dma_writel(dw, CFG, 0);
960953

961954
channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
@@ -966,9 +959,6 @@ void do_dw_dma_off(struct dw_dma *dw)
966959

967960
while (dma_readl(dw, CFG) & DW_CFG_DMA_EN)
968961
cpu_relax();
969-
970-
for (i = 0; i < dw->dma.chancnt; i++)
971-
clear_bit(DW_DMA_IS_INITIALIZED, &dw->chan[i].flags);
972962
}
973963

974964
void do_dw_dma_on(struct dw_dma *dw)
@@ -1032,8 +1022,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
10321022
/* Clear custom channel configuration */
10331023
memset(&dwc->dws, 0, sizeof(struct dw_dma_slave));
10341024

1035-
clear_bit(DW_DMA_IS_INITIALIZED, &dwc->flags);
1036-
10371025
/* Disable interrupts */
10381026
channel_clear_bit(dw, MASK.XFER, dwc->mask);
10391027
channel_clear_bit(dw, MASK.BLOCK, dwc->mask);

drivers/dma/fsl-edma-common.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -352,26 +352,28 @@ static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
352352
/*
353353
* TCD parameters are stored in struct fsl_edma_hw_tcd in little
354354
* endian format. However, we need to load the TCD registers in
355-
* big- or little-endian obeying the eDMA engine model endian.
355+
* big- or little-endian obeying the eDMA engine model endian,
356+
* and this is performed from specific edma_write functions
356357
*/
357358
edma_writew(edma, 0, &regs->tcd[ch].csr);
358-
edma_writel(edma, le32_to_cpu(tcd->saddr), &regs->tcd[ch].saddr);
359-
edma_writel(edma, le32_to_cpu(tcd->daddr), &regs->tcd[ch].daddr);
360359

361-
edma_writew(edma, le16_to_cpu(tcd->attr), &regs->tcd[ch].attr);
362-
edma_writew(edma, le16_to_cpu(tcd->soff), &regs->tcd[ch].soff);
360+
edma_writel(edma, (s32)tcd->saddr, &regs->tcd[ch].saddr);
361+
edma_writel(edma, (s32)tcd->daddr, &regs->tcd[ch].daddr);
363362

364-
edma_writel(edma, le32_to_cpu(tcd->nbytes), &regs->tcd[ch].nbytes);
365-
edma_writel(edma, le32_to_cpu(tcd->slast), &regs->tcd[ch].slast);
363+
edma_writew(edma, (s16)tcd->attr, &regs->tcd[ch].attr);
364+
edma_writew(edma, tcd->soff, &regs->tcd[ch].soff);
366365

367-
edma_writew(edma, le16_to_cpu(tcd->citer), &regs->tcd[ch].citer);
368-
edma_writew(edma, le16_to_cpu(tcd->biter), &regs->tcd[ch].biter);
369-
edma_writew(edma, le16_to_cpu(tcd->doff), &regs->tcd[ch].doff);
366+
edma_writel(edma, (s32)tcd->nbytes, &regs->tcd[ch].nbytes);
367+
edma_writel(edma, (s32)tcd->slast, &regs->tcd[ch].slast);
370368

371-
edma_writel(edma, le32_to_cpu(tcd->dlast_sga),
369+
edma_writew(edma, (s16)tcd->citer, &regs->tcd[ch].citer);
370+
edma_writew(edma, (s16)tcd->biter, &regs->tcd[ch].biter);
371+
edma_writew(edma, (s16)tcd->doff, &regs->tcd[ch].doff);
372+
373+
edma_writel(edma, (s32)tcd->dlast_sga,
372374
&regs->tcd[ch].dlast_sga);
373375

374-
edma_writew(edma, le16_to_cpu(tcd->csr), &regs->tcd[ch].csr);
376+
edma_writew(edma, (s16)tcd->csr, &regs->tcd[ch].csr);
375377
}
376378

377379
static inline
@@ -589,6 +591,8 @@ void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)
589591
{
590592
struct virt_dma_desc *vdesc;
591593

594+
lockdep_assert_held(&fsl_chan->vchan.lock);
595+
592596
vdesc = vchan_next_desc(&fsl_chan->vchan);
593597
if (!vdesc)
594598
return;

drivers/dma/fsl-edma-common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#define EDMA_TCD_ATTR_DSIZE_16BIT BIT(0)
3434
#define EDMA_TCD_ATTR_DSIZE_32BIT BIT(1)
3535
#define EDMA_TCD_ATTR_DSIZE_64BIT (BIT(0) | BIT(1))
36-
#define EDMA_TCD_ATTR_DSIZE_32BYTE (BIT(3) | BIT(0))
36+
#define EDMA_TCD_ATTR_DSIZE_32BYTE (BIT(2) | BIT(0))
3737
#define EDMA_TCD_ATTR_SSIZE_8BIT 0
3838
#define EDMA_TCD_ATTR_SSIZE_16BIT (EDMA_TCD_ATTR_DSIZE_16BIT << 8)
3939
#define EDMA_TCD_ATTR_SSIZE_32BIT (EDMA_TCD_ATTR_DSIZE_32BIT << 8)

drivers/dma/fsl-edma.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ static irqreturn_t fsl_edma_tx_handler(int irq, void *dev_id)
4545
fsl_chan = &fsl_edma->chans[ch];
4646

4747
spin_lock(&fsl_chan->vchan.lock);
48+
49+
if (!fsl_chan->edesc) {
50+
/* terminate_all called before */
51+
spin_unlock(&fsl_chan->vchan.lock);
52+
continue;
53+
}
54+
4855
if (!fsl_chan->edesc->iscyclic) {
4956
list_del(&fsl_chan->edesc->vdesc.node);
5057
vchan_cookie_complete(&fsl_chan->edesc->vdesc);

drivers/dma/idxd/cdev.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,35 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp)
7474
struct idxd_device *idxd;
7575
struct idxd_wq *wq;
7676
struct device *dev;
77+
int rc = 0;
7778

7879
wq = inode_wq(inode);
7980
idxd = wq->idxd;
8081
dev = &idxd->pdev->dev;
8182

8283
dev_dbg(dev, "%s called: %d\n", __func__, idxd_wq_refcount(wq));
8384

84-
if (idxd_wq_refcount(wq) > 0 && wq_dedicated(wq))
85-
return -EBUSY;
86-
8785
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
8886
if (!ctx)
8987
return -ENOMEM;
9088

89+
mutex_lock(&wq->wq_lock);
90+
91+
if (idxd_wq_refcount(wq) > 0 && wq_dedicated(wq)) {
92+
rc = -EBUSY;
93+
goto failed;
94+
}
95+
9196
ctx->wq = wq;
9297
filp->private_data = ctx;
9398
idxd_wq_get(wq);
99+
mutex_unlock(&wq->wq_lock);
94100
return 0;
101+
102+
failed:
103+
mutex_unlock(&wq->wq_lock);
104+
kfree(ctx);
105+
return rc;
95106
}
96107

97108
static int idxd_cdev_release(struct inode *node, struct file *filep)
@@ -105,7 +116,9 @@ static int idxd_cdev_release(struct inode *node, struct file *filep)
105116
filep->private_data = NULL;
106117

107118
kfree(ctx);
119+
mutex_lock(&wq->wq_lock);
108120
idxd_wq_put(wq);
121+
mutex_unlock(&wq->wq_lock);
109122
return 0;
110123
}
111124

drivers/dma/idxd/device.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,31 @@ void idxd_wq_unmap_portal(struct idxd_wq *wq)
320320
devm_iounmap(dev, wq->dportal);
321321
}
322322

323+
void idxd_wq_disable_cleanup(struct idxd_wq *wq)
324+
{
325+
struct idxd_device *idxd = wq->idxd;
326+
struct device *dev = &idxd->pdev->dev;
327+
int i, wq_offset;
328+
329+
lockdep_assert_held(&idxd->dev_lock);
330+
memset(&wq->wqcfg, 0, sizeof(wq->wqcfg));
331+
wq->type = IDXD_WQT_NONE;
332+
wq->size = 0;
333+
wq->group = NULL;
334+
wq->threshold = 0;
335+
wq->priority = 0;
336+
clear_bit(WQ_FLAG_DEDICATED, &wq->flags);
337+
memset(wq->name, 0, WQ_NAME_SIZE);
338+
339+
for (i = 0; i < 8; i++) {
340+
wq_offset = idxd->wqcfg_offset + wq->id * 32 + i * sizeof(u32);
341+
iowrite32(0, idxd->reg_base + wq_offset);
342+
dev_dbg(dev, "WQ[%d][%d][%#x]: %#x\n",
343+
wq->id, i, wq_offset,
344+
ioread32(idxd->reg_base + wq_offset));
345+
}
346+
}
347+
323348
/* Device control bits */
324349
static inline bool idxd_is_enabled(struct idxd_device *idxd)
325350
{

drivers/dma/idxd/idxd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ int idxd_wq_enable(struct idxd_wq *wq);
290290
int idxd_wq_disable(struct idxd_wq *wq);
291291
int idxd_wq_map_portal(struct idxd_wq *wq);
292292
void idxd_wq_unmap_portal(struct idxd_wq *wq);
293+
void idxd_wq_disable_cleanup(struct idxd_wq *wq);
293294

294295
/* submission */
295296
int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc);

drivers/dma/idxd/irq.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ irqreturn_t idxd_misc_thread(int vec, void *data)
141141

142142
iowrite32(cause, idxd->reg_base + IDXD_INTCAUSE_OFFSET);
143143
if (!err)
144-
return IRQ_HANDLED;
144+
goto out;
145145

146146
gensts.bits = ioread32(idxd->reg_base + IDXD_GENSTATS_OFFSET);
147147
if (gensts.state == IDXD_DEVICE_STATE_HALT) {
@@ -162,6 +162,7 @@ irqreturn_t idxd_misc_thread(int vec, void *data)
162162
spin_unlock_bh(&idxd->dev_lock);
163163
}
164164

165+
out:
165166
idxd_unmask_msix_vector(idxd, irq_entry->id);
166167
return IRQ_HANDLED;
167168
}

0 commit comments

Comments
 (0)