Commit 374dab23 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'fixes' of git://git.infradead.org/users/vkoul/slave-dma

Pull slave-dmaengine fixes from Vinod Koul:
 "This contains small fixes spread across the drivers"

* 'fixes' of git://git.infradead.org/users/vkoul/slave-dma:
  dmaengine: mmp_pdma: fix warning about slave caps
  dmaengine: qcom_bam_dma: fix wrong register offsets
  dmaengine: bam-dma: fix a warning about missing capabilities
  dmaengine: ioatdma: workaround for incorrect DMACAP register
  dmaengine: at_xdmac: fix for chan conf simplification
  dmaengine: dw: don't handle interrupt when dmaengine is not used
  dma: mmp-tdma: refine dma disable and dma-pos update
  dmaengine: shdma: Move DMA stop to (runtime) suspend callbacks
  dmaenegine: mmp-pdma: fix irq handler overwrite physical chan issue
parents 9aae0df6 ecb9b424
...@@ -664,7 +664,6 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, ...@@ -664,7 +664,6 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr,
struct at_xdmac_desc *first = NULL, *prev = NULL; struct at_xdmac_desc *first = NULL, *prev = NULL;
unsigned int periods = buf_len / period_len; unsigned int periods = buf_len / period_len;
int i; int i;
u32 cfg;
dev_dbg(chan2dev(chan), "%s: buf_addr=%pad, buf_len=%zd, period_len=%zd, dir=%s, flags=0x%lx\n", dev_dbg(chan2dev(chan), "%s: buf_addr=%pad, buf_len=%zd, period_len=%zd, dir=%s, flags=0x%lx\n",
__func__, &buf_addr, buf_len, period_len, __func__, &buf_addr, buf_len, period_len,
...@@ -700,17 +699,17 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, ...@@ -700,17 +699,17 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr,
if (direction == DMA_DEV_TO_MEM) { if (direction == DMA_DEV_TO_MEM) {
desc->lld.mbr_sa = atchan->per_src_addr; desc->lld.mbr_sa = atchan->per_src_addr;
desc->lld.mbr_da = buf_addr + i * period_len; desc->lld.mbr_da = buf_addr + i * period_len;
cfg = atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG]; desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG];
} else { } else {
desc->lld.mbr_sa = buf_addr + i * period_len; desc->lld.mbr_sa = buf_addr + i * period_len;
desc->lld.mbr_da = atchan->per_dst_addr; desc->lld.mbr_da = atchan->per_dst_addr;
cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG]; desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG];
} }
desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV1 desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV1
| AT_XDMAC_MBR_UBC_NDEN | AT_XDMAC_MBR_UBC_NDEN
| AT_XDMAC_MBR_UBC_NSEN | AT_XDMAC_MBR_UBC_NSEN
| AT_XDMAC_MBR_UBC_NDE | AT_XDMAC_MBR_UBC_NDE
| period_len >> at_xdmac_get_dwidth(cfg); | period_len >> at_xdmac_get_dwidth(desc->lld.mbr_cfg);
dev_dbg(chan2dev(chan), dev_dbg(chan2dev(chan),
"%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n", "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n",
......
...@@ -626,7 +626,7 @@ static irqreturn_t dw_dma_interrupt(int irq, void *dev_id) ...@@ -626,7 +626,7 @@ static irqreturn_t dw_dma_interrupt(int irq, void *dev_id)
dev_vdbg(dw->dma.dev, "%s: status=0x%x\n", __func__, status); dev_vdbg(dw->dma.dev, "%s: status=0x%x\n", __func__, status);
/* Check if we have any interrupt from the DMAC */ /* Check if we have any interrupt from the DMAC */
if (!status) if (!status || !dw->in_use)
return IRQ_NONE; return IRQ_NONE;
/* /*
......
...@@ -230,6 +230,10 @@ static bool is_bwd_noraid(struct pci_dev *pdev) ...@@ -230,6 +230,10 @@ static bool is_bwd_noraid(struct pci_dev *pdev)
switch (pdev->device) { switch (pdev->device) {
case PCI_DEVICE_ID_INTEL_IOAT_BWD2: case PCI_DEVICE_ID_INTEL_IOAT_BWD2:
case PCI_DEVICE_ID_INTEL_IOAT_BWD3: case PCI_DEVICE_ID_INTEL_IOAT_BWD3:
case PCI_DEVICE_ID_INTEL_IOAT_BDXDE0:
case PCI_DEVICE_ID_INTEL_IOAT_BDXDE1:
case PCI_DEVICE_ID_INTEL_IOAT_BDXDE2:
case PCI_DEVICE_ID_INTEL_IOAT_BDXDE3:
return true; return true;
default: default:
return false; return false;
......
...@@ -219,6 +219,9 @@ static irqreturn_t mmp_pdma_int_handler(int irq, void *dev_id) ...@@ -219,6 +219,9 @@ static irqreturn_t mmp_pdma_int_handler(int irq, void *dev_id)
while (dint) { while (dint) {
i = __ffs(dint); i = __ffs(dint);
/* only handle interrupts belonging to pdma driver*/
if (i >= pdev->dma_channels)
break;
dint &= (dint - 1); dint &= (dint - 1);
phy = &pdev->phy[i]; phy = &pdev->phy[i];
ret = mmp_pdma_chan_handler(irq, phy); ret = mmp_pdma_chan_handler(irq, phy);
...@@ -999,6 +1002,9 @@ static int mmp_pdma_probe(struct platform_device *op) ...@@ -999,6 +1002,9 @@ static int mmp_pdma_probe(struct platform_device *op)
struct resource *iores; struct resource *iores;
int i, ret, irq = 0; int i, ret, irq = 0;
int dma_channels = 0, irq_num = 0; int dma_channels = 0, irq_num = 0;
const enum dma_slave_buswidth widths =
DMA_SLAVE_BUSWIDTH_1_BYTE | DMA_SLAVE_BUSWIDTH_2_BYTES |
DMA_SLAVE_BUSWIDTH_4_BYTES;
pdev = devm_kzalloc(&op->dev, sizeof(*pdev), GFP_KERNEL); pdev = devm_kzalloc(&op->dev, sizeof(*pdev), GFP_KERNEL);
if (!pdev) if (!pdev)
...@@ -1066,6 +1072,10 @@ static int mmp_pdma_probe(struct platform_device *op) ...@@ -1066,6 +1072,10 @@ static int mmp_pdma_probe(struct platform_device *op)
pdev->device.device_config = mmp_pdma_config; pdev->device.device_config = mmp_pdma_config;
pdev->device.device_terminate_all = mmp_pdma_terminate_all; pdev->device.device_terminate_all = mmp_pdma_terminate_all;
pdev->device.copy_align = PDMA_ALIGNMENT; pdev->device.copy_align = PDMA_ALIGNMENT;
pdev->device.src_addr_widths = widths;
pdev->device.dst_addr_widths = widths;
pdev->device.directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM);
pdev->device.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
if (pdev->dev->coherent_dma_mask) if (pdev->dev->coherent_dma_mask)
dma_set_mask(pdev->dev, pdev->dev->coherent_dma_mask); dma_set_mask(pdev->dev, pdev->dev->coherent_dma_mask);
......
...@@ -110,7 +110,7 @@ struct mmp_tdma_chan { ...@@ -110,7 +110,7 @@ struct mmp_tdma_chan {
struct tasklet_struct tasklet; struct tasklet_struct tasklet;
struct mmp_tdma_desc *desc_arr; struct mmp_tdma_desc *desc_arr;
phys_addr_t desc_arr_phys; dma_addr_t desc_arr_phys;
int desc_num; int desc_num;
enum dma_transfer_direction dir; enum dma_transfer_direction dir;
dma_addr_t dev_addr; dma_addr_t dev_addr;
...@@ -166,9 +166,12 @@ static void mmp_tdma_enable_chan(struct mmp_tdma_chan *tdmac) ...@@ -166,9 +166,12 @@ static void mmp_tdma_enable_chan(struct mmp_tdma_chan *tdmac)
static int mmp_tdma_disable_chan(struct dma_chan *chan) static int mmp_tdma_disable_chan(struct dma_chan *chan)
{ {
struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
u32 tdcr;
writel(readl(tdmac->reg_base + TDCR) & ~TDCR_CHANEN, tdcr = readl(tdmac->reg_base + TDCR);
tdmac->reg_base + TDCR); tdcr |= TDCR_ABR;
tdcr &= ~TDCR_CHANEN;
writel(tdcr, tdmac->reg_base + TDCR);
tdmac->status = DMA_COMPLETE; tdmac->status = DMA_COMPLETE;
...@@ -296,12 +299,27 @@ static int mmp_tdma_clear_chan_irq(struct mmp_tdma_chan *tdmac) ...@@ -296,12 +299,27 @@ static int mmp_tdma_clear_chan_irq(struct mmp_tdma_chan *tdmac)
return -EAGAIN; return -EAGAIN;
} }
static size_t mmp_tdma_get_pos(struct mmp_tdma_chan *tdmac)
{
size_t reg;
if (tdmac->idx == 0) {
reg = __raw_readl(tdmac->reg_base + TDSAR);
reg -= tdmac->desc_arr[0].src_addr;
} else if (tdmac->idx == 1) {
reg = __raw_readl(tdmac->reg_base + TDDAR);
reg -= tdmac->desc_arr[0].dst_addr;
} else
return -EINVAL;
return reg;
}
static irqreturn_t mmp_tdma_chan_handler(int irq, void *dev_id) static irqreturn_t mmp_tdma_chan_handler(int irq, void *dev_id)
{ {
struct mmp_tdma_chan *tdmac = dev_id; struct mmp_tdma_chan *tdmac = dev_id;
if (mmp_tdma_clear_chan_irq(tdmac) == 0) { if (mmp_tdma_clear_chan_irq(tdmac) == 0) {
tdmac->pos = (tdmac->pos + tdmac->period_len) % tdmac->buf_len;
tasklet_schedule(&tdmac->tasklet); tasklet_schedule(&tdmac->tasklet);
return IRQ_HANDLED; return IRQ_HANDLED;
} else } else
...@@ -343,7 +361,7 @@ static void mmp_tdma_free_descriptor(struct mmp_tdma_chan *tdmac) ...@@ -343,7 +361,7 @@ static void mmp_tdma_free_descriptor(struct mmp_tdma_chan *tdmac)
int size = tdmac->desc_num * sizeof(struct mmp_tdma_desc); int size = tdmac->desc_num * sizeof(struct mmp_tdma_desc);
gpool = tdmac->pool; gpool = tdmac->pool;
if (tdmac->desc_arr) if (gpool && tdmac->desc_arr)
gen_pool_free(gpool, (unsigned long)tdmac->desc_arr, gen_pool_free(gpool, (unsigned long)tdmac->desc_arr,
size); size);
tdmac->desc_arr = NULL; tdmac->desc_arr = NULL;
...@@ -499,6 +517,7 @@ static enum dma_status mmp_tdma_tx_status(struct dma_chan *chan, ...@@ -499,6 +517,7 @@ static enum dma_status mmp_tdma_tx_status(struct dma_chan *chan,
{ {
struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
tdmac->pos = mmp_tdma_get_pos(tdmac);
dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie, dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie,
tdmac->buf_len - tdmac->pos); tdmac->buf_len - tdmac->pos);
...@@ -610,7 +629,7 @@ static int mmp_tdma_probe(struct platform_device *pdev) ...@@ -610,7 +629,7 @@ static int mmp_tdma_probe(struct platform_device *pdev)
int i, ret; int i, ret;
int irq = 0, irq_num = 0; int irq = 0, irq_num = 0;
int chan_num = TDMA_CHANNEL_NUM; int chan_num = TDMA_CHANNEL_NUM;
struct gen_pool *pool; struct gen_pool *pool = NULL;
of_id = of_match_device(mmp_tdma_dt_ids, &pdev->dev); of_id = of_match_device(mmp_tdma_dt_ids, &pdev->dev);
if (of_id) if (of_id)
......
...@@ -162,9 +162,9 @@ static const struct reg_offset_data bam_v1_4_reg_info[] = { ...@@ -162,9 +162,9 @@ static const struct reg_offset_data bam_v1_4_reg_info[] = {
[BAM_P_IRQ_STTS] = { 0x1010, 0x1000, 0x00, 0x00 }, [BAM_P_IRQ_STTS] = { 0x1010, 0x1000, 0x00, 0x00 },
[BAM_P_IRQ_CLR] = { 0x1014, 0x1000, 0x00, 0x00 }, [BAM_P_IRQ_CLR] = { 0x1014, 0x1000, 0x00, 0x00 },
[BAM_P_IRQ_EN] = { 0x1018, 0x1000, 0x00, 0x00 }, [BAM_P_IRQ_EN] = { 0x1018, 0x1000, 0x00, 0x00 },
[BAM_P_EVNT_DEST_ADDR] = { 0x102C, 0x00, 0x1000, 0x00 }, [BAM_P_EVNT_DEST_ADDR] = { 0x182C, 0x00, 0x1000, 0x00 },
[BAM_P_EVNT_REG] = { 0x1018, 0x00, 0x1000, 0x00 }, [BAM_P_EVNT_REG] = { 0x1818, 0x00, 0x1000, 0x00 },
[BAM_P_SW_OFSTS] = { 0x1000, 0x00, 0x1000, 0x00 }, [BAM_P_SW_OFSTS] = { 0x1800, 0x00, 0x1000, 0x00 },
[BAM_P_DATA_FIFO_ADDR] = { 0x1824, 0x00, 0x1000, 0x00 }, [BAM_P_DATA_FIFO_ADDR] = { 0x1824, 0x00, 0x1000, 0x00 },
[BAM_P_DESC_FIFO_ADDR] = { 0x181C, 0x00, 0x1000, 0x00 }, [BAM_P_DESC_FIFO_ADDR] = { 0x181C, 0x00, 0x1000, 0x00 },
[BAM_P_EVNT_GEN_TRSHLD] = { 0x1828, 0x00, 0x1000, 0x00 }, [BAM_P_EVNT_GEN_TRSHLD] = { 0x1828, 0x00, 0x1000, 0x00 },
...@@ -1143,6 +1143,10 @@ static int bam_dma_probe(struct platform_device *pdev) ...@@ -1143,6 +1143,10 @@ static int bam_dma_probe(struct platform_device *pdev)
dma_cap_set(DMA_SLAVE, bdev->common.cap_mask); dma_cap_set(DMA_SLAVE, bdev->common.cap_mask);
/* initialize dmaengine apis */ /* initialize dmaengine apis */
bdev->common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
bdev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
bdev->common.src_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES;
bdev->common.dst_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES;
bdev->common.device_alloc_chan_resources = bam_alloc_chan; bdev->common.device_alloc_chan_resources = bam_alloc_chan;
bdev->common.device_free_chan_resources = bam_free_chan; bdev->common.device_free_chan_resources = bam_free_chan;
bdev->common.device_prep_slave_sg = bam_prep_slave_sg; bdev->common.device_prep_slave_sg = bam_prep_slave_sg;
......
...@@ -582,15 +582,12 @@ static void sh_dmae_chan_remove(struct sh_dmae_device *shdev) ...@@ -582,15 +582,12 @@ static void sh_dmae_chan_remove(struct sh_dmae_device *shdev)
} }
} }
static void sh_dmae_shutdown(struct platform_device *pdev)
{
struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
sh_dmae_ctl_stop(shdev);
}
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int sh_dmae_runtime_suspend(struct device *dev) static int sh_dmae_runtime_suspend(struct device *dev)
{ {
struct sh_dmae_device *shdev = dev_get_drvdata(dev);
sh_dmae_ctl_stop(shdev);
return 0; return 0;
} }
...@@ -605,6 +602,9 @@ static int sh_dmae_runtime_resume(struct device *dev) ...@@ -605,6 +602,9 @@ static int sh_dmae_runtime_resume(struct device *dev)
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int sh_dmae_suspend(struct device *dev) static int sh_dmae_suspend(struct device *dev)
{ {
struct sh_dmae_device *shdev = dev_get_drvdata(dev);
sh_dmae_ctl_stop(shdev);
return 0; return 0;
} }
...@@ -929,13 +929,12 @@ static int sh_dmae_remove(struct platform_device *pdev) ...@@ -929,13 +929,12 @@ static int sh_dmae_remove(struct platform_device *pdev)
} }
static struct platform_driver sh_dmae_driver = { static struct platform_driver sh_dmae_driver = {
.driver = { .driver = {
.pm = &sh_dmae_pm, .pm = &sh_dmae_pm,
.name = SH_DMAE_DRV_NAME, .name = SH_DMAE_DRV_NAME,
.of_match_table = sh_dmae_of_match, .of_match_table = sh_dmae_of_match,
}, },
.remove = sh_dmae_remove, .remove = sh_dmae_remove,
.shutdown = sh_dmae_shutdown,
}; };
static int __init sh_dmae_init(void) static int __init sh_dmae_init(void)
......
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