Skip to content

Commit 89a8567

Browse files
claudiubezneavinodkoul
authored andcommitted
dmaengine: sh: rz-dmac: Move CHCTRL updates under spinlock
Both rz_dmac_disable_hw() and rz_dmac_irq_handle_channel() update the CHCTRL register. To avoid concurrency issues when configuring functionalities exposed by this registers, take the virtual channel lock. All other CHCTRL updates were already protected by the same lock. Previously, rz_dmac_disable_hw() disabled and re-enabled local IRQs, before accessing CHCTRL registers but this does not ensure race-free access. Remove the local IRQ disable/enable code as well. Fixes: 5000d37 ("dmaengine: sh: Add DMAC driver for RZ/G2L SoC") Cc: [email protected] Reviewed-by: Biju Das <[email protected]> Reviewed-by: Frank Li <[email protected]> Signed-off-by: Claudiu Beznea <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent abb863e commit 89a8567

1 file changed

Lines changed: 4 additions & 5 deletions

File tree

drivers/dma/sh/rz-dmac.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -297,13 +297,10 @@ static void rz_dmac_disable_hw(struct rz_dmac_chan *channel)
297297
{
298298
struct dma_chan *chan = &channel->vc.chan;
299299
struct rz_dmac *dmac = to_rz_dmac(chan->device);
300-
unsigned long flags;
301300

302301
dev_dbg(dmac->dev, "%s channel %d\n", __func__, channel->index);
303302

304-
local_irq_save(flags);
305303
rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1);
306-
local_irq_restore(flags);
307304
}
308305

309306
static void rz_dmac_set_dmars_register(struct rz_dmac *dmac, int nr, u32 dmars)
@@ -568,8 +565,8 @@ static int rz_dmac_terminate_all(struct dma_chan *chan)
568565
unsigned int i;
569566
LIST_HEAD(head);
570567

571-
rz_dmac_disable_hw(channel);
572568
spin_lock_irqsave(&channel->vc.lock, flags);
569+
rz_dmac_disable_hw(channel);
573570
for (i = 0; i < DMAC_NR_LMDESC; i++)
574571
lmdesc[i].header = 0;
575572

@@ -706,7 +703,9 @@ static void rz_dmac_irq_handle_channel(struct rz_dmac_chan *channel)
706703
if (chstat & CHSTAT_ER) {
707704
dev_err(dmac->dev, "DMAC err CHSTAT_%d = %08X\n",
708705
channel->index, chstat);
709-
rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1);
706+
707+
scoped_guard(spinlock_irqsave, &channel->vc.lock)
708+
rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1);
710709
goto done;
711710
}
712711

0 commit comments

Comments
 (0)