Message ID | 1617809456-17693-6-git-send-email-yibin.gong@nxp.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | add ecspi ERR009165 for i.mx6/7 soc family | expand |
Am Mittwoch, dem 07.04.2021 um 23:30 +0800 schrieb Robin Gong: > Add 'fw_loaded' and 'is_ram_script' to check if the script used by channel > is ram script and it's loaded or not, so that could prevent meaningless > following malloc dma descriptor and bd allocate in sdma_transfer_init(), > otherwise memory may be consumed out potentially without free in case > that spi fallback into pio while dma transfer failed by sdma firmware not > ready(next ERR009165 patch depends on sdma RAM scripts/firmware). > > Signed-off-by: Robin Gong <yibin.gong@nxp.com> > Acked-by: Vinod Koul <vkoul@kernel.org> > --- > drivers/dma/imx-sdma.c | 13 +++++++++++++ > 1 file changed, 13 insertions(+) > > diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c > index 1c636d2..78dcfe2 100644 > --- a/drivers/dma/imx-sdma.c > +++ b/drivers/dma/imx-sdma.c > @@ -381,6 +381,7 @@ struct sdma_channel { > enum dma_status status; > struct imx_dma_data data; > struct work_struct terminate_worker; > + bool is_ram_script; > }; > > #define IMX_DMA_SG_LOOP BIT(0) > @@ -444,6 +445,7 @@ struct sdma_engine { > struct sdma_buffer_descriptor *bd0; > /* clock ratio for AHB:SDMA core. 1:1 is 1, 2:1 is 0*/ > bool clk_ratio; > + bool fw_loaded; > }; > > static int sdma_config_write(struct dma_chan *chan, > @@ -899,6 +901,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac, > case IMX_DMATYPE_SSI_DUAL: > per_2_emi = sdma->script_addrs->ssish_2_mcu_addr; > emi_2_per = sdma->script_addrs->mcu_2_ssish_addr; > + sdmac->is_ram_script = true; > break; > case IMX_DMATYPE_SSI_SP: > case IMX_DMATYPE_MMC: > @@ -913,6 +916,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac, > per_2_emi = sdma->script_addrs->asrc_2_mcu_addr; > emi_2_per = sdma->script_addrs->asrc_2_mcu_addr; > per_2_per = sdma->script_addrs->per_2_per_addr; > + sdmac->is_ram_script = true; > break; > case IMX_DMATYPE_ASRC_SP: > per_2_emi = sdma->script_addrs->shp_2_mcu_addr; > @@ -1309,6 +1313,11 @@ static struct sdma_desc *sdma_transfer_init(struct sdma_channel *sdmac, > { > struct sdma_desc *desc; > > + if (!sdmac->sdma->fw_loaded && sdmac->is_ram_script) { > + dev_warn_once(sdmac->sdma->dev, "sdma firmware not ready!\n"); > + goto err_out; > + } > + > desc = kzalloc((sizeof(*desc)), GFP_NOWAIT); > if (!desc) > goto err_out; > @@ -1559,6 +1568,8 @@ static int sdma_config_write(struct dma_chan *chan, > { > struct sdma_channel *sdmac = to_sdma_chan(chan); > > + sdmac->is_ram_script = false; > + While it's working correctly, I find it confusing to have this initialization at this point in the code. Please fold this into sdma_get_pc(), where it gets changed as needed. Other than this small issue, this patch is: Reviewed-by: Lucas Stach <l.stach@pengutronix.de> > if (direction == DMA_DEV_TO_MEM) { > sdmac->per_address = dmaengine_cfg->src_addr; > sdmac->watermark_level = dmaengine_cfg->src_maxburst * > @@ -1738,6 +1749,8 @@ static void sdma_load_firmware(const struct firmware *fw, void *context) > > sdma_add_scripts(sdma, addr); > > + sdma->fw_loaded = true; > + > dev_info(sdma->dev, "loaded firmware %d.%d\n", > header->version_major, > header->version_minor);
On 09/07/21 17:25 Lucas Stach <l.stach@pengutronix.de> wrote: > Am Mittwoch, dem 07.04.2021 um 23:30 +0800 schrieb Robin Gong: > > Add 'fw_loaded' and 'is_ram_script' to check if the script used by > > channel is ram script and it's loaded or not, so that could prevent > > meaningless following malloc dma descriptor and bd allocate in > > sdma_transfer_init(), otherwise memory may be consumed out potentially > > without free in case that spi fallback into pio while dma transfer > > failed by sdma firmware not ready(next ERR009165 patch depends on sdma > RAM scripts/firmware). > > > > Signed-off-by: Robin Gong <yibin.gong@nxp.com> > > Acked-by: Vinod Koul <vkoul@kernel.org> > > --- > > drivers/dma/imx-sdma.c | 13 +++++++++++++ > > 1 file changed, 13 insertions(+) > > > > diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index > > 1c636d2..78dcfe2 100644 > > --- a/drivers/dma/imx-sdma.c > > +++ b/drivers/dma/imx-sdma.c > > @@ -381,6 +381,7 @@ struct sdma_channel { > > enum dma_status status; > > struct imx_dma_data data; > > struct work_struct terminate_worker; > > + bool is_ram_script; > > }; > > > > #define IMX_DMA_SG_LOOP BIT(0) > > @@ -444,6 +445,7 @@ struct sdma_engine { > > struct sdma_buffer_descriptor *bd0; > > /* clock ratio for AHB:SDMA core. 1:1 is 1, 2:1 is 0*/ > > bool clk_ratio; > > + bool fw_loaded; > > }; > > > > static int sdma_config_write(struct dma_chan *chan, @@ -899,6 +901,7 > > @@ static void sdma_get_pc(struct sdma_channel *sdmac, > > case IMX_DMATYPE_SSI_DUAL: > > per_2_emi = sdma->script_addrs->ssish_2_mcu_addr; > > emi_2_per = sdma->script_addrs->mcu_2_ssish_addr; > > + sdmac->is_ram_script = true; > > break; > > case IMX_DMATYPE_SSI_SP: > > case IMX_DMATYPE_MMC: > > @@ -913,6 +916,7 @@ static void sdma_get_pc(struct sdma_channel > *sdmac, > > per_2_emi = sdma->script_addrs->asrc_2_mcu_addr; > > emi_2_per = sdma->script_addrs->asrc_2_mcu_addr; > > per_2_per = sdma->script_addrs->per_2_per_addr; > > + sdmac->is_ram_script = true; > > break; > > case IMX_DMATYPE_ASRC_SP: > > per_2_emi = sdma->script_addrs->shp_2_mcu_addr; > > @@ -1309,6 +1313,11 @@ static struct sdma_desc > > *sdma_transfer_init(struct sdma_channel *sdmac, { > > struct sdma_desc *desc; > > > > + if (!sdmac->sdma->fw_loaded && sdmac->is_ram_script) { > > + dev_warn_once(sdmac->sdma->dev, "sdma firmware not ready!\n"); > > + goto err_out; > > + } > > + > > desc = kzalloc((sizeof(*desc)), GFP_NOWAIT); > > if (!desc) > > goto err_out; > > @@ -1559,6 +1568,8 @@ static int sdma_config_write(struct dma_chan > > *chan, { > > struct sdma_channel *sdmac = to_sdma_chan(chan); > > > > + sdmac->is_ram_script = false; > > + > While it's working correctly, I find it confusing to have this initialization at this > point in the code. Please fold this into sdma_get_pc(), where it gets changed as > needed. Here 'is_ram_script = false' just clear is_ram_script so that the later sdma_get_pc() could set is_ram_script correctly if it's a ram script. Yes, move it to early part of sdma_get_pc also works. > > Other than this small issue, this patch is: > Reviewed-by: Lucas Stach <l.stach@pengutronix.de> > > > if (direction == DMA_DEV_TO_MEM) { > > sdmac->per_address = dmaengine_cfg->src_addr; > > sdmac->watermark_level = dmaengine_cfg->src_maxburst * @@ > -1738,6 > > +1749,8 @@ static void sdma_load_firmware(const struct firmware *fw, > > void *context) > > > > sdma_add_scripts(sdma, addr); > > > > + sdma->fw_loaded = true; > > + > > dev_info(sdma->dev, "loaded firmware %d.%d\n", > > header->version_major, > > header->version_minor); >
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 1c636d2..78dcfe2 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -381,6 +381,7 @@ struct sdma_channel { enum dma_status status; struct imx_dma_data data; struct work_struct terminate_worker; + bool is_ram_script; }; #define IMX_DMA_SG_LOOP BIT(0) @@ -444,6 +445,7 @@ struct sdma_engine { struct sdma_buffer_descriptor *bd0; /* clock ratio for AHB:SDMA core. 1:1 is 1, 2:1 is 0*/ bool clk_ratio; + bool fw_loaded; }; static int sdma_config_write(struct dma_chan *chan, @@ -899,6 +901,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac, case IMX_DMATYPE_SSI_DUAL: per_2_emi = sdma->script_addrs->ssish_2_mcu_addr; emi_2_per = sdma->script_addrs->mcu_2_ssish_addr; + sdmac->is_ram_script = true; break; case IMX_DMATYPE_SSI_SP: case IMX_DMATYPE_MMC: @@ -913,6 +916,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac, per_2_emi = sdma->script_addrs->asrc_2_mcu_addr; emi_2_per = sdma->script_addrs->asrc_2_mcu_addr; per_2_per = sdma->script_addrs->per_2_per_addr; + sdmac->is_ram_script = true; break; case IMX_DMATYPE_ASRC_SP: per_2_emi = sdma->script_addrs->shp_2_mcu_addr; @@ -1309,6 +1313,11 @@ static struct sdma_desc *sdma_transfer_init(struct sdma_channel *sdmac, { struct sdma_desc *desc; + if (!sdmac->sdma->fw_loaded && sdmac->is_ram_script) { + dev_warn_once(sdmac->sdma->dev, "sdma firmware not ready!\n"); + goto err_out; + } + desc = kzalloc((sizeof(*desc)), GFP_NOWAIT); if (!desc) goto err_out; @@ -1559,6 +1568,8 @@ static int sdma_config_write(struct dma_chan *chan, { struct sdma_channel *sdmac = to_sdma_chan(chan); + sdmac->is_ram_script = false; + if (direction == DMA_DEV_TO_MEM) { sdmac->per_address = dmaengine_cfg->src_addr; sdmac->watermark_level = dmaengine_cfg->src_maxburst * @@ -1738,6 +1749,8 @@ static void sdma_load_firmware(const struct firmware *fw, void *context) sdma_add_scripts(sdma, addr); + sdma->fw_loaded = true; + dev_info(sdma->dev, "loaded firmware %d.%d\n", header->version_major, header->version_minor);