Commit 5972eb05 authored by AngeloGioacchino Del Regno's avatar AngeloGioacchino Del Regno Committed by Mark Brown

spi: spi-mt65xx: Use threaded interrupt for non-SPIMEM transfer

In order to avoid blocking for an excessive amount of time, eventually
impacting on system responsiveness, interrupt handlers should finish
executing in as little time as possible.

Use threaded interrupt and move the SPI transfer handling (both
CPU and DMA) for the non-spimem case to an interrupt thread instead.

For SPI-MEM (IPM) controllers, handling is kept in the blocking
interrupt as it simply consists in signalling completion.
Signed-off-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patch.msgid.link/20240726114721.142196-1-angelogioacchino.delregno@collabora.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent dc58d15a
......@@ -743,25 +743,13 @@ static int mtk_spi_setup(struct spi_device *spi)
return 0;
}
static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
static irqreturn_t mtk_spi_interrupt_thread(int irq, void *dev_id)
{
u32 cmd, reg_val, cnt, remainder, len;
struct spi_controller *host = dev_id;
struct mtk_spi *mdata = spi_controller_get_devdata(host);
struct spi_transfer *xfer = mdata->cur_transfer;
reg_val = readl(mdata->base + SPI_STATUS0_REG);
if (reg_val & MTK_SPI_PAUSE_INT_STATUS)
mdata->state = MTK_SPI_PAUSED;
else
mdata->state = MTK_SPI_IDLE;
/* SPI-MEM ops */
if (mdata->use_spimem) {
complete(&mdata->spimem_done);
return IRQ_HANDLED;
}
if (!host->can_dma(host, NULL, xfer)) {
if (xfer->rx_buf) {
cnt = mdata->xfer_len / 4;
......@@ -845,6 +833,27 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
{
struct spi_controller *host = dev_id;
struct mtk_spi *mdata = spi_controller_get_devdata(host);
u32 reg_val;
reg_val = readl(mdata->base + SPI_STATUS0_REG);
if (reg_val & MTK_SPI_PAUSE_INT_STATUS)
mdata->state = MTK_SPI_PAUSED;
else
mdata->state = MTK_SPI_IDLE;
/* SPI-MEM ops */
if (mdata->use_spimem) {
complete(&mdata->spimem_done);
return IRQ_HANDLED;
}
return IRQ_WAKE_THREAD;
}
static int mtk_spi_mem_adjust_op_size(struct spi_mem *mem,
struct spi_mem_op *op)
{
......@@ -1255,8 +1264,9 @@ static int mtk_spi_probe(struct platform_device *pdev)
dev_notice(dev, "SPI dma_set_mask(%d) failed, ret:%d\n",
addr_bits, ret);
ret = devm_request_irq(dev, irq, mtk_spi_interrupt,
IRQF_TRIGGER_NONE, dev_name(dev), host);
ret = devm_request_threaded_irq(dev, irq, mtk_spi_interrupt,
mtk_spi_interrupt_thread,
IRQF_TRIGGER_NONE, dev_name(dev), host);
if (ret)
return dev_err_probe(dev, ret, "failed to register irq\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment