in bcm-flexrm-mailbox.c [1369:1446]
static void flexrm_shutdown(struct mbox_chan *chan)
{
u32 reqid;
unsigned int timeout;
struct brcm_message *msg;
struct flexrm_ring *ring = chan->con_priv;
/* Disable/inactivate ring */
writel_relaxed(0x0, ring->regs + RING_CONTROL);
/* Set ring flush state */
timeout = 1000; /* timeout of 1s */
writel_relaxed(BIT(CONTROL_FLUSH_SHIFT),
ring->regs + RING_CONTROL);
do {
if (readl_relaxed(ring->regs + RING_FLUSH_DONE) &
FLUSH_DONE_MASK)
break;
mdelay(1);
} while (--timeout);
if (!timeout)
dev_err(ring->mbox->dev,
"setting ring%d flush state timedout\n", ring->num);
/* Clear ring flush state */
timeout = 1000; /* timeout of 1s */
writel_relaxed(0x0, ring->regs + RING_CONTROL);
do {
if (!(readl_relaxed(ring->regs + RING_FLUSH_DONE) &
FLUSH_DONE_MASK))
break;
mdelay(1);
} while (--timeout);
if (!timeout)
dev_err(ring->mbox->dev,
"clearing ring%d flush state timedout\n", ring->num);
/* Abort all in-flight requests */
for (reqid = 0; reqid < RING_MAX_REQ_COUNT; reqid++) {
msg = ring->requests[reqid];
if (!msg)
continue;
/* Release reqid for recycling */
ring->requests[reqid] = NULL;
/* Unmap DMA mappings */
flexrm_dma_unmap(ring->mbox->dev, msg);
/* Give-back message to mailbox client */
msg->error = -EIO;
mbox_chan_received_data(chan, msg);
}
/* Clear requests bitmap */
bitmap_zero(ring->requests_bmap, RING_MAX_REQ_COUNT);
/* Release IRQ */
if (ring->irq_requested) {
irq_update_affinity_hint(ring->irq, NULL);
free_irq(ring->irq, ring);
ring->irq_requested = false;
}
/* Free-up completion descriptor ring */
if (ring->cmpl_base) {
dma_pool_free(ring->mbox->cmpl_pool,
ring->cmpl_base, ring->cmpl_dma_base);
ring->cmpl_base = NULL;
}
/* Free-up BD descriptor ring */
if (ring->bd_base) {
dma_pool_free(ring->mbox->bd_pool,
ring->bd_base, ring->bd_dma_base);
ring->bd_base = NULL;
}
}