Commit fa7279ac authored by Witold Sadowski's avatar Witold Sadowski Committed by Mark Brown

spi: cadence: Add Marvell xSPI interrupt changes

It is possible that before enabling interrupt, interrupt bit will be
set. It might cause improper IRQ handler behaviour. To fix it, clear
interrupt bit before enabling interrupts. That behaviour is specific to
Marvell xSPI implementation.
In addition in Marvell xSPI interrupt must be cleared in two places -
xSPI itself, and Marvell overlay.
Signed-off-by: default avatarWitold Sadowski <wsadowski@marvell.com>
Link: https://patch.msgid.link/20240724154739.582367-6-wsadowski@marvell.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 75128e2a
......@@ -311,6 +311,7 @@ struct cdns_xspi_dev {
const struct cdns_xspi_driver_data *driver_data;
void (*sdma_handler)(struct cdns_xspi_dev *cdns_xspi);
void (*set_interrupts_handler)(struct cdns_xspi_dev *cdns_xspi, bool enabled);
};
static void cdns_xspi_reset_dll(struct cdns_xspi_dev *cdns_xspi)
......@@ -472,6 +473,23 @@ static void cdns_xspi_set_interrupts(struct cdns_xspi_dev *cdns_xspi,
writel(intr_enable, cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG);
}
static void marvell_xspi_set_interrupts(struct cdns_xspi_dev *cdns_xspi,
bool enabled)
{
u32 intr_enable;
u32 irq_status;
irq_status = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG);
writel(irq_status, cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG);
intr_enable = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG);
if (enabled)
intr_enable |= CDNS_XSPI_INTR_MASK;
else
intr_enable &= ~CDNS_XSPI_INTR_MASK;
writel(intr_enable, cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG);
}
static int cdns_xspi_controller_init(struct cdns_xspi_dev *cdns_xspi)
{
u32 ctrl_ver;
......@@ -489,7 +507,7 @@ static int cdns_xspi_controller_init(struct cdns_xspi_dev *cdns_xspi)
ctrl_features = readl(cdns_xspi->iobase + CDNS_XSPI_CTRL_FEATURES_REG);
cdns_xspi->hw_num_banks = FIELD_GET(CDNS_XSPI_NUM_BANKS, ctrl_features);
cdns_xspi_set_interrupts(cdns_xspi, false);
cdns_xspi->set_interrupts_handler(cdns_xspi, false);
return 0;
}
......@@ -604,7 +622,7 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,
writel(FIELD_PREP(CDNS_XSPI_CTRL_WORK_MODE, CDNS_XSPI_WORK_MODE_STIG),
cdns_xspi->iobase + CDNS_XSPI_CTRL_CONFIG_REG);
cdns_xspi_set_interrupts(cdns_xspi, true);
cdns_xspi->set_interrupts_handler(cdns_xspi, true);
cdns_xspi->sdma_error = false;
memset(cmd_regs, 0, sizeof(cmd_regs));
......@@ -636,14 +654,14 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,
wait_for_completion(&cdns_xspi->sdma_complete);
if (cdns_xspi->sdma_error) {
cdns_xspi_set_interrupts(cdns_xspi, false);
cdns_xspi->set_interrupts_handler(cdns_xspi, false);
return -EIO;
}
cdns_xspi->sdma_handler(cdns_xspi);
}
wait_for_completion(&cdns_xspi->cmd_complete);
cdns_xspi_set_interrupts(cdns_xspi, false);
cdns_xspi->set_interrupts_handler(cdns_xspi, false);
cmd_status = cdns_xspi_check_command_status(cdns_xspi);
if (cmd_status)
......@@ -812,9 +830,11 @@ static int cdns_xspi_probe(struct platform_device *pdev)
if (cdns_xspi->driver_data->mrvl_hw_overlay) {
host->mem_ops = &marvell_xspi_mem_ops;
cdns_xspi->sdma_handler = &marvell_xspi_sdma_handle;
cdns_xspi->set_interrupts_handler = &marvell_xspi_set_interrupts;
} else {
host->mem_ops = &cadence_xspi_mem_ops;
cdns_xspi->sdma_handler = &cdns_xspi_sdma_handle;
cdns_xspi->set_interrupts_handler = &cdns_xspi_set_interrupts;
}
host->dev.of_node = pdev->dev.of_node;
host->bus_num = -1;
......
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