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
This commit is contained in:
@@ -29,6 +29,7 @@ properties:
|
||||
interrupts:
|
||||
description:
|
||||
Interrupt lines for each GPI instance
|
||||
minItems: 1
|
||||
maxItems: 13
|
||||
|
||||
"#dma-cells":
|
||||
|
@@ -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 *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;
|
||||
enum dma_status ret;
|
||||
int residue, retry;
|
||||
@@ -1568,12 +1568,14 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
|
||||
* microblock.
|
||||
*/
|
||||
descs_list = &desc->descs_list;
|
||||
list_for_each_entry_safe(desc, _desc, descs_list, desc_node) {
|
||||
dwidth = at_xdmac_get_dwidth(desc->lld.mbr_cfg);
|
||||
residue -= (desc->lld.mbr_ubc & 0xffffff) << dwidth;
|
||||
if ((desc->lld.mbr_nda & 0xfffffffc) == cur_nda)
|
||||
list_for_each_entry_safe(iter, _desc, descs_list, desc_node) {
|
||||
dwidth = at_xdmac_get_dwidth(iter->lld.mbr_cfg);
|
||||
residue -= (iter->lld.mbr_ubc & 0xffffff) << dwidth;
|
||||
if ((iter->lld.mbr_nda & 0xfffffffc) == cur_nda) {
|
||||
desc = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
residue += cur_ubc << dwidth;
|
||||
|
||||
dma_set_residue(txstate, residue);
|
||||
|
@@ -414,9 +414,13 @@ void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
|
||||
SET_CH_32(dw, chan->dir, chan->id, ch_control1,
|
||||
(DW_EDMA_V0_CCS | DW_EDMA_V0_LLE));
|
||||
/* Linked list */
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
SET_CH_64(dw, chan->dir, chan->id, llp.reg,
|
||||
chunk->ll_region.paddr);
|
||||
/* llp is not aligned on 64bit -> keep 32bit accesses */
|
||||
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 */
|
||||
SET_CH_32(dw, chan->dir, chan->id, llp.lsb,
|
||||
lower_32_bits(chunk->ll_region.paddr));
|
||||
|
@@ -373,7 +373,6 @@ static void idxd_wq_device_reset_cleanup(struct idxd_wq *wq)
|
||||
{
|
||||
lockdep_assert_held(&wq->wq_lock);
|
||||
|
||||
idxd_wq_disable_cleanup(wq);
|
||||
wq->size = 0;
|
||||
wq->group = NULL;
|
||||
}
|
||||
@@ -701,14 +700,17 @@ static void idxd_device_wqs_clear_state(struct idxd_device *idxd)
|
||||
|
||||
if (wq->state == IDXD_WQ_ENABLED) {
|
||||
idxd_wq_disable_cleanup(wq);
|
||||
idxd_wq_device_reset_cleanup(wq);
|
||||
wq->state = IDXD_WQ_DISABLED;
|
||||
}
|
||||
idxd_wq_device_reset_cleanup(wq);
|
||||
}
|
||||
}
|
||||
|
||||
void idxd_device_clear_state(struct idxd_device *idxd)
|
||||
{
|
||||
if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
|
||||
return;
|
||||
|
||||
idxd_groups_clear_state(idxd);
|
||||
idxd_engines_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,
|
||||
*/
|
||||
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 {
|
||||
rc = enqcmds(portal, desc);
|
||||
if (rc == 0)
|
||||
break;
|
||||
cpu_relax();
|
||||
} while (retries++ < wq->enqcmds_retries);
|
||||
} while (retries--);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@@ -905,6 +905,9 @@ static ssize_t wq_max_transfer_size_store(struct device *dev, struct device_attr
|
||||
u64 xfer_size;
|
||||
int rc;
|
||||
|
||||
if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
|
||||
return -EPERM;
|
||||
|
||||
if (wq->state != IDXD_WQ_DISABLED)
|
||||
return -EPERM;
|
||||
|
||||
@@ -939,6 +942,9 @@ static ssize_t wq_max_batch_size_store(struct device *dev, struct device_attribu
|
||||
u64 batch_size;
|
||||
int rc;
|
||||
|
||||
if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
|
||||
return -EPERM;
|
||||
|
||||
if (wq->state != IDXD_WQ_DISABLED)
|
||||
return -EPERM;
|
||||
|
||||
|
@@ -198,12 +198,12 @@ struct sdma_script_start_addrs {
|
||||
s32 per_2_firi_addr;
|
||||
s32 mcu_2_firi_addr;
|
||||
s32 uart_2_per_addr;
|
||||
s32 uart_2_mcu_ram_addr;
|
||||
s32 uart_2_mcu_addr;
|
||||
s32 per_2_app_addr;
|
||||
s32 mcu_2_app_addr;
|
||||
s32 per_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 mcu_2_shp_addr;
|
||||
s32 ata_2_mcu_addr;
|
||||
@@ -232,8 +232,8 @@ struct sdma_script_start_addrs {
|
||||
s32 mcu_2_ecspi_addr;
|
||||
s32 mcu_2_sai_addr;
|
||||
s32 sai_2_mcu_addr;
|
||||
s32 uart_2_mcu_addr;
|
||||
s32 uartsh_2_mcu_addr;
|
||||
s32 uart_2_mcu_rom_addr;
|
||||
s32 uartsh_2_mcu_rom_addr;
|
||||
/* End of v3 array */
|
||||
s32 mcu_2_zqspi_addr;
|
||||
/* End of v4 array */
|
||||
@@ -1796,17 +1796,17 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
|
||||
saddr_arr[i] = addr_arr[i];
|
||||
|
||||
/*
|
||||
* get uart_2_mcu_addr/uartsh_2_mcu_addr rom script specially because
|
||||
* they are now replaced by uart_2_mcu_ram_addr/uartsh_2_mcu_ram_addr
|
||||
* to be compatible with legacy freescale/nxp sdma firmware, and they
|
||||
* are located in the bottom part of sdma_script_start_addrs which are
|
||||
* beyond the SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1.
|
||||
* For compatibility with NXP internal legacy kernel before 4.19 which
|
||||
* is based on uart ram script and mainline kernel based on uart rom
|
||||
* script, both uart ram/rom scripts are present in newer sdma
|
||||
* firmware. Use the rom versions if they are present (V3 or newer).
|
||||
*/
|
||||
if (addr->uart_2_mcu_addr)
|
||||
sdma->script_addrs->uart_2_mcu_addr = addr->uart_2_mcu_addr;
|
||||
if (addr->uartsh_2_mcu_addr)
|
||||
sdma->script_addrs->uartsh_2_mcu_addr = addr->uartsh_2_mcu_addr;
|
||||
|
||||
if (sdma->script_number >= SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3) {
|
||||
if (addr->uart_2_mcu_rom_addr)
|
||||
sdma->script_addrs->uart_2_mcu_addr = addr->uart_2_mcu_rom_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)
|
||||
@@ -1885,7 +1885,7 @@ static int sdma_event_remap(struct sdma_engine *sdma)
|
||||
u32 reg, val, shift, num_map, i;
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ERR(np) || IS_ERR(gpr_np))
|
||||
if (IS_ERR(np) || !gpr_np)
|
||||
goto out;
|
||||
|
||||
event_remap = of_find_property(np, propname, NULL);
|
||||
@@ -1933,7 +1933,7 @@ static int sdma_event_remap(struct sdma_engine *sdma)
|
||||
}
|
||||
|
||||
out:
|
||||
if (!IS_ERR(gpr_np))
|
||||
if (gpr_np)
|
||||
of_node_put(gpr_np);
|
||||
|
||||
return ret;
|
||||
|
@@ -274,7 +274,7 @@ static int mtk_uart_apdma_alloc_chan_resources(struct dma_chan *chan)
|
||||
unsigned int status;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(mtkd->ddev.dev);
|
||||
ret = pm_runtime_resume_and_get(mtkd->ddev.dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(chan->device->dev);
|
||||
return ret;
|
||||
@@ -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,
|
||||
status, !status, 10, 100);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_pm;
|
||||
|
||||
ret = request_irq(c->irq, mtk_uart_apdma_irq_handler,
|
||||
IRQF_TRIGGER_NONE, KBUILD_MODNAME, chan);
|
||||
if (ret < 0) {
|
||||
dev_err(chan->device->dev, "Can't request dma IRQ\n");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto err_pm;
|
||||
}
|
||||
|
||||
if (mtkd->support_33bits)
|
||||
mtk_uart_apdma_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_CLR_B);
|
||||
|
||||
err_pm:
|
||||
pm_runtime_put_noidle(mtkd->ddev.dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user