Commit b05a5683 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull dmaengine fixes from Vinod Koul:
 "A bunch of driver fixes:

   - idxd device RO checks and device cleanup

   - dw-edma unaligned access and alignment

   - qcom: missing minItems in binding

   - mediatek pm usage fix

   - imx init script"

* tag 'dmaengine-fix-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine:
  dt-bindings: dmaengine: qcom: gpi: Add minItems for interrupts
  dmaengine: idxd: skip clearing device context when device is read-only
  dmaengine: idxd: add RO check for wq max_transfer_size write
  dmaengine: idxd: add RO check for wq max_batch_size write
  dmaengine: idxd: fix retry value to be constant for duration of function call
  dmaengine: idxd: match type for retries var in idxd_enqcmds()
  dmaengine: dw-edma: Fix inconsistent indenting
  dmaengine: dw-edma: Fix unaligned 64bit access
  dmaengine: mediatek:Fix PM usage reference leak of mtk_uart_apdma_alloc_chan_resources
  dmaengine: imx-sdma: Fix error checking in sdma_event_remap
  dma: at_xdmac: fix a missing check on list iterator
  dmaengine: imx-sdma: fix init of uart scripts
  dmaengine: idxd: fix device cleanup on disable
parents 59f0c244 7495a5bb
...@@ -29,6 +29,7 @@ properties: ...@@ -29,6 +29,7 @@ properties:
interrupts: interrupts:
description: description:
Interrupt lines for each GPI instance Interrupt lines for each GPI instance
minItems: 1
maxItems: 13 maxItems: 13
"#dma-cells": "#dma-cells":
......
...@@ -1453,7 +1453,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, ...@@ -1453,7 +1453,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
{ {
struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan);
struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device);
struct at_xdmac_desc *desc, *_desc; struct at_xdmac_desc *desc, *_desc, *iter;
struct list_head *descs_list; struct list_head *descs_list;
enum dma_status ret; enum dma_status ret;
int residue, retry; int residue, retry;
...@@ -1568,11 +1568,13 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, ...@@ -1568,11 +1568,13 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
* microblock. * microblock.
*/ */
descs_list = &desc->descs_list; descs_list = &desc->descs_list;
list_for_each_entry_safe(desc, _desc, descs_list, desc_node) { list_for_each_entry_safe(iter, _desc, descs_list, desc_node) {
dwidth = at_xdmac_get_dwidth(desc->lld.mbr_cfg); dwidth = at_xdmac_get_dwidth(iter->lld.mbr_cfg);
residue -= (desc->lld.mbr_ubc & 0xffffff) << dwidth; residue -= (iter->lld.mbr_ubc & 0xffffff) << dwidth;
if ((desc->lld.mbr_nda & 0xfffffffc) == cur_nda) if ((iter->lld.mbr_nda & 0xfffffffc) == cur_nda) {
desc = iter;
break; break;
}
} }
residue += cur_ubc << dwidth; residue += cur_ubc << dwidth;
......
...@@ -414,14 +414,18 @@ void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first) ...@@ -414,14 +414,18 @@ void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
SET_CH_32(dw, chan->dir, chan->id, ch_control1, SET_CH_32(dw, chan->dir, chan->id, ch_control1,
(DW_EDMA_V0_CCS | DW_EDMA_V0_LLE)); (DW_EDMA_V0_CCS | DW_EDMA_V0_LLE));
/* Linked list */ /* Linked list */
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
SET_CH_64(dw, chan->dir, chan->id, llp.reg, /* llp is not aligned on 64bit -> keep 32bit accesses */
chunk->ll_region.paddr); SET_CH_32(dw, chan->dir, chan->id, llp.lsb,
lower_32_bits(chunk->ll_region.paddr));
SET_CH_32(dw, chan->dir, chan->id, llp.msb,
upper_32_bits(chunk->ll_region.paddr));
#else /* CONFIG_64BIT */ #else /* CONFIG_64BIT */
SET_CH_32(dw, chan->dir, chan->id, llp.lsb, SET_CH_32(dw, chan->dir, chan->id, llp.lsb,
lower_32_bits(chunk->ll_region.paddr)); lower_32_bits(chunk->ll_region.paddr));
SET_CH_32(dw, chan->dir, chan->id, llp.msb, SET_CH_32(dw, chan->dir, chan->id, llp.msb,
upper_32_bits(chunk->ll_region.paddr)); upper_32_bits(chunk->ll_region.paddr));
#endif /* CONFIG_64BIT */ #endif /* CONFIG_64BIT */
} }
/* Doorbell */ /* Doorbell */
......
...@@ -373,7 +373,6 @@ static void idxd_wq_device_reset_cleanup(struct idxd_wq *wq) ...@@ -373,7 +373,6 @@ static void idxd_wq_device_reset_cleanup(struct idxd_wq *wq)
{ {
lockdep_assert_held(&wq->wq_lock); lockdep_assert_held(&wq->wq_lock);
idxd_wq_disable_cleanup(wq);
wq->size = 0; wq->size = 0;
wq->group = NULL; wq->group = NULL;
} }
...@@ -701,14 +700,17 @@ static void idxd_device_wqs_clear_state(struct idxd_device *idxd) ...@@ -701,14 +700,17 @@ static void idxd_device_wqs_clear_state(struct idxd_device *idxd)
if (wq->state == IDXD_WQ_ENABLED) { if (wq->state == IDXD_WQ_ENABLED) {
idxd_wq_disable_cleanup(wq); idxd_wq_disable_cleanup(wq);
idxd_wq_device_reset_cleanup(wq);
wq->state = IDXD_WQ_DISABLED; wq->state = IDXD_WQ_DISABLED;
} }
idxd_wq_device_reset_cleanup(wq);
} }
} }
void idxd_device_clear_state(struct idxd_device *idxd) void idxd_device_clear_state(struct idxd_device *idxd)
{ {
if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
return;
idxd_groups_clear_state(idxd); idxd_groups_clear_state(idxd);
idxd_engines_clear_state(idxd); idxd_engines_clear_state(idxd);
idxd_device_wqs_clear_state(idxd); idxd_device_wqs_clear_state(idxd);
......
...@@ -150,14 +150,15 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie, ...@@ -150,14 +150,15 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie,
*/ */
int idxd_enqcmds(struct idxd_wq *wq, void __iomem *portal, const void *desc) int idxd_enqcmds(struct idxd_wq *wq, void __iomem *portal, const void *desc)
{ {
int rc, retries = 0; unsigned int retries = wq->enqcmds_retries;
int rc;
do { do {
rc = enqcmds(portal, desc); rc = enqcmds(portal, desc);
if (rc == 0) if (rc == 0)
break; break;
cpu_relax(); cpu_relax();
} while (retries++ < wq->enqcmds_retries); } while (retries--);
return rc; return rc;
} }
......
...@@ -905,6 +905,9 @@ static ssize_t wq_max_transfer_size_store(struct device *dev, struct device_attr ...@@ -905,6 +905,9 @@ static ssize_t wq_max_transfer_size_store(struct device *dev, struct device_attr
u64 xfer_size; u64 xfer_size;
int rc; int rc;
if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
return -EPERM;
if (wq->state != IDXD_WQ_DISABLED) if (wq->state != IDXD_WQ_DISABLED)
return -EPERM; return -EPERM;
...@@ -939,6 +942,9 @@ static ssize_t wq_max_batch_size_store(struct device *dev, struct device_attribu ...@@ -939,6 +942,9 @@ static ssize_t wq_max_batch_size_store(struct device *dev, struct device_attribu
u64 batch_size; u64 batch_size;
int rc; int rc;
if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
return -EPERM;
if (wq->state != IDXD_WQ_DISABLED) if (wq->state != IDXD_WQ_DISABLED)
return -EPERM; return -EPERM;
......
...@@ -198,12 +198,12 @@ struct sdma_script_start_addrs { ...@@ -198,12 +198,12 @@ struct sdma_script_start_addrs {
s32 per_2_firi_addr; s32 per_2_firi_addr;
s32 mcu_2_firi_addr; s32 mcu_2_firi_addr;
s32 uart_2_per_addr; s32 uart_2_per_addr;
s32 uart_2_mcu_ram_addr; s32 uart_2_mcu_addr;
s32 per_2_app_addr; s32 per_2_app_addr;
s32 mcu_2_app_addr; s32 mcu_2_app_addr;
s32 per_2_per_addr; s32 per_2_per_addr;
s32 uartsh_2_per_addr; s32 uartsh_2_per_addr;
s32 uartsh_2_mcu_ram_addr; s32 uartsh_2_mcu_addr;
s32 per_2_shp_addr; s32 per_2_shp_addr;
s32 mcu_2_shp_addr; s32 mcu_2_shp_addr;
s32 ata_2_mcu_addr; s32 ata_2_mcu_addr;
...@@ -232,8 +232,8 @@ struct sdma_script_start_addrs { ...@@ -232,8 +232,8 @@ struct sdma_script_start_addrs {
s32 mcu_2_ecspi_addr; s32 mcu_2_ecspi_addr;
s32 mcu_2_sai_addr; s32 mcu_2_sai_addr;
s32 sai_2_mcu_addr; s32 sai_2_mcu_addr;
s32 uart_2_mcu_addr; s32 uart_2_mcu_rom_addr;
s32 uartsh_2_mcu_addr; s32 uartsh_2_mcu_rom_addr;
/* End of v3 array */ /* End of v3 array */
s32 mcu_2_zqspi_addr; s32 mcu_2_zqspi_addr;
/* End of v4 array */ /* End of v4 array */
...@@ -1796,17 +1796,17 @@ static void sdma_add_scripts(struct sdma_engine *sdma, ...@@ -1796,17 +1796,17 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
saddr_arr[i] = addr_arr[i]; saddr_arr[i] = addr_arr[i];
/* /*
* get uart_2_mcu_addr/uartsh_2_mcu_addr rom script specially because * For compatibility with NXP internal legacy kernel before 4.19 which
* they are now replaced by uart_2_mcu_ram_addr/uartsh_2_mcu_ram_addr * is based on uart ram script and mainline kernel based on uart rom
* to be compatible with legacy freescale/nxp sdma firmware, and they * script, both uart ram/rom scripts are present in newer sdma
* are located in the bottom part of sdma_script_start_addrs which are * firmware. Use the rom versions if they are present (V3 or newer).
* beyond the SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1.
*/ */
if (addr->uart_2_mcu_addr) if (sdma->script_number >= SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3) {
sdma->script_addrs->uart_2_mcu_addr = addr->uart_2_mcu_addr; if (addr->uart_2_mcu_rom_addr)
if (addr->uartsh_2_mcu_addr) sdma->script_addrs->uart_2_mcu_addr = addr->uart_2_mcu_rom_addr;
sdma->script_addrs->uartsh_2_mcu_addr = addr->uartsh_2_mcu_addr; if (addr->uartsh_2_mcu_rom_addr)
sdma->script_addrs->uartsh_2_mcu_addr = addr->uartsh_2_mcu_rom_addr;
}
} }
static void sdma_load_firmware(const struct firmware *fw, void *context) static void sdma_load_firmware(const struct firmware *fw, void *context)
...@@ -1885,7 +1885,7 @@ static int sdma_event_remap(struct sdma_engine *sdma) ...@@ -1885,7 +1885,7 @@ static int sdma_event_remap(struct sdma_engine *sdma)
u32 reg, val, shift, num_map, i; u32 reg, val, shift, num_map, i;
int ret = 0; int ret = 0;
if (IS_ERR(np) || IS_ERR(gpr_np)) if (IS_ERR(np) || !gpr_np)
goto out; goto out;
event_remap = of_find_property(np, propname, NULL); event_remap = of_find_property(np, propname, NULL);
...@@ -1933,7 +1933,7 @@ static int sdma_event_remap(struct sdma_engine *sdma) ...@@ -1933,7 +1933,7 @@ static int sdma_event_remap(struct sdma_engine *sdma)
} }
out: out:
if (!IS_ERR(gpr_np)) if (gpr_np)
of_node_put(gpr_np); of_node_put(gpr_np);
return ret; return ret;
......
...@@ -274,7 +274,7 @@ static int mtk_uart_apdma_alloc_chan_resources(struct dma_chan *chan) ...@@ -274,7 +274,7 @@ static int mtk_uart_apdma_alloc_chan_resources(struct dma_chan *chan)
unsigned int status; unsigned int status;
int ret; int ret;
ret = pm_runtime_get_sync(mtkd->ddev.dev); ret = pm_runtime_resume_and_get(mtkd->ddev.dev);
if (ret < 0) { if (ret < 0) {
pm_runtime_put_noidle(chan->device->dev); pm_runtime_put_noidle(chan->device->dev);
return ret; return ret;
...@@ -288,18 +288,21 @@ static int mtk_uart_apdma_alloc_chan_resources(struct dma_chan *chan) ...@@ -288,18 +288,21 @@ static int mtk_uart_apdma_alloc_chan_resources(struct dma_chan *chan)
ret = readx_poll_timeout(readl, c->base + VFF_EN, ret = readx_poll_timeout(readl, c->base + VFF_EN,
status, !status, 10, 100); status, !status, 10, 100);
if (ret) if (ret)
return ret; goto err_pm;
ret = request_irq(c->irq, mtk_uart_apdma_irq_handler, ret = request_irq(c->irq, mtk_uart_apdma_irq_handler,
IRQF_TRIGGER_NONE, KBUILD_MODNAME, chan); IRQF_TRIGGER_NONE, KBUILD_MODNAME, chan);
if (ret < 0) { if (ret < 0) {
dev_err(chan->device->dev, "Can't request dma IRQ\n"); dev_err(chan->device->dev, "Can't request dma IRQ\n");
return -EINVAL; ret = -EINVAL;
goto err_pm;
} }
if (mtkd->support_33bits) if (mtkd->support_33bits)
mtk_uart_apdma_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_CLR_B); mtk_uart_apdma_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_CLR_B);
err_pm:
pm_runtime_put_noidle(mtkd->ddev.dev);
return ret; return ret;
} }
......
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