dmaengine-4.10-rc4
dmaengine fixes for 4.10-rc4 The fixes this time around are spread over drivers, pretty normal update. o PCI ID for SKL ioatdma, workaround for SKX and ioat_alloc_chan_resources sleepy allocation fix. o dw kconfig typo fix o null pointer deref for stm32 o MAINTAINERS Update for at_hdmac o pl330 runtime pm fixes o omap-dma port window fix o rcar-dmac unmap slave resource fix. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJYekAeAAoJEHwUBw8lI4NHyWAQAMQxH4dOms2p4PuM65HCwJFW BvEsljmvn+XmlqwhaMxrwGcyMPUpVSkQUkMQZYa9hMAH4fwWLIAemxdHYR9WpXL4 YsVz9pAgDs6G3XbunhMA6mM5vyR18uKkzUaLWtU/z4nw45RWe7NkG9Gw7k2gWKfK rNYIOYts4Ue3sPXsYjYn4mdHkWslFcaKuxxRZGpKAmF/V7i7m5xg6WVEykVRK7EL 0e944zdAwmRkc3dcW+SWmZqbZwp+Sjj0Vn5kCbTEoItUQN40VnxOK25ZN+YAxpxg 28pljjTfo0LRW0rgNUGulFhg0ssMns4J3gArfqbzRvDWOFCH6MZ1e1CwbLmZLF9U rK/escqsKuXFG76EstdZzfjq0H15vfF1backq23ww6WXr9w4TAUwUJR7mwShVP+O 9WTkfjwlXEnUoixutfsfTr7YSdztCBXB34BLJxNKItl5Mm7N923BTPW06e9J7S61 Fiv8E85U4WnMe1BLBPNK550Zz6YUAtqfBeYBFWZExury9jSX5tIjeoEbaxDO+FEJ fvWcjFoHZ2nQfigyafaoEIkpvjnTgveSs39tPWhTat/pucCb7za/aiA7syR9oGF2 kRa7++5TKt7q+hr1KOzvK3TNgI8fVItBd0Asi0LejIdJa4OoxAPNa7EuRLNh+vZG YQoKllPDYToI/RowjGKW =pJ7d -----END PGP SIGNATURE----- Merge tag 'dmaengine-fix-4.10-rc4' of git://git.infradead.org/users/vkoul/slave-dma Pull dmaengine fixes from Vinod Koul: "The fixes this time around are spread over drivers, pretty normal update: - PCI ID for SKL ioatdma, workaround for SKX and ioat_alloc_chan_resources sleepy allocation fix - dw kconfig typo fix - null pointer deref for stm32 - MAINTAINERS Update for at_hdmac - pl330 runtime pm fixes - omap-dma port window fix - rcar-dmac unmap slave resource fix" * tag 'dmaengine-fix-4.10-rc4' of git://git.infradead.org/users/vkoul/slave-dma: dmaengine: rcar-dmac: unmap slave resource when channel is freed dmaengine: omap-dma: Fix the port_window support dmaengine: iota: ioat_alloc_chan_resources should not perform sleeping allocations. dmaengine: pl330: Fix runtime PM support for terminated transfers MAINTAINERS: dmaengine: Update + Hand over the at_hdmac driver to Ludovic dmaengine: omap-dma: Fix dynamic lch_map allocation dmaengine: ti-dma-crossbar: Add some 'of_node_put()' in error path. dmaengine: stm32-dma: Fix null pointer dereference in stm32_dma_tx_status dmaengine: stm32-dma: Set correct args number for DMA request from DT dmaengine: dw: fix typo in Kconfig dmaengine: ioatdma: workaround SKX ioatdma version dmaengine: ioatdma: Add Skylake PCI Dev ID
This commit is contained in:
commit
f0ad17712b
17
MAINTAINERS
17
MAINTAINERS
|
@ -2193,14 +2193,6 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
|||
S: Supported
|
||||
F: sound/soc/atmel
|
||||
|
||||
ATMEL DMA DRIVER
|
||||
M: Nicolas Ferre <nicolas.ferre@atmel.com>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Supported
|
||||
F: drivers/dma/at_hdmac.c
|
||||
F: drivers/dma/at_hdmac_regs.h
|
||||
F: include/linux/platform_data/dma-atmel.h
|
||||
|
||||
ATMEL XDMA DRIVER
|
||||
M: Ludovic Desroches <ludovic.desroches@atmel.com>
|
||||
L: linux-arm-kernel@lists.infradead.org
|
||||
|
@ -8178,6 +8170,15 @@ S: Maintained
|
|||
F: drivers/tty/serial/atmel_serial.c
|
||||
F: include/linux/atmel_serial.h
|
||||
|
||||
MICROCHIP / ATMEL DMA DRIVER
|
||||
M: Ludovic Desroches <ludovic.desroches@microchip.com>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
L: dmaengine@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/dma/at_hdmac.c
|
||||
F: drivers/dma/at_hdmac_regs.h
|
||||
F: include/linux/platform_data/dma-atmel.h
|
||||
|
||||
MICROCHIP / ATMEL ISC DRIVER
|
||||
M: Songjun Wu <songjun.wu@microchip.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
|
|
@ -24,5 +24,5 @@ config DW_DMAC_PCI
|
|||
select DW_DMAC_CORE
|
||||
help
|
||||
Support the Synopsys DesignWare AHB DMA controller on the
|
||||
platfroms that enumerate it as a PCI device. For example,
|
||||
platforms that enumerate it as a PCI device. For example,
|
||||
Intel Medfield has integrated this GPDMA controller.
|
||||
|
|
|
@ -64,6 +64,8 @@
|
|||
#define PCI_DEVICE_ID_INTEL_IOAT_BDX8 0x6f2e
|
||||
#define PCI_DEVICE_ID_INTEL_IOAT_BDX9 0x6f2f
|
||||
|
||||
#define PCI_DEVICE_ID_INTEL_IOAT_SKX 0x2021
|
||||
|
||||
#define IOAT_VER_1_2 0x12 /* Version 1.2 */
|
||||
#define IOAT_VER_2_0 0x20 /* Version 2.0 */
|
||||
#define IOAT_VER_3_0 0x30 /* Version 3.0 */
|
||||
|
|
|
@ -106,6 +106,8 @@ static struct pci_device_id ioat_pci_tbl[] = {
|
|||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX8) },
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX9) },
|
||||
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SKX) },
|
||||
|
||||
/* I/OAT v3.3 platforms */
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_BWD0) },
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_BWD1) },
|
||||
|
@ -243,10 +245,15 @@ static bool is_bdx_ioat(struct pci_dev *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool is_skx_ioat(struct pci_dev *pdev)
|
||||
{
|
||||
return (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_SKX) ? true : false;
|
||||
}
|
||||
|
||||
static bool is_xeon_cb32(struct pci_dev *pdev)
|
||||
{
|
||||
return is_jf_ioat(pdev) || is_snb_ioat(pdev) || is_ivb_ioat(pdev) ||
|
||||
is_hsw_ioat(pdev) || is_bdx_ioat(pdev);
|
||||
is_hsw_ioat(pdev) || is_bdx_ioat(pdev) || is_skx_ioat(pdev);
|
||||
}
|
||||
|
||||
bool is_bwd_ioat(struct pci_dev *pdev)
|
||||
|
@ -693,7 +700,7 @@ static int ioat_alloc_chan_resources(struct dma_chan *c)
|
|||
/* doing 2 32bit writes to mmio since 1 64b write doesn't work */
|
||||
ioat_chan->completion =
|
||||
dma_pool_zalloc(ioat_chan->ioat_dma->completion_pool,
|
||||
GFP_KERNEL, &ioat_chan->completion_dma);
|
||||
GFP_NOWAIT, &ioat_chan->completion_dma);
|
||||
if (!ioat_chan->completion)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -703,7 +710,7 @@ static int ioat_alloc_chan_resources(struct dma_chan *c)
|
|||
ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH);
|
||||
|
||||
order = IOAT_MAX_ORDER;
|
||||
ring = ioat_alloc_ring(c, order, GFP_KERNEL);
|
||||
ring = ioat_alloc_ring(c, order, GFP_NOWAIT);
|
||||
if (!ring)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1357,6 +1364,8 @@ static int ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
|
||||
device->version = readb(device->reg_base + IOAT_VER_OFFSET);
|
||||
if (device->version >= IOAT_VER_3_0) {
|
||||
if (is_skx_ioat(pdev))
|
||||
device->version = IOAT_VER_3_2;
|
||||
err = ioat3_dma_probe(device, ioat_dca_enabled);
|
||||
|
||||
if (device->version >= IOAT_VER_3_3)
|
||||
|
|
|
@ -938,6 +938,23 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
|
|||
d->ccr |= CCR_DST_AMODE_POSTINC;
|
||||
if (port_window) {
|
||||
d->ccr |= CCR_SRC_AMODE_DBLIDX;
|
||||
|
||||
if (port_window_bytes >= 64)
|
||||
d->csdp |= CSDP_SRC_BURST_64;
|
||||
else if (port_window_bytes >= 32)
|
||||
d->csdp |= CSDP_SRC_BURST_32;
|
||||
else if (port_window_bytes >= 16)
|
||||
d->csdp |= CSDP_SRC_BURST_16;
|
||||
|
||||
} else {
|
||||
d->ccr |= CCR_SRC_AMODE_CONSTANT;
|
||||
}
|
||||
} else {
|
||||
d->csdp = CSDP_SRC_BURST_64 | CSDP_SRC_PACKED;
|
||||
|
||||
d->ccr |= CCR_SRC_AMODE_POSTINC;
|
||||
if (port_window) {
|
||||
d->ccr |= CCR_DST_AMODE_DBLIDX;
|
||||
d->ei = 1;
|
||||
/*
|
||||
* One frame covers the port_window and by configure
|
||||
|
@ -948,27 +965,11 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
|
|||
d->fi = -(port_window_bytes - 1);
|
||||
|
||||
if (port_window_bytes >= 64)
|
||||
d->csdp = CSDP_SRC_BURST_64 | CSDP_SRC_PACKED;
|
||||
d->csdp |= CSDP_DST_BURST_64;
|
||||
else if (port_window_bytes >= 32)
|
||||
d->csdp = CSDP_SRC_BURST_32 | CSDP_SRC_PACKED;
|
||||
d->csdp |= CSDP_DST_BURST_32;
|
||||
else if (port_window_bytes >= 16)
|
||||
d->csdp = CSDP_SRC_BURST_16 | CSDP_SRC_PACKED;
|
||||
} else {
|
||||
d->ccr |= CCR_SRC_AMODE_CONSTANT;
|
||||
}
|
||||
} else {
|
||||
d->csdp = CSDP_SRC_BURST_64 | CSDP_SRC_PACKED;
|
||||
|
||||
d->ccr |= CCR_SRC_AMODE_POSTINC;
|
||||
if (port_window) {
|
||||
d->ccr |= CCR_DST_AMODE_DBLIDX;
|
||||
|
||||
if (port_window_bytes >= 64)
|
||||
d->csdp = CSDP_DST_BURST_64 | CSDP_DST_PACKED;
|
||||
else if (port_window_bytes >= 32)
|
||||
d->csdp = CSDP_DST_BURST_32 | CSDP_DST_PACKED;
|
||||
else if (port_window_bytes >= 16)
|
||||
d->csdp = CSDP_DST_BURST_16 | CSDP_DST_PACKED;
|
||||
d->csdp |= CSDP_DST_BURST_16;
|
||||
} else {
|
||||
d->ccr |= CCR_DST_AMODE_CONSTANT;
|
||||
}
|
||||
|
@ -1017,7 +1018,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
|
|||
osg->addr = sg_dma_address(sgent);
|
||||
osg->en = en;
|
||||
osg->fn = sg_dma_len(sgent) / frame_bytes;
|
||||
if (port_window && dir == DMA_MEM_TO_DEV) {
|
||||
if (port_window && dir == DMA_DEV_TO_MEM) {
|
||||
osg->ei = 1;
|
||||
/*
|
||||
* One frame covers the port_window and by configure
|
||||
|
@ -1452,6 +1453,7 @@ static int omap_dma_probe(struct platform_device *pdev)
|
|||
struct omap_dmadev *od;
|
||||
struct resource *res;
|
||||
int rc, i, irq;
|
||||
u32 lch_count;
|
||||
|
||||
od = devm_kzalloc(&pdev->dev, sizeof(*od), GFP_KERNEL);
|
||||
if (!od)
|
||||
|
@ -1494,20 +1496,31 @@ static int omap_dma_probe(struct platform_device *pdev)
|
|||
spin_lock_init(&od->lock);
|
||||
spin_lock_init(&od->irq_lock);
|
||||
|
||||
if (!pdev->dev.of_node) {
|
||||
od->dma_requests = od->plat->dma_attr->lch_count;
|
||||
if (unlikely(!od->dma_requests))
|
||||
od->dma_requests = OMAP_SDMA_REQUESTS;
|
||||
} else if (of_property_read_u32(pdev->dev.of_node, "dma-requests",
|
||||
&od->dma_requests)) {
|
||||
/* Number of DMA requests */
|
||||
od->dma_requests = OMAP_SDMA_REQUESTS;
|
||||
if (pdev->dev.of_node && of_property_read_u32(pdev->dev.of_node,
|
||||
"dma-requests",
|
||||
&od->dma_requests)) {
|
||||
dev_info(&pdev->dev,
|
||||
"Missing dma-requests property, using %u.\n",
|
||||
OMAP_SDMA_REQUESTS);
|
||||
od->dma_requests = OMAP_SDMA_REQUESTS;
|
||||
}
|
||||
|
||||
od->lch_map = devm_kcalloc(&pdev->dev, od->dma_requests,
|
||||
sizeof(*od->lch_map), GFP_KERNEL);
|
||||
/* Number of available logical channels */
|
||||
if (!pdev->dev.of_node) {
|
||||
lch_count = od->plat->dma_attr->lch_count;
|
||||
if (unlikely(!lch_count))
|
||||
lch_count = OMAP_SDMA_CHANNELS;
|
||||
} else if (of_property_read_u32(pdev->dev.of_node, "dma-channels",
|
||||
&lch_count)) {
|
||||
dev_info(&pdev->dev,
|
||||
"Missing dma-channels property, using %u.\n",
|
||||
OMAP_SDMA_CHANNELS);
|
||||
lch_count = OMAP_SDMA_CHANNELS;
|
||||
}
|
||||
|
||||
od->lch_map = devm_kcalloc(&pdev->dev, lch_count, sizeof(*od->lch_map),
|
||||
GFP_KERNEL);
|
||||
if (!od->lch_map)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
@ -448,6 +448,9 @@ struct dma_pl330_chan {
|
|||
|
||||
/* for cyclic capability */
|
||||
bool cyclic;
|
||||
|
||||
/* for runtime pm tracking */
|
||||
bool active;
|
||||
};
|
||||
|
||||
struct pl330_dmac {
|
||||
|
@ -2033,6 +2036,7 @@ static void pl330_tasklet(unsigned long data)
|
|||
_stop(pch->thread);
|
||||
spin_unlock(&pch->thread->dmac->lock);
|
||||
power_down = true;
|
||||
pch->active = false;
|
||||
} else {
|
||||
/* Make sure the PL330 Channel thread is active */
|
||||
spin_lock(&pch->thread->dmac->lock);
|
||||
|
@ -2052,6 +2056,7 @@ static void pl330_tasklet(unsigned long data)
|
|||
desc->status = PREP;
|
||||
list_move_tail(&desc->node, &pch->work_list);
|
||||
if (power_down) {
|
||||
pch->active = true;
|
||||
spin_lock(&pch->thread->dmac->lock);
|
||||
_start(pch->thread);
|
||||
spin_unlock(&pch->thread->dmac->lock);
|
||||
|
@ -2166,6 +2171,7 @@ static int pl330_terminate_all(struct dma_chan *chan)
|
|||
unsigned long flags;
|
||||
struct pl330_dmac *pl330 = pch->dmac;
|
||||
LIST_HEAD(list);
|
||||
bool power_down = false;
|
||||
|
||||
pm_runtime_get_sync(pl330->ddma.dev);
|
||||
spin_lock_irqsave(&pch->lock, flags);
|
||||
|
@ -2176,6 +2182,8 @@ static int pl330_terminate_all(struct dma_chan *chan)
|
|||
pch->thread->req[0].desc = NULL;
|
||||
pch->thread->req[1].desc = NULL;
|
||||
pch->thread->req_running = -1;
|
||||
power_down = pch->active;
|
||||
pch->active = false;
|
||||
|
||||
/* Mark all desc done */
|
||||
list_for_each_entry(desc, &pch->submitted_list, node) {
|
||||
|
@ -2193,6 +2201,8 @@ static int pl330_terminate_all(struct dma_chan *chan)
|
|||
list_splice_tail_init(&pch->completed_list, &pl330->desc_pool);
|
||||
spin_unlock_irqrestore(&pch->lock, flags);
|
||||
pm_runtime_mark_last_busy(pl330->ddma.dev);
|
||||
if (power_down)
|
||||
pm_runtime_put_autosuspend(pl330->ddma.dev);
|
||||
pm_runtime_put_autosuspend(pl330->ddma.dev);
|
||||
|
||||
return 0;
|
||||
|
@ -2357,6 +2367,7 @@ static void pl330_issue_pending(struct dma_chan *chan)
|
|||
* updated on work_list emptiness status.
|
||||
*/
|
||||
WARN_ON(list_empty(&pch->submitted_list));
|
||||
pch->active = true;
|
||||
pm_runtime_get_sync(pch->dmac->ddma.dev);
|
||||
}
|
||||
list_splice_tail_init(&pch->submitted_list, &pch->work_list);
|
||||
|
|
|
@ -986,6 +986,7 @@ static void rcar_dmac_free_chan_resources(struct dma_chan *chan)
|
|||
{
|
||||
struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
|
||||
struct rcar_dmac *dmac = to_rcar_dmac(chan->device);
|
||||
struct rcar_dmac_chan_map *map = &rchan->map;
|
||||
struct rcar_dmac_desc_page *page, *_page;
|
||||
struct rcar_dmac_desc *desc;
|
||||
LIST_HEAD(list);
|
||||
|
@ -1019,6 +1020,13 @@ static void rcar_dmac_free_chan_resources(struct dma_chan *chan)
|
|||
free_page((unsigned long)page);
|
||||
}
|
||||
|
||||
/* Remove slave mapping if present. */
|
||||
if (map->slave.xfer_size) {
|
||||
dma_unmap_resource(chan->device->dev, map->addr,
|
||||
map->slave.xfer_size, map->dir, 0);
|
||||
map->slave.xfer_size = 0;
|
||||
}
|
||||
|
||||
pm_runtime_put(chan->device->dev);
|
||||
}
|
||||
|
||||
|
|
|
@ -880,7 +880,7 @@ static enum dma_status stm32_dma_tx_status(struct dma_chan *c,
|
|||
struct virt_dma_desc *vdesc;
|
||||
enum dma_status status;
|
||||
unsigned long flags;
|
||||
u32 residue;
|
||||
u32 residue = 0;
|
||||
|
||||
status = dma_cookie_status(c, cookie, state);
|
||||
if ((status == DMA_COMPLETE) || (!state))
|
||||
|
@ -888,16 +888,12 @@ static enum dma_status stm32_dma_tx_status(struct dma_chan *c,
|
|||
|
||||
spin_lock_irqsave(&chan->vchan.lock, flags);
|
||||
vdesc = vchan_find_desc(&chan->vchan, cookie);
|
||||
if (cookie == chan->desc->vdesc.tx.cookie) {
|
||||
if (chan->desc && cookie == chan->desc->vdesc.tx.cookie)
|
||||
residue = stm32_dma_desc_residue(chan, chan->desc,
|
||||
chan->next_sg);
|
||||
} else if (vdesc) {
|
||||
else if (vdesc)
|
||||
residue = stm32_dma_desc_residue(chan,
|
||||
to_stm32_dma_desc(vdesc), 0);
|
||||
} else {
|
||||
residue = 0;
|
||||
}
|
||||
|
||||
dma_set_residue(state, residue);
|
||||
|
||||
spin_unlock_irqrestore(&chan->vchan.lock, flags);
|
||||
|
@ -972,21 +968,18 @@ static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec,
|
|||
struct stm32_dma_chan *chan;
|
||||
struct dma_chan *c;
|
||||
|
||||
if (dma_spec->args_count < 3)
|
||||
if (dma_spec->args_count < 4)
|
||||
return NULL;
|
||||
|
||||
cfg.channel_id = dma_spec->args[0];
|
||||
cfg.request_line = dma_spec->args[1];
|
||||
cfg.stream_config = dma_spec->args[2];
|
||||
cfg.threshold = 0;
|
||||
cfg.threshold = dma_spec->args[3];
|
||||
|
||||
if ((cfg.channel_id >= STM32_DMA_MAX_CHANNELS) || (cfg.request_line >=
|
||||
STM32_DMA_MAX_REQUEST_ID))
|
||||
return NULL;
|
||||
|
||||
if (dma_spec->args_count > 3)
|
||||
cfg.threshold = dma_spec->args[3];
|
||||
|
||||
chan = &dmadev->chan[cfg.channel_id];
|
||||
|
||||
c = dma_get_slave_channel(&chan->vchan.chan);
|
||||
|
|
|
@ -149,6 +149,7 @@ static int ti_am335x_xbar_probe(struct platform_device *pdev)
|
|||
match = of_match_node(ti_am335x_master_match, dma_node);
|
||||
if (!match) {
|
||||
dev_err(&pdev->dev, "DMA master is not supported\n");
|
||||
of_node_put(dma_node);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -339,6 +340,7 @@ static int ti_dra7_xbar_probe(struct platform_device *pdev)
|
|||
match = of_match_node(ti_dra7_master_match, dma_node);
|
||||
if (!match) {
|
||||
dev_err(&pdev->dev, "DMA master is not supported\n");
|
||||
of_node_put(dma_node);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue