dmaengine: sh: rz-dmac: handle configs where one address is zero
authorWolfram Sang <wsa+renesas@sang-engineering.com>
Mon, 7 Oct 2024 11:02:01 +0000 (13:02 +0200)
committerVinod Koul <vkoul@kernel.org>
Mon, 14 Oct 2024 17:40:58 +0000 (23:10 +0530)
Configs like the ones coming from the MMC subsystem will have either
'src' or 'dst' zeroed, resulting in an unknown bus width. This will bail
out on the RZ DMA driver because of the sanity check for a valid bus
width. Reorder the code, so that the check will only be applied when the
corresponding address is non-zero.

Fixes: 5000d37042a6 ("dmaengine: sh: Add DMAC driver for RZ/G2L SoC")
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Biju Das <biju.das.jz@bp.renesas.com>
Tested-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Link: https://lore.kernel.org/r/20241007110200.43166-6-wsa+renesas@sang-engineering.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/dma/sh/rz-dmac.c

index 65a27c5..811389f 100644 (file)
@@ -601,22 +601,25 @@ static int rz_dmac_config(struct dma_chan *chan,
        struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
        u32 val;
 
-       channel->src_per_address = config->src_addr;
        channel->dst_per_address = config->dst_addr;
-
-       val = rz_dmac_ds_to_val_mapping(config->dst_addr_width);
-       if (val == CHCFG_DS_INVALID)
-               return -EINVAL;
-
        channel->chcfg &= ~CHCFG_FILL_DDS_MASK;
-       channel->chcfg |= FIELD_PREP(CHCFG_FILL_DDS_MASK, val);
+       if (channel->dst_per_address) {
+               val = rz_dmac_ds_to_val_mapping(config->dst_addr_width);
+               if (val == CHCFG_DS_INVALID)
+                       return -EINVAL;
 
-       val = rz_dmac_ds_to_val_mapping(config->src_addr_width);
-       if (val == CHCFG_DS_INVALID)
-               return -EINVAL;
+               channel->chcfg |= FIELD_PREP(CHCFG_FILL_DDS_MASK, val);
+       }
 
+       channel->src_per_address = config->src_addr;
        channel->chcfg &= ~CHCFG_FILL_SDS_MASK;
-       channel->chcfg |= FIELD_PREP(CHCFG_FILL_SDS_MASK, val);
+       if (channel->src_per_address) {
+               val = rz_dmac_ds_to_val_mapping(config->src_addr_width);
+               if (val == CHCFG_DS_INVALID)
+                       return -EINVAL;
+
+               channel->chcfg |= FIELD_PREP(CHCFG_FILL_SDS_MASK, val);
+       }
 
        return 0;
 }